From 2d213f757d5305f4f6b585ac65bd960cb74b0b84 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 Jan 2023 20:46:56 +0000 Subject: [PATCH 01/76] Make ExitStatus an inhabited type on all platforms Even where actually running processes is not supported. Needed for the next commit. The manual trait implementations now belong on ExitStatusError, which still can't exist. --- library/std/src/sys/unsupported/process.rs | 61 +++++++++++----------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs index a494f2d6b4c1..d8259ce6e549 100644 --- a/library/std/src/sys/unsupported/process.rs +++ b/library/std/src/sys/unsupported/process.rs @@ -99,58 +99,59 @@ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -pub struct ExitStatus(!); +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[non_exhaustive] +pub struct ExitStatus(); impl ExitStatus { pub fn exit_ok(&self) -> Result<(), ExitStatusError> { - self.0 + Ok(()) } pub fn code(&self) -> Option { - self.0 - } -} - -impl Clone for ExitStatus { - fn clone(&self) -> ExitStatus { - self.0 - } -} - -impl Copy for ExitStatus {} - -impl PartialEq for ExitStatus { - fn eq(&self, _other: &ExitStatus) -> bool { - self.0 - } -} - -impl Eq for ExitStatus {} - -impl fmt::Debug for ExitStatus { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0 + Some(0) } } impl fmt::Display for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "") + } +} + +pub struct ExitStatusError(!); + +impl Clone for ExitStatusError { + fn clone(&self) -> ExitStatusError { + self.0 + } +} + +impl Copy for ExitStatusError {} + +impl PartialEq for ExitStatusError { + fn eq(&self, _other: &ExitStatusError) -> bool { + self.0 + } +} + +impl Eq for ExitStatusError {} + +impl fmt::Debug for ExitStatusError { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0 } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatusError(ExitStatus); - impl Into for ExitStatusError { fn into(self) -> ExitStatus { - self.0.0 + self.0 } } impl ExitStatusError { pub fn code(self) -> Option { - self.0.0 + self.0 } } From 23a5c0a66374f7372ce84d97028697471b108887 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 11 Jul 2023 19:51:51 +0000 Subject: [PATCH 02/76] Mention style for new syntax in tracking issue template --- .github/ISSUE_TEMPLATE/tracking_issue.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md index 006596050717..5f17f30b3b0b 100644 --- a/.github/ISSUE_TEMPLATE/tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/tracking_issue.md @@ -39,10 +39,13 @@ for larger features an implementation could be broken up into multiple PRs. - [ ] Implement the RFC (cc @rust-lang/XXX -- can anyone write up mentoring instructions?) - [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) +- [ ] Formatting for new syntax has been added to the [Style Guide] ([nightly-style-procedure]) - [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [stabilization-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr [doc-guide]: https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#documentation-prs +[nightly-style-procedure]: https://github.com/rust-lang/style-team/blob/master/nightly-style-procedure.md +[Style Guide]: https://github.com/rust-lang/rust/tree/master/src/doc/style-guide ### Unresolved Questions $DIR/arbitrary_self_type_mut_difference.rs:11:18 | LL | Pin::new(&S).x(); | ^ help: there is a method with a similar name: `y` | note: method is available for `Pin<&mut S>` --> $DIR/arbitrary_self_type_mut_difference.rs:6:5 | LL | fn x(self: Pin<&mut Self>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ``` Related to #57994, as one of the presented cases can lead to code like this. --- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 45 +++++++++++++++---- .../arbitrary_self_type_mut_difference.rs | 13 ++++++ .../arbitrary_self_type_mut_difference.stderr | 27 +++++++++++ 4 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 tests/ui/self/arbitrary_self_type_mut_difference.rs create mode 100644 tests/ui/self/arbitrary_self_type_mut_difference.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 8f5737dd4ad1..9de4c28190ee 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1293,7 +1293,7 @@ fn check_method_call( segment.ident, SelfSource::MethodCall(rcvr), error, - Some((rcvr, args)), + Some((rcvr, args, expr)), expected, false, ) { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index f6c07931023e..9418624debc2 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -115,7 +115,7 @@ pub fn report_method_error( item_name: Ident, source: SelfSource<'tcx>, error: MethodError<'tcx>, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, expected: Expectation<'tcx>, trait_missing_method: bool, ) -> Option> { @@ -257,7 +257,7 @@ pub fn report_method_error( fn suggest_missing_writer( &self, rcvr_ty: Ty<'tcx>, - args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]), + args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>), ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty); let mut err = @@ -282,7 +282,7 @@ pub fn report_no_match_method_error( rcvr_ty: Ty<'tcx>, item_name: Ident, source: SelfSource<'tcx>, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, sugg_span: Span, no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, @@ -953,6 +953,33 @@ trait bound{s}", unsatisfied_bounds = true; } + } else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some((rcvr, _, expr)) = args { + // This is useful for methods on arbitrary self types that might have a simple + // mutability difference, like calling a method on `Pin<&mut Self>` that is on + // `Pin<&Self>`. + if targs.len() == 1 { + let mut item_segment = hir::PathSegment::invalid(); + item_segment.ident = item_name; + for t in [Ty::new_mut_ref, Ty::new_imm_ref, |_, _, t| t] { + let new_args = tcx.mk_args_from_iter( + targs + .iter() + .map(|arg| match arg.as_type() { + Some(ty) => ty::GenericArg::from( + t(tcx, tcx.lifetimes.re_erased, ty.peel_refs()), + ), + _ => arg, + }) + ); + let rcvr_ty = Ty::new_adt(tcx, *def, new_args); + if let Ok(method) = self.lookup_method_for_diagnostic(rcvr_ty, &item_segment, span, expr, rcvr) { + err.span_note( + tcx.def_span(method.def_id), + format!("{item_kind} is available for `{rcvr_ty}`"), + ); + } + } + } } let label_span_not_found = |err: &mut Diagnostic| { @@ -1111,7 +1138,7 @@ trait bound{s}", span, rcvr_ty, item_name, - args.map(|(_, args)| args.len() + 1), + args.map(|(_, args, _)| args.len() + 1), source, no_match_data.out_of_scope_traits.clone(), &unsatisfied_predicates, @@ -1192,7 +1219,7 @@ fn note_candidates_on_method_error( &self, rcvr_ty: Ty<'tcx>, item_name: Ident, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, span: Span, err: &mut Diagnostic, sources: &mut Vec, @@ -1343,7 +1370,7 @@ fn suggest_associated_call_syntax( rcvr_ty: Ty<'tcx>, source: SelfSource<'tcx>, item_name: Ident, - args: Option<(&hir::Expr<'tcx>, &[hir::Expr<'tcx>])>, + args: Option<(&hir::Expr<'tcx>, &[hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, sugg_span: Span, ) { let mut has_unsuggestable_args = false; @@ -1415,7 +1442,7 @@ fn suggest_associated_call_syntax( None }; let mut applicability = Applicability::MachineApplicable; - let args = if let Some((receiver, args)) = args { + let args = if let Some((receiver, args, _)) = args { // The first arg is the same kind as the receiver let explicit_args = if first_arg.is_some() { std::iter::once(receiver).chain(args.iter()).collect::>() @@ -2995,7 +3022,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec { fn print_disambiguation_help<'tcx>( item_name: Ident, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, + args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, err: &mut Diagnostic, trait_name: String, rcvr_ty: Ty<'_>, @@ -3007,7 +3034,7 @@ fn print_disambiguation_help<'tcx>( fn_has_self_parameter: bool, ) { let mut applicability = Applicability::MachineApplicable; - let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) { + let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args, _))) = (kind, args) { let args = format!( "({}{})", rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()), diff --git a/tests/ui/self/arbitrary_self_type_mut_difference.rs b/tests/ui/self/arbitrary_self_type_mut_difference.rs new file mode 100644 index 000000000000..e75c00ae956b --- /dev/null +++ b/tests/ui/self/arbitrary_self_type_mut_difference.rs @@ -0,0 +1,13 @@ +// Related to #57994. +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) {} //~ NOTE method is available for `Pin<&mut S>` + fn y(self: Pin<&Self>) {} //~ NOTE method is available for `Pin<&S>` +} + +fn main() { + Pin::new(&S).x(); //~ ERROR no method named `x` found for struct `Pin<&S>` in the current scope + Pin::new(&mut S).y(); //~ ERROR no method named `y` found for struct `Pin<&mut S>` in the current scope +} diff --git a/tests/ui/self/arbitrary_self_type_mut_difference.stderr b/tests/ui/self/arbitrary_self_type_mut_difference.stderr new file mode 100644 index 000000000000..a56d58694aa3 --- /dev/null +++ b/tests/ui/self/arbitrary_self_type_mut_difference.stderr @@ -0,0 +1,27 @@ +error[E0599]: no method named `x` found for struct `Pin<&S>` in the current scope + --> $DIR/arbitrary_self_type_mut_difference.rs:11:18 + | +LL | Pin::new(&S).x(); + | ^ help: there is a method with a similar name: `y` + | +note: method is available for `Pin<&mut S>` + --> $DIR/arbitrary_self_type_mut_difference.rs:6:5 + | +LL | fn x(self: Pin<&mut Self>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `y` found for struct `Pin<&mut S>` in the current scope + --> $DIR/arbitrary_self_type_mut_difference.rs:12:22 + | +LL | Pin::new(&mut S).y(); + | ^ help: there is a method with a similar name: `x` + | +note: method is available for `Pin<&S>` + --> $DIR/arbitrary_self_type_mut_difference.rs:7:5 + | +LL | fn y(self: Pin<&Self>) {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. From 5881e5f88d9245ef9259ca600b32af80d5972a7f Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Fri, 4 Aug 2023 12:11:34 -0400 Subject: [PATCH 22/76] Update tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs fix to test as proposed by wesleywiser Co-authored-by: Wesley Wiser --- tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs index 087c9a2f0652..de2ca496cafb 100644 --- a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs +++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs @@ -1,4 +1,4 @@ -// run-pass +// build-pass // aux-build:exports_no_mangle.rs #![crate_type = "proc-macro"] From f7486ffd1888172b0f6453274c4caf6f755d330f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 4 Aug 2023 16:17:39 +0000 Subject: [PATCH 23/76] Add tests for #57994 --- ...lf_types_needing_box_or_arc_wrapping.fixed | 17 ++++++++ ..._self_types_needing_box_or_arc_wrapping.rs | 17 ++++++++ ...f_types_needing_box_or_arc_wrapping.stderr | 43 +++++++++++++++++++ ...arbitrary_self_types_needing_mut_pin.fixed | 12 ++++++ .../arbitrary_self_types_needing_mut_pin.rs | 12 ++++++ ...rbitrary_self_types_needing_mut_pin.stderr | 20 +++++++++ ...arbitrary_self_types_pin_needing_borrow.rs | 13 ++++++ ...trary_self_types_pin_needing_borrow.stderr | 33 ++++++++++++++ 8 files changed, 167 insertions(+) create mode 100644 tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed create mode 100644 tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs create mode 100644 tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr create mode 100644 tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed create mode 100644 tests/ui/self/arbitrary_self_types_needing_mut_pin.rs create mode 100644 tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr create mode 100644 tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs create mode 100644 tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed new file mode 100644 index 000000000000..6a94b85b9ba5 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.fixed @@ -0,0 +1,17 @@ +// run-rustfix +#![allow(dead_code)] +mod first { + trait Foo { fn m(self: Box); } + fn foo(a: T) { + Box::new(a).m(); //~ ERROR no method named `m` found + } +} +mod second { + use std::sync::Arc; + trait Bar { fn m(self: Arc); } + fn bar(b: impl Bar) { + Arc::new(b).m(); //~ ERROR no method named `m` found + } +} + +fn main() {} diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs new file mode 100644 index 000000000000..fa480b1f72b2 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.rs @@ -0,0 +1,17 @@ +// run-rustfix +#![allow(dead_code)] +mod first { + trait Foo { fn m(self: Box); } + fn foo(a: T) { + a.m(); //~ ERROR no method named `m` found + } +} +mod second { + use std::sync::Arc; + trait Bar { fn m(self: Arc); } + fn bar(b: impl Bar) { + b.m(); //~ ERROR no method named `m` found + } +} + +fn main() {} diff --git a/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr new file mode 100644 index 000000000000..2ab634ad3e87 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_box_or_arc_wrapping.stderr @@ -0,0 +1,43 @@ +error[E0599]: no method named `m` found for type parameter `T` in the current scope + --> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:6:11 + | +LL | trait Foo { fn m(self: Box); } + | - --------- the method might not be found because of this arbitrary self type + | | + | the method is available for `Box` here +LL | fn foo(a: T) { + | - method `m` not found for this type parameter +LL | a.m(); + | ^ method not found in `T` +... +LL | trait Bar { fn m(self: Arc); } + | --------- the method might not be found because of this arbitrary self type + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Box::new(a).m(); + | +++++++++ + + +error[E0599]: no method named `m` found for type parameter `impl Bar` in the current scope + --> $DIR/arbitrary_self_types_needing_box_or_arc_wrapping.rs:13:11 + | +LL | trait Foo { fn m(self: Box); } + | --------- the method might not be found because of this arbitrary self type +... +LL | trait Bar { fn m(self: Arc); } + | - --------- the method might not be found because of this arbitrary self type + | | + | the method is available for `Arc` here +LL | fn bar(b: impl Bar) { + | -------- method `m` not found for this type parameter +LL | b.m(); + | ^ method not found in `impl Bar` + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Arc::new(b).m(); + | +++++++++ + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed new file mode 100644 index 000000000000..ccd65ff40913 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.fixed @@ -0,0 +1,12 @@ +// run-rustfix +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) { + } +} + +fn main() { + Pin::new(&mut S).x(); //~ ERROR no method named `x` found +} diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs b/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs new file mode 100644 index 000000000000..d15676a623d3 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.rs @@ -0,0 +1,12 @@ +// run-rustfix +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) { + } +} + +fn main() { + S.x(); //~ ERROR no method named `x` found +} diff --git a/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr new file mode 100644 index 000000000000..f34ce4dce490 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_needing_mut_pin.stderr @@ -0,0 +1,20 @@ +error[E0599]: no method named `x` found for struct `S` in the current scope + --> $DIR/arbitrary_self_types_needing_mut_pin.rs:11:7 + | +LL | struct S; + | -------- method `x` not found for this struct +... +LL | fn x(self: Pin<&mut Self>) { + | - the method is available for `Pin<&mut S>` here +... +LL | S.x(); + | ^ method not found in `S` + | +help: consider wrapping the receiver expression with the appropriate type + | +LL | Pin::new(&mut S).x(); + | +++++++++++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs new file mode 100644 index 000000000000..d877dbe60754 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.rs @@ -0,0 +1,13 @@ +use std::pin::Pin; +struct S; + +impl S { + fn x(self: Pin<&mut Self>) { + } +} + +fn main() { + Pin::new(S).x(); + //~^ ERROR the trait bound `S: Deref` is not satisfied + //~| ERROR no method named `x` found for struct `Pin` in the current scope +} diff --git a/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr new file mode 100644 index 000000000000..ec985b254b34 --- /dev/null +++ b/tests/ui/self/arbitrary_self_types_pin_needing_borrow.stderr @@ -0,0 +1,33 @@ +error[E0277]: the trait bound `S: Deref` is not satisfied + --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:14 + | +LL | Pin::new(S).x(); + | -------- ^ the trait `Deref` is not implemented for `S` + | | + | required by a bound introduced by this call + | +note: required by a bound in `Pin::

::new` + --> $SRC_DIR/core/src/pin.rs:LL:COL +help: consider borrowing here + | +LL | Pin::new(&S).x(); + | + +LL | Pin::new(&mut S).x(); + | ++++ + +error[E0599]: no method named `x` found for struct `Pin` in the current scope + --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:10:17 + | +LL | Pin::new(S).x(); + | ^ method not found in `Pin` + | +note: method is available for `Pin<&mut S>` + --> $DIR/arbitrary_self_types_pin_needing_borrow.rs:5:5 + | +LL | fn x(self: Pin<&mut Self>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. From 80f2b018c65f1679f92b2764478e420b123c993a Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 4 Aug 2023 13:28:04 +0800 Subject: [PATCH 24/76] Fix ICE failed to get layout for ReferencesError --- src/common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.rs b/src/common.rs index 67ea20112fe3..3081dcfa2b7a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -477,7 +477,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let layout::LayoutError::SizeOverflow(_) = err { + if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { self.0.sess.span_fatal(span, err.to_string()) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) From 0b16456efa95060beedb0e2fe1ed0aa5fa1b7e02 Mon Sep 17 00:00:00 2001 From: Meysam Azad Date: Fri, 4 Aug 2023 20:08:22 +0700 Subject: [PATCH 25/76] =?UTF-8?q?fix(bootstrap):=20rename=20exclude=20flag?= =?UTF-8?q?=20to=20skip=20=F0=9F=90=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 +- src/bootstrap/builder.rs | 10 +-- src/bootstrap/builder/tests.rs | 4 +- src/bootstrap/config.rs | 4 +- src/bootstrap/doc.rs | 2 +- src/bootstrap/flags.rs | 7 +- src/bootstrap/mk/Makefile.in | 4 +- src/bootstrap/test.rs | 6 +- src/ci/docker/host-x86_64/i686-gnu/Dockerfile | 10 +-- src/ci/docker/host-x86_64/wasm32/Dockerfile | 2 +- .../host-x86_64/x86_64-gnu-llvm-15/script.sh | 4 +- src/ci/github-actions/ci.yml | 4 +- src/etc/completions/x.py.fish | 16 +++- src/etc/completions/x.py.ps1 | 14 ++++ src/etc/completions/x.py.sh | 84 +++++++++++++++---- src/tools/opt-dist/src/main.rs | 2 +- src/tools/opt-dist/src/tests.rs | 2 +- 17 files changed, 130 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4121e392ae8c..6ff0f5e2736f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -336,7 +336,7 @@ jobs: os: macos-13 - name: x86_64-apple-1 env: - SCRIPT: "./x.py --stage 2 test --exclude tests/ui --exclude tests/rustdoc --exclude tests/run-make-fulldeps" + SCRIPT: "./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps" RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false" RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.8 diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d369e8eeda92..b36661928533 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -317,19 +317,17 @@ fn maybe_run(&self, builder: &Builder<'_>, pathsets: Vec) { } fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool { - if builder.config.exclude.iter().any(|e| pathset.has(&e, builder.kind)) { + if builder.config.skip.iter().any(|e| pathset.has(&e, builder.kind)) { if !matches!(builder.config.dry_run, DryRun::SelfCheck) { println!("Skipping {pathset:?} because it is excluded"); } return true; } - if !builder.config.exclude.is_empty() - && !matches!(builder.config.dry_run, DryRun::SelfCheck) - { + if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) { builder.verbose(&format!( "{:?} not skipped for {:?} -- not in {:?}", - pathset, self.name, builder.config.exclude + pathset, self.name, builder.config.skip )); } false @@ -2129,7 +2127,7 @@ pub(crate) fn ensure_if_default>>( let desc = StepDescription::from::(kind); let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind)); - // Avoid running steps contained in --exclude + // Avoid running steps contained in --skip for pathset in &should_run.paths { if desc.is_excluded(self, pathset) { return None; diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 65b8f7fd3b7e..d9540946c2ea 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -119,7 +119,7 @@ fn test_intersection() { #[test] fn test_exclude() { let mut config = configure("test", &["A"], &["A"]); - config.exclude = vec!["src/tools/tidy".into()]; + config.skip = vec!["src/tools/tidy".into()]; let cache = run_build(&[], config); // Ensure we have really excluded tidy @@ -137,7 +137,7 @@ fn test_exclude_kind() { // Ensure our test is valid, and `test::Rustc` would be run without the exclude. assert!(run_build(&[], config.clone()).contains::()); // Ensure tests for rustc are skipped. - config.exclude = vec![path.clone()]; + config.skip = vec![path.clone()]; assert!(!run_build(&[], config.clone()).contains::()); // Ensure builds for rustc are not skipped. assert!(run_build(&[], config).contains::()); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index da60166b84d3..cdb34f991648 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -130,7 +130,7 @@ pub struct Config { pub sanitizers: bool, pub profiler: bool, pub omit_git_hash: bool, - pub exclude: Vec, + pub skip: Vec, pub include_default_paths: bool, pub rustc_error_format: Option, pub json_output: bool, @@ -1112,7 +1112,7 @@ fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfig) -> Confi // Set flags. config.paths = std::mem::take(&mut flags.paths); - config.exclude = flags.exclude; + config.skip = flags.skip.into_iter().chain(flags.exclude).collect(); config.include_default_paths = flags.include_default_paths; config.rustc_error_format = flags.rustc_error_format; config.json_output = flags.json_output; diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 9cb3546ba0a5..505f06ed12d7 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -570,7 +570,7 @@ fn doc_std( if builder.no_std(target) == Some(true) { panic!( "building std documentation for no_std target {target} is not supported\n\ - Set `docs = false` in the config to disable documentation, or pass `--exclude doc::library`." + Set `docs = false` in the config to disable documentation, or pass `--skip library`." ); } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index a1e0a4407299..f5022b74fb2a 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -68,7 +68,10 @@ pub struct Flags { #[arg(global(true), long, value_name = "PATH")] /// build paths to exclude - pub exclude: Vec, + pub exclude: Vec, // keeping for client backward compatibility + #[arg(global(true), long, value_name = "PATH")] + /// build paths to skip + pub skip: Vec, #[arg(global(true), long)] /// include default paths in addition to the provided ones pub include_default_paths: bool, @@ -318,7 +321,7 @@ pub enum Subcommand { no_fail_fast: bool, #[arg(long, value_name = "SUBSTRING")] /// skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times - skip: Vec, + skip: Vec, #[arg(long, value_name = "ARGS", allow_hyphen_values(true))] /// extra arguments to be passed for the test tool being used /// (e.g. libtest, compiletest or rustdoc) diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 9476137968b2..a9865e262fec 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -63,7 +63,7 @@ prepare: ci-msvc-py: $(Q)$(CFG_SRC_DIR)/x.py test --stage 2 tidy ci-msvc-ps1: - $(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 --exclude tidy + $(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 --skip tidy ci-msvc: ci-msvc-py ci-msvc-ps1 ## MingW native builders @@ -72,7 +72,7 @@ ci-msvc: ci-msvc-py ci-msvc-ps1 ci-mingw-x: $(Q)$(CFG_SRC_DIR)/x test --stage 2 tidy ci-mingw-bootstrap: - $(Q)$(BOOTSTRAP) test --stage 2 --exclude tidy + $(Q)$(BOOTSTRAP) test --stage 2 --skip tidy ci-mingw: ci-mingw-x ci-mingw-bootstrap .PHONY: dist diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 4bfb16928f1d..3462700759a2 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -122,7 +122,7 @@ fn run(self, builder: &Builder<'_>) { if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() { panic!( "Linkcheck currently does not support builds with different hosts and targets. -You can skip linkcheck with --exclude src/tools/linkchecker" +You can skip linkcheck with --skip src/tools/linkchecker" ); } @@ -1104,7 +1104,7 @@ fn run(self, builder: &Builder<'_>) { error: no `rustfmt` binary found in {PATH} info: `rust.channel` is currently set to \"{CHAN}\" help: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `config.toml` file -help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` to `x.py test`", +help: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to `x.py test`", PATH = inferred_rustfmt_dir.display(), CHAN = builder.config.channel, ); @@ -1650,7 +1650,7 @@ fn run(self, builder: &Builder<'_>) { cmd.arg("--run-clang-based-tests-with").arg(clang_exe); } - for exclude in &builder.config.exclude { + for exclude in &builder.config.skip { cmd.arg("--skip"); cmd.arg(&exclude); } diff --git a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile index b5abf6564a63..61811c41904c 100644 --- a/src/ci/docker/host-x86_64/i686-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/i686-gnu/Dockerfile @@ -24,10 +24,10 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu -# Exclude some tests that are unlikely to be platform specific, to speed up +# Skip some tests that are unlikely to be platform specific, to speed up # this slow job. ENV SCRIPT python3 ../x.py --stage 2 test \ - --exclude src/bootstrap \ - --exclude tests/rustdoc-js \ - --exclude src/tools/error_index_generator \ - --exclude src/tools/linkchecker + --skip src/bootstrap \ + --skip tests/rustdoc-js \ + --skip src/tools/error_index_generator \ + --skip src/tools/linkchecker diff --git a/src/ci/docker/host-x86_64/wasm32/Dockerfile b/src/ci/docker/host-x86_64/wasm32/Dockerfile index 24a1ccb7fc2c..02b4664eb557 100644 --- a/src/ci/docker/host-x86_64/wasm32/Dockerfile +++ b/src/ci/docker/host-x86_64/wasm32/Dockerfile @@ -59,4 +59,4 @@ RUN chown 10719 -R /emsdk-portable/ # Exclude library/alloc due to OOM in benches. ENV SCRIPT python3 ../x.py test --stage 2 --host='' --target $TARGETS \ - --exclude library/alloc + --skip library/alloc diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh index 0120fd982988..390304b6ad5a 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/script.sh @@ -4,7 +4,7 @@ set -ex # Only run the stage 1 tests on merges, not on PR CI jobs. if [[ -z "${PR_CI_JOB}" ]]; then -../x.py --stage 1 test --exclude src/tools/tidy && \ +../x.py --stage 1 test --skip src/tools/tidy && \ # Run the `mir-opt` tests again but this time for a 32-bit target. # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have # both 32-bit and 64-bit outputs updated by the PR author, before @@ -16,7 +16,7 @@ if [[ -z "${PR_CI_JOB}" ]]; then fi # NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux. -../x.py --stage 2 test --exclude src/tools/tidy && \ +../x.py --stage 2 test --skip src/tools/tidy && \ # Run the `mir-opt` tests again but this time for a 32-bit target. # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have # both 32-bit and 64-bit outputs updated by the PR author, before diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 6efc1980e60e..f900a5eb5767 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -14,7 +14,6 @@ # step CI will fail. --- - ############################### # YAML Anchors Definition # ############################### @@ -30,7 +29,6 @@ # The expand-yaml-anchors tool will automatically remove this block from the # output YAML file. x--expand-yaml-anchors--remove: - - &shared-ci-variables CI_JOB_NAME: ${{ matrix.name }} CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse @@ -520,7 +518,7 @@ jobs: - name: x86_64-apple-1 env: &env-x86_64-apple-tests - SCRIPT: ./x.py --stage 2 test --exclude tests/ui --exclude tests/rustdoc --exclude tests/run-make-fulldeps + SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.8 diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 238b5aa4d5ad..1dc176a01281 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -4,6 +4,7 @@ complete -c x.py -n "__fish_use_subcommand" -l build -d 'build target of the sta complete -c x.py -n "__fish_use_subcommand" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_use_subcommand" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_use_subcommand" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_use_subcommand" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_use_subcommand" -l rustc-error-format -r -f complete -c x.py -n "__fish_use_subcommand" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_use_subcommand" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -47,6 +48,7 @@ complete -c x.py -n "__fish_seen_subcommand_from build" -l build -d 'build targe complete -c x.py -n "__fish_seen_subcommand_from build" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from build" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from build" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from build" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from build" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from build" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from build" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -76,6 +78,7 @@ complete -c x.py -n "__fish_seen_subcommand_from check" -l build -d 'build targe complete -c x.py -n "__fish_seen_subcommand_from check" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from check" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from check" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from check" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from check" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from check" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from check" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -110,6 +113,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clippy" -l build -d 'build targ complete -c x.py -n "__fish_seen_subcommand_from clippy" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from clippy" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from clippy" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clippy" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from clippy" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from clippy" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from clippy" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -140,6 +144,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fix" -l build -d 'build target complete -c x.py -n "__fish_seen_subcommand_from fix" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from fix" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from fix" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fix" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from fix" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from fix" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from fix" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -169,6 +174,7 @@ complete -c x.py -n "__fish_seen_subcommand_from fmt" -l build -d 'build target complete -c x.py -n "__fish_seen_subcommand_from fmt" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from fmt" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from fmt" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from fmt" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from fmt" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from fmt" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from fmt" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -199,6 +205,7 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l build -d 'build target complete -c x.py -n "__fish_seen_subcommand_from doc" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from doc" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from doc" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from doc" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from doc" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from doc" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from doc" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -224,7 +231,7 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l dry-run -d 'dry run; do complete -c x.py -n "__fish_seen_subcommand_from doc" -l json-output -d 'use message-format=json' complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc' complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')' -complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r +complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r -F complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-args -d 'extra options to pass the compiler when running tests' -r complete -c x.py -n "__fish_seen_subcommand_from test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r @@ -273,6 +280,7 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l build -d 'build targe complete -c x.py -n "__fish_seen_subcommand_from bench" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from bench" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from bench" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from bench" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from bench" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from bench" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from bench" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -303,6 +311,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l build -d 'build targe complete -c x.py -n "__fish_seen_subcommand_from clean" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from clean" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from clean" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from clean" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f @@ -332,6 +341,7 @@ complete -c x.py -n "__fish_seen_subcommand_from dist" -l build -d 'build target complete -c x.py -n "__fish_seen_subcommand_from dist" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from dist" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from dist" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from dist" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from dist" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from dist" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from dist" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -361,6 +371,7 @@ complete -c x.py -n "__fish_seen_subcommand_from install" -l build -d 'build tar complete -c x.py -n "__fish_seen_subcommand_from install" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from install" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from install" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from install" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from install" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from install" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from install" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -391,6 +402,7 @@ complete -c x.py -n "__fish_seen_subcommand_from run" -l build -d 'build target complete -c x.py -n "__fish_seen_subcommand_from run" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from run" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from run" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from run" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from run" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from run" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from run" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -420,6 +432,7 @@ complete -c x.py -n "__fish_seen_subcommand_from setup" -l build -d 'build targe complete -c x.py -n "__fish_seen_subcommand_from setup" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from setup" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from setup" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from setup" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from setup" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from setup" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from setup" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f @@ -449,6 +462,7 @@ complete -c x.py -n "__fish_seen_subcommand_from suggest" -l build -d 'build tar complete -c x.py -n "__fish_seen_subcommand_from suggest" -l host -d 'host targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from suggest" -l target -d 'target targets to build' -r -f complete -c x.py -n "__fish_seen_subcommand_from suggest" -l exclude -d 'build paths to exclude' -r -F +complete -c x.py -n "__fish_seen_subcommand_from suggest" -l skip -d 'build paths to skip' -r -F complete -c x.py -n "__fish_seen_subcommand_from suggest" -l rustc-error-format -r -f complete -c x.py -n "__fish_seen_subcommand_from suggest" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)" complete -c x.py -n "__fish_seen_subcommand_from suggest" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index ff7d49d5e30a..a4a86564c446 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -27,6 +27,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -77,6 +78,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -113,6 +115,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -154,6 +157,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -191,6 +195,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -227,6 +232,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -264,6 +270,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -352,6 +359,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -389,6 +397,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)') @@ -425,6 +434,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -461,6 +471,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -498,6 +509,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -534,6 +546,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') @@ -570,6 +583,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build') [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build') [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude') + [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip') [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format') [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure') [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index 4e9286ae1e81..c24ab0ed8253 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -61,7 +61,7 @@ _x.py() { case "${cmd}" in x.py) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest" + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -91,6 +91,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -167,7 +171,7 @@ _x.py() { return 0 ;; x.py__bench) - opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -201,6 +205,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -277,7 +285,7 @@ _x.py() { return 0 ;; x.py__build) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -307,6 +315,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -383,7 +395,7 @@ _x.py() { return 0 ;; x.py__check) - opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -413,6 +425,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -489,7 +505,7 @@ _x.py() { return 0 ;; x.py__clean) - opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -523,6 +539,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -595,7 +615,7 @@ _x.py() { return 0 ;; x.py__clippy) - opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-A -D -W -F -v -i -j -h --fix --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -641,6 +661,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -717,7 +741,7 @@ _x.py() { return 0 ;; x.py__dist) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -747,6 +771,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -823,7 +851,7 @@ _x.py() { return 0 ;; x.py__doc) - opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -853,6 +881,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -929,7 +961,7 @@ _x.py() { return 0 ;; x.py__fix) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -959,6 +991,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -1035,7 +1071,7 @@ _x.py() { return 0 ;; x.py__fmt) - opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --check --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1065,6 +1101,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -1141,7 +1181,7 @@ _x.py() { return 0 ;; x.py__install) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1171,6 +1211,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -1247,7 +1291,7 @@ _x.py() { return 0 ;; x.py__run) - opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1281,6 +1325,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -1357,7 +1405,7 @@ _x.py() { return 0 ;; x.py__setup) - opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [|hook|vscode|link] [PATHS]... [ARGS]..." + opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [|hook|vscode|link] [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1387,6 +1435,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 @@ -1463,7 +1515,7 @@ _x.py() { return 0 ;; x.py__suggest) - opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -1493,6 +1545,10 @@ _x.py() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; + --skip) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; --rustc-error-format) COMPREPLY=("${cur}") return 0 diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index f6edd008845c..8ab19674d05b 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -197,7 +197,7 @@ fn main() -> anyhow::Result<()> { "miri", "rustfmt", ] { - build_args.extend(["--exclude".to_string(), target.to_string()]); + build_args.extend(["--skip".to_string(), target.to_string()]); } } diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index c85418baecd1..3dd1a3223f5a 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -96,7 +96,7 @@ pub fn run_tests(env: &dyn Environment) -> anyhow::Result<()> { "tests/ui", ]; for test_path in env.skipped_tests() { - args.extend(["--exclude", test_path]); + args.extend(["--skip", test_path]); } cmd(&args).env("COMPILETEST_FORCE_STAGE0", "1").run().context("Cannot execute tests") } From 92f4c59e4847005752a358ccacb5ae264700fbc4 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 25 Jul 2023 05:58:53 +0000 Subject: [PATCH 26/76] lower impl const to bind to host effect param --- compiler/rustc_ast/src/ast.rs | 10 +++ compiler/rustc_ast_lowering/src/asm.rs | 1 + compiler/rustc_ast_lowering/src/expr.rs | 6 ++ compiler/rustc_ast_lowering/src/item.rs | 84 ++++++++++++------ compiler/rustc_ast_lowering/src/lib.rs | 85 +++++++++++++++++-- compiler/rustc_ast_lowering/src/pat.rs | 3 + compiler/rustc_ast_lowering/src/path.rs | 13 ++- .../src/const_eval/fn_queries.rs | 2 +- .../src/transform/check_consts/mod.rs | 9 +- .../src/transform/check_consts/ops.rs | 7 +- compiler/rustc_hir/src/hir.rs | 1 - compiler/rustc_hir/src/intravisit.rs | 1 - .../rustc_hir_analysis/src/astconv/mod.rs | 12 ++- compiler/rustc_hir_analysis/src/collect.rs | 45 ++++------ .../src/collect/generics_of.rs | 2 +- .../wrong_number_of_generic_args.rs | 3 + compiler/rustc_hir_pretty/src/lib.rs | 5 -- compiler/rustc_hir_typeck/src/callee.rs | 37 ++++---- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 5 +- compiler/rustc_middle/src/ty/context.rs | 4 +- compiler/rustc_middle/src/ty/print/pretty.rs | 5 ++ compiler/rustc_passes/src/stability.rs | 10 +-- .../src/traits/error_reporting/mod.rs | 21 ----- .../const-drop-fail-2.rs | 2 +- 24 files changed, 236 insertions(+), 137 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 2a268c2da85c..f0434b0294f1 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -313,6 +313,16 @@ pub enum TraitBoundModifier { MaybeConstMaybe, } +impl TraitBoundModifier { + pub fn to_constness(self) -> Const { + match self { + // FIXME(effects) span + Self::MaybeConst => Const::Yes(DUMMY_SP), + _ => Const::No, + } + } +} + /// The AST represents all type param bounds as types. /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index ab55c09465b1..a1e626996800 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -207,6 +207,7 @@ pub(crate) fn lower_inline_asm( &sym.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); hir::InlineAsmOperand::SymStatic { path, def_id } } else { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0954cf03da9a..f06d6fc6e5bd 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -100,6 +100,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { ParamMode::Optional, ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, )); let receiver = self.lower_expr(receiver); let args = @@ -260,6 +261,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); hir::ExprKind::Path(qpath) } @@ -307,6 +309,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { &se.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, )), self.arena .alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))), @@ -1179,6 +1182,7 @@ fn destructure_assign_mut( path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); // Destructure like a tuple struct. let tuple_struct_pat = hir::PatKind::TupleStruct( @@ -1198,6 +1202,7 @@ fn destructure_assign_mut( path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); // Destructure like a unit struct. let unit_struct_pat = hir::PatKind::Path(qpath); @@ -1222,6 +1227,7 @@ fn destructure_assign_mut( &se.path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let fields_omitted = match &se.rest { StructRest::Base(e) => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 5a0474dbc01d..201094667a1e 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -85,6 +85,7 @@ fn with_lctx( allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()), allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()), generics_def_id_map: Default::default(), + host_param_id: None, }; lctx.with_hir_id_owner(owner, |lctx| f(lctx)); @@ -139,8 +140,24 @@ fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) { // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. - if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind { - lctx.is_in_trait_impl = impl_.of_trait.is_some(); + match parent_hir.node().expect_item().kind { + hir::ItemKind::Impl(impl_) => { + lctx.is_in_trait_impl = impl_.of_trait.is_some(); + } + hir::ItemKind::Trait(_, _, generics, _, _) if lctx.tcx.features().effects => { + lctx.host_param_id = generics + .params + .iter() + .find(|param| { + parent_hir + .attrs + .get(param.hir_id.local_id) + .iter() + .any(|attr| attr.has_name(sym::rustc_host)) + }) + .map(|param| param.def_id); + } + _ => {} } match ctxt { @@ -384,6 +401,7 @@ fn lower_item_kind( self.lower_generics(ast_generics, *constness, id, &itctx, |this| { let trait_ref = trait_ref.as_ref().map(|trait_ref| { this.lower_trait_ref( + *constness, trait_ref, &ImplTraitContext::Disallowed(ImplTraitPosition::Trait), ) @@ -414,7 +432,6 @@ fn lower_item_kind( polarity, defaultness, defaultness_span, - constness: self.lower_constness(*constness), generics, of_trait: trait_ref, self_ty: lowered_ty, @@ -1358,6 +1375,29 @@ fn lower_generics( } } + // Desugar `~const` bound in generics into an additional `const host: bool` param + // if the effects feature is enabled. This needs to be done before we lower where + // clauses since where clauses need to bind to the DefId of the host param + let host_param_parts = if let Const::Yes(span) = constness && self.tcx.features().effects { + if let Some(param) = generics.params.iter().find(|x| { + x.attrs.iter().any(|x| x.has_name(sym::rustc_host)) + }) { + // user has manually specified a `rustc_host` param, in this case, we set + // the param id so that lowering logic can use that. But we don't create + // another host param, so this gives `None`. + self.host_param_id = Some(self.local_def_id(param.id)); + None + } else { + let param_node_id = self.next_node_id(); + let hir_id = self.next_id(); + let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); + self.host_param_id = Some(def_id); + Some((span, hir_id, def_id)) + } + } else { + None + }; + let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new(); predicates.extend(generics.params.iter().filter_map(|param| { self.lower_generic_bound_predicate( @@ -1405,22 +1445,11 @@ fn lower_generics( let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds); predicates.extend(impl_trait_bounds.into_iter()); - // Desugar `~const` bound in generics into an additional `const host: bool` param - // if the effects feature is enabled. - if let Const::Yes(span) = constness && self.tcx.features().effects - // Do not add host param if it already has it (manually specified) - && !params.iter().any(|x| { - self.attrs.get(&x.hir_id.local_id).map_or(false, |attrs| { - attrs.iter().any(|x| x.has_name(sym::rustc_host)) - }) - }) - { - let param_node_id = self.next_node_id(); + if let Some((span, hir_id, def_id)) = host_param_parts { let const_node_id = self.next_node_id(); - let def_id = self.create_def(self.local_def_id(parent_node_id), param_node_id, DefPathData::TypeNs(sym::host), span); - let anon_const: LocalDefId = self.create_def(def_id, const_node_id, DefPathData::AnonConst, span); + let anon_const: LocalDefId = + self.create_def(def_id, const_node_id, DefPathData::AnonConst, span); - let hir_id = self.next_id(); let const_id = self.next_id(); let const_expr_id = self.next_id(); let bool_id = self.next_id(); @@ -1430,14 +1459,15 @@ fn lower_generics( let attr_id = self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(); - let attrs = self.arena.alloc_from_iter([ - Attribute { - kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))), + let attrs = self.arena.alloc_from_iter([Attribute { + kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new( + sym::rustc_host, span, - id: attr_id, - style: AttrStyle::Outer, - }, - ]); + )))), + span, + id: attr_id, + style: AttrStyle::Outer, + }]); self.attrs.insert(hir_id.local_id, attrs); let const_body = self.lower_body(|this| { @@ -1476,7 +1506,11 @@ fn lower_generics( }), )), )), - default: Some(hir::AnonConst { def_id: anon_const, hir_id: const_id, body: const_body }), + default: Some(hir::AnonConst { + def_id: anon_const, + hir_id: const_id, + body: const_body, + }), }, colon_span: None, pure_wrt_drop: false, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ac7506900467..dd081fafafba 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -142,6 +142,8 @@ struct LoweringContext<'a, 'hir> { /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this /// field from the original parameter 'a to the new parameter 'a1. generics_def_id_map: Vec>, + + host_param_id: Option, } trait ResolverAstLoweringExt { @@ -1267,6 +1269,7 @@ fn lower_path_ty( span: t.span }, itctx, + ast::Const::No, ); let bounds = this.arena.alloc_from_iter([bound]); let lifetime_bound = this.elided_dyn_bound(t.span); @@ -1277,7 +1280,7 @@ fn lower_path_ty( } let id = self.lower_node_id(t.id); - let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx); + let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None); self.ty_path(id, t.span, qpath) } @@ -1361,10 +1364,12 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound { GenericBound::Trait( ty, - TraitBoundModifier::None + modifier @ (TraitBoundModifier::None | TraitBoundModifier::MaybeConst - | TraitBoundModifier::Negative, - ) => Some(this.lower_poly_trait_ref(ty, itctx)), + | TraitBoundModifier::Negative), + ) => { + Some(this.lower_poly_trait_ref(ty, itctx, modifier.to_constness())) + } // `~const ?Bound` will cause an error during AST validation // anyways, so treat it like `?Bound` as compilation proceeds. GenericBound::Trait( @@ -2189,7 +2194,7 @@ fn lower_param_bound( ) -> hir::GenericBound<'hir> { match tpb { GenericBound::Trait(p, modifier) => hir::GenericBound::Trait( - self.lower_poly_trait_ref(p, itctx), + self.lower_poly_trait_ref(p, itctx, modifier.to_constness()), self.lower_trait_bound_modifier(*modifier), ), GenericBound::Outlives(lifetime) => { @@ -2332,8 +2337,20 @@ fn lower_generic_param_kind( } } - fn lower_trait_ref(&mut self, p: &TraitRef, itctx: &ImplTraitContext) -> hir::TraitRef<'hir> { - let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) { + fn lower_trait_ref( + &mut self, + constness: ast::Const, + p: &TraitRef, + itctx: &ImplTraitContext, + ) -> hir::TraitRef<'hir> { + let path = match self.lower_qpath( + p.ref_id, + &None, + &p.path, + ParamMode::Explicit, + itctx, + Some(constness), + ) { hir::QPath::Resolved(None, path) => path, qpath => panic!("lower_trait_ref: unexpected QPath `{qpath:?}`"), }; @@ -2345,10 +2362,11 @@ fn lower_poly_trait_ref( &mut self, p: &PolyTraitRef, itctx: &ImplTraitContext, + constness: ast::Const, ) -> hir::PolyTraitRef<'hir> { let bound_generic_params = self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params); - let trait_ref = self.lower_trait_ref(&p.trait_ref, itctx); + let trait_ref = self.lower_trait_ref(constness, &p.trait_ref, itctx); hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) } } @@ -2702,6 +2720,57 @@ struct GenericArgsCtor<'hir> { } impl<'hir> GenericArgsCtor<'hir> { + fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast::Const) { + if !lcx.tcx.features().effects { + return; + } + + // if bound is non-const, don't add host effect param + let ast::Const::Yes(span) = constness else { return }; + + let span = lcx.lower_span(span); + + let id = lcx.next_node_id(); + let hir_id = lcx.next_id(); + let body = lcx.lower_body(|lcx| { + ( + &[], + match constness { + ast::Const::Yes(_) => { + let hir_id = lcx.next_id(); + let res = + Res::Def(DefKind::ConstParam, lcx.host_param_id.unwrap().to_def_id()); + let expr_kind = hir::ExprKind::Path(hir::QPath::Resolved( + None, + lcx.arena.alloc(hir::Path { + span, + res, + segments: arena_vec![lcx; hir::PathSegment::new(Ident { + name: sym::host, + span, + }, hir_id, res)], + }), + )); + lcx.expr(span, expr_kind) + } + ast::Const::No => lcx.expr( + span, + hir::ExprKind::Lit( + lcx.arena.alloc(hir::Lit { span, node: ast::LitKind::Bool(true) }), + ), + ), + }, + ) + }); + let def_id = + lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); + lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); + self.args.push(hir::GenericArg::Const(hir::ConstArg { + value: hir::AnonConst { def_id, hir_id, body }, + span, + })) + } + fn is_empty(&self) -> bool { self.args.is_empty() && self.bindings.is_empty() diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 2509b7056395..a30f264bc7dc 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -38,6 +38,7 @@ pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct"); break hir::PatKind::TupleStruct(qpath, pats, ddpos); @@ -54,6 +55,7 @@ pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); break hir::PatKind::Path(qpath); } @@ -64,6 +66,7 @@ pub(crate) fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'hir> { path, ParamMode::Optional, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ); let fs = self.arena.alloc_from_iter(fields.iter().map(|f| { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 441282c05b42..899f92a99582 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -23,6 +23,8 @@ pub(crate) fn lower_qpath( p: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, + // constness of the impl/bound if this is a trait path + constness: Option, ) -> hir::QPath<'hir> { let qself_position = qself.as_ref().map(|q| q.position); let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx)); @@ -73,6 +75,8 @@ pub(crate) fn lower_qpath( param_mode, parenthesized_generic_args, itctx, + // if this is the last segment, add constness to the trait path + if i == proj_start - 1 { constness } else { None }, ) }, )), @@ -119,6 +123,7 @@ pub(crate) fn lower_qpath( param_mode, ParenthesizedGenericArgs::Err, itctx, + None, )); let qpath = hir::QPath::TypeRelative(ty, hir_segment); @@ -159,6 +164,7 @@ pub(crate) fn lower_use_path( param_mode, ParenthesizedGenericArgs::Err, &ImplTraitContext::Disallowed(ImplTraitPosition::Path), + None, ) })), span: self.lower_span(p.span), @@ -172,8 +178,9 @@ pub(crate) fn lower_path_segment( param_mode: ParamMode, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: &ImplTraitContext, + constness: Option, ) -> hir::PathSegment<'hir> { - debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,); + debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment); let (mut generic_args, infer_args) = if let Some(generic_args) = segment.args.as_deref() { match generic_args { GenericArgs::AngleBracketed(data) => { @@ -231,6 +238,10 @@ pub(crate) fn lower_path_segment( ) }; + if let Some(constness) = constness { + generic_args.push_constness(self, constness); + } + let has_lifetimes = generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))); diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index cc39387c41fc..4ee4ebbb9e44 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -40,7 +40,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { | hir::Node::AnonConst(_) | hir::Node::ConstBlock(_) | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => hir::Constness::Const, - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => tcx.generics_of(def_id).host_effect_index.map_or(hir::Constness::NotConst, |_| hir::Constness::Const), hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index e77fb4ea2a2c..e51082e1ec0e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -127,15 +127,8 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let hir_id = tcx.local_def_id_to_hir_id(local_def_id); let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false }; - let parent_def = tcx.hir().get(parent); - if !matches!( - parent_def, - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), - .. - }) - ) { + if !tcx.is_const_trait_impl_raw(parent.owner.def_id.to_def_id()) { return false; } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index e785196c744c..1f3cda35c2ba 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -145,8 +145,11 @@ fn build_error( let implsrc = selcx.select(&obligation); if let Ok(Some(ImplSource::UserDefined(data))) = implsrc { - let span = tcx.def_span(data.impl_def_id); - err.subdiagnostic(errors::NonConstImplNote { span }); + // FIXME(effects) revisit this + if !tcx.is_const_trait_impl_raw(data.impl_def_id) { + let span = tcx.def_span(data.impl_def_id); + err.subdiagnostic(errors::NonConstImplNote { span }); + } } } _ => {} diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 6b76e16825f7..3922dadfdb1b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3357,7 +3357,6 @@ pub struct Impl<'hir> { // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata // decoding as `Span`s cannot be decoded when a `Session` is not available. pub defaultness_span: Option, - pub constness: Constness, pub generics: &'hir Generics<'hir>, /// The trait being implemented, if any. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index a8a94e6a4768..056b68949a2c 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -522,7 +522,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { unsafety: _, defaultness: _, polarity: _, - constness: _, defaultness_span: _, ref generics, ref of_trait, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index b40e31235228..7c03c1794f0f 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -532,6 +532,7 @@ fn inferred_kind( if let Err(guar) = ty.error_reported() { return ty::Const::new_error(tcx, guar, ty).into(); } + // FIXME(effects) see if we should special case effect params here if !infer_args && has_default { tcx.const_param_default(param.def_id) .instantiate(tcx, args.unwrap()) @@ -659,7 +660,6 @@ pub fn instantiate_mono_trait_ref( &self, trait_ref: &hir::TraitRef<'_>, self_ty: Ty<'tcx>, - constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx> { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); @@ -669,7 +669,7 @@ pub fn instantiate_mono_trait_ref( self_ty, trait_ref.path.segments.last().unwrap(), true, - constness, + ty::BoundConstness::NotConst, ) } @@ -849,6 +849,7 @@ fn ast_path_to_mono_trait_ref( self_ty: Ty<'tcx>, trait_segment: &hir::PathSegment<'_>, is_impl: bool, + // FIXME(effects) move all host param things in astconv to hir lowering constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx> { let (generic_args, _) = self.create_args_for_ast_trait_ref( @@ -2712,11 +2713,8 @@ fn suggest_trait_fn_ty_for_impl_fn_infer( }; let i = hir.get_parent(fn_hir_id).expect_item().expect_impl(); - let trait_ref = self.instantiate_mono_trait_ref( - i.of_trait.as_ref()?, - self.ast_ty_to_ty(i.self_ty), - ty::BoundConstness::NotConst, - ); + let trait_ref = + self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty)); let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind( tcx, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f568b7519519..c65cd25f12c3 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1358,38 +1358,29 @@ fn impl_trait_ref( .of_trait .as_ref() .map(|ast_trait_ref| { - let selfty = tcx.type_of(def_id).instantiate_identity(); - icx.astconv().instantiate_mono_trait_ref( + check_impl_constness( + tcx, + tcx.is_const_trait_impl_raw(def_id.to_def_id()), ast_trait_ref, - selfty, - check_impl_constness(tcx, impl_.constness, ast_trait_ref), - ) + ); + let selfty = tcx.type_of(def_id).instantiate_identity(); + icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty) }) .map(ty::EarlyBinder::bind) } -fn check_impl_constness( - tcx: TyCtxt<'_>, - constness: hir::Constness, - ast_trait_ref: &hir::TraitRef<'_>, -) -> ty::BoundConstness { - match constness { - hir::Constness::Const => { - if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) { - let trait_name = tcx.item_name(trait_def_id).to_string(); - tcx.sess.emit_err(errors::ConstImplForNonConstTrait { - trait_ref_span: ast_trait_ref.path.span, - trait_name, - local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), - marking: (), - adding: (), - }); - ty::BoundConstness::NotConst - } else { - ty::BoundConstness::ConstIfConst - } - }, - hir::Constness::NotConst => ty::BoundConstness::NotConst, +fn check_impl_constness(tcx: TyCtxt<'_>, is_const: bool, ast_trait_ref: &hir::TraitRef<'_>) { + if is_const { + if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) { + let trait_name = tcx.item_name(trait_def_id).to_string(); + tcx.sess.emit_err(errors::ConstImplForNonConstTrait { + trait_ref_span: ast_trait_ref.path.span, + trait_name, + local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), + marking: (), + adding: (), + }); + } } } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 6e1762c54f21..4842008279a9 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -320,7 +320,7 @@ enum Defaults { bug!("parent also has host effect param? index: {idx}, def: {def_id:?}"); } - host_effect_index = Some(parent_count + index as usize); + host_effect_index = Some(index as usize); } Some(ty::GenericParamDef { diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 6be8d72aed20..61b182b1be78 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -578,6 +578,9 @@ fn suggest_adding_args(&self, err: &mut Diagnostic) { MissingTypesOrConsts { .. } => { self.suggest_adding_type_and_const_args(err); } + ExcessTypesOrConsts { .. } => { + // this can happen with `~const T` where T isn't a const_trait. + } _ => unreachable!(), } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2d8b956771bb..e2aecccb6e9b 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -626,7 +626,6 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) { unsafety, polarity, defaultness, - constness, defaultness_span: _, generics, ref of_trait, @@ -643,10 +642,6 @@ pub fn print_item(&mut self, item: &hir::Item<'_>) { self.space(); } - if constness == hir::Constness::Const { - self.word_nbsp("const"); - } - if let hir::ImplPolarity::Negative(_) = polarity { self.word("!"); } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index c68f2d94f352..ba00954db918 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -767,9 +767,15 @@ pub(super) fn enforce_context_effects( ) { let tcx = self.tcx; - if !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you { - return; - } + // fast-reject if callee doesn't have the host effect param (non-const) + let generics = tcx.generics_of(callee_did); + let Some(host_effect_index) = generics.host_effect_index else { return }; + + // if the callee does have the param, we need to equate the param to some const + // value no matter whether the effects feature is enabled in the local crate, + // because inference will fail if we don't. + let mut host_always_on = + !tcx.features().effects || tcx.sess.opts.unstable_opts.unleash_the_miri_inside_of_you; // Compute the constness required by the context. let context = tcx.hir().enclosing_body_owner(call_expr_hir); @@ -780,10 +786,11 @@ pub(super) fn enforce_context_effects( if tcx.has_attr(context.to_def_id(), sym::rustc_do_not_const_check) { trace!("do not const check this context"); - return; + host_always_on = true; } let effect = match const_context { + _ if host_always_on => tcx.consts.true_, Some(hir::ConstContext::Static(_) | hir::ConstContext::Const) => tcx.consts.false_, Some(hir::ConstContext::ConstFn) => { let args = ty::GenericArgs::identity_for_item(tcx, context); @@ -792,21 +799,17 @@ pub(super) fn enforce_context_effects( None => tcx.consts.true_, }; - let generics = tcx.generics_of(callee_did); - trace!(?effect, ?generics, ?callee_args); - if let Some(idx) = generics.host_effect_index { - let param = callee_args.const_at(idx); - let cause = self.misc(span); - match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) { - Ok(infer::InferOk { obligations, value: () }) => { - self.register_predicates(obligations); - } - Err(e) => { - // FIXME(effects): better diagnostic - self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit(); - } + let param = callee_args.const_at(host_effect_index); + let cause = self.misc(span); + match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) { + Ok(infer::InferOk { obligations, value: () }) => { + self.register_predicates(obligations); + } + Err(e) => { + // FIXME(effects): better diagnostic + self.err_ctxt().report_mismatched_consts(&cause, effect, param, e).emit(); } } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 1433c67d55dc..6b118ea5a293 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1349,7 +1349,10 @@ fn inferred_kind( } } GenericParamDefKind::Const { has_default } => { - if !infer_args && has_default { + if !infer_args + && has_default + && !tcx.has_attr(param.def_id, sym::rustc_host) + { tcx.const_param_default(param.def_id) .instantiate(tcx, args.unwrap()) .into() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5eef3e45f327..30f60abe31c8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1963,9 +1963,9 @@ pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool { matches!( node, hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), + kind: hir::ItemKind::Impl(hir::Impl { generics, .. }), .. - }) + }) if generics.params.iter().any(|p| self.has_attr(p.def_id, sym::rustc_host)) ) } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d3fd49150ba2..ed0af6f5eb19 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2841,6 +2841,11 @@ pub struct PrintClosureAsImpl<'tcx> { ty::TraitPredicate<'tcx> { p!(print(self.trait_ref.self_ty()), ": "); + if let Some(idx) = cx.tcx().generics_of(self.trait_ref.def_id).host_effect_index { + if self.trait_ref.args.const_at(idx) != cx.tcx().consts.true_ { + p!("~const "); + } + } // FIXME(effects) print `~const` here if let ty::ImplPolarity::Negative = self.polarity { p!("!"); diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 25a3d38c1442..3950ac9dd31c 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -732,13 +732,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(hir::Impl { - of_trait: Some(ref t), - self_ty, - items, - constness, - .. - }) => { + hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => { let features = self.tcx.features(); if features.staged_api { let attrs = self.tcx.hir().attrs(item.hir_id()); @@ -769,7 +763,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { // `#![feature(const_trait_impl)]` is unstable, so any impl declared stable // needs to have an error emitted. if features.const_trait_impl - && *constness == hir::Constness::Const + && self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id()) && const_stab.is_some_and(|(stab, _)| stab.is_const_stable()) { self.tcx.sess.emit_err(errors::TraitImplConstStable { span: item.span }); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index eae13eb63029..f56b4425b125 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -3102,27 +3102,6 @@ fn maybe_add_note_for_unsatisfied_const( ) -> UnsatisfiedConst { let unsatisfied_const = UnsatisfiedConst(false); // FIXME(effects) - /* if trait_predicate.is_const_if_const() { - let non_const_predicate = trait_ref.without_const(); - let non_const_obligation = Obligation { - cause: obligation.cause.clone(), - param_env: obligation.param_env, - predicate: non_const_predicate.to_predicate(self.tcx), - recursion_depth: obligation.recursion_depth, - }; - if self.predicate_may_hold(&non_const_obligation) { - unsatisfied_const = UnsatisfiedConst(true); - err.span_note( - span, - format!( - "the trait `{}` is implemented for `{}`, \ - but that implementation is not `const`", - non_const_predicate.print_modifiers_and_trait_path(), - trait_ref.skip_binder().self_ty(), - ), - ); - } - } */ unsatisfied_const } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 3de9d37d4933..10f6c5c064a3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -1,5 +1,5 @@ // known-bug: #110395 -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(const_mut_refs)] #![cfg_attr(precise, feature(const_precise_live_drops))] From 6c1e3bb6e97f4c6d760859c4e804f98b8cc64fe2 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 6 Aug 2023 13:20:55 +0000 Subject: [PATCH 27/76] bless tests --- .../const_trait_fn-issue-88433.rs | 2 +- .../unify-op-with-fn-call.stderr | 42 +++++++++++++++---- tests/ui/consts/const-try.stderr | 33 +++++++++------ tests/ui/consts/rustc-impl-const-stability.rs | 2 +- .../consts/rustc-impl-const-stability.stderr | 19 ++++++++- .../auxiliary/cross-crate.rs | 2 +- .../auxiliary/staged-api.rs | 2 +- .../call-const-trait-method-fail.rs | 4 +- .../call-const-trait-method-fail.stderr | 8 ++-- .../call-const-trait-method-pass.stderr | 34 ++++++++------- .../call-generic-method-chain.stderr | 11 +---- .../call-generic-method-dup-bound.stderr | 11 +---- .../call-generic-method-pass.stderr | 11 +---- .../const-and-non-const-impl.stderr | 27 +++++++----- .../const-check-fns-in-const-impl.rs | 2 +- .../const-default-method-bodies.rs | 4 +- .../const-default-method-bodies.stderr | 8 ++-- .../const-drop-fail-2.rs | 9 ++-- .../const-drop-fail-2.stderr | 23 ++-------- .../const-drop.precise.stderr | 13 +----- .../const-drop.stock.stderr | 13 +----- .../const-impl-requires-const-trait.rs | 8 ++-- .../const-impl-requires-const-trait.stderr | 17 +++++++- .../const_derives/derive-const-gate.rs | 1 - .../const_derives/derive-const-gate.stderr | 12 +----- .../derive-const-non-const-type.rs | 2 +- .../derive-const-non-const-type.stderr | 11 ++++- .../const_derives/derive-const-use.stderr | 40 +----------------- .../derive-const-with-params.stderr | 12 +----- .../cross-crate.gatednc.stderr | 8 ++-- .../rfc-2632-const-trait-impl/cross-crate.rs | 4 +- ...-method-body-is-const-same-trait-ck.stderr | 2 +- .../do-not-const-check-override.rs | 2 +- .../effects/helloworld.rs | 6 +-- .../generic-bound.stderr | 17 +++++--- .../hir-const-check.rs | 2 +- ...default-impl-non-const-specialized-impl.rs | 2 +- .../specializing-constness.rs | 2 +- .../rfc-2632-const-trait-impl/staged-api.rs | 2 +- .../trait-default-body-stability.stderr | 33 +++++++++------ .../trait-where-clause-run.rs | 2 +- .../missing-const-stability.rs | 2 +- 42 files changed, 224 insertions(+), 243 deletions(-) diff --git a/tests/ui/const-generics/const_trait_fn-issue-88433.rs b/tests/ui/const-generics/const_trait_fn-issue-88433.rs index 6e04cfaec31f..88dff9192067 100644 --- a/tests/ui/const-generics/const_trait_fn-issue-88433.rs +++ b/tests/ui/const-generics/const_trait_fn-issue-88433.rs @@ -1,6 +1,6 @@ // build-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Func { diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index 7f28771cee83..eb71ebb62ebb 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -1,11 +1,39 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/unify-op-with-fn-call.rs:10:12 +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:18:29 | -LL | impl const std::ops::Add for Foo { - | ^^^^^^^^^^^^^ +LL | struct Evaluatable; + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change -error: aborting due to previous error +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:20:17 + | +LL | fn foo(a: Evaluatable<{ N + N }>) { + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); + | +error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter + --> $DIR/unify-op-with-fn-call.rs:24:17 + | +LL | fn bar() {} + | ^^^ + | +help: add `#[derive(ConstParamTy)]` to the struct + | +LL + #[derive(ConstParamTy)] +LL | struct Foo(u8); + | + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 37014f9b83f6..94f4153a29e7 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -1,20 +1,29 @@ -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/const-try.rs:15:12 +error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions + --> $DIR/const-try.rs:33:5 | -LL | impl const FromResidual for TryMe { - | ^^^^^^^^^^^^^^^^^^^ +LL | TryMe?; + | ^^^^^^ | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/const-try.rs:21:12 +note: impl defined here, but it is not `const` + --> $DIR/const-try.rs:21:1 | LL | impl const Try for TryMe { - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions + --> $DIR/const-try.rs:33:5 | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change +LL | TryMe?; + | ^^^^^^ + | +note: impl defined here, but it is not `const` + --> $DIR/const-try.rs:15:1 + | +LL | impl const FromResidual for TryMe { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs index a1a741e80e55..2b67c2f2cffe 100644 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ b/tests/ui/consts/rustc-impl-const-stability.rs @@ -2,7 +2,7 @@ #![crate_type = "lib"] #![feature(staged_api)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![stable(feature = "foo", since = "1.0.0")] #[stable(feature = "potato", since = "1.27.0")] diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index e6930da71ec7..7992bfe7752f 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -7,5 +7,22 @@ LL | impl const Default for Data { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to previous error +error[E0107]: missing generics for trait `Default` + --> $DIR/rustc-impl-const-stability.rs:15:12 + | +LL | impl const Default for Data { + | ^^^^^^^ expected 18446744073709551615 generic arguments +error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates + --> $DIR/rustc-impl-const-stability.rs:15:6 + | +LL | impl const Default for Data { + | ^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0207. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs index e73082c11276..f40dc27cb4c6 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs index 589e3f02420f..687cb128b05b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/auxiliary/staged-api.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs index 646955fd867f..771c35cf6ab9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait Plus { @@ -23,7 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 { pub const fn add_u32(a: u32, b: u32) -> u32 { a.plus(b) - //~^ ERROR cannot call + //~^ ERROR the trait bound } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr index 0ee1b1a5cb25..2d9c49af85a9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr @@ -1,11 +1,11 @@ -error[E0015]: cannot call non-const fn `::plus` in constant functions +error[E0277]: the trait bound `u32: ~const Plus` is not satisfied --> $DIR/call-const-trait-method-fail.rs:25:7 | LL | a.plus(b) - | ^^^^^^^ + | ^^^^ the trait `Plus` is not implemented for `u32` | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: the trait `Plus` is implemented for `u32` error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr index ff53eea1110c..60cd000f2d8c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -1,20 +1,24 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/call-const-trait-method-pass.rs:7:12 +error[E0015]: cannot call non-const fn `::plus` in constant functions + --> $DIR/call-const-trait-method-pass.rs:36:7 + | +LL | a.plus(b) + | ^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const operator in constants + --> $DIR/call-const-trait-method-pass.rs:39:22 + | +LL | const ADD_INT: Int = Int(1i32) + Int(2i32); + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $DIR/call-const-trait-method-pass.rs:7:1 | LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-const-trait-method-pass.rs:15:12 - | -LL | impl const PartialEq for Int { - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr index 529a472e0bda..37faa3f6bce2 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -1,12 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-chain.rs:9:12 - | -LL | impl const PartialEq for S { - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - error: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-chain.rs:18:32 | @@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits LL | const fn equals_self_wrapper(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr index bdc6ccc8aec2..90cfe04a9a86 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -1,12 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-dup-bound.rs:7:12 - | -LL | impl const PartialEq for S { - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - error: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-dup-bound.rs:18:44 | @@ -19,5 +10,5 @@ error: ~const can only be applied to `#[const_trait]` traits LL | const fn equals_self2(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr index 7fbe89dba3cb..bea1846e79be 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -1,17 +1,8 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/call-generic-method-pass.rs:9:12 - | -LL | impl const PartialEq for S { - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - error: ~const can only be applied to `#[const_trait]` traits --> $DIR/call-generic-method-pass.rs:18:32 | LL | const fn equals_self(t: &T) -> bool { | ^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 4f858d61eeba..54bc43477229 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,20 +1,25 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:7:12 +error[E0117]: only traits defined in the current crate can be implemented for primitive types + --> $DIR/const-and-non-const-impl.rs:7:1 | LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^-------------^^^^^--- + | | | | + | | | `i32` is not defined in the current crate + | | `i32` is not defined in the current crate + | impl doesn't use only types from inside the current crate | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change + = note: define and implement a trait or new type instead -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/const-and-non-const-impl.rs:23:12 +error[E0119]: conflicting implementations of trait `Add` for type `Int` + --> $DIR/const-and-non-const-impl.rs:23:1 | +LL | impl std::ops::Add for Int { + | -------------------------- first implementation here +... LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int` error: aborting due to 2 previous errors +Some errors have detailed explanations: E0117, E0119. +For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs index 52984fb6be49..4854f41bf04f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-check-fns-in-const-impl.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] struct S; #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs index 3370f32061c2..be668b4f13a8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] trait ConstDefaultFn: Sized { @@ -22,7 +22,7 @@ fn b(self) {} const fn test() { NonConstImpl.a(); - //~^ ERROR cannot call + //~^ ERROR the trait bound ConstImpl.a(); } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr index 414688f71edf..7b558e3f773c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-default-method-bodies.stderr @@ -1,11 +1,11 @@ -error[E0015]: cannot call non-const fn `::a` in constant functions +error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied --> $DIR/const-default-method-bodies.rs:24:18 | LL | NonConstImpl.a(); - | ^^^ + | ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl` | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: the trait `ConstDefaultFn` is implemented for `NonConstImpl` error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 10f6c5c064a3..747ccbf0fabc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -1,5 +1,5 @@ // known-bug: #110395 -#![feature(const_trait_impl, effects)] +#![feature(const_trait_impl)] #![feature(const_mut_refs)] #![cfg_attr(precise, feature(const_precise_live_drops))] @@ -18,6 +18,10 @@ trait A { fn a() { } } impl A for NonTrivialDrop {} +const fn check(_: T) {} + + +/* FIXME(effects) struct ConstDropImplWithBounds(PhantomData); impl const Drop for ConstDropImplWithBounds { @@ -26,11 +30,10 @@ fn drop(&mut self) { } } -const fn check(_: T) {} - const _: () = check::>( ConstDropImplWithBounds(PhantomData) ); +*/ struct ConstDropImplWithNonConstBounds(PhantomData); diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr index 7de33003c48b..100d1df87d69 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop-fail-2.stderr @@ -1,28 +1,11 @@ -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/const-drop-fail-2.rs:25:9 - | -LL | T::a(); - | ^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - error[E0493]: destructor of `T` cannot be evaluated at compile-time - --> $DIR/const-drop-fail-2.rs:29:36 + --> $DIR/const-drop-fail-2.rs:21:36 | LL | const fn check(_: T) {} | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/const-drop-fail-2.rs:39:9 - | -LL | T::a(); - | ^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +error: aborting due to previous error -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0015, E0493. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr index b28584e7e36f..23e368870258 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.precise.stderr @@ -14,15 +14,6 @@ LL | let _ = S(&mut c); | | | the destructor for this type cannot be evaluated in constant functions -error[E0015]: cannot call non-const fn `::foo` in constant functions - --> $DIR/const-drop.rs:70:13 - | -LL | T::foo(); - | ^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0015, E0493. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr index b28584e7e36f..23e368870258 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-drop.stock.stderr @@ -14,15 +14,6 @@ LL | let _ = S(&mut c); | | | the destructor for this type cannot be evaluated in constant functions -error[E0015]: cannot call non-const fn `::foo` in constant functions - --> $DIR/const-drop.rs:70:13 - | -LL | T::foo(); - | ^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0015, E0493. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs index 2b4963991dbe..fc3a83876c5b 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs @@ -1,9 +1,11 @@ -#![feature(const_trait_impl)] +// known-bug: #110395 + +#![feature(const_trait_impl, effects)] pub trait A {} -//~^ HELP: mark `A` as const +// FIXME ~^ HELP: mark `A` as const impl const A for () {} -//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` +// FIXME ~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index 478adcf3e9e8..becb2ca10425 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -1,5 +1,5 @@ error: const `impl` for trait `A` which is not marked with `#[const_trait]` - --> $DIR/const-impl-requires-const-trait.rs:6:12 + --> $DIR/const-impl-requires-const-trait.rs:8:12 | LL | pub trait A {} | - help: mark `A` as const: `#[const_trait]` @@ -10,5 +10,18 @@ LL | impl const A for () {} = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error: aborting due to previous error +error[E0107]: missing generics for trait `A` + --> $DIR/const-impl-requires-const-trait.rs:8:12 + | +LL | impl const A for () {} + | ^ expected 18446744073709551615 generic arguments + | +note: trait defined here, with 18446744073709551615 generic parameters: + --> $DIR/const-impl-requires-const-trait.rs:5:11 + | +LL | pub trait A {} + | ^ +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs index dba3ad7f8701..348ca0ab1906 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs @@ -1,5 +1,4 @@ #[derive_const(Default)] //~ ERROR use of unstable library feature -//~^ ERROR not marked with `#[const_trait]` pub struct S; fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr index 6a81f96d88d2..cc9bdd2715f7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr @@ -6,16 +6,6 @@ LL | #[derive_const(Default)] | = help: add `#![feature(derive_const)]` to the crate attributes to enable -error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-gate.rs:1:16 - | -LL | #[derive_const(Default)] - | ^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs index b575ea8dae29..ce39045d71b3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs @@ -1,5 +1,5 @@ // known-bug: #110395 -#![feature(derive_const)] +#![feature(derive_const, effects)] pub struct A; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 1c69ad431714..7d7518a887fa 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -8,5 +8,14 @@ LL | #[derive_const(Default)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error[E0107]: missing generics for trait `Default` + --> $DIR/derive-const-non-const-type.rs:10:16 + | +LL | #[derive_const(Default)] + | ^^^^^^^ expected 18446744073709551615 generic arguments + | + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index 88054096e630..046dbae0eae7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -10,44 +10,6 @@ error[E0635]: unknown feature `const_default_impls` LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] | ^^^^^^^^^^^^^^^^^^^ -error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:6:12 - | -LL | impl const Default for A { - | ^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:10:12 - | -LL | impl const PartialEq for A { - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: const `impl` for trait `Default` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:14:16 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-use.rs:14:25 - | -LL | #[derive_const(Default, PartialEq)] - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 6 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr index fa78326587c7..37d123e4ccc4 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -1,13 +1,3 @@ -error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` - --> $DIR/derive-const-with-params.rs:6:16 - | -LL | #[derive_const(PartialEq)] - | ^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - error: ~const can only be applied to `#[const_trait]` traits --> $DIR/derive-const-with-params.rs:6:16 | @@ -16,5 +6,5 @@ LL | #[derive_const(PartialEq)] | = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr index c936270de266..428286e0b12a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.gatednc.stderr @@ -1,11 +1,11 @@ -error[E0015]: cannot call non-const fn `::func` in constant functions +error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied --> $DIR/cross-crate.rs:17:14 | LL | NonConst.func(); - | ^^^^^^ + | ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst` | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst` error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs index 1f78af794185..95edbdc0efa1 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate.rs @@ -1,6 +1,6 @@ // revisions: stock gated stocknc gatednc // [gated] check-pass -#![cfg_attr(any(gated, gatednc), feature(const_trait_impl))] +#![cfg_attr(any(gated, gatednc), feature(const_trait_impl, effects))] // aux-build: cross-crate.rs extern crate cross_crate; @@ -16,7 +16,7 @@ const fn const_context() { #[cfg(any(stocknc, gatednc))] NonConst.func(); //[stocknc]~^ ERROR: cannot call - //[gatednc]~^^ ERROR: cannot call + //[gatednc]~^^ ERROR: the trait bound Const.func(); //[stock]~^ ERROR: cannot call //[stocknc]~^^ ERROR: cannot call diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr index c21c73f40f28..a6881b8fed51 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/default-method-body-is-const-same-trait-ck.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `(): Tr` is not satisfied +error[E0277]: the trait bound `(): ~const Tr` is not satisfied --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12 | LL | ().a() diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs index 730e268c0912..5a0db816a2bc 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/do-not-const-check-override.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(const_trait_impl, rustc_attrs)] +#![feature(const_trait_impl, rustc_attrs, effects)] #[const_trait] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs index 49457354cc9f..e7ba0505d9b7 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/helloworld.rs @@ -7,7 +7,7 @@ // ensure we are passing in the correct host effect in always const contexts. -pub const fn hmm() -> usize { +pub const fn hmm() -> usize { if host { 1 } else { @@ -16,14 +16,12 @@ pub const fn hmm() -> usize { } const _: () = { - let x = hmm(); + let x = hmm::<()>(); assert!(0 == x); }; -/* FIXME(effects) pub const fn uwu(x: [u8; hmm::<()>()]) { let [] = x; } -*/ fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr index 1b21d7c0e0e6..6a177592b645 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr @@ -1,11 +1,16 @@ -error: const `impl` for trait `Add` which is not marked with `#[const_trait]` - --> $DIR/generic-bound.rs:16:15 +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/generic-bound.rs:25:5 + | +LL | arg + arg + | ^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $DIR/generic-bound.rs:16:1 | LL | impl const std::ops::Add for S { - | ^^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to previous error +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs index 337c733403b2..426534deb67e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/hir-const-check.rs @@ -1,6 +1,6 @@ // Regression test for #69615. -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] pub trait MyTrait { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs index a3bb9b3f93ed..9a93d01ed06e 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs @@ -1,6 +1,6 @@ // Tests that specializing trait impls must be at least as const as the default impl. -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(min_specialization)] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs index 0a28da9e65e6..7206a89e5c58 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl, min_specialization, rustc_attrs)] +#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] #[rustc_specialization_trait] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs index 1d79f5adf93f..b3977e6cede0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs @@ -1,7 +1,7 @@ // revisions: stable unstable #![cfg_attr(unstable, feature(unstable))] // The feature from the ./auxiliary/staged-api.rs file. -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(staged_api)] #![stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index 35dc1ca129b1..deed05ae1798 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -1,20 +1,29 @@ -error: const `impl` for trait `Try` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:18:12 +error[E0015]: `?` cannot determine the branch of `T` in constant functions + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ + | +note: impl defined here, but it is not `const` + --> $DIR/trait-default-body-stability.rs:18:1 | LL | impl const Try for T { - | ^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change + | ^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` - --> $DIR/trait-default-body-stability.rs:33:12 +error[E0015]: `?` cannot convert from residual of `T` in constant functions + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ + | +note: impl defined here, but it is not `const` + --> $DIR/trait-default-body-stability.rs:33:1 | LL | impl const FromResidual for T { - | ^^^^^^^^^^^^ - | - = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs index 29809a2ee569..6e1074035b74 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-run.rs @@ -1,7 +1,7 @@ // known-bug: #110395 // FIXME run-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Bar { diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs index 6eff899bfbf1..621e85762491 100644 --- a/tests/ui/stability-attribute/missing-const-stability.rs +++ b/tests/ui/stability-attribute/missing-const-stability.rs @@ -1,5 +1,5 @@ #![feature(staged_api)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![stable(feature = "stable", since = "1.0.0")] #[stable(feature = "stable", since = "1.0.0")] From 3f92261579e5b03265f1f7e2ce759b7a1c06530f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 6 Aug 2023 07:20:31 -0700 Subject: [PATCH 28/76] Generate better function argument names in global_allocator expansion --- src/allocator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index e92280b26b05..4e4c595de825 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -39,8 +39,8 @@ fn codegen_inner( if kind == AllocatorKind::Default { for method in ALLOCATOR_METHODS { let mut arg_tys = Vec::with_capacity(method.inputs.len()); - for ty in method.inputs.iter() { - match *ty { + for input in method.inputs.iter() { + match input.ty { AllocatorTy::Layout => { arg_tys.push(usize_ty); // size arg_tys.push(usize_ty); // align From b66b322a2aaecbcc5dd254c799393cbb702946fe Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Aug 2023 13:23:12 +0200 Subject: [PATCH 29/76] add testcase that hits valtree_into_mplace with a custom DST --- tests/ui/const-generics/slice-const-param.rs | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/ui/const-generics/slice-const-param.rs b/tests/ui/const-generics/slice-const-param.rs index 05d21e08d745..90c573ab3658 100644 --- a/tests/ui/const-generics/slice-const-param.rs +++ b/tests/ui/const-generics/slice-const-param.rs @@ -11,9 +11,30 @@ pub fn function_with_bytes() -> &'static [u8] { BYTES } +// Also check the codepaths for custom DST +#[derive(PartialEq, Eq)] +struct MyStr(str); +impl std::marker::ConstParamTy for MyStr {} + +fn function_with_my_str() -> &'static MyStr { + S +} + +impl MyStr { + const fn new(s: &'static str) -> &'static MyStr { + unsafe { std::mem::transmute(s) } + } + + fn as_str(&self) -> &str { + &self.0 + } +} + pub fn main() { assert_eq!(function_with_str::<"Rust">(), "Rust"); assert_eq!(function_with_str::<"ℇ㇈↦">(), "ℇ㇈↦"); assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]); assert_eq!(function_with_bytes::<{&[0x41, 0x41, 0x41, 0x41]}>(), b"AAAA"); + + assert_eq!(function_with_my_str::<{ MyStr::new("hello") }>().as_str(), "hello"); } From b6e3bc23efef39277deecf991b1ec74d077125b0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Aug 2023 13:24:16 +0200 Subject: [PATCH 30/76] remove an unnecessary special case in valtree_into_mplace --- .../src/const_eval/valtrees.rs | 43 ++----------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index f785bcfed6ca..ea72e4bb92d1 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -9,7 +9,7 @@ }; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; -use rustc_target::abi::{Align, FieldIdx, VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{Align, VariantIdx}; #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( @@ -399,45 +399,8 @@ fn valtree_into_mplace<'tcx>( debug!(?i, ?inner_valtree); let place_inner = match ty.kind() { - ty::Str | ty::Slice(_) => ecx.project_index(place, i as u64).unwrap(), - _ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) - && i == branches.len() - 1 => - { - // Note: For custom DSTs we need to manually process the last unsized field. - // We created a `Pointer` for the `Allocation` of the complete sized version of - // the Adt in `create_pointee_place` and now we fill that `Allocation` with the - // values in the ValTree. For the unsized field we have to additionally add the meta - // data. - - let (unsized_inner_ty, num_elems) = - get_info_on_unsized_field(ty, valtree, tcx); - debug!(?unsized_inner_ty); - - let inner_ty = match ty.kind() { - ty::Adt(def, args) => { - let i = FieldIdx::from_usize(i); - def.variant(FIRST_VARIANT).fields[i].ty(tcx, args) - } - ty::Tuple(inner_tys) => inner_tys[i], - _ => bug!("unexpected unsized type {:?}", ty), - }; - - let inner_layout = - tcx.layout_of(ty::ParamEnv::empty().and(inner_ty)).unwrap(); - debug!(?inner_layout); - - let offset = place_adjusted.layout.fields.offset(i); - place - .offset_with_meta( - offset, - MemPlaceMeta::Meta(Scalar::from_target_usize( - num_elems as u64, - &tcx, - )), - inner_layout, - &tcx, - ) - .unwrap() + ty::Str | ty::Slice(_) | ty::Array(..) => { + ecx.project_index(place, i as u64).unwrap() } _ => ecx.project_field(&place_adjusted, i).unwrap(), }; From 997ec63fb1183d062501946f4d7493491a0847e7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Aug 2023 16:05:30 +0200 Subject: [PATCH 31/76] simplify handling of valtrees for unsized types --- .../src/const_eval/valtrees.rs | 99 ++++++------------- .../rustc_const_eval/src/interpret/place.rs | 16 ++- .../src/interpret/terminator.rs | 10 +- 3 files changed, 43 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index ea72e4bb92d1..b15a65d67a3d 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -7,9 +7,10 @@ intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemPlaceMeta, MemoryKind, Place, Projectable, Scalar, }; +use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; -use rustc_target::abi::{Align, VariantIdx}; +use rustc_target::abi::VariantIdx; #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( @@ -154,52 +155,37 @@ pub(crate) fn const_to_valtree_inner<'tcx>( } } -#[instrument(skip(ecx), level = "debug")] -fn create_mplace_from_layout<'tcx>( - ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, - ty: Ty<'tcx>, -) -> MPlaceTy<'tcx> { - let tcx = ecx.tcx; - let param_env = ecx.param_env; - let layout = tcx.layout_of(param_env.and(ty)).unwrap(); - debug!(?layout); - - ecx.allocate(layout, MemoryKind::Stack).unwrap() -} - -// Walks custom DSTs and gets the type of the unsized field and the number of elements -// in the unsized field. -fn get_info_on_unsized_field<'tcx>( - ty: Ty<'tcx>, +/// Valtrees don't store the `MemPlaceMeta` that all dynamically sized values have in the interpreter. +/// This function reconstructs it. +fn reconstruct_place_meta<'tcx>( + layout: TyAndLayout<'tcx>, valtree: ty::ValTree<'tcx>, tcx: TyCtxt<'tcx>, -) -> (Ty<'tcx>, usize) { +) -> MemPlaceMeta { + if layout.is_sized() { + return MemPlaceMeta::None; + } + let mut last_valtree = valtree; + // Traverse the type, and update `last_valtree` as we go. let tail = tcx.struct_tail_with_normalize( - ty, + layout.ty, |ty| ty, || { let branches = last_valtree.unwrap_branch(); - last_valtree = branches[branches.len() - 1]; + last_valtree = *branches.last().unwrap(); debug!(?branches, ?last_valtree); }, ); - let unsized_inner_ty = match tail.kind() { - ty::Slice(t) => *t, - ty::Str => tail, - _ => bug!("expected Slice or Str"), + // Sanity-check that we got a tail we support. + match tail.kind() { + ty::Slice(..) | ty::Str => {} + _ => bug!("unsized tail of a valtree must be Slice or Str"), }; - // Have to adjust type for ty::Str - let unsized_inner_ty = match unsized_inner_ty.kind() { - ty::Str => tcx.types.u8, - _ => unsized_inner_ty, - }; - - // Get the number of elements in the unsized field + // Get the number of elements in the unsized field. let num_elems = last_valtree.unwrap_branch().len(); - - (unsized_inner_ty, num_elems) + MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx)) } #[instrument(skip(ecx), level = "debug", ret)] @@ -208,41 +194,9 @@ fn create_pointee_place<'tcx>( ty: Ty<'tcx>, valtree: ty::ValTree<'tcx>, ) -> MPlaceTy<'tcx> { - let tcx = ecx.tcx.tcx; - - if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) { - // We need to create `Allocation`s for custom DSTs - - let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx); - let unsized_inner_ty = match unsized_inner_ty.kind() { - ty::Str => tcx.types.u8, - _ => unsized_inner_ty, - }; - let unsized_inner_ty_size = - tcx.layout_of(ty::ParamEnv::empty().and(unsized_inner_ty)).unwrap().layout.size(); - debug!(?unsized_inner_ty, ?unsized_inner_ty_size, ?num_elems); - - // for custom DSTs only the last field/element is unsized, but we need to also allocate - // space for the other fields/elements - let layout = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap(); - let size_of_sized_part = layout.layout.size(); - - // Get the size of the memory behind the DST - let dst_size = unsized_inner_ty_size.checked_mul(num_elems as u64, &tcx).unwrap(); - - let size = size_of_sized_part.checked_add(dst_size, &tcx).unwrap(); - let align = Align::from_bytes(size.bytes().next_power_of_two()).unwrap(); - let ptr = ecx.allocate_ptr(size, align, MemoryKind::Stack).unwrap(); - debug!(?ptr); - - MPlaceTy::from_aligned_ptr_with_meta( - ptr.into(), - layout, - MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx)), - ) - } else { - create_mplace_from_layout(ecx, ty) - } + let layout = ecx.layout_of(ty).unwrap(); + let meta = reconstruct_place_meta(layout, valtree, ecx.tcx.tcx); + ecx.allocate_dyn(layout, MemoryKind::Stack, meta).unwrap() } /// Converts a `ValTree` to a `ConstValue`, which is needed after mir @@ -282,10 +236,13 @@ pub fn valtree_to_const_value<'tcx>( ty::Ref(_, _, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => { let place = match ty.kind() { ty::Ref(_, inner_ty, _) => { - // Need to create a place for the pointee to fill for Refs + // Need to create a place for the pointee (the reference itself will be an immediate) create_pointee_place(&mut ecx, *inner_ty, valtree) } - _ => create_mplace_from_layout(&mut ecx, ty), + _ => { + // Need to create a place for this valtree. + create_pointee_place(&mut ecx, ty, valtree) + } }; debug!(?place); diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 2dc856528f58..a82c9566bc4f 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -934,14 +934,26 @@ pub fn force_allocation( Ok(MPlaceTy { mplace, layout: place.layout, align: place.align }) } + pub fn allocate_dyn( + &mut self, + layout: TyAndLayout<'tcx>, + kind: MemoryKind, + meta: MemPlaceMeta, + ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { + let Some((size, align)) = self.size_and_align_of(&meta, &layout)? else { + span_bug!(self.cur_span(), "cannot allocate space for `extern` type, size is not known") + }; + let ptr = self.allocate_ptr(size, align, kind)?; + Ok(MPlaceTy::from_aligned_ptr_with_meta(ptr.into(), layout, meta)) + } + pub fn allocate( &mut self, layout: TyAndLayout<'tcx>, kind: MemoryKind, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { assert!(layout.is_sized()); - let ptr = self.allocate_ptr(layout.size, layout.align.abi, kind)?; - Ok(MPlaceTy::from_aligned_ptr(ptr.into(), layout)) + self.allocate_dyn(layout, kind, MemPlaceMeta::None) } /// Returns a wide MPlace of type `&'static [mut] str` to a new 1-aligned allocation. diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 1bd214731829..3c03172bbeff 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -393,15 +393,7 @@ fn pass_argument<'x, 'y>( )); assert_eq!(dest_offset, None); // Allocate enough memory to hold `src`. - let Some((size, align)) = self.size_and_align_of_mplace(&src)? else { - span_bug!( - self.cur_span(), - "unsized fn arg with `extern` type tail should not be allowed" - ) - }; - let ptr = self.allocate_ptr(size, align, MemoryKind::Stack)?; - let dest_place = - MPlaceTy::from_aligned_ptr_with_meta(ptr.into(), callee_arg.layout, src.meta); + let dest_place = self.allocate_dyn(src.layout, MemoryKind::Stack, src.meta)?; // Update the local to be that new place. *M::access_local_mut(self, dest_frame, dest_local)? = Operand::Indirect(*dest_place); } From 4e958a532b38a0d504457c40982eb02ec8dc0f4e Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 2 Aug 2023 12:45:52 -0700 Subject: [PATCH 32/76] Add a new `compare_bytes` intrinsic instead of calling `memcmp` directly --- src/intrinsics/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index e3006b253b7a..dcb080b9ec14 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -1155,6 +1155,19 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, CValue::by_val(is_eq_value, ret.layout())); } + sym::compare_bytes => { + intrinsic_args!(fx, args => (lhs_ptr, rhs_ptr, bytes_val); intrinsic); + let lhs_ptr = lhs_ptr.load_scalar(fx); + let rhs_ptr = rhs_ptr.load_scalar(fx); + let bytes_val = bytes_val.load_scalar(fx); + + let params = vec![AbiParam::new(fx.pointer_type); 3]; + let returns = vec![AbiParam::new(types::I32)]; + let args = &[lhs_ptr, rhs_ptr, bytes_val]; + let cmp = fx.lib_call("memcmp", params, returns, args)[0]; + ret.write_cvalue(fx, CValue::by_val(cmp, ret.layout())); + } + sym::const_allocate => { intrinsic_args!(fx, args => (_size, _align); intrinsic); From 659fabde50c185a4ea62aa333b05e313bea247a0 Mon Sep 17 00:00:00 2001 From: scottmcm Date: Fri, 4 Aug 2023 06:22:50 +0000 Subject: [PATCH 33/76] Apply suggestions from code review Co-authored-by: Ralf Jung --- src/intrinsics/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index dcb080b9ec14..36e9ba9c7f8e 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -1164,6 +1164,7 @@ fn codegen_regular_intrinsic_call<'tcx>( let params = vec![AbiParam::new(fx.pointer_type); 3]; let returns = vec![AbiParam::new(types::I32)]; let args = &[lhs_ptr, rhs_ptr, bytes_val]; + // Here we assume that the `memcmp` provided by the target is a NOP for size 0. let cmp = fx.lib_call("memcmp", params, returns, args)[0]; ret.write_cvalue(fx, CValue::by_val(cmp, ret.layout())); } From 1ca4bc966ec5215a8daacf584d337f75322c0e9a Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 6 Aug 2023 14:00:12 +0000 Subject: [PATCH 34/76] Migrate a trait selection error to use diagnostic translation --- compiler/rustc_middle/src/ty/closure.rs | 19 ++++++- compiler/rustc_middle/src/ty/print/pretty.rs | 6 +-- compiler/rustc_trait_selection/messages.ftl | 9 ++++ compiler/rustc_trait_selection/src/errors.rs | 36 ++++++++++++- .../src/traits/error_reporting/mod.rs | 50 +++++++------------ 5 files changed, 79 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 2e5c6a445790..74bdd07a1c94 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -7,6 +7,7 @@ use crate::query::Providers; use rustc_data_structures::fx::FxIndexMap; +use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{self as hir, LangItem}; use rustc_span::def_id::LocalDefIdMap; @@ -89,10 +90,18 @@ pub enum ClosureKind { FnOnce, } -impl<'tcx> ClosureKind { +impl ClosureKind { /// This is the initial value used when doing upvar inference. pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn; + pub const fn as_str(self) -> &'static str { + match self { + ClosureKind::Fn => "Fn", + ClosureKind::FnMut => "FnMut", + ClosureKind::FnOnce => "FnOnce", + } + } + /// Returns `true` if a type that impls this closure kind /// must also implement `other`. pub fn extends(self, other: ty::ClosureKind) -> bool { @@ -115,7 +124,7 @@ pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId { /// Returns the representative scalar type for this closure kind. /// See `Ty::to_opt_closure_kind` for more details. - pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match self { ClosureKind::Fn => tcx.types.i8, ClosureKind::FnMut => tcx.types.i16, @@ -124,6 +133,12 @@ pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { } } +impl IntoDiagnosticArg for ClosureKind { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(self.as_str().into()) + } +} + /// A composite describing a `Place` that is captured by a closure. #[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d3fd49150ba2..0c90e223a84c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2870,11 +2870,7 @@ pub struct PrintClosureAsImpl<'tcx> { } ty::ClosureKind { - match *self { - ty::ClosureKind::Fn => p!("Fn"), - ty::ClosureKind::FnMut => p!("FnMut"), - ty::ClosureKind::FnOnce => p!("FnOnce"), - } + p!(write("{}", self.as_str())) } ty::Predicate<'tcx> { diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl index f57f1bad15dc..f4c9dfa34882 100644 --- a/compiler/rustc_trait_selection/messages.ftl +++ b/compiler/rustc_trait_selection/messages.ftl @@ -8,6 +8,15 @@ trait_selection_adjust_signature_remove_borrow = consider adjusting the signatur *[other] arguments } +trait_selection_closure_fn_mut_label = closure is `FnMut` because it mutates the variable `{$place}` here + +trait_selection_closure_fn_once_label = closure is `FnOnce` because it moves the variable `{$place}` out of its environment + +trait_selection_closure_kind_mismatch = expected a closure that implements the `{$expected}` trait, but this closure only implements `{$found}` + .label = this closure implements `{$found}`, not `{$expected}` + +trait_selection_closure_kind_requirement = the requirement to implement `{$expected}` derives from here + trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries} trait_selection_empty_on_clause_in_rustc_on_unimplemented = empty `on`-clause in `#[rustc_on_unimplemented]` diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index dde9e9c9ac69..c1fb287d63ef 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -4,7 +4,7 @@ SubdiagnosticMessage, }; use rustc_macros::Diagnostic; -use rustc_middle::ty::{self, PolyTraitRef, Ty}; +use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty}; use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] @@ -131,3 +131,37 @@ fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) } } } + +#[derive(Diagnostic)] +#[diag(trait_selection_closure_kind_mismatch, code = "E0525")] +pub struct ClosureKindMismatch { + #[primary_span] + #[label] + pub closure_span: Span, + pub expected: ClosureKind, + pub found: ClosureKind, + #[label(trait_selection_closure_kind_requirement)] + pub cause_span: Span, + + #[subdiagnostic] + pub fn_once_label: Option, + + #[subdiagnostic] + pub fn_mut_label: Option, +} + +#[derive(Subdiagnostic)] +#[label(trait_selection_closure_fn_once_label)] +pub struct ClosureFnOnceLabel { + #[primary_span] + pub span: Span, + pub place: String, +} + +#[derive(Subdiagnostic)] +#[label(trait_selection_closure_fn_mut_label)] +pub struct ClosureFnMutLabel { + #[primary_span] + pub span: Span, + pub place: String, +} diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 4d85e2b60893..071d545251d8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -7,6 +7,7 @@ ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionError, TraitNotObjectSafe, }; +use crate::errors::{ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch}; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{self, InferCtxt}; @@ -3142,24 +3143,15 @@ fn report_closure_error( kind: ty::ClosureKind, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let closure_span = self.tcx.def_span(closure_def_id); - let mut err = struct_span_err!( - self.tcx.sess, - closure_span, - E0525, - "expected a closure that implements the `{}` trait, \ - but this closure only implements `{}`", - kind, - found_kind - ); - err.span_label( + let mut err = ClosureKindMismatch { closure_span, - format!("this closure implements `{found_kind}`, not `{kind}`"), - ); - err.span_label( - obligation.cause.span, - format!("the requirement to implement `{kind}` derives from here"), - ); + expected: kind, + found: found_kind, + cause_span: obligation.cause.span, + fn_once_label: None, + fn_mut_label: None, + }; // Additional context information explaining why the closure only implements // a particular trait. @@ -3167,30 +3159,22 @@ fn report_closure_error( let hir_id = self.tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local()); match (found_kind, typeck_results.closure_kind_origins().get(hir_id)) { (ty::ClosureKind::FnOnce, Some((span, place))) => { - err.span_label( - *span, - format!( - "closure is `FnOnce` because it moves the \ - variable `{}` out of its environment", - ty::place_to_string_for_capture(self.tcx, place) - ), - ); + err.fn_once_label = Some(ClosureFnOnceLabel { + span: *span, + place: ty::place_to_string_for_capture(self.tcx, &place), + }) } (ty::ClosureKind::FnMut, Some((span, place))) => { - err.span_label( - *span, - format!( - "closure is `FnMut` because it mutates the \ - variable `{}` here", - ty::place_to_string_for_capture(self.tcx, place) - ), - ); + err.fn_mut_label = Some(ClosureFnMutLabel { + span: *span, + place: ty::place_to_string_for_capture(self.tcx, &place), + }) } _ => {} } } - err + self.tcx.sess.create_err(err) } fn report_type_parameter_mismatch_cyclic_type_error( From b6ac5764872a8b2d236460d889ccd745be6fff7d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 7 Aug 2023 14:23:01 +0800 Subject: [PATCH 35/76] rustc_interface: Dismantle `register_plugins` query --- compiler/rustc_driver_impl/src/lib.rs | 16 +-- compiler/rustc_interface/src/passes.rs | 47 ++----- compiler/rustc_interface/src/queries.rs | 167 +++++++++++++----------- compiler/rustc_metadata/src/creader.rs | 8 +- compiler/rustc_metadata/src/locator.rs | 13 +- 5 files changed, 119 insertions(+), 132 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 60dc9b200775..ec77569d4b87 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -32,7 +32,7 @@ use rustc_fluent_macro::fluent_messages; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; -use rustc_lint::LintStore; +use rustc_lint::{unerased_lint_store, LintStore}; use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutFileName, OutputType, TrimmedDefPaths}; @@ -411,15 +411,11 @@ fn run_compiler( return early_exit(); } - { - let plugins = queries.register_plugins()?; - let (.., lint_store) = &*plugins.borrow(); - - // Lint plugins are registered; now we can process command line flags. - if sess.opts.describe_lints { - describe_lints(sess, lint_store, true); - return early_exit(); - } + if sess.opts.describe_lints { + queries + .global_ctxt()? + .enter(|tcx| describe_lints(sess, unerased_lint_store(tcx), true)); + return early_exit(); } // Make sure name resolution and macro expansion is run. diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a34fdf4ecc9f..07c559354c09 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -12,7 +12,7 @@ use rustc_errors::PResult; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_fs_util::try_canonicalize; -use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE}; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_lint::{unerased_lint_store, BufferedEarlyLint, EarlyCheckNode, LintStore}; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; @@ -72,43 +72,16 @@ fn count_nodes(krate: &ast::Crate) -> usize { counter.count } -pub fn register_plugins<'a>( - sess: &'a Session, - metadata_loader: &'a dyn MetadataLoader, - register_lints: impl Fn(&Session, &mut LintStore), +pub(crate) fn create_lint_store( + sess: &Session, + metadata_loader: &dyn MetadataLoader, + register_lints: Option, pre_configured_attrs: &[ast::Attribute], - crate_name: Symbol, -) -> Result { - // these need to be set "early" so that expansion sees `quote` if enabled. - let features = rustc_expand::config::features(sess, pre_configured_attrs); - sess.init_features(features); - - let crate_types = util::collect_crate_types(sess, pre_configured_attrs); - sess.init_crate_types(crate_types); - - let stable_crate_id = StableCrateId::new( - crate_name, - sess.crate_types().contains(&CrateType::Executable), - sess.opts.cg.metadata.clone(), - sess.cfg_version, - ); - sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized"); - rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?; - - if sess.opts.incremental.is_some() { - sess.time("incr_comp_garbage_collect_session_directories", || { - if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) { - warn!( - "Error while trying to garbage collect incremental \ - compilation cache directory: {}", - e - ); - } - }); - } - +) -> LintStore { let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints()); - register_lints(sess, &mut lint_store); + if let Some(register_lints) = register_lints { + register_lints(sess, &mut lint_store); + } let registrars = sess.time("plugin_loading", || { plugin::load::load_plugins(sess, metadata_loader, pre_configured_attrs) @@ -120,7 +93,7 @@ pub fn register_plugins<'a>( } }); - Ok(lint_store) + lint_store } fn pre_expansion_lint<'a>( diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 8c4cdc6696a4..b805ff09ee4c 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -1,6 +1,6 @@ use crate::errors::{FailedWritingFile, RustcErrorFatal, RustcErrorUnexpectedAnnotation}; use crate::interface::{Compiler, Result}; -use crate::passes; +use crate::{passes, util}; use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; @@ -9,15 +9,14 @@ use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{AppendOnlyIndexVec, Lrc, OnceCell, RwLock, WorkerLocal}; -use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_incremental::DepGraphFuture; -use rustc_lint::LintStore; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; use rustc_middle::dep_graph::DepGraph; use rustc_middle::ty::{GlobalCtxt, TyCtxt}; -use rustc_session::config::{self, OutputFilenames, OutputType}; +use rustc_session::config::{self, CrateType, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; use rustc_session::{output::find_crate_name, Session}; use rustc_span::symbol::sym; @@ -85,12 +84,11 @@ pub struct Queries<'tcx> { arena: WorkerLocal>, hir_arena: WorkerLocal>, - dep_graph_future: Query>, parse: Query, pre_configure: Query<(ast::Crate, ast::AttrVec)>, crate_name: Query, - register_plugins: Query<(ast::Crate, ast::AttrVec, Lrc)>, - dep_graph: Query, + crate_types: Query>, + stable_crate_id: Query, // This just points to what's in `gcx_cell`. gcx: Query<&'tcx GlobalCtxt<'tcx>>, } @@ -102,12 +100,11 @@ pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> { gcx_cell: OnceCell::new(), arena: WorkerLocal::new(|_| Arena::default()), hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()), - dep_graph_future: Default::default(), parse: Default::default(), pre_configure: Default::default(), crate_name: Default::default(), - register_plugins: Default::default(), - dep_graph: Default::default(), + crate_types: Default::default(), + stable_crate_id: Default::default(), gcx: Default::default(), } } @@ -119,13 +116,6 @@ fn codegen_backend(&self) -> &Lrc { self.compiler.codegen_backend() } - fn dep_graph_future(&self) -> Result>> { - self.dep_graph_future.compute(|| { - let sess = self.session(); - Ok(sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess))) - }) - } - pub fn parse(&self) -> Result> { self.parse .compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit())) @@ -148,84 +138,111 @@ pub fn pre_configure(&self) -> Result Result)>> { - self.register_plugins.compute(|| { - let crate_name = *self.crate_name()?.borrow(); - let (krate, pre_configured_attrs) = self.pre_configure()?.steal(); - - let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {}; - let lint_store = passes::register_plugins( - self.session(), - &*self.codegen_backend().metadata_loader(), - self.compiler.register_lints.as_deref().unwrap_or_else(|| empty), - &pre_configured_attrs, - crate_name, - )?; - - // Compute the dependency graph (in the background). We want to do - // this as early as possible, to give the DepGraph maximum time to - // load before dep_graph() is called, but it also can't happen - // until after rustc_incremental::prepare_session_directory() is - // called, which happens within passes::register_plugins(). - self.dep_graph_future().ok(); - - Ok((krate, pre_configured_attrs, Lrc::new(lint_store))) - }) - } - fn crate_name(&self) -> Result> { self.crate_name.compute(|| { - Ok({ - let pre_configure_result = self.pre_configure()?; - let (_, pre_configured_attrs) = &*pre_configure_result.borrow(); - // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. - find_crate_name(self.session(), pre_configured_attrs) - }) + let pre_configure_result = self.pre_configure()?; + let (_, pre_configured_attrs) = &*pre_configure_result.borrow(); + // parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches. + Ok(find_crate_name(self.session(), pre_configured_attrs)) }) } - fn dep_graph(&self) -> Result> { - self.dep_graph.compute(|| { - let sess = self.session(); - let future_opt = self.dep_graph_future()?.steal(); - let dep_graph = future_opt - .and_then(|future| { - let (prev_graph, mut prev_work_products) = - sess.time("blocked_on_dep_graph_loading", || future.open().open(sess)); - // Convert from UnordMap to FxIndexMap by sorting - let prev_work_product_ids = - prev_work_products.items().map(|x| *x.0).into_sorted_stable_ord(); - let prev_work_products = prev_work_product_ids - .into_iter() - .map(|x| (x, prev_work_products.remove(&x).unwrap())) - .collect::>(); - rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products) - }) - .unwrap_or_else(DepGraph::new_disabled); - Ok(dep_graph) + fn crate_types(&self) -> Result>> { + self.crate_types.compute(|| { + let pre_configure_result = self.pre_configure()?; + let (_, pre_configured_attrs) = &*pre_configure_result.borrow(); + Ok(util::collect_crate_types(&self.session(), &pre_configured_attrs)) }) } + fn stable_crate_id(&self) -> Result> { + self.stable_crate_id.compute(|| { + let sess = self.session(); + Ok(StableCrateId::new( + *self.crate_name()?.borrow(), + self.crate_types()?.borrow().contains(&CrateType::Executable), + sess.opts.cg.metadata.clone(), + sess.cfg_version, + )) + }) + } + + fn dep_graph_future(&self) -> Result> { + let sess = self.session(); + let crate_name = *self.crate_name()?.borrow(); + let stable_crate_id = *self.stable_crate_id()?.borrow(); + + // `load_dep_graph` can only be called after `prepare_session_directory`. + rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?; + let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess)); + + if sess.opts.incremental.is_some() { + sess.time("incr_comp_garbage_collect_session_directories", || { + if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) { + warn!( + "Error while trying to garbage collect incremental \ + compilation cache directory: {}", + e + ); + } + }); + } + + Ok(res) + } + + fn dep_graph(&self, dep_graph_future: Option) -> DepGraph { + dep_graph_future + .and_then(|future| { + let sess = self.session(); + let (prev_graph, mut prev_work_products) = + sess.time("blocked_on_dep_graph_loading", || future.open().open(sess)); + // Convert from UnordMap to FxIndexMap by sorting + let prev_work_product_ids = + prev_work_products.items().map(|x| *x.0).into_sorted_stable_ord(); + let prev_work_products = prev_work_product_ids + .into_iter() + .map(|x| (x, prev_work_products.remove(&x).unwrap())) + .collect::>(); + rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products) + }) + .unwrap_or_else(DepGraph::new_disabled) + } + pub fn global_ctxt(&'tcx self) -> Result>> { self.gcx.compute(|| { - let crate_name = *self.crate_name()?.borrow(); - let (krate, pre_configured_attrs, lint_store) = self.register_plugins()?.steal(); + // Compute the dependency graph (in the background). We want to do this as early as + // possible, to give the DepGraph maximum time to load before `dep_graph` is called. + let dep_graph_future = self.dep_graph_future()?; + + let crate_name = self.crate_name()?.steal(); + let crate_types = self.crate_types()?.steal(); + let stable_crate_id = self.stable_crate_id()?.steal(); + let (krate, pre_configured_attrs) = self.pre_configure()?.steal(); let sess = self.session(); - - let cstore = RwLock::new(Box::new(CStore::new(sess)) as _); - let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id())); + let lint_store = Lrc::new(passes::create_lint_store( + sess, + &*self.codegen_backend().metadata_loader(), + self.compiler.register_lints.as_deref(), + &pre_configured_attrs, + )); + let cstore = RwLock::new(Box::new(CStore::new(stable_crate_id)) as _); + let definitions = RwLock::new(Definitions::new(stable_crate_id)); let source_span = AppendOnlyIndexVec::new(); let _id = source_span.push(krate.spans.inner_span); debug_assert_eq!(_id, CRATE_DEF_ID); let untracked = Untracked { cstore, source_span, definitions }; + // FIXME: Move these fields from session to tcx and make them immutable. + sess.init_crate_types(crate_types); + sess.stable_crate_id.set(stable_crate_id).expect("not yet initialized"); + sess.init_features(rustc_expand::config::features(sess, &pre_configured_attrs)); + let qcx = passes::create_global_ctxt( self.compiler, lint_store, - self.dep_graph()?.steal(), + self.dep_graph(dep_graph_future), untracked, &self.gcx_cell, &self.arena, diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 571af82d13a3..7c9aaeb5762b 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -20,7 +20,6 @@ use rustc_session::lint; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; -use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -262,9 +261,9 @@ pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) { } } - pub fn new(sess: &Session) -> CStore { + pub fn new(local_stable_crate_id: StableCrateId) -> CStore { let mut stable_crate_ids = StableCrateIdMap::default(); - stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE); + stable_crate_ids.insert(local_stable_crate_id, LOCAL_CRATE); CStore { // We add an empty entry for LOCAL_CRATE (which maps to zero) in // order to make array indices in `metas` match with the @@ -544,6 +543,9 @@ fn maybe_resolve_crate<'b>( self.sess, &**metadata_loader, name, + // The all loop is because `--crate-type=rlib --crate-type=rlib` is + // legal and produces both inside this type. + self.sess.crate_types().iter().all(|c| *c == CrateType::Rlib), hash, extra_filename, false, // is_host diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index a0c552f5fd6d..bf6004ba8644 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -222,7 +222,7 @@ use rustc_data_structures::svh::Svh; use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg}; use rustc_fs_util::try_canonicalize; -use rustc_session::config::{self, CrateType}; +use rustc_session::config; use rustc_session::cstore::{CrateSource, MetadataLoader}; use rustc_session::filesearch::FileSearch; use rustc_session::search_paths::PathKind; @@ -305,14 +305,12 @@ pub(crate) fn new( sess: &'a Session, metadata_loader: &'a dyn MetadataLoader, crate_name: Symbol, + is_rlib: bool, hash: Option, extra_filename: Option<&'a str>, is_host: bool, path_kind: PathKind, ) -> CrateLocator<'a> { - // The all loop is because `--crate-type=rlib --crate-type=rlib` is - // legal and produces both inside this type. - let is_rlib = sess.crate_types().iter().all(|c| *c == CrateType::Rlib); let needs_object_code = sess.opts.output_types.should_codegen(); // If we're producing an rlib, then we don't need object code. // Or, if we're not producing object code, then we don't need it either @@ -883,9 +881,10 @@ fn find_plugin_registrar_impl<'a>( sess, metadata_loader, name, - None, // hash - None, // extra_filename - true, // is_host + false, // is_rlib + None, // hash + None, // extra_filename + true, // is_host PathKind::Crate, ); From 1f1d49a2b722d2190a0f6caf4786bfaeadc37832 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 Jan 2023 20:47:07 +0000 Subject: [PATCH 36/76] impl Default for ExitStatus --- library/std/src/process.rs | 2 +- library/std/src/sys/unix/process/process_fuchsia.rs | 2 +- library/std/src/sys/unix/process/process_unix.rs | 2 +- library/std/src/sys/unix/process/process_unsupported.rs | 2 +- library/std/src/sys/unix/process/process_vxworks.rs | 2 +- library/std/src/sys/unsupported/process.rs | 2 +- library/std/src/sys/windows/process.rs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 62ce2cb33dc5..a2962da67175 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1460,7 +1460,7 @@ fn from(file: fs::File) -> Stdio { // vs `_exit`. Naming of Unix system calls is not standardised across Unices, so terminology is a // matter of convention and tradition. For clarity we usually speak of `exit`, even when we might // mean an underlying system call such as `_exit`. -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] #[stable(feature = "process", since = "1.0.0")] pub struct ExitStatus(imp::ExitStatus); diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs index 4c99d758c93a..6919cbd74a0e 100644 --- a/library/std/src/sys/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/unix/process/process_fuchsia.rs @@ -237,7 +237,7 @@ pub fn try_wait(&mut self) -> io::Result> { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(i64); impl ExitStatus { diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 39d1c8b1d8eb..4a1639787cc4 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -647,7 +647,7 @@ pub fn try_wait(&mut self) -> io::Result> { // // This is not actually an "exit status" in Unix terminology. Rather, it is a "wait status". // See the discussion in comments and doc comments for `std::process::ExitStatus`. -#[derive(PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy, Default)] pub struct ExitStatus(c_int); impl fmt::Debug for ExitStatus { diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs index f28ca58d0203..8e0b971af731 100644 --- a/library/std/src/sys/unix/process/process_unsupported.rs +++ b/library/std/src/sys/unix/process/process_unsupported.rs @@ -55,7 +55,7 @@ pub fn try_wait(&mut self) -> io::Result> { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c_int); impl ExitStatus { diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs index f549d37c3011..e3c0dfd4ce1e 100644 --- a/library/std/src/sys/unix/process/process_vxworks.rs +++ b/library/std/src/sys/unix/process/process_vxworks.rs @@ -182,7 +182,7 @@ pub fn try_wait(&mut self) -> io::Result> { } /// Unix exit statuses -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c_int); impl ExitStatus { diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs index d8259ce6e549..77b675aaa4e4 100644 --- a/library/std/src/sys/unsupported/process.rs +++ b/library/std/src/sys/unsupported/process.rs @@ -99,7 +99,7 @@ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] #[non_exhaustive] pub struct ExitStatus(); diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 10bc949e1f45..2cc7521eaaaf 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -647,7 +647,7 @@ pub fn into_handle(self) -> Handle { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c::DWORD); impl ExitStatus { From 057be381c60bf9b5c26497a42ad51917c3027b65 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 6 Aug 2023 17:00:26 +0000 Subject: [PATCH 37/76] Fix ICE --- compiler/rustc_ast_lowering/src/lib.rs | 16 ++++- compiler/rustc_hir_analysis/src/collect.rs | 65 ++++++++++++++----- .../consts/rustc-impl-const-stability.stderr | 11 +--- .../const-impl-requires-const-trait.stderr | 15 +---- .../derive-const-non-const-type.stderr | 11 +--- 5 files changed, 65 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dd081fafafba..8953c4fb27ab 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2746,9 +2746,9 @@ fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast span, res, segments: arena_vec![lcx; hir::PathSegment::new(Ident { - name: sym::host, - span, - }, hir_id, res)], + name: sym::host, + span, + }, hir_id, res)], }), )); lcx.expr(span, expr_kind) @@ -2762,6 +2762,16 @@ fn push_constness(&mut self, lcx: &mut LoweringContext<'_, 'hir>, constness: ast }, ) }); + + let attr_id = lcx.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(); + let attr = lcx.arena.alloc(Attribute { + kind: AttrKind::Normal(P(NormalAttr::from_ident(Ident::new(sym::rustc_host, span)))), + span, + id: attr_id, + style: AttrStyle::Outer, + }); + lcx.attrs.insert(hir_id.local_id, std::slice::from_ref(attr)); + let def_id = lcx.create_def(lcx.current_hir_id_owner.def_id, id, DefPathData::AnonConst, span); lcx.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index c65cd25f12c3..02a5d28b1e23 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1358,30 +1358,61 @@ fn impl_trait_ref( .of_trait .as_ref() .map(|ast_trait_ref| { - check_impl_constness( + let selfty = tcx.type_of(def_id).instantiate_identity(); + + if let Some(ErrorGuaranteed { .. }) = check_impl_constness( tcx, tcx.is_const_trait_impl_raw(def_id.to_def_id()), - ast_trait_ref, - ); - let selfty = tcx.type_of(def_id).instantiate_identity(); - icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty) + &ast_trait_ref, + ) { + // we have a const impl, but for a trait without `#[const_trait]`, so + // without the host param. If we continue with the HIR trait ref, we get + // ICEs for generic arg count mismatch. We do a little HIR editing to + // make astconv happy. + let mut path_segments = ast_trait_ref.path.segments.to_vec(); + let last_segment = path_segments.len() - 1; + let mut args = path_segments[last_segment].args().clone(); + let last_arg = args.args.len() - 1; + assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host))); + args.args = &args.args[..args.args.len() - 1]; + path_segments[last_segment].args = Some(&args); + let path = hir::Path { + span: ast_trait_ref.path.span, + res: ast_trait_ref.path.res, + segments: &path_segments, + }; + let trait_ref = hir::TraitRef { path: &path, hir_ref_id: ast_trait_ref.hir_ref_id }; + icx.astconv().instantiate_mono_trait_ref(&trait_ref, selfty) + } else { + icx.astconv().instantiate_mono_trait_ref(&ast_trait_ref, selfty) + } }) .map(ty::EarlyBinder::bind) } -fn check_impl_constness(tcx: TyCtxt<'_>, is_const: bool, ast_trait_ref: &hir::TraitRef<'_>) { - if is_const { - if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) { - let trait_name = tcx.item_name(trait_def_id).to_string(); - tcx.sess.emit_err(errors::ConstImplForNonConstTrait { - trait_ref_span: ast_trait_ref.path.span, - trait_name, - local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), - marking: (), - adding: (), - }); - } +fn check_impl_constness( + tcx: TyCtxt<'_>, + is_const: bool, + ast_trait_ref: &hir::TraitRef<'_>, +) -> Option { + if !is_const { + return None; } + + let trait_def_id = ast_trait_ref.trait_def_id()?; + if tcx.has_attr(trait_def_id, sym::const_trait) { + return None; + } + + let trait_name = tcx.item_name(trait_def_id).to_string(); + Some(tcx.sess.emit_err(errors::ConstImplForNonConstTrait { + trait_ref_span: ast_trait_ref.path.span, + trait_name, + local_trait_span: + trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), + marking: (), + adding: (), + })) } fn impl_polarity(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplPolarity { diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr index 7992bfe7752f..ba8e6c1555ce 100644 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -7,12 +7,6 @@ LL | impl const Default for Data { = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0107]: missing generics for trait `Default` - --> $DIR/rustc-impl-const-stability.rs:15:12 - | -LL | impl const Default for Data { - | ^^^^^^^ expected 18446744073709551615 generic arguments - error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates --> $DIR/rustc-impl-const-stability.rs:15:6 | @@ -22,7 +16,6 @@ LL | impl const Default for Data { = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0207. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index becb2ca10425..c45af1a9f8ac 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -10,18 +10,5 @@ LL | impl const A for () {} = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` = note: adding a non-const method body in the future would be a breaking change -error[E0107]: missing generics for trait `A` - --> $DIR/const-impl-requires-const-trait.rs:8:12 - | -LL | impl const A for () {} - | ^ expected 18446744073709551615 generic arguments - | -note: trait defined here, with 18446744073709551615 generic parameters: - --> $DIR/const-impl-requires-const-trait.rs:5:11 - | -LL | pub trait A {} - | ^ +error: aborting due to previous error -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 7d7518a887fa..1c69ad431714 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -8,14 +8,5 @@ LL | #[derive_const(Default)] = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0107]: missing generics for trait `Default` - --> $DIR/derive-const-non-const-type.rs:10:16 - | -LL | #[derive_const(Default)] - | ^^^^^^^ expected 18446744073709551615 generic arguments - | - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) +error: aborting due to previous error -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0107`. From a2058ddbed82adda55ce39f0e0915996706cb2b9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 7 Aug 2023 13:31:14 -0400 Subject: [PATCH 38/76] Review feedback: return empty iff !should_codegen, and use simpler unconditional logic otherwise. --- compiler/rustc_codegen_ssa/src/back/linker.rs | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 74b81733356a..a1e322f4b313 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1698,23 +1698,16 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) - } fn exported_symbols_for_proc_macro_crate(tcx: TyCtxt<'_>) -> Vec { - let mut symbols = Vec::new(); + // `exported_symbols` will be empty when !should_codegen. + if !tcx.sess.opts.output_types.should_codegen() { + return Vec::new(); + } let stable_crate_id = tcx.sess.local_stable_crate_id(); let proc_macro_decls_name = tcx.sess.generate_proc_macro_decls_symbol(stable_crate_id); let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx); - // You would think that both the two names would always be there, but in - // pnkfelix's local experiments that was not case. So instead we walk the - // list and only add them if they *are* there. - for_each_exported_symbols_include_dep(tcx, CrateType::ProcMacro, |symbol, _info, cnum| { - let name = symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum); - if name == proc_macro_decls_name || name == metadata_symbol_name { - symbols.push(name); - } - }); - - return symbols; + vec![proc_macro_decls_name, metadata_symbol_name] } pub(crate) fn linked_symbols( From f837c48f0d8da1a205b7ab97846bc90f8d497271 Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Tue, 11 Jul 2023 16:19:42 -0700 Subject: [PATCH 39/76] CFI: Fix error compiling core with LLVM CFI enabled Fix #90546 by filtering out global value function pointer types from the type tests, and adding the LowerTypeTests pass to the rustc LTO optimization pipelines. --- compiler/rustc_codegen_llvm/src/back/write.rs | 3 ++ compiler/rustc_codegen_llvm/src/builder.rs | 43 ++++++++++--------- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 4 ++ .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 16 +++++++ .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 11 +++++ compiler/rustc_session/messages.ftl | 4 +- compiler/rustc_session/src/errors.rs | 4 ++ compiler/rustc_session/src/session.rs | 12 ++++-- tests/ui/lto/issue-100772.rs | 4 +- .../issue-111184-generator-witness.rs | 4 +- .../ui/sanitize/sanitizer-cfi-requires-lto.rs | 2 +- .../sanitizer-cfi-requires-lto.stderr | 2 +- ...-rustc-lto-requires-single-codegen-unit.rs | 8 ++++ ...tc-lto-requires-single-codegen-unit.stderr | 4 ++ 14 files changed, 90 insertions(+), 31 deletions(-) create mode 100644 tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs create mode 100644 tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 53b4296802ef..d12f7615361a 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -449,6 +449,8 @@ pub(crate) unsafe fn llvm_optimize( Some(llvm::SanitizerOptions { sanitize_address: config.sanitizer.contains(SanitizerSet::ADDRESS), sanitize_address_recover: config.sanitizer_recover.contains(SanitizerSet::ADDRESS), + sanitize_cfi: config.sanitizer.contains(SanitizerSet::CFI), + sanitize_kcfi: config.sanitizer.contains(SanitizerSet::KCFI), sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY), sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY), sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int, @@ -484,6 +486,7 @@ pub(crate) unsafe fn llvm_optimize( &*module.module_llvm.tm, to_pass_builder_opt_level(opt_level), opt_stage, + cgcx.opts.cg.linker_plugin_lto.enabled(), config.no_prepopulate_passes, config.verify_llvm_ir, using_thin_buffers, diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 43258078bd77..169123d36f7e 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1525,9 +1525,9 @@ fn cfi_type_test( fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, ) { - let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; - if is_indirect_call && fn_abi.is_some() && self.tcx.sess.is_sanitizer_cfi_enabled() { - if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::CFI) { + let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) }; + if self.tcx.sess.is_sanitizer_cfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call { + if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::CFI) { return; } @@ -1539,7 +1539,7 @@ fn cfi_type_test( options.insert(TypeIdOptions::NORMALIZE_INTEGERS); } - let typeid = typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options); + let typeid = typeid_for_fnabi(self.tcx, fn_abi, options); let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap(); // Test whether the function pointer is associated with the type identifier. @@ -1563,25 +1563,26 @@ fn kcfi_operand_bundle( fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, ) -> Option> { - let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; - let kcfi_bundle = if is_indirect_call && self.tcx.sess.is_sanitizer_kcfi_enabled() { - if fn_attrs.is_some() && fn_attrs.unwrap().no_sanitize.contains(SanitizerSet::KCFI) { - return None; - } + let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) }; + let kcfi_bundle = + if self.tcx.sess.is_sanitizer_kcfi_enabled() && let Some(fn_abi) = fn_abi && is_indirect_call { + if let Some(fn_attrs) = fn_attrs && fn_attrs.no_sanitize.contains(SanitizerSet::KCFI) { + return None; + } - let mut options = TypeIdOptions::empty(); - if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() { - options.insert(TypeIdOptions::GENERALIZE_POINTERS); - } - if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() { - options.insert(TypeIdOptions::NORMALIZE_INTEGERS); - } + let mut options = TypeIdOptions::empty(); + if self.tcx.sess.is_sanitizer_cfi_generalize_pointers_enabled() { + options.insert(TypeIdOptions::GENERALIZE_POINTERS); + } + if self.tcx.sess.is_sanitizer_cfi_normalize_integers_enabled() { + options.insert(TypeIdOptions::NORMALIZE_INTEGERS); + } - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap(), options); - Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) - } else { - None - }; + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options); + Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) + } else { + None + }; kcfi_bundle } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 6ef3418cc5f7..5c680d1e638a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -477,6 +477,8 @@ pub enum OptStage { pub struct SanitizerOptions { pub sanitize_address: bool, pub sanitize_address_recover: bool, + pub sanitize_cfi: bool, + pub sanitize_kcfi: bool, pub sanitize_memory: bool, pub sanitize_memory_recover: bool, pub sanitize_memory_track_origins: c_int, @@ -1083,6 +1085,7 @@ pub fn LLVMStructTypeInContext<'a>( pub fn LLVMRustGlobalAddMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata); pub fn LLVMValueAsMetadata(Node: &Value) -> &Metadata; pub fn LLVMIsAFunction(Val: &Value) -> Option<&Value>; + pub fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool; // Operations on constants of any type pub fn LLVMConstNull(Ty: &Type) -> &Value; @@ -2319,6 +2322,7 @@ pub fn LLVMRustOptimize<'a>( TM: &'a TargetMachine, OptLevel: PassBuilderOptLevel, OptStage: OptStage, + IsLinkerPluginLTO: bool, NoPrepopulatePasses: bool, VerifyIR: bool, UseThinLTOBuffers: bool, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c43a02724773..3efa888e57fa 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -29,6 +29,7 @@ #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" #include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/IPO/LowerTypeTests.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/Utils/AddDiscriminators.h" #include "llvm/Transforms/Utils/FunctionImportUtils.h" @@ -599,6 +600,8 @@ enum class LLVMRustOptStage { struct LLVMRustSanitizerOptions { bool SanitizeAddress; bool SanitizeAddressRecover; + bool SanitizeCFI; + bool SanitizeKCFI; bool SanitizeMemory; bool SanitizeMemoryRecover; int SanitizeMemoryTrackOrigins; @@ -615,6 +618,7 @@ LLVMRustOptimize( LLVMTargetMachineRef TMRef, LLVMRustPassBuilderOptLevel OptLevelRust, LLVMRustOptStage OptStage, + bool IsLinkerPluginLTO, bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers, bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, @@ -722,6 +726,18 @@ LLVMRustOptimize( std::vector> OptimizerLastEPCallbacks; + if (!IsLinkerPluginLTO + && SanitizerOptions && SanitizerOptions->SanitizeCFI + && !NoPrepopulatePasses) { + PipelineStartEPCallbacks.push_back( + [](ModulePassManager &MPM, OptimizationLevel Level) { + MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr, + /*ImportSummary=*/nullptr, + /*DropTypeTests=*/false)); + } + ); + } + if (VerifyIR) { PipelineStartEPCallbacks.push_back( [VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) { diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index ea04899ab687..bc2b9f908f4f 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1952,3 +1952,14 @@ extern "C" int32_t LLVMRustGetElementTypeArgIndex(LLVMValueRef CallSite) { extern "C" bool LLVMRustIsBitcode(char *ptr, size_t len) { return identify_magic(StringRef(ptr, len)) == file_magic::bitcode; } + +extern "C" bool LLVMRustIsNonGVFunctionPointerTy(LLVMValueRef V) { + if (unwrap(V)->getType()->isPointerTy()) { + if (auto *GV = dyn_cast(unwrap(V))) { + if (GV->getValueType()->isFunctionTy()) + return false; + } + return true; + } + return false; +} diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index 4897bd8d5dae..7c1e6954df20 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -86,7 +86,9 @@ session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-genera session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` -session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` +session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto` + +session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1` session_sanitizer_not_supported = {$us} sanitizer is not supported for this target diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 4a3e668da111..42c7b929bb1b 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -114,6 +114,10 @@ pub struct CannotMixAndMatchSanitizers { #[diag(session_sanitizer_cfi_requires_lto)] pub struct SanitizerCfiRequiresLto; +#[derive(Diagnostic)] +#[diag(session_sanitizer_cfi_requires_single_codegen_unit)] +pub struct SanitizerCfiRequiresSingleCodegenUnit; + #[derive(Diagnostic)] #[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)] pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi; diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index ea5beb6f8beb..e6db759032eb 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1616,13 +1616,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) { // LLVM CFI requires LTO. if sess.is_sanitizer_cfi_enabled() - && !(sess.lto() == config::Lto::Fat - || sess.lto() == config::Lto::Thin - || sess.opts.cg.linker_plugin_lto.enabled()) + && !(sess.lto() == config::Lto::Fat || sess.opts.cg.linker_plugin_lto.enabled()) { sess.emit_err(errors::SanitizerCfiRequiresLto); } + // LLVM CFI using rustc LTO requires a single codegen unit. + if sess.is_sanitizer_cfi_enabled() + && sess.lto() == config::Lto::Fat + && !(sess.codegen_units().as_usize() == 1) + { + sess.emit_err(errors::SanitizerCfiRequiresSingleCodegenUnit); + } + // LLVM CFI is incompatible with LLVM KCFI. if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() { sess.emit_err(errors::CannotMixAndMatchSanitizers { diff --git a/tests/ui/lto/issue-100772.rs b/tests/ui/lto/issue-100772.rs index d6b06719277e..eeb511962362 100644 --- a/tests/ui/lto/issue-100772.rs +++ b/tests/ui/lto/issue-100772.rs @@ -1,6 +1,6 @@ -// run-pass +// build-pass // needs-sanitizer-cfi -// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi +// compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi // no-prefer-dynamic // only-x86_64-unknown-linux-gnu diff --git a/tests/ui/sanitize/issue-111184-generator-witness.rs b/tests/ui/sanitize/issue-111184-generator-witness.rs index 8f4118057cec..d36d8bce561f 100644 --- a/tests/ui/sanitize/issue-111184-generator-witness.rs +++ b/tests/ui/sanitize/issue-111184-generator-witness.rs @@ -2,10 +2,10 @@ // encode_ty and caused the compiler to ICE. // // needs-sanitizer-cfi -// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021 +// compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021 // no-prefer-dynamic // only-x86_64-unknown-linux-gnu -// run-pass +// build-pass use std::future::Future; diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs index 29e32889fcc7..e9a49dd3ff11 100644 --- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs +++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.rs @@ -1,4 +1,4 @@ -// Verifies that `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`. +// Verifies that `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`. // // needs-sanitizer-cfi // compile-flags: -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi diff --git a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr index 5e706b513b91..8cd9c544417f 100644 --- a/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr +++ b/tests/ui/sanitize/sanitizer-cfi-requires-lto.stderr @@ -1,4 +1,4 @@ -error: `-Zsanitizer=cfi` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` +error: `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto` error: aborting due to previous error diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs new file mode 100644 index 000000000000..a13c12c17878 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.rs @@ -0,0 +1,8 @@ +// Verifies that `-Zsanitizer=cfi` with `-Clto` or `-Clto=thin` requires `-Ccodegen-units=1`. +// +// needs-sanitizer-cfi +// compile-flags: -Ccodegen-units=2 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr new file mode 100644 index 000000000000..136f49360849 --- /dev/null +++ b/tests/ui/sanitize/sanitizer-cfi-with-rustc-lto-requires-single-codegen-unit.stderr @@ -0,0 +1,4 @@ +error: `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1` + +error: aborting due to previous error + From a75e2284fb6c97fcc703a37e2ec1d1d1a0b4d501 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Mon, 7 Aug 2023 16:38:09 -0700 Subject: [PATCH 40/76] Bump compiler_builtins to 0.1.100 --- Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45959c039e7e..f863123531c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -641,9 +641,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.98" +version = "0.1.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbefa16407456e5cad1ad066c84dfcb980afe4437103a0007d1c2f136130210" +checksum = "d6c0f24437059853f0fa64afc51f338f93647a3de4cf3358ba1bb4171a199775" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index c47f910dadfa..73197532dcc0 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } libc = { version = "0.2.146", default-features = false, features = ['rustc-dep-of-std'], public = true } -compiler_builtins = { version = "0.1.98" } +compiler_builtins = { version = "0.1.100" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.14", default-features = false, features = ['rustc-dep-of-std'] } From 8dcb8e0759ea48df925968557bd81e37c084e2d0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 7 Aug 2023 22:09:12 +0000 Subject: [PATCH 41/76] Unconditionally record lifetime mapping --- compiler/rustc_ast_lowering/src/lib.rs | 6 +----- compiler/rustc_hir/src/hir.rs | 2 +- compiler/rustc_hir_analysis/src/collect/predicates_of.rs | 2 +- compiler/rustc_ty_utils/src/implied_bounds.rs | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d29e9f9b3f65..a8151ccfff3c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1663,11 +1663,7 @@ fn lower_opaque_inner( ); debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params); - let lifetime_mapping = if in_trait { - Some(&*self.arena.alloc_slice(&synthesized_lifetime_args)) - } else { - None - }; + let lifetime_mapping = self.arena.alloc_slice(&synthesized_lifetime_args); let opaque_ty_item = hir::OpaqueTy { generics: this.arena.alloc(hir::Generics { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c6f8d1e211d5..61353c7b1ec5 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2675,7 +2675,7 @@ pub struct OpaqueTy<'hir> { /// /// This mapping associated a captured lifetime (first parameter) with the new /// early-bound lifetime that was generated for the opaque. - pub lifetime_mapping: Option<&'hir [(&'hir Lifetime, LocalDefId)]>, + pub lifetime_mapping: &'hir [(&'hir Lifetime, LocalDefId)], /// Whether the opaque is a return-position impl trait (or async future) /// originating from a trait method. This makes it so that the opaque is /// lowered as an associated type. diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 83220be68838..f0a426722c30 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -59,7 +59,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen let opaque_ty_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id.expect_local()); let opaque_ty_node = tcx.hir().get(opaque_ty_id); let Node::Item(&Item { - kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping: Some(lifetime_mapping), .. }), + kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping, .. }), .. }) = opaque_ty_node else { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 7eb1042d2f8b..01fe3a408e86 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -67,7 +67,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' let mut mapping = FxHashMap::default(); let generics = tcx.generics_of(def_id); for &(lifetime, new_early_bound_def_id) in - lifetime_mapping.expect("expected lifetime mapping for RPITIT") + lifetime_mapping { if let Some(rbv::ResolvedArg::LateBound(_, _, def_id)) = tcx.named_bound_var(lifetime.hir_id) From 9215346d35f4315206131b4ef53138a10429fbde Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 8 Aug 2023 10:31:42 +0200 Subject: [PATCH 42/76] offset_of: guard against invalid use (with unsized fields) --- compiler/rustc_target/src/abi/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 084c917cc317..dd435dbb0a30 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -39,7 +39,7 @@ fn deref(&self) -> &&'a LayoutS { /// Trait that needs to be implemented by the higher-level type representation /// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality. -pub trait TyAbiInterface<'a, C>: Sized { +pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug { fn ty_and_layout_for_variant( this: TyAndLayout<'a, Self>, cx: &C, @@ -135,6 +135,11 @@ pub fn offset_of_subfield(self, cx: &C, indices: impl Iterator) for index in indices { offset += layout.fields.offset(index); layout = layout.field(cx, index); + assert!( + layout.is_sized(), + "offset of unsized field (type {:?}) cannot be computed statically", + layout.ty + ); } offset From a7132bf3873d63d3534c28dc7be85c5b363395f6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 8 Aug 2023 10:31:44 +0200 Subject: [PATCH 43/76] interpret: remove incomplete protection against invalid where clauses --- compiler/rustc_const_eval/messages.ftl | 2 - compiler/rustc_const_eval/src/errors.rs | 4 - .../rustc_const_eval/src/interpret/step.rs | 7 +- .../rustc_middle/src/mir/interpret/error.rs | 2 - src/tools/compiletest/src/runtest.rs | 2 +- .../generic_const_exprs/issue-80742.rs | 8 +- .../generic_const_exprs/issue-80742.stderr | 75 ++----------------- 7 files changed, 16 insertions(+), 84 deletions(-) diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 0b336109921f..e5dd5729d890 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -303,8 +303,6 @@ const_eval_remainder_overflow = overflow in signed remainder (dividing MIN by -1) const_eval_scalar_size_mismatch = scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead -const_eval_size_of_unsized = - size_of called on unsized type `{$ty}` const_eval_size_overflow = overflow computing total size of `{$name}` diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 3a4e2648b808..4362cae7ed74 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -862,7 +862,6 @@ fn diagnostic_message(&self) -> DiagnosticMessage { InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => { rustc_middle::error::middle_adjust_for_foreign_abi_error } - InvalidProgramInfo::SizeOfUnsizedType(_) => const_eval_size_of_unsized, InvalidProgramInfo::ConstPropNonsense => { panic!("We had const-prop nonsense, this should never be printed") } @@ -890,9 +889,6 @@ fn add_args( builder.set_arg("arch", arch); builder.set_arg("abi", abi.name()); } - InvalidProgramInfo::SizeOfUnsizedType(ty) => { - builder.set_arg("ty", ty); - } } } } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index f04c73105d22..0740894a4ffa 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -269,13 +269,10 @@ pub fn eval_rvalue_into_place( let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?; let layout = self.layout_of(ty)?; if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() { - // FIXME: This should be a span_bug, but const generics can run MIR - // that is not properly type-checked yet (#97477). - self.tcx.sess.delay_span_bug( + span_bug!( self.frame().current_span(), - format!("{null_op:?} MIR operator called for unsized type {ty}"), + "{null_op:?} MIR operator called for unsized type {ty}", ); - throw_inval!(SizeOfUnsizedType(ty)); } let val = match null_op { mir::NullOp::SizeOf => layout.size.bytes(), diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 2e46bfc1a381..e6ef5a41ee0c 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -184,8 +184,6 @@ pub enum InvalidProgramInfo<'tcx> { /// (which unfortunately typeck does not reject). /// Not using `FnAbiError` as that contains a nested `LayoutError`. FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), - /// SizeOf of unsized type was requested. - SizeOfUnsizedType(Ty<'tcx>), /// We are runnning into a nonsense situation due to ConstProp violating our invariants. ConstPropNonsense, } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index c19874204170..3d237eb25cc9 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1645,7 +1645,7 @@ fn check_expected_errors(&self, expected_errors: Vec, proc_res: & if self.props.known_bug { if !expected_errors.is_empty() { self.fatal_proc_rec( - "`known_bug` tests should not have an expected errors", + "`known_bug` tests should not have an expected error", proc_res, ); } diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs index 275f69953024..6b2a0153f510 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs @@ -1,4 +1,9 @@ // check-fail +// known-bug: #97477 +// failure-status: 101 +// normalize-stderr-test "note: .*\n\n" -> "" +// normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +// rustc-env:RUST_BACKTRACE=0 // This test used to cause an ICE in rustc_mir::interpret::step::eval_rvalue_into_place @@ -27,6 +32,5 @@ pub fn new(val: T) -> Inline { } fn main() { - let dst = Inline::::new(0); //~ ERROR - //~^ ERROR + let dst = Inline::::new(0); } diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr index dc3a400cbaa8..79ed82e02e0d 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.stderr @@ -1,71 +1,10 @@ -error[E0080]: evaluation of `Inline::::{constant#0}` failed +error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:272:21: SizeOf MIR operator called for unsized type dyn Debug --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: size_of called on unsized type `dyn Debug` - | -note: inside `std::mem::size_of::` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `Inline::::{constant#0}` - --> $DIR/issue-80742.rs:22:10 - | -LL | [u8; size_of::() + 1]: , - | ^^^^^^^^^^^^^^ -error[E0599]: the function or associated item `new` exists for struct `Inline`, but its trait bounds were not satisfied - --> $DIR/issue-80742.rs:30:36 - | -LL | struct Inline - | ---------------- function or associated item `new` not found for this struct -... -LL | let dst = Inline::::new(0); - | ^^^ function or associated item cannot be called on `Inline` due to unsatisfied trait bounds - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - | - = note: doesn't satisfy `dyn Debug: Sized` - | -note: trait bound `dyn Debug: Sized` was not satisfied - --> $DIR/issue-80742.rs:20:6 - | -LL | impl Inline - | ^ --------- - | | - | unsatisfied trait bound introduced here -help: consider relaxing the type parameter's implicit `Sized` bound - | -LL | impl Inline - | ++++++++ +Box +query stack during panic: +#0 [eval_to_allocation_raw] const-evaluating + checking `::{constant#0}` +#1 [eval_to_valtree] evaluating type-level constant +end of query stack +error: aborting due to previous error -error[E0080]: evaluation of `Inline::::{constant#0}` failed - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL - | - = note: size_of called on unsized type `dyn Debug` - | -note: inside `std::mem::size_of::` - --> $SRC_DIR/core/src/mem/mod.rs:LL:COL -note: inside `Inline::::{constant#0}` - --> $DIR/issue-80742.rs:14:10 - | -LL | [u8; size_of::() + 1]: , - | ^^^^^^^^^^^^^^ - -error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time - --> $DIR/issue-80742.rs:30:15 - | -LL | let dst = Inline::::new(0); - | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `dyn Debug` -note: required by a bound in `Inline` - --> $DIR/issue-80742.rs:12:15 - | -LL | struct Inline - | ^ required by this bound in `Inline` -help: consider relaxing the implicit `Sized` restriction - | -LL | struct Inline - | ++++++++ - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0080, E0277, E0599. -For more information about an error, try `rustc --explain E0080`. From 420ee167a8fbda2a078cb3a294fa1108c0180c98 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 7 Aug 2023 23:37:57 +0000 Subject: [PATCH 44/76] Install bidirectional outlives predicates for RPITITs (and RPITs) correctly --- .../src/collect/predicates_of.rs | 94 ++++++------------- compiler/rustc_middle/src/ty/context.rs | 69 ++++++++++++++ compiler/rustc_ty_utils/src/implied_bounds.rs | 35 +++---- .../in-trait/outlives-in-nested-rpit.rs | 11 +++ 4 files changed, 121 insertions(+), 88 deletions(-) create mode 100644 tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index f0a426722c30..495e663666cb 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -2,16 +2,16 @@ use crate::bounds::Bounds; use crate::collect::ItemCtxt; use crate::constrained_generic_params as cgp; -use hir::{HirId, Lifetime, Node}; +use hir::{HirId, Node}; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate}; +use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate}; use rustc_span::symbol::Ident; -use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_span::{Span, DUMMY_SP}; /// Returns a list of all type predicates (explicit and implicit) for the definition with /// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus @@ -55,17 +55,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen use rustc_hir::*; match tcx.opt_rpitit_info(def_id.to_def_id()) { - Some(ImplTraitInTraitData::Trait { opaque_def_id, fn_def_id }) => { - let opaque_ty_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id.expect_local()); - let opaque_ty_node = tcx.hir().get(opaque_ty_id); - let Node::Item(&Item { - kind: ItemKind::OpaqueTy(OpaqueTy { lifetime_mapping, .. }), - .. - }) = opaque_ty_node - else { - bug!("unexpected {opaque_ty_node:?}") - }; - + Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) => { let mut predicates = Vec::new(); // RPITITs should inherit the predicates of their parent. This is @@ -78,13 +68,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // We also install bidirectional outlives predicates for the RPITIT // to keep the duplicates lifetimes from opaque lowering in sync. + // We only need to compute bidirectional outlives for the duplicated + // opaque lifetimes, which explains the slicing below. compute_bidirectional_outlives_predicates( tcx, - def_id, - lifetime_mapping.iter().map(|(lifetime, def_id)| { - (**lifetime, (*def_id, lifetime.ident.name, lifetime.ident.span)) - }), - tcx.generics_of(def_id.to_def_id()), + &tcx.generics_of(def_id.to_def_id()).params + [tcx.generics_of(fn_def_id).params.len()..], &mut predicates, ); @@ -351,21 +340,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen }; debug!(?lifetimes); - let lifetime_mapping = std::iter::zip(lifetimes, ast_generics.params) - .map(|(arg, dup)| { - let hir::GenericArg::Lifetime(arg) = arg else { bug!() }; - (**arg, dup) - }) - .filter(|(_, dup)| matches!(dup.kind, hir::GenericParamKind::Lifetime { .. })) - .map(|(lifetime, dup)| (lifetime, (dup.def_id, dup.name.ident().name, dup.span))); - - compute_bidirectional_outlives_predicates( - tcx, - def_id, - lifetime_mapping, - generics, - &mut predicates, - ); + compute_bidirectional_outlives_predicates(tcx, &generics.params, &mut predicates); debug!(?predicates); } @@ -379,41 +354,28 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen /// enforce that these lifetimes stay in sync. fn compute_bidirectional_outlives_predicates<'tcx>( tcx: TyCtxt<'tcx>, - item_def_id: LocalDefId, - lifetime_mapping: impl Iterator, - generics: &Generics, + opaque_own_params: &[ty::GenericParamDef], predicates: &mut Vec<(ty::Clause<'tcx>, Span)>, ) { - let icx = ItemCtxt::new(tcx, item_def_id); - - for (arg, (dup_def, name, span)) in lifetime_mapping { - let orig_region = icx.astconv().ast_region_to_region(&arg, None); - if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) { - // There is no late-bound lifetime to actually match up here, since the lifetime doesn't - // show up in the opaque's parent's args. - continue; + for param in opaque_own_params { + let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); + if let ty::ReEarlyBound(..) = *orig_lifetime { + let dup_lifetime = ty::Region::new_early_bound( + tcx, + ty::EarlyBoundRegion { def_id: param.def_id, index: param.index, name: param.name }, + ); + let span = tcx.def_span(param.def_id); + predicates.push(( + ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_lifetime, dup_lifetime)) + .to_predicate(tcx), + span, + )); + predicates.push(( + ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_lifetime, orig_lifetime)) + .to_predicate(tcx), + span, + )); } - - let Some(dup_index) = generics.param_def_id_to_index(icx.tcx, dup_def.to_def_id()) else { - bug!() - }; - - let dup_region = ty::Region::new_early_bound( - tcx, - ty::EarlyBoundRegion { def_id: dup_def.to_def_id(), index: dup_index, name }, - ); - - predicates.push(( - ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(orig_region, dup_region)) - .to_predicate(tcx), - span, - )); - - predicates.push(( - ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(dup_region, orig_region)) - .to_predicate(tcx), - span, - )); } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5eef3e45f327..75a2c6cbd20b 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1931,6 +1931,75 @@ pub fn late_bound_vars(self, id: HirId) -> &'tcx List { ) } + /// Given the def-id of an early-bound lifetime on an RPIT corresponding to + /// a duplicated captured lifetime, map it back to the early- or late-bound + /// lifetime of the function from which it originally as captured. If it is + /// a late-bound lifetime, this will represent the liberated (`ReFree`) lifetime + /// of the signature. + // FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just + // re-use the generics of the opaque, this function will need to be tweaked slightly. + pub fn map_rpit_lifetime_to_fn_lifetime( + self, + mut rpit_lifetime_param_def_id: LocalDefId, + ) -> ty::Region<'tcx> { + debug_assert!( + matches!(self.def_kind(rpit_lifetime_param_def_id), DefKind::LifetimeParam), + "{rpit_lifetime_param_def_id:?} is a {}", + self.def_descr(rpit_lifetime_param_def_id.to_def_id()) + ); + + loop { + let parent = self.local_parent(rpit_lifetime_param_def_id); + let hir::OpaqueTy { lifetime_mapping, .. } = + self.hir().get_by_def_id(parent).expect_item().expect_opaque_ty(); + + let Some((lifetime, _)) = lifetime_mapping + .iter() + .find(|(_, duplicated_param)| *duplicated_param == rpit_lifetime_param_def_id) + else { + bug!("duplicated lifetime param should be present"); + }; + + match self.named_bound_var(lifetime.hir_id) { + Some(resolve_bound_vars::ResolvedArg::EarlyBound(ebv)) => { + let new_parent = self.parent(ebv); + + // If we map to another opaque, then it should be a parent + // of the opaque we mapped from. Continue mapping. + if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) { + debug_assert_eq!(self.parent(parent.to_def_id()), new_parent); + rpit_lifetime_param_def_id = ebv.expect_local(); + continue; + } + + let generics = self.generics_of(new_parent); + return ty::Region::new_early_bound( + self, + ty::EarlyBoundRegion { + def_id: ebv, + index: generics + .param_def_id_to_index(self, ebv) + .expect("early-bound var should be present in fn generics"), + name: self.hir().name(self.local_def_id_to_hir_id(ebv.expect_local())), + }, + ); + } + Some(resolve_bound_vars::ResolvedArg::LateBound(_, _, lbv)) => { + let new_parent = self.parent(lbv); + return ty::Region::new_free( + self, + new_parent, + ty::BoundRegionKind::BrNamed( + lbv, + self.hir().name(self.local_def_id_to_hir_id(lbv.expect_local())), + ), + ); + } + _ => bug!(), + } + } + } + /// Whether the `def_id` counts as const fn in the current crate, considering all active /// feature gates pub fn is_const_fn(self, def_id: DefId) -> bool { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 01fe3a408e86..ec2e0daaf88b 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -2,7 +2,6 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; @@ -52,9 +51,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap()))) } DefKind::AssocTy if let Some(data) = tcx.opt_rpitit_info(def_id.to_def_id()) => match data { - ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => { - let hir::OpaqueTy { lifetime_mapping, .. } = - *tcx.hir().expect_item(opaque_def_id.expect_local()).expect_opaque_ty(); + ty::ImplTraitInTraitData::Trait { fn_def_id, .. } => { // We need to remap all of the late-bound lifetimes in theassumed wf types // of the fn (which are represented as ReFree) to the early-bound lifetimes // of the RPITIT (which are represented by ReEarlyBound owned by the opaque). @@ -66,28 +63,22 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' // predicates we insert in the `explicit_predicates_of` query for RPITITs. let mut mapping = FxHashMap::default(); let generics = tcx.generics_of(def_id); - for &(lifetime, new_early_bound_def_id) in - lifetime_mapping - { - if let Some(rbv::ResolvedArg::LateBound(_, _, def_id)) = - tcx.named_bound_var(lifetime.hir_id) - { - let name = tcx.hir().name(lifetime.hir_id); - let index = generics - .param_def_id_to_index(tcx, new_early_bound_def_id.to_def_id()) - .unwrap(); + + // For each captured opaque lifetime, if it's late-bound (`ReFree` in this case, + // since it has been liberated), map it back to the early-bound lifetime of + // the GAT. Since RPITITs also have all of the fn's generics, we slice only + // the end of the list corresponding to the opaque's generics. + for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] { + let orig_lt = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()); + if matches!(*orig_lt, ty::ReFree(..)) { mapping.insert( - ty::Region::new_free( - tcx, - fn_def_id, - ty::BoundRegionKind::BrNamed(def_id, name), - ), + orig_lt, ty::Region::new_early_bound( tcx, ty::EarlyBoundRegion { - def_id: new_early_bound_def_id.to_def_id(), - index, - name, + def_id: param.def_id, + index: param.index, + name: param.name, }, ), ); diff --git a/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs b/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs new file mode 100644 index 000000000000..6330242ceebc --- /dev/null +++ b/tests/ui/impl-trait/in-trait/outlives-in-nested-rpit.rs @@ -0,0 +1,11 @@ +// check-pass + +#![feature(return_position_impl_trait_in_trait)] + +trait Foo { + fn early<'a, T: 'a>(x: &'a T) -> impl Iterator>; + + fn late<'a, T>(x: &'a T) -> impl Iterator>; +} + +fn main() {} From 67703b9161e4869c5ac155e9a12317c1a2fee339 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 7 Aug 2023 08:33:25 +0000 Subject: [PATCH 45/76] Stop using identity args for opaque type wf checks and instead load the args from the single use of a RPIT in its parent function's return type --- .../rustc_hir_analysis/src/check/check.rs | 193 +++++++++++------- .../wf-check-rpit-lifetimes.rs | 19 ++ 2 files changed, 134 insertions(+), 78 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 73627a818e5d..f0a8ae9b7a8c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -13,7 +13,7 @@ use rustc_hir::{ItemKind, Node, PathSegment}; use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; +use rustc_infer::infer::{LateBoundRegionConversionTime, RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; use rustc_middle::hir::nested_filter; @@ -407,7 +407,38 @@ fn check_opaque_meets_bounds<'tcx>( .build(); let ocx = ObligationCtxt::new(&infcx); - let args = GenericArgs::identity_for_item(tcx, def_id.to_def_id()); + let mut args = GenericArgs::identity_for_item(tcx, def_id.to_def_id()); + assert!(!args.has_escaping_bound_vars(), "{args:#?}"); + if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin { + // Find use of the RPIT in the function signature and thus find the right args to + // convert it into the parameter space of the function signature. This is needed, + // because that's what `type_of` returns, against which we compare later. + let ret = tcx.fn_sig(defining_use_anchor).instantiate_identity().output(); + + let a = ret + .skip_binder() + .visit_with(&mut FindOpaqueTypeArgs { + tcx, + opaque: def_id.to_def_id(), + fn_def_id: defining_use_anchor.to_def_id(), + seen: Default::default(), + depth: ty::INNERMOST, + }) + .break_value() + .ok_or_else(|| { + tcx.sess.delay_span_bug( + tcx.def_span(defining_use_anchor), + format!("return type of {defining_use_anchor:?} does not contain {def_id:?}"), + ) + })?; + let a = infcx.instantiate_binder_with_fresh_vars( + span, + LateBoundRegionConversionTime::HigherRankedType, + ret.rebind(a), + ); + assert!(!a.has_escaping_bound_vars(), "{a:#?}"); + args = ty::EarlyBinder::bind(args).instantiate(tcx, a); + } let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); // `ReErased` regions appear in the "parent_args" of closures/generators. @@ -468,9 +499,10 @@ fn check_opaque_meets_bounds<'tcx>( } } // Check that any hidden types found during wf checking match the hidden types that `type_of` sees. - for (key, mut ty) in infcx.take_opaque_types() { + for (mut key, mut ty) in infcx.take_opaque_types() { ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty); - sanity_check_found_hidden_type(tcx, key, ty.hidden_type, defining_use_anchor, origin)?; + key = infcx.resolve_vars_if_possible(key); + sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?; } Ok(()) } @@ -479,8 +511,6 @@ fn sanity_check_found_hidden_type<'tcx>( tcx: TyCtxt<'tcx>, key: ty::OpaqueTypeKey<'tcx>, mut ty: ty::OpaqueHiddenType<'tcx>, - defining_use_anchor: LocalDefId, - origin: &hir::OpaqueTyOrigin, ) -> Result<(), ErrorGuaranteed> { if ty.ty.is_ty_var() { // Nothing was actually constrained. @@ -493,29 +523,23 @@ fn sanity_check_found_hidden_type<'tcx>( return Ok(()); } } + let strip_vars = |ty: Ty<'tcx>| { + ty.fold_with(&mut BottomUpFolder { + tcx, + ty_op: |t| t, + ct_op: |c| c, + lt_op: |l| match l.kind() { + RegionKind::ReVar(_) => tcx.lifetimes.re_erased, + _ => l, + }, + }) + }; // Closures frequently end up containing erased lifetimes in their final representation. // These correspond to lifetime variables that never got resolved, so we patch this up here. - ty.ty = ty.ty.fold_with(&mut BottomUpFolder { - tcx, - ty_op: |t| t, - ct_op: |c| c, - lt_op: |l| match l.kind() { - RegionKind::ReVar(_) => tcx.lifetimes.re_erased, - _ => l, - }, - }); + ty.ty = strip_vars(ty.ty); // Get the hidden type. - let mut hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args); - if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin { - if hidden_ty != ty.ty { - hidden_ty = find_and_apply_rpit_args( - tcx, - hidden_ty, - defining_use_anchor.to_def_id(), - key.def_id.to_def_id(), - )?; - } - } + let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args); + let hidden_ty = strip_vars(hidden_ty); // If the hidden types differ, emit a type mismatch diagnostic. if hidden_ty == ty.ty { @@ -563,67 +587,80 @@ fn sanity_check_found_hidden_type<'tcx>( /// x /// } /// ``` -fn find_and_apply_rpit_args<'tcx>( +struct FindOpaqueTypeArgs<'tcx> { tcx: TyCtxt<'tcx>, - mut hidden_ty: Ty<'tcx>, - function: DefId, opaque: DefId, -) -> Result, ErrorGuaranteed> { - // Find use of the RPIT in the function signature and thus find the right args to - // convert it into the parameter space of the function signature. This is needed, - // because that's what `type_of` returns, against which we compare later. - let ret = tcx.fn_sig(function).instantiate_identity().output(); - struct Visitor<'tcx> { - tcx: TyCtxt<'tcx>, - opaque: DefId, - seen: FxHashSet, - } - impl<'tcx> ty::TypeVisitor> for Visitor<'tcx> { - type BreakTy = GenericArgsRef<'tcx>; + seen: FxHashSet, + fn_def_id: DefId, + depth: ty::DebruijnIndex, +} +impl<'tcx> ty::TypeVisitor> for FindOpaqueTypeArgs<'tcx> { + type BreakTy = GenericArgsRef<'tcx>; - #[instrument(level = "trace", skip(self), ret)] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - trace!("{:#?}", t.kind()); - match t.kind() { - ty::Alias(ty::Opaque, alias) => { - trace!(?alias.def_id); - if alias.def_id == self.opaque { - return ControlFlow::Break(alias.args); - } else if self.seen.insert(alias.def_id) { - for clause in self - .tcx - .explicit_item_bounds(alias.def_id) - .iter_instantiated_copied(self.tcx, alias.args) - { - trace!(?clause); - clause.visit_with(self)?; + #[instrument(level = "trace", skip(self), ret)] + fn visit_binder>>( + &mut self, + t: &ty::Binder<'tcx, T>, + ) -> ControlFlow { + self.depth.shift_in(1); + let binder = t.super_visit_with(self); + self.depth.shift_out(1); + binder + } + + #[instrument(level = "trace", skip(self), ret)] + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + trace!("{:#?}", t.kind()); + match t.kind() { + ty::Alias(ty::Opaque, alias) => { + trace!(?alias.def_id); + if alias.def_id == self.opaque { + let args = self.tcx.fold_regions(alias.args, |re, depth| { + if let ty::ReLateBound(index, bv) = re.kind() { + if depth != ty::INNERMOST { + return ty::Region::new_error_with_message( + self.tcx, + self.tcx.def_span(self.opaque), + "opaque type behind meaningful binders are not supported yet", + ); + } + ty::Region::new_late_bound( + self.tcx, + index.shifted_out_to_binder(self.depth), + bv, + ) + } else { + re } + }); + return ControlFlow::Break(args); + } else if self.seen.insert(alias.def_id) { + for clause in self + .tcx + .explicit_item_bounds(alias.def_id) + .iter_instantiated_copied(self.tcx, alias.args) + { + trace!(?clause); + clause.visit_with(self)?; } } - ty::Alias(ty::Weak, alias) => { - self.tcx - .type_of(alias.def_id) - .instantiate(self.tcx, alias.args) - .visit_with(self)?; - } - _ => (), } - - t.super_visit_with(self) + ty::Alias(ty::Projection, alias) => { + if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = self.tcx.opt_rpitit_info(alias.def_id) && fn_def_id == self.fn_def_id { + self.tcx.type_of(alias.def_id).instantiate(self.tcx, alias.args).visit_with(self)?; + } + } + ty::Alias(ty::Weak, alias) => { + self.tcx + .type_of(alias.def_id) + .instantiate(self.tcx, alias.args) + .visit_with(self)?; + } + _ => (), } + + t.super_visit_with(self) } - if let ControlFlow::Break(args) = - ret.visit_with(&mut Visitor { tcx, opaque, seen: Default::default() }) - { - trace!(?args); - trace!("expected: {hidden_ty:#?}"); - hidden_ty = ty::EarlyBinder::bind(hidden_ty).instantiate(tcx, args); - trace!("expected: {hidden_ty:#?}"); - } else { - tcx.sess - .delay_span_bug(tcx.def_span(function), format!("{ret:?} does not contain {opaque:?}")); - } - Ok(hidden_ty) } fn is_enum_of_nonnullable_ptr<'tcx>( diff --git a/tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs b/tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs new file mode 100644 index 000000000000..b92e15aad561 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-check-rpit-lifetimes.rs @@ -0,0 +1,19 @@ +//check-pass + +pub struct Key; +#[derive(Clone)] +pub struct Value; + +use std::collections::HashMap; + +pub struct DiagnosticBuilder<'db> { + inner: HashMap<&'db Key, Vec<&'db Value>>, +} + +impl<'db> DiagnosticBuilder<'db> { + pub fn iter<'a>(&'a self) -> impl Iterator)> { + self.inner.iter().map(|(key, values)| (*key, values.iter().map(|v| *v))) + } +} + +fn main() {} From ef2a611803964e50853333e34d41f4347434513c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 7 Aug 2023 23:54:04 +0000 Subject: [PATCH 46/76] Simplify via map_rpit_lifetime_to_fn_lifetime --- .../rustc_hir_analysis/src/check/check.rs | 155 ++---------------- compiler/rustc_middle/src/ty/context.rs | 11 +- 2 files changed, 21 insertions(+), 145 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f0a8ae9b7a8c..1c4ee9a2bc3a 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -13,7 +13,7 @@ use rustc_hir::{ItemKind, Node, PathSegment}; use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{LateBoundRegionConversionTime, RegionVariableOrigin, TyCtxtInferExt}; +use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; use rustc_middle::hir::nested_filter; @@ -407,38 +407,17 @@ fn check_opaque_meets_bounds<'tcx>( .build(); let ocx = ObligationCtxt::new(&infcx); - let mut args = GenericArgs::identity_for_item(tcx, def_id.to_def_id()); - assert!(!args.has_escaping_bound_vars(), "{args:#?}"); - if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin { - // Find use of the RPIT in the function signature and thus find the right args to - // convert it into the parameter space of the function signature. This is needed, - // because that's what `type_of` returns, against which we compare later. - let ret = tcx.fn_sig(defining_use_anchor).instantiate_identity().output(); - - let a = ret - .skip_binder() - .visit_with(&mut FindOpaqueTypeArgs { + let args = match *origin { + hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => { + GenericArgs::identity_for_item(tcx, parent).extend_to( tcx, - opaque: def_id.to_def_id(), - fn_def_id: defining_use_anchor.to_def_id(), - seen: Default::default(), - depth: ty::INNERMOST, - }) - .break_value() - .ok_or_else(|| { - tcx.sess.delay_span_bug( - tcx.def_span(defining_use_anchor), - format!("return type of {defining_use_anchor:?} does not contain {def_id:?}"), - ) - })?; - let a = infcx.instantiate_binder_with_fresh_vars( - span, - LateBoundRegionConversionTime::HigherRankedType, - ret.rebind(a), - ); - assert!(!a.has_escaping_bound_vars(), "{a:#?}"); - args = ty::EarlyBinder::bind(args).instantiate(tcx, a); - } + def_id.to_def_id(), + |param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(), + ) + } + hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id), + }; + let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); // `ReErased` regions appear in the "parent_args" of closures/generators. @@ -551,118 +530,6 @@ fn sanity_check_found_hidden_type<'tcx>( } } -/// In case it is in a nested opaque type, find that opaque type's -/// usage in the function signature and use the generic arguments from the usage site. -/// We need to do because RPITs ignore the lifetimes of the function, -/// as they have their own copies of all the lifetimes they capture. -/// So the only way to get the lifetimes represented in terms of the function, -/// is to look how they are used in the function signature (or do some other fancy -/// recording of this mapping at ast -> hir lowering time). -/// -/// As an example: -/// ```text -/// trait Id { -/// type Assoc; -/// } -/// impl<'a> Id for &'a () { -/// type Assoc = &'a (); -/// } -/// fn func<'a>(x: &'a ()) -> impl Id { x } -/// // desugared to -/// fn func<'a>(x: &'a () -> Outer<'a> where as Id>::Assoc = Inner<'a> { -/// // Note that in contrast to other nested items, RPIT type aliases can -/// // access their parents' generics. -/// -/// // hidden type is `&'aDupOuter ()` -/// // During wfcheck the hidden type of `Inner<'aDupOuter>` is `&'a ()`, but -/// // `typeof(Inner<'aDupOuter>) = &'aDupOuter ()`. -/// // So we walk the signature of `func` to find the use of `Inner<'a>` -/// // and then use that to replace the lifetimes in the hidden type, obtaining -/// // `&'a ()`. -/// type Outer<'aDupOuter> = impl Id>; -/// -/// // hidden type is `&'aDupInner ()` -/// type Inner<'aDupInner> = impl Sized + 'aDupInner; -/// -/// x -/// } -/// ``` -struct FindOpaqueTypeArgs<'tcx> { - tcx: TyCtxt<'tcx>, - opaque: DefId, - seen: FxHashSet, - fn_def_id: DefId, - depth: ty::DebruijnIndex, -} -impl<'tcx> ty::TypeVisitor> for FindOpaqueTypeArgs<'tcx> { - type BreakTy = GenericArgsRef<'tcx>; - - #[instrument(level = "trace", skip(self), ret)] - fn visit_binder>>( - &mut self, - t: &ty::Binder<'tcx, T>, - ) -> ControlFlow { - self.depth.shift_in(1); - let binder = t.super_visit_with(self); - self.depth.shift_out(1); - binder - } - - #[instrument(level = "trace", skip(self), ret)] - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - trace!("{:#?}", t.kind()); - match t.kind() { - ty::Alias(ty::Opaque, alias) => { - trace!(?alias.def_id); - if alias.def_id == self.opaque { - let args = self.tcx.fold_regions(alias.args, |re, depth| { - if let ty::ReLateBound(index, bv) = re.kind() { - if depth != ty::INNERMOST { - return ty::Region::new_error_with_message( - self.tcx, - self.tcx.def_span(self.opaque), - "opaque type behind meaningful binders are not supported yet", - ); - } - ty::Region::new_late_bound( - self.tcx, - index.shifted_out_to_binder(self.depth), - bv, - ) - } else { - re - } - }); - return ControlFlow::Break(args); - } else if self.seen.insert(alias.def_id) { - for clause in self - .tcx - .explicit_item_bounds(alias.def_id) - .iter_instantiated_copied(self.tcx, alias.args) - { - trace!(?clause); - clause.visit_with(self)?; - } - } - } - ty::Alias(ty::Projection, alias) => { - if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = self.tcx.opt_rpitit_info(alias.def_id) && fn_def_id == self.fn_def_id { - self.tcx.type_of(alias.def_id).instantiate(self.tcx, alias.args).visit_with(self)?; - } - } - ty::Alias(ty::Weak, alias) => { - self.tcx - .type_of(alias.def_id) - .instantiate(self.tcx, alias.args) - .visit_with(self)?; - } - _ => (), - } - - t.super_visit_with(self) - } -} - fn is_enum_of_nonnullable_ptr<'tcx>( tcx: TyCtxt<'tcx>, adt_def: AdtDef<'tcx>, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 75a2c6cbd20b..e25ca75bba88 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1995,7 +1995,16 @@ pub fn map_rpit_lifetime_to_fn_lifetime( ), ); } - _ => bug!(), + Some(resolve_bound_vars::ResolvedArg::Error(guar)) => { + return ty::Region::new_error(self, guar); + } + _ => { + return ty::Region::new_error_with_message( + self, + lifetime.ident.span, + "cannot resolve lifetime", + ); + } } } } From 0adf7048d23649d561bb121d7e1ab00b4c0269b0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 8 Aug 2023 00:28:17 +0000 Subject: [PATCH 47/76] add'l test --- .../mapping-duplicated-lifetimes-issue-114597.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs diff --git a/tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs b/tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs new file mode 100644 index 000000000000..a2dd0a9308d3 --- /dev/null +++ b/tests/ui/impl-trait/mapping-duplicated-lifetimes-issue-114597.rs @@ -0,0 +1,15 @@ +// check-pass +// issue: 114597 +// edition: 2021 + +struct A<'a> { + dat: &'a (), +} + +impl<'a> A<'a> { + async fn a(&self) -> impl Iterator> { + std::iter::repeat(()).map(|()| std::iter::repeat(())) + } +} + +fn main() {} From da00356e5570e66dc90e6f403345bbbab255b95a Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 8 Aug 2023 10:19:21 +0200 Subject: [PATCH 48/76] prevent constant rebuilds of rustc-main (and thus everything else) --- src/bootstrap/compile.rs | 37 +++++++++++++++++++++++++++++-------- src/bootstrap/llvm.rs | 20 +++++++------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 2c63ec80c3e5..62c7b96b5be9 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -31,6 +31,7 @@ use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date}; use crate::LLVM_TOOLS; use crate::{CLang, Compiler, DependencyType, GitRepo, Mode}; +use filetime::FileTime; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Std { @@ -904,19 +905,12 @@ fn run(self, builder: &Builder<'_>) { // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with // debuginfo (via the debuginfo level of the executables using it): strip this debuginfo // away after the fact. - // FIXME: to make things simpler for now, limit this to the host and target where we know - // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not - // cross-compiling. Expand this to other appropriate targets in the future. if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None - && target == "x86_64-unknown-linux-gnu" - && target == builder.config.build { let target_root_dir = stamp.parent().unwrap(); let rustc_driver = target_root_dir.join("librustc_driver.so"); - if rustc_driver.exists() { - output(Command::new("strip").arg("--strip-debug").arg(rustc_driver)); - } + strip_debug(builder, target, &rustc_driver); } builder.ensure(RustcLink::from_rustc( @@ -1974,3 +1968,30 @@ pub enum CargoMessage<'a> { success: bool, }, } + +pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) { + // FIXME: to make things simpler for now, limit this to the host and target where we know + // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not + // cross-compiling. Expand this to other appropriate targets in the future. + if target != "x86_64-unknown-linux-gnu" || target != builder.config.build || !path.exists() { + return; + } + + let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap()); + // Note: `output` will propagate any errors here. + output(Command::new("strip").arg("--strip-debug").arg(path)); + + // After running `strip`, we have to set the file modification time to what it was before, + // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time + // bootstrap is invoked. + // + // An example of this is if we run this on librustc_driver.so. In the first invocation: + // - Cargo will build librustc_driver.so (mtime of 1) + // - Cargo will build rustc-main (mtime of 2) + // - Bootstrap will strip librustc_driver.so (changing the mtime to 3). + // + // In the second invocation of bootstrap, Cargo will see that the mtime of librustc_driver.so + // is greater than the mtime of rustc-main, and will rebuild rustc-main. That will then cause + // everything else (standard library, future stages...) to be rebuilt. + t!(filetime::set_file_mtime(path, previous_mtime)); +} diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index 14ee5659ed56..4943f93fa9a0 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -512,27 +512,21 @@ fn run(self, builder: &Builder<'_>) -> LlvmResult { // When building LLVM as a shared library on linux, it can contain unexpected debuginfo: // some can come from the C++ standard library. Unless we're explicitly requesting LLVM to // be built with debuginfo, strip it away after the fact, to make dist artifacts smaller. - // FIXME: to make things simpler for now, limit this to the host and target where we know - // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not - // cross-compiling. Expand this to other appropriate targets in the future. if builder.llvm_link_shared() && builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo - && target == "x86_64-unknown-linux-gnu" - && target == builder.config.build { // Find the name of the LLVM shared library that we just built. let lib_name = find_llvm_lib_name("so"); // If the shared library exists in LLVM's `/build/lib/` or `/lib/` folders, strip its - // debuginfo. Note: `output` will propagate any errors here. - let strip_if_possible = |path: PathBuf| { - if path.exists() { - output(Command::new("strip").arg("--strip-debug").arg(path)); - } - }; - strip_if_possible(out_dir.join("lib").join(&lib_name)); - strip_if_possible(out_dir.join("build").join("lib").join(&lib_name)); + // debuginfo. + crate::compile::strip_debug(builder, target, &out_dir.join("lib").join(&lib_name)); + crate::compile::strip_debug( + builder, + target, + &out_dir.join("build").join("lib").join(&lib_name), + ); } t!(stamp.write()); From bcf7bfc9f4b6fb01cf36d7a3834cbd60a70f660a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 8 Aug 2023 07:12:15 +0000 Subject: [PATCH 49/76] remove llvm-wrapper include to silence deprecation warning Includes of `include/llvm/Support/Host.h` now emit a deprecated warning: `warning: This header is deprecated, please use llvm/TargetParser/Host.h`. --- compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h | 1 - compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index ea0454628452..3f2bf2c9b444 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -15,7 +15,6 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/JSON.h" -#include "llvm/Support/Host.h" #include "llvm/Support/Memory.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 48b5fd6e283b..69580c0f76e5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -25,7 +25,6 @@ #if LLVM_VERSION_GE(17, 0) #include "llvm/Support/VirtualFileSystem.h" #endif -#include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" From 9d417d7c86259498855fc50ba0e853edbb13320d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 7 Aug 2023 17:56:57 +0200 Subject: [PATCH 50/76] Only enable hotness information when PGO is available --- compiler/rustc_codegen_llvm/src/back/write.rs | 2 ++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 9 ++++++--- tests/run-make/optimization-remarks-dir-pgo/Makefile | 4 ++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 46e6daed21f1..6134d8fc1741 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -320,6 +320,7 @@ pub fn new( }) .and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok())); + let pgo_available = cgcx.opts.cg.profile_use.is_some(); let data = Box::into_raw(Box::new((cgcx, handler))); unsafe { let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx); @@ -333,6 +334,7 @@ pub fn new( // The `as_ref()` is important here, otherwise the `CString` will be dropped // too soon! remark_file.as_ref().map(|dir| dir.as_ptr()).unwrap_or(std::ptr::null()), + pgo_available, ); DiagnosticHandlers { data, llcx, old_handler } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index b167facfb02d..7fb4d3227dba 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2332,6 +2332,7 @@ pub fn LLVMRustContextConfigureDiagnosticHandler( remark_passes: *const *const c_char, remark_passes_len: usize, remark_file: *const c_char, + pgo_available: bool, ); #[allow(improper_ctypes)] diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 8c04a4305734..a701827e057f 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1869,7 +1869,8 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( LLVMContextRef C, LLVMDiagnosticHandlerTy DiagnosticHandlerCallback, void *DiagnosticHandlerContext, bool RemarkAllPasses, const char * const * RemarkPasses, size_t RemarkPassesLen, - const char * RemarkFilePath + const char * RemarkFilePath, + bool PGOAvailable ) { class RustDiagnosticHandler final : public DiagnosticHandler { @@ -1967,8 +1968,10 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( std::unique_ptr LlvmRemarkStreamer; if (RemarkFilePath != nullptr) { - // Enable PGO hotness data for remarks, if available - unwrap(C)->setDiagnosticsHotnessRequested(true); + if (PGOAvailable) { + // Enable PGO hotness data for remarks, if available + unwrap(C)->setDiagnosticsHotnessRequested(true); + } std::error_code EC; RemarkFile = std::make_unique( diff --git a/tests/run-make/optimization-remarks-dir-pgo/Makefile b/tests/run-make/optimization-remarks-dir-pgo/Makefile index 93be1472037d..c88ec1e6cb30 100644 --- a/tests/run-make/optimization-remarks-dir-pgo/Makefile +++ b/tests/run-make/optimization-remarks-dir-pgo/Makefile @@ -1,4 +1,8 @@ # needs-profiler-support +# ignore-windows-gnu + +# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works +# properly. Since we only have GCC on the CI ignore the test for now. include ../tools.mk From 15d408c6b04044a8a0ad2f1810259c5ce4e18f2d Mon Sep 17 00:00:00 2001 From: cedihegi Date: Tue, 8 Aug 2023 16:25:15 +0200 Subject: [PATCH 51/76] Allow reimplementation of drops_elaborated query Make module inner and function run_analysis_to_runtime_passes in rustc_mir_transform public to allow re-implementing the query from the rust compiler interface. --- compiler/rustc_mir_transform/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index f99a51fea0bc..32e8af53def4 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -75,7 +75,7 @@ mod ffi_unwind_calls; mod function_item_references; mod generator; -mod inline; +pub mod inline; mod instsimplify; mod large_enums; mod lower_intrinsics; @@ -431,7 +431,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & tcx.alloc_steal_mir(body) } -fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial)); let did = body.source.def_id(); From ff574b77ab05c4b74225746c1bc0082c114f902a Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sun, 6 Aug 2023 21:02:09 +0200 Subject: [PATCH 52/76] tests: Uncomment now valid GAT code behind FIXME The code fails to parse with `nightly-2021-02-05`: $ cargo +nightly-2021-02-05 build error: generic associated types in trait paths are currently not implemented --> src/main.rs:9:42 | 9 | fn _bar StreamingIterator = &'a [i32]>>(_iter: T) { /* ... */ | ^^^^ but parses with `nightly-2021-02-06`: $ cargo +nightly-2021-02-06 build warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes warning: 1 warning emitted because it was (with high probability) fixed by PR 79554 which was merged within that nightly range. --- tests/ui/generic-associated-types/streaming_iterator.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/ui/generic-associated-types/streaming_iterator.rs b/tests/ui/generic-associated-types/streaming_iterator.rs index 408b8dc99eb4..656fb743ee43 100644 --- a/tests/ui/generic-associated-types/streaming_iterator.rs +++ b/tests/ui/generic-associated-types/streaming_iterator.rs @@ -15,8 +15,7 @@ struct Foo { // Users can bound parameters by the type constructed by that trait's associated type constructor // of a trait using HRTB. Both type equality bounds and trait bounds of this kind are valid: -//FIXME(#44265): This next line should parse and be valid -//fn foo StreamingIterator=&'a [i32]>>(_iter: T) { /* ... */ } +fn _bar StreamingIterator=&'a [i32]>>(_iter: T) { /* ... */ } fn _foo(_iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } // Full example of enumerate iterator From 0166092f87274e9a1bc2d860177ff730ad48efb1 Mon Sep 17 00:00:00 2001 From: cedihegi Date: Tue, 8 Aug 2023 17:34:12 +0200 Subject: [PATCH 53/76] Added comment on reason for method being public --- compiler/rustc_mir_transform/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 32e8af53def4..bf798adee199 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -431,6 +431,8 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> & tcx.alloc_steal_mir(body) } +// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden +// by custom rustc drivers, running all the steps by themselves. pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { assert!(body.phase == MirPhase::Analysis(AnalysisPhase::Initial)); let did = body.source.def_id(); From a2a7f27fd2548874b203f1f577f64cf61627e0a5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Tue, 8 Aug 2023 11:40:35 -0400 Subject: [PATCH 54/76] fix proc-macro test added here to solely be exercised as a build product for the host. thus we should no longer see test failures for e.g. wasm32 target. --- tests/ui/proc-macro/auxiliary/exports_no_mangle.rs | 2 ++ tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs index ef5bf94b0358..a8a478ffc74c 100644 --- a/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs +++ b/tests/ui/proc-macro/auxiliary/exports_no_mangle.rs @@ -1,3 +1,5 @@ +// force-host +// no-prefer-dynamic #![crate_type="lib"] // Issue 111888: this crate (1.) is imported by a proc-macro crate and (2.) diff --git a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs index de2ca496cafb..4e5208e50580 100644 --- a/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs +++ b/tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs @@ -1,4 +1,6 @@ // build-pass +// force-host +// no-prefer-dynamic // aux-build:exports_no_mangle.rs #![crate_type = "proc-macro"] From 95d1f6bab50e72db1e7fd3495617ac8884297661 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 8 Aug 2023 18:07:38 +0200 Subject: [PATCH 55/76] add test from chalk#788 for new solver --- .../cycles/inductive-not-on-stack.rs | 46 +++++++++++++++++++ .../cycles/inductive-not-on-stack.stderr | 29 ++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs create mode 100644 tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs new file mode 100644 index 000000000000..f06b98a79cfe --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs @@ -0,0 +1,46 @@ +// compile-flags: -Ztrait-solver=next +#![feature(rustc_attrs, trivial_bounds)] + +// We have to be careful here: +// +// We either have the provisional result of `A -> B -> A` on the +// stack, which is a fully coinductive cycle. Accessing the +// provisional result for `B` as part of the `A -> C -> B -> A` cycle +// has to make sure we don't just use the result of `A -> B -> A` as the +// new cycle is inductive. +// +// Alternatively, if we have `A -> C -> A` first, then `A -> B -> A` has +// a purely inductive stack, so something could also go wrong here. + +#[rustc_coinductive] +trait A {} +#[rustc_coinductive] +trait B {} +trait C {} + +impl A for T {} +impl B for T {} +impl C for T {} + +fn impls_a() {} + +// The same test with reordered where clauses to make sure we're actually testing anything. +#[rustc_coinductive] +trait AR {} +#[rustc_coinductive] +trait BR {} +trait CR {} + +impl AR for T {} +impl BR for T {} +impl CR for T {} + +fn impls_ar() {} + +fn main() { + impls_a::<()>(); + //~^ ERROR overflow evaluating the requirement `(): A` + + impls_ar::<()>(); + //~^ ERROR overflow evaluating the requirement `(): AR` +} diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr new file mode 100644 index 000000000000..33fac603cbdd --- /dev/null +++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr @@ -0,0 +1,29 @@ +error[E0275]: overflow evaluating the requirement `(): A` + --> $DIR/inductive-not-on-stack.rs:41:5 + | +LL | impls_a::<()>(); + | ^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`) +note: required by a bound in `impls_a` + --> $DIR/inductive-not-on-stack.rs:25:15 + | +LL | fn impls_a() {} + | ^ required by this bound in `impls_a` + +error[E0275]: overflow evaluating the requirement `(): AR` + --> $DIR/inductive-not-on-stack.rs:44:5 + | +LL | impls_ar::<()>(); + | ^^^^^^^^^^^^^^ + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`) +note: required by a bound in `impls_ar` + --> $DIR/inductive-not-on-stack.rs:38:16 + | +LL | fn impls_ar() {} + | ^^ required by this bound in `impls_ar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. From da35a81148fd92175bc7f4c7cce874cae3143bc1 Mon Sep 17 00:00:00 2001 From: Chris Wailes Date: Tue, 8 Aug 2023 10:33:36 -0700 Subject: [PATCH 56/76] Mention riscv64-linux-android support in Android documentation This CL brings the android.md file in-line with the list of supported targets from platform-support.md. --- src/doc/rustc/src/platform-support/android.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index e351cfaf89c2..4ef74295e0fd 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -39,6 +39,8 @@ edition of the [Android NDK]. Supported Android targets are: * thumbv7neon-linux-androideabi * x86_64-linux-android +The riscv64-linux-android target is supported as a Tier 3 target. + [Android NDK]: https://developer.android.com/ndk/downloads A list of all supported targets can be found From 381ef83240f845ffc75e98a4d12c39935e9b989d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 8 Aug 2023 16:55:28 +0200 Subject: [PATCH 57/76] Migrate GUI colors test to original CSS color format --- tests/rustdoc-gui/links-color.goml | 72 +++++++++++++++--------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml index 2ee4bce10156..0789d785f588 100644 --- a/tests/rustdoc-gui/links-color.goml +++ b/tests/rustdoc-gui/links-color.goml @@ -46,53 +46,53 @@ call-function: ( "check-colors", { "theme": "ayu", - "mod": "rgb(57, 175, 215)", - "macro": "rgb(163, 122, 204)", - "struct": "rgb(255, 160, 165)", - "enum": "rgb(255, 160, 165)", - "trait": "rgb(57, 175, 215)", - "fn": "rgb(253, 214, 135)", - "type": "rgb(255, 160, 165)", - "union": "rgb(255, 160, 165)", - "keyword": "rgb(57, 175, 215)", - "sidebar": "rgb(83, 177, 219)", - "sidebar_current": "rgb(255, 180, 76)", - "sidebar_current_background": "rgba(0, 0, 0, 0)", + "mod": "#39afd7", + "macro": "#a37acc", + "struct": "#ffa0a5", + "enum": "#ffa0a5", + "trait": "#39afd7", + "fn": "#fdd687", + "type": "#ffa0a5", + "union": "#ffa0a5", + "keyword": "#39afd7", + "sidebar": "#53b1db", + "sidebar_current": "#ffb44c", + "sidebar_current_background": "transparent", }, ) call-function: ( "check-colors", { "theme": "dark", - "mod": "rgb(210, 153, 29)", - "macro": "rgb(9, 189, 0)", - "struct": "rgb(45, 191, 184)", - "enum": "rgb(45, 191, 184)", - "trait": "rgb(183, 140, 242)", - "fn": "rgb(43, 171, 99)", - "type": "rgb(45, 191, 184)", - "union": "rgb(45, 191, 184)", - "keyword": "rgb(210, 153, 29)", - "sidebar": "rgb(253, 191, 53)", - "sidebar_current": "rgb(253, 191, 53)", - "sidebar_current_background": "rgb(68, 68, 68)", + "mod": "#d2991d", + "macro": "#09bd00", + "struct": "#2dbfb8", + "enum": "#2dbfb8", + "trait": "#b78cf2", + "fn": "#2bab63", + "type": "#2dbfb8", + "union": "#2dbfb8", + "keyword": "#d2991d", + "sidebar": "#fdbf35", + "sidebar_current": "#fdbf35", + "sidebar_current_background": "#444", }, ) call-function: ( "check-colors", { "theme": "light", - "mod": "rgb(56, 115, 173)", - "macro": "rgb(6, 128, 0)", - "struct": "rgb(173, 55, 138)", - "enum": "rgb(173, 55, 138)", - "trait": "rgb(110, 79, 201)", - "fn": "rgb(173, 124, 55)", - "type": "rgb(173, 55, 138)", - "union": "rgb(173, 55, 138)", - "keyword": "rgb(56, 115, 173)", - "sidebar": "rgb(53, 109, 164)", - "sidebar_current": "rgb(53, 109, 164)", - "sidebar_current_background": "rgb(255, 255, 255)", + "mod": "#3873ad", + "macro": "#068000", + "struct": "#ad378a", + "enum": "#ad378a", + "trait": "#6e4fc9", + "fn": "#ad7c37", + "type": "#ad378a", + "union": "#ad378a", + "keyword": "#3873ad", + "sidebar": "#356da4", + "sidebar_current": "#356da4", + "sidebar_current_background": "#fff", }, ) From 8d349c15982a38f40ad97d9ed9db1fd30741141d Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 22 Jul 2023 02:30:13 +0200 Subject: [PATCH 58/76] open pidfd in child process and send to the parent via SOCK_SEQPACKET+CMSG This is a 100% race-free way to obtain a child's pidfd while avoiding `clone3`. --- .../std/src/sys/unix/process/process_unix.rs | 221 +++++++++++------- .../sys/unix/process/process_unix/tests.rs | 25 ++ 2 files changed, 156 insertions(+), 90 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 0ce93af66ac0..cb4032163f35 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -10,9 +10,6 @@ #[cfg(target_os = "linux")] use crate::os::linux::process::PidFd; -#[cfg(target_os = "linux")] -use crate::sys::weak::raw_syscall; - #[cfg(any( target_os = "macos", target_os = "watchos", @@ -91,6 +88,11 @@ pub fn spawn( if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? { return Ok((ret, ours)); } + + #[cfg(target_os = "linux")] + let (input, output) = sys::net::Socket::new_pair(libc::AF_UNIX, libc::SOCK_SEQPACKET)?; + + #[cfg(not(target_os = "linux"))] let (input, output) = sys::pipe::anon_pipe()?; // Whatever happens after the fork is almost for sure going to touch or @@ -104,12 +106,16 @@ pub fn spawn( // The child calls `mem::forget` to leak the lock, which is crucial because // releasing a lock is not async-signal-safe. let env_lock = sys::os::env_read_lock(); - let (pid, pidfd) = unsafe { self.do_fork()? }; + let pid = unsafe { self.do_fork()? }; if pid == 0 { crate::panic::always_abort(); mem::forget(env_lock); // avoid non-async-signal-safe unlocking drop(input); + #[cfg(target_os = "linux")] + if self.get_create_pidfd() { + self.send_pidfd(&output); + } let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) }; let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; let errno = errno.to_be_bytes(); @@ -133,6 +139,12 @@ pub fn spawn( drop(env_lock); drop(output); + #[cfg(target_os = "linux")] + let pidfd = if self.get_create_pidfd() { self.recv_pidfd(&input) } else { -1 }; + + #[cfg(not(target_os = "linux"))] + let pidfd = -1; + // Safety: We obtained the pidfd from calling `clone3` with // `CLONE_PIDFD` so it's valid an otherwise unowned. let mut p = unsafe { Process::new(pid, pidfd) }; @@ -160,6 +172,7 @@ pub fn spawn( } Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic + // similarly SOCK_SEQPACKET messages should arrive whole assert!(p.wait().is_ok(), "wait() should either return Ok or panic"); panic!("short read on the CLOEXEC pipe") } @@ -185,20 +198,19 @@ pub fn output(&mut self) -> io::Result<(ExitStatus, Vec, Vec)> { ); #[cfg(any(target_os = "tvos", target_os = "watchos"))] - unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { + unsafe fn do_fork(&mut self) -> Result { return Err(Self::ERR_APPLE_TV_WATCH_NO_FORK_EXEC); } // Attempts to fork the process. If successful, returns Ok((0, -1)) // in the child, and Ok((child_pid, -1)) in the parent. #[cfg(not(any( - target_os = "linux", target_os = "watchos", target_os = "tvos", all(target_os = "nto", target_env = "nto71"), )))] - unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { - cvt(libc::fork()).map(|res| (res, -1)) + unsafe fn do_fork(&mut self) -> Result { + cvt(libc::fork()) } // On QNX Neutrino, fork can fail with EBADF in case "another thread might have opened @@ -206,7 +218,7 @@ unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { // Documentation says "... or try calling fork() again". This is what we do here. // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html #[cfg(all(target_os = "nto", target_env = "nto71"))] - unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { + unsafe fn do_fork(&mut self) -> Result { use crate::sys::os::errno; let mut delay = MIN_FORKSPAWN_SLEEP; @@ -229,91 +241,11 @@ unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { delay *= 2; continue; } else { - return cvt(r).map(|res| (res, -1)); + return cvt(r); } } } - // Attempts to fork the process. If successful, returns Ok((0, -1)) - // in the child, and Ok((child_pid, child_pidfd)) in the parent. - #[cfg(target_os = "linux")] - unsafe fn do_fork(&mut self) -> Result<(pid_t, pid_t), io::Error> { - use crate::sync::atomic::{AtomicBool, Ordering}; - - static HAS_CLONE3: AtomicBool = AtomicBool::new(true); - const CLONE_PIDFD: u64 = 0x00001000; - - #[repr(C)] - struct clone_args { - flags: u64, - pidfd: u64, - child_tid: u64, - parent_tid: u64, - exit_signal: u64, - stack: u64, - stack_size: u64, - tls: u64, - set_tid: u64, - set_tid_size: u64, - cgroup: u64, - } - - raw_syscall! { - fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long - } - - // Bypassing libc for `clone3` can make further libc calls unsafe, - // so we use it sparingly for now. See #89522 for details. - // Some tools (e.g. sandboxing tools) may also expect `fork` - // rather than `clone3`. - let want_clone3_pidfd = self.get_create_pidfd(); - - // If we fail to create a pidfd for any reason, this will - // stay as -1, which indicates an error. - let mut pidfd: pid_t = -1; - - // Attempt to use the `clone3` syscall, which supports more arguments - // (in particular, the ability to create a pidfd). If this fails, - // we will fall through this block to a call to `fork()` - if want_clone3_pidfd && HAS_CLONE3.load(Ordering::Relaxed) { - let mut args = clone_args { - flags: CLONE_PIDFD, - pidfd: &mut pidfd as *mut pid_t as u64, - child_tid: 0, - parent_tid: 0, - exit_signal: libc::SIGCHLD as u64, - stack: 0, - stack_size: 0, - tls: 0, - set_tid: 0, - set_tid_size: 0, - cgroup: 0, - }; - - let args_ptr = &mut args as *mut clone_args; - let args_size = crate::mem::size_of::(); - - let res = cvt(clone3(args_ptr, args_size)); - match res { - Ok(n) => return Ok((n as pid_t, pidfd)), - Err(e) => match e.raw_os_error() { - // Multiple threads can race to execute this store, - // but that's fine - that just means that multiple threads - // will have tried and failed to execute the same syscall, - // with no other side effects. - Some(libc::ENOSYS) => HAS_CLONE3.store(false, Ordering::Relaxed), - // Fallback to fork if `EPERM` is returned. (e.g. blocked by seccomp) - Some(libc::EPERM) => {} - _ => return Err(e), - }, - } - } - - // Generally, we just call `fork`. If we get here after wanting `clone3`, - // then the syscall does not exist or we do not have permission to call it. - cvt(libc::fork()).map(|res| (res, pidfd)) - } - pub fn exec(&mut self, default: Stdio) -> io::Error { let envp = self.capture_env(); @@ -722,6 +654,115 @@ fn drop(&mut self) { Ok(Some(p)) } } + + #[cfg(target_os = "linux")] + fn send_pidfd(&self, sock: &crate::sys::net::Socket) { + use crate::io::IoSlice; + use crate::os::fd::RawFd; + use crate::sys::cvt_r; + use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET}; + + unsafe { + let child_pid = libc::getpid(); + // pidfd_open sets CLOEXEC by default + let pidfd = libc::syscall(libc::SYS_pidfd_open, child_pid, 0); + + let fds: [c_int; 1] = [pidfd as RawFd]; + + const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>(); + + #[repr(C)] + union Cmsg { + buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }], + _align: libc::cmsghdr, + } + + let mut cmsg: Cmsg = mem::zeroed(); + + // 0-length message to send through the socket so we can pass along the fd + let mut iov = [IoSlice::new(b"")]; + let mut msg: libc::msghdr = mem::zeroed(); + + msg.msg_iov = &mut iov as *mut _ as *mut _; + msg.msg_iovlen = 1; + msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _; + msg.msg_control = &mut cmsg.buf as *mut _ as *mut _; + + // only attach cmsg if we successfully acquired the pidfd + if pidfd >= 0 { + let hdr = CMSG_FIRSTHDR(&mut msg as *mut _ as *mut _); + (*hdr).cmsg_level = SOL_SOCKET; + (*hdr).cmsg_type = SCM_RIGHTS; + (*hdr).cmsg_len = CMSG_LEN(SCM_MSG_LEN as _) as _; + let data = CMSG_DATA(hdr); + crate::ptr::copy_nonoverlapping( + fds.as_ptr().cast::(), + data as *mut _, + SCM_MSG_LEN, + ); + } + + // we send the 0-length message even if we failed to acquire the pidfd + // so we get a consistent SEQPACKET order + match cvt_r(|| libc::sendmsg(sock.as_raw(), &msg, 0)) { + Ok(0) => {} + _ => rtabort!("failed to communicate with parent process"), + } + } + } + + #[cfg(target_os = "linux")] + fn recv_pidfd(&self, sock: &crate::sys::net::Socket) -> pid_t { + use crate::io::IoSliceMut; + use crate::sys::cvt_r; + + use libc::{CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_SPACE, SCM_RIGHTS, SOL_SOCKET}; + + unsafe { + const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>(); + + #[repr(C)] + union Cmsg { + _buf: [u8; unsafe { CMSG_SPACE(SCM_MSG_LEN as u32) as usize }], + _align: libc::cmsghdr, + } + let mut cmsg: Cmsg = mem::zeroed(); + // 0-length read to get the fd + let mut iov = [IoSliceMut::new(&mut [])]; + + let mut msg: libc::msghdr = mem::zeroed(); + + msg.msg_iov = &mut iov as *mut _ as *mut _; + msg.msg_iovlen = 1; + msg.msg_controllen = mem::size_of::() as _; + msg.msg_control = &mut cmsg as *mut _ as *mut _; + + match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, 0)) { + Err(_) => return -1, + Ok(_) => {} + } + + let hdr = CMSG_FIRSTHDR(&mut msg as *mut _ as *mut _); + if hdr.is_null() + || (*hdr).cmsg_level != SOL_SOCKET + || (*hdr).cmsg_type != SCM_RIGHTS + || (*hdr).cmsg_len != CMSG_LEN(SCM_MSG_LEN as _) as _ + { + return -1; + } + let data = CMSG_DATA(hdr); + + let mut fds = [-1 as c_int]; + + crate::ptr::copy_nonoverlapping( + data as *const _, + fds.as_mut_ptr().cast::(), + SCM_MSG_LEN, + ); + + fds[0] + } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/library/std/src/sys/unix/process/process_unix/tests.rs b/library/std/src/sys/unix/process/process_unix/tests.rs index e5e1f956bc35..6aa79e7f9e71 100644 --- a/library/std/src/sys/unix/process/process_unix/tests.rs +++ b/library/std/src/sys/unix/process/process_unix/tests.rs @@ -60,3 +60,28 @@ fn test_command_fork_no_unwind() { || signal == libc::SIGSEGV ); } + +#[test] +#[cfg(target_os = "linux")] +fn test_command_pidfd() { + use crate::os::fd::RawFd; + use crate::os::linux::process::{ChildExt, CommandExt}; + use crate::process::Command; + + let our_pid = crate::process::id(); + let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) }; + let pidfd_open_available = if pidfd >= 0 { + unsafe { libc::close(pidfd as RawFd) }; + true + } else { + false + }; + + // always exercise creation attempts + let child = Command::new("echo").create_pidfd(true).spawn().unwrap(); + + // but only check if we know that the kernel supports pidfds + if pidfd_open_available { + assert!(child.pidfd().is_ok()) + } +} From 07695178f81493b28f4bcd785330134eddbff516 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 8 Aug 2023 20:41:53 +0000 Subject: [PATCH 59/76] Remove dangling tests --- ...le-desugared-boxed-in-trait.current.stderr | 17 ------ ...ample-desugared-boxed-in-trait.next.stderr | 17 ------ ...ync-example-desugared-boxed.current.stderr | 11 ---- .../async-example-desugared-boxed.next.stderr | 11 ---- ...nc-example-desugared-manual.current.stderr | 11 ---- ...async-example-desugared-manual.next.stderr | 11 ---- .../async-generics-and-bounds.current.stderr | 37 ----------- .../async-generics-and-bounds.next.stderr | 37 ----------- .../in-trait/async-generics.current.stderr | 37 ----------- .../in-trait/async-generics.next.stderr | 37 ----------- .../async-recursive-generic.current.stderr | 12 ---- .../async-recursive-generic.next.stderr | 12 ---- .../in-trait/async-recursive.current.stderr | 12 ---- .../in-trait/async-recursive.next.stderr | 12 ---- .../in-trait/bad-signatures.current.stderr | 17 ------ .../in-trait/bad-signatures.next.stderr | 17 ------ ...to-specializable-projection.current.stderr | 10 --- ...ct-to-specializable-projection.next.stderr | 25 -------- .../in-trait/fn-not-async-err2.current.stderr | 12 ---- .../in-trait/fn-not-async-err2.next.stderr | 12 ---- .../in-trait/generics-mismatch.current.stderr | 16 ----- .../in-trait/generics-mismatch.next.stderr | 16 ----- .../in-trait/lifetime-mismatch.current.stderr | 12 ---- .../in-trait/lifetime-mismatch.next.stderr | 12 ---- .../missing-feature-flag.current.stderr | 30 --------- .../in-trait/missing-feature-flag.next.stderr | 30 --------- .../missing-send-bound.current.stderr | 20 ------ .../in-trait/missing-send-bound.next.stderr | 20 ------ .../in-trait/object-safety.current.stderr | 18 ------ .../in-trait/object-safety.next.stderr | 18 ------ .../return-not-existing-pair.current.stderr | 39 ------------ .../return-not-existing-pair.next.stderr | 39 ------------ ...isting-type-wrapping-rpitit.current.stderr | 9 --- ...-existing-type-wrapping-rpitit.next.stderr | 9 --- .../return-type-suggestion.current.stderr | 14 ----- .../return-type-suggestion.next.stderr | 14 ----- .../in-trait/deep-match.current.stderr | 15 ----- .../in-trait/deep-match.next.stderr | 15 ----- .../default-body-type-err-2.current.stderr | 11 ---- .../default-body-type-err-2.next.stderr | 11 ---- .../default-body-type-err.current.stderr | 12 ---- .../default-body-type-err.next.stderr | 12 ---- .../default-body-with-rpit.current.stderr | 24 -------- .../default-body-with-rpit.next.stderr | 24 -------- .../in-trait/doesnt-satisfy.current.stderr | 17 ------ .../in-trait/doesnt-satisfy.next.stderr | 17 ------ ...ect-to-rpitit-with-no-value.current.stderr | 12 ---- ...roject-to-rpitit-with-no-value.next.stderr | 12 ---- .../in-trait/generics-mismatch.current.stderr | 12 ---- .../in-trait/generics-mismatch.next.stderr | 12 ---- .../in-trait/issue-102140.current.stderr | 33 ---------- .../in-trait/issue-102140.next.stderr | 29 --------- .../in-trait/issue-102571.current.stderr | 14 ----- .../in-trait/issue-102571.next.stderr | 14 ----- .../in-trait/object-safety.current.stderr | 49 --------------- .../in-trait/object-safety.next.stderr | 49 --------------- .../opaque-in-impl-is-opaque.current.stderr | 17 ------ .../opaque-in-impl-is-opaque.next.stderr | 17 ------ .../return-dont-satisfy-bounds.current.stderr | 16 ----- .../return-dont-satisfy-bounds.next.stderr | 16 ----- .../signature-mismatch.current.stderr | 61 ------------------- .../in-trait/signature-mismatch.next.stderr | 61 ------------------- .../specialization-broken.current.stderr | 31 ---------- .../specialization-broken.next.stderr | 31 ---------- ...ait-more-generics-than-impl.current.stderr | 12 ---- .../trait-more-generics-than-impl.next.stderr | 12 ---- .../in-trait/unconstrained-lt.current.stderr | 9 --- .../in-trait/unconstrained-lt.next.stderr | 9 --- .../in-trait/wf-bounds.current.stderr | 57 ----------------- .../impl-trait/in-trait/wf-bounds.next.stderr | 57 ----------------- 70 files changed, 1483 deletions(-) delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr delete mode 100644 tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr delete mode 100644 tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr delete mode 100644 tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr delete mode 100644 tests/ui/async-await/in-trait/async-generics.current.stderr delete mode 100644 tests/ui/async-await/in-trait/async-generics.next.stderr delete mode 100644 tests/ui/async-await/in-trait/async-recursive-generic.current.stderr delete mode 100644 tests/ui/async-await/in-trait/async-recursive-generic.next.stderr delete mode 100644 tests/ui/async-await/in-trait/async-recursive.current.stderr delete mode 100644 tests/ui/async-await/in-trait/async-recursive.next.stderr delete mode 100644 tests/ui/async-await/in-trait/bad-signatures.current.stderr delete mode 100644 tests/ui/async-await/in-trait/bad-signatures.next.stderr delete mode 100644 tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr delete mode 100644 tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr delete mode 100644 tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr delete mode 100644 tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr delete mode 100644 tests/ui/async-await/in-trait/generics-mismatch.current.stderr delete mode 100644 tests/ui/async-await/in-trait/generics-mismatch.next.stderr delete mode 100644 tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr delete mode 100644 tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr delete mode 100644 tests/ui/async-await/in-trait/missing-feature-flag.current.stderr delete mode 100644 tests/ui/async-await/in-trait/missing-feature-flag.next.stderr delete mode 100644 tests/ui/async-await/in-trait/missing-send-bound.current.stderr delete mode 100644 tests/ui/async-await/in-trait/missing-send-bound.next.stderr delete mode 100644 tests/ui/async-await/in-trait/object-safety.current.stderr delete mode 100644 tests/ui/async-await/in-trait/object-safety.next.stderr delete mode 100644 tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr delete mode 100644 tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr delete mode 100644 tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr delete mode 100644 tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr delete mode 100644 tests/ui/async-await/in-trait/return-type-suggestion.current.stderr delete mode 100644 tests/ui/async-await/in-trait/return-type-suggestion.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/deep-match.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/deep-match.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/issue-102140.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/issue-102140.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/issue-102571.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/issue-102571.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/object-safety.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/object-safety.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/specialization-broken.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/specialization-broken.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr delete mode 100644 tests/ui/impl-trait/in-trait/wf-bounds.current.stderr delete mode 100644 tests/ui/impl-trait/in-trait/wf-bounds.next.stderr diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr deleted file mode 100644 index b5ace9ada4f8..000000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28 - | -LL | async fn foo(&self) -> i32 { - | ^^^ expected `Pin>>`, found future - | -note: type in trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22 - | -LL | fn foo(&self) -> Pin + '_>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected signature `fn(&i32) -> Pin>>` - found signature `fn(&i32) -> impl Future` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr deleted file mode 100644 index b5ace9ada4f8..000000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:17:28 - | -LL | async fn foo(&self) -> i32 { - | ^^^ expected `Pin>>`, found future - | -note: type in trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:13:22 - | -LL | fn foo(&self) -> Pin + '_>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected signature `fn(&i32) -> Pin>>` - found signature `fn(&i32) -> impl Future` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr deleted file mode 100644 index 6c0b5859186b..000000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-boxed.rs:17:5 - | -LL | async fn foo(&self) -> i32; - | --------------------------- required because the trait method is async -... -LL | fn foo(&self) -> Pin + '_>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr deleted file mode 100644 index 6c0b5859186b..000000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-boxed.rs:17:5 - | -LL | async fn foo(&self) -> i32; - | --------------------------- required because the trait method is async -... -LL | fn foo(&self) -> Pin + '_>> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr deleted file mode 100644 index 0d2551ab84f9..000000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-manual.rs:25:5 - | -LL | async fn foo(&self) -> i32; - | --------------------------- required because the trait method is async -... -LL | fn foo(&self) -> MyFuture { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr deleted file mode 100644 index 0d2551ab84f9..000000000000 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: method `foo` should be async because the method from the trait is async - --> $DIR/async-example-desugared-manual.rs:25:5 - | -LL | async fn foo(&self) -> i32; - | --------------------------- required because the trait method is async -... -LL | fn foo(&self) -> MyFuture { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr deleted file mode 100644 index 780da0689629..000000000000 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - | -note: the parameter type `U` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics-and-bounds.rs:14:18 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - -error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - | -note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics-and-bounds.rs:14:18 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0311`. diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr deleted file mode 100644 index 780da0689629..000000000000 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - | -note: the parameter type `U` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics-and-bounds.rs:14:18 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - -error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - | -note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics-and-bounds.rs:14:18 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:14:28 - | -LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0311`. diff --git a/tests/ui/async-await/in-trait/async-generics.current.stderr b/tests/ui/async-await/in-trait/async-generics.current.stderr deleted file mode 100644 index 04e1ab6d7697..000000000000 --- a/tests/ui/async-await/in-trait/async-generics.current.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - | -note: the parameter type `U` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics.rs:11:18 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - -error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - | -note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics.rs:11:18 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0311`. diff --git a/tests/ui/async-await/in-trait/async-generics.next.stderr b/tests/ui/async-await/in-trait/async-generics.next.stderr deleted file mode 100644 index 04e1ab6d7697..000000000000 --- a/tests/ui/async-await/in-trait/async-generics.next.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - | -note: the parameter type `U` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics.rs:11:18 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - -error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - | -note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics.rs:11:18 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^ -note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:11:28 - | -LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0311`. diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr deleted file mode 100644 index 67b491f19d26..000000000000 --- a/tests/ui/async-await/in-trait/async-recursive-generic.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive-generic.rs:13:48 - | -LL | async fn foo_recursive(&self, n: usize) -> T { - | ^ recursive `async fn` - | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` - = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr b/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr deleted file mode 100644 index 67b491f19d26..000000000000 --- a/tests/ui/async-await/in-trait/async-recursive-generic.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive-generic.rs:13:48 - | -LL | async fn foo_recursive(&self, n: usize) -> T { - | ^ recursive `async fn` - | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` - = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/async-await/in-trait/async-recursive.current.stderr b/tests/ui/async-await/in-trait/async-recursive.current.stderr deleted file mode 100644 index 85af27e37465..000000000000 --- a/tests/ui/async-await/in-trait/async-recursive.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive.rs:13:48 - | -LL | async fn foo_recursive(&self, n: usize) -> i32 { - | ^^^ recursive `async fn` - | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` - = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/async-await/in-trait/async-recursive.next.stderr b/tests/ui/async-await/in-trait/async-recursive.next.stderr deleted file mode 100644 index 85af27e37465..000000000000 --- a/tests/ui/async-await/in-trait/async-recursive.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/async-recursive.rs:13:48 - | -LL | async fn foo_recursive(&self, n: usize) -> i32 { - | ^^^ recursive `async fn` - | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` - = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0733`. diff --git a/tests/ui/async-await/in-trait/bad-signatures.current.stderr b/tests/ui/async-await/in-trait/bad-signatures.current.stderr deleted file mode 100644 index ae590fb057f3..000000000000 --- a/tests/ui/async-await/in-trait/bad-signatures.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: expected identifier, found keyword `self` - --> $DIR/bad-signatures.rs:8:23 - | -LL | async fn bar(&abc self); - | ^^^^ expected identifier, found keyword - -error: expected one of `:`, `@`, or `|`, found keyword `self` - --> $DIR/bad-signatures.rs:8:23 - | -LL | async fn bar(&abc self); - | -----^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/async-await/in-trait/bad-signatures.next.stderr b/tests/ui/async-await/in-trait/bad-signatures.next.stderr deleted file mode 100644 index ae590fb057f3..000000000000 --- a/tests/ui/async-await/in-trait/bad-signatures.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: expected identifier, found keyword `self` - --> $DIR/bad-signatures.rs:8:23 - | -LL | async fn bar(&abc self); - | ^^^^ expected identifier, found keyword - -error: expected one of `:`, `@`, or `|`, found keyword `self` - --> $DIR/bad-signatures.rs:8:23 - | -LL | async fn bar(&abc self); - | -----^^^^ - | | | - | | expected one of `:`, `@`, or `|` - | help: declare the type after the parameter binding: `: ` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr deleted file mode 100644 index eec5ab065397..000000000000 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: async associated function in trait cannot be specialized - --> $DIR/dont-project-to-specializable-projection.rs:16:5 - | -LL | default async fn foo(_: T) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed - -error: aborting due to previous error - diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr deleted file mode 100644 index 25a7f3bb56a5..000000000000 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/dont-project-to-specializable-projection.rs:16:35 - | -LL | default async fn foo(_: T) -> &'static str { - | ^^^^^^^^^^^^ expected associated type, found future - | -note: type in trait - --> $DIR/dont-project-to-specializable-projection.rs:12:27 - | -LL | async fn foo(_: T) -> &'static str; - | ^^^^^^^^^^^^ - = note: expected signature `fn(_) -> impl Future` - found signature `fn(_) -> impl Future` - -error: async associated function in trait cannot be specialized - --> $DIR/dont-project-to-specializable-projection.rs:16:5 - | -LL | default async fn foo(_: T) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr deleted file mode 100644 index 1a7495149899..000000000000 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types - --> $DIR/fn-not-async-err2.rs:15:22 - | -LL | fn foo(&self) -> impl Future { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr deleted file mode 100644 index 1a7495149899..000000000000 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types - --> $DIR/fn-not-async-err2.rs:15:22 - | -LL | fn foo(&self) -> impl Future { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 for more information - = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/async-await/in-trait/generics-mismatch.current.stderr b/tests/ui/async-await/in-trait/generics-mismatch.current.stderr deleted file mode 100644 index be23384e049d..000000000000 --- a/tests/ui/async-await/in-trait/generics-mismatch.current.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo` - --> $DIR/generics-mismatch.rs:13:18 - | -LL | trait Foo { - | --- -LL | async fn foo(); - | - expected type parameter -... -LL | impl Foo for () { - | --------------- -LL | async fn foo() {} - | ^^^^^^^^^^^^^^ found const parameter of type `usize` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/generics-mismatch.next.stderr b/tests/ui/async-await/in-trait/generics-mismatch.next.stderr deleted file mode 100644 index be23384e049d..000000000000 --- a/tests/ui/async-await/in-trait/generics-mismatch.next.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0053]: method `foo` has an incompatible generic parameter for trait `Foo` - --> $DIR/generics-mismatch.rs:13:18 - | -LL | trait Foo { - | --- -LL | async fn foo(); - | - expected type parameter -... -LL | impl Foo for () { - | --------------- -LL | async fn foo() {} - | ^^^^^^^^^^^^^^ found const parameter of type `usize` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr deleted file mode 100644 index 69e7c65ee3e7..000000000000 --- a/tests/ui/async-await/in-trait/lifetime-mismatch.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration - --> $DIR/lifetime-mismatch.rs:13:17 - | -LL | async fn foo<'a>(&self); - | ---- lifetimes in impl do not match this method in trait -... -LL | async fn foo(&self) {} - | ^ lifetimes do not match method in trait - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0195`. diff --git a/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr b/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr deleted file mode 100644 index 69e7c65ee3e7..000000000000 --- a/tests/ui/async-await/in-trait/lifetime-mismatch.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration - --> $DIR/lifetime-mismatch.rs:13:17 - | -LL | async fn foo<'a>(&self); - | ---- lifetimes in impl do not match this method in trait -... -LL | async fn foo(&self) {} - | ^ lifetimes do not match method in trait - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0195`. diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr deleted file mode 100644 index e6ac9bc2277b..000000000000 --- a/tests/ui/async-await/in-trait/missing-feature-flag.current.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/missing-feature-flag.rs:14:1 - | -LL | async fn foo(_: T) -> &'static str; - | ----------------------------------- `foo` from trait -... -LL | impl MyTrait for MyStruct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation - -error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/missing-feature-flag.rs:18:5 - | -LL | impl MyTrait for MyStruct {} - | ------------------------------- parent `impl` is here -... -LL | async fn foo(_: i32) -> &'static str {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` - | - = note: to specialize, `foo` in the parent `impl` must be marked `default` - -error[E0308]: mismatched types - --> $DIR/missing-feature-flag.rs:18:42 - | -LL | async fn foo(_: i32) -> &'static str {} - | ^^ expected `&str`, found `()` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0046, E0308, E0520. -For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr b/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr deleted file mode 100644 index e6ac9bc2277b..000000000000 --- a/tests/ui/async-await/in-trait/missing-feature-flag.next.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/missing-feature-flag.rs:14:1 - | -LL | async fn foo(_: T) -> &'static str; - | ----------------------------------- `foo` from trait -... -LL | impl MyTrait for MyStruct {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation - -error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/missing-feature-flag.rs:18:5 - | -LL | impl MyTrait for MyStruct {} - | ------------------------------- parent `impl` is here -... -LL | async fn foo(_: i32) -> &'static str {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot specialize default item `foo` - | - = note: to specialize, `foo` in the parent `impl` must be marked `default` - -error[E0308]: mismatched types - --> $DIR/missing-feature-flag.rs:18:42 - | -LL | async fn foo(_: i32) -> &'static str {} - | ^^ expected `&str`, found `()` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0046, E0308, E0520. -For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/async-await/in-trait/missing-send-bound.current.stderr b/tests/ui/async-await/in-trait/missing-send-bound.current.stderr deleted file mode 100644 index 9aa37f7437e4..000000000000 --- a/tests/ui/async-await/in-trait/missing-send-bound.current.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: future cannot be sent between threads safely - --> $DIR/missing-send-bound.rs:16:20 - | -LL | assert_is_send(test::()); - | ^^^^^^^^^^^ future returned by `test` is not `Send` - | - = help: within `impl Future`, the trait `Send` is not implemented for `impl Future` -note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/missing-send-bound.rs:12:5 - | -LL | T::bar().await; - | ^^^^^^^^ await occurs here on type `impl Future`, which is not `Send` -note: required by a bound in `assert_is_send` - --> $DIR/missing-send-bound.rs:20:27 - | -LL | fn assert_is_send(_: impl Send) {} - | ^^^^ required by this bound in `assert_is_send` - -error: aborting due to previous error - diff --git a/tests/ui/async-await/in-trait/missing-send-bound.next.stderr b/tests/ui/async-await/in-trait/missing-send-bound.next.stderr deleted file mode 100644 index 9aa37f7437e4..000000000000 --- a/tests/ui/async-await/in-trait/missing-send-bound.next.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: future cannot be sent between threads safely - --> $DIR/missing-send-bound.rs:16:20 - | -LL | assert_is_send(test::()); - | ^^^^^^^^^^^ future returned by `test` is not `Send` - | - = help: within `impl Future`, the trait `Send` is not implemented for `impl Future` -note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/missing-send-bound.rs:12:5 - | -LL | T::bar().await; - | ^^^^^^^^ await occurs here on type `impl Future`, which is not `Send` -note: required by a bound in `assert_is_send` - --> $DIR/missing-send-bound.rs:20:27 - | -LL | fn assert_is_send(_: impl Send) {} - | ^^^^ required by this bound in `assert_is_send` - -error: aborting due to previous error - diff --git a/tests/ui/async-await/in-trait/object-safety.current.stderr b/tests/ui/async-await/in-trait/object-safety.current.stderr deleted file mode 100644 index 7f7ec39142cd..000000000000 --- a/tests/ui/async-await/in-trait/object-safety.current.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:12:12 - | -LL | let x: &dyn Foo = todo!(); - | ^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:8:14 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | async fn foo(&self); - | ^^^ ...because method `foo` is `async` - = help: consider moving `foo` to another trait - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/in-trait/object-safety.next.stderr b/tests/ui/async-await/in-trait/object-safety.next.stderr deleted file mode 100644 index 7f7ec39142cd..000000000000 --- a/tests/ui/async-await/in-trait/object-safety.next.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:12:12 - | -LL | let x: &dyn Foo = todo!(); - | ^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:8:14 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | async fn foo(&self); - | ^^^ ...because method `foo` is `async` - = help: consider moving `foo` to another trait - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr deleted file mode 100644 index 56973a1d11a9..000000000000 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.current.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0726]: implicit elided lifetime not allowed here - --> $DIR/return-not-existing-pair.rs:12:20 - | -LL | impl<'a, 'b, T, U> MyTrait for U { - | ^^^^^^^^^^ expected lifetime parameters - | -help: indicate the anonymous lifetimes - | -LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U { - | +++++++ - -error[E0412]: cannot find type `ConnImpl` in this scope - --> $DIR/return-not-existing-pair.rs:8:48 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); - | ^^^^^^^^ not found in this scope - -error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl - --> $DIR/return-not-existing-pair.rs:14:5 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); - | ------------------------------------------------------------ `&self` used in trait -... -LL | async fn foo(_: T) -> (&'a U, &'b T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl - -error[E0308]: mismatched types - --> $DIR/return-not-existing-pair.rs:14:42 - | -LL | async fn foo(_: T) -> (&'a U, &'b T) {} - | ^^ expected `(&U, &T)`, found `()` - | - = note: expected tuple `(&'a U, &'b T)` - found unit type `()` - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0186, E0308, E0412, E0726. -For more information about an error, try `rustc --explain E0186`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr deleted file mode 100644 index 56973a1d11a9..000000000000 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.next.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0726]: implicit elided lifetime not allowed here - --> $DIR/return-not-existing-pair.rs:12:20 - | -LL | impl<'a, 'b, T, U> MyTrait for U { - | ^^^^^^^^^^ expected lifetime parameters - | -help: indicate the anonymous lifetimes - | -LL | impl<'a, 'b, T, U> MyTrait<'_, '_, T> for U { - | +++++++ - -error[E0412]: cannot find type `ConnImpl` in this scope - --> $DIR/return-not-existing-pair.rs:8:48 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); - | ^^^^^^^^ not found in this scope - -error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl - --> $DIR/return-not-existing-pair.rs:14:5 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); - | ------------------------------------------------------------ `&self` used in trait -... -LL | async fn foo(_: T) -> (&'a U, &'b T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl - -error[E0308]: mismatched types - --> $DIR/return-not-existing-pair.rs:14:42 - | -LL | async fn foo(_: T) -> (&'a U, &'b T) {} - | ^^ expected `(&U, &T)`, found `()` - | - = note: expected tuple `(&'a U, &'b T)` - found unit type `()` - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0186, E0308, E0412, E0726. -For more information about an error, try `rustc --explain E0186`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr deleted file mode 100644 index 2564d68d591a..000000000000 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.current.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0412]: cannot find type `Missing` in this scope - --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25 - | -LL | fn bar() -> Wrapper>; - | ^^^^^^^ not found in this scope - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr b/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr deleted file mode 100644 index 2564d68d591a..000000000000 --- a/tests/ui/async-await/in-trait/return-not-existing-type-wrapping-rpitit.next.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0412]: cannot find type `Missing` in this scope - --> $DIR/return-not-existing-type-wrapping-rpitit.rs:10:25 - | -LL | fn bar() -> Wrapper>; - | ^^^^^^^ not found in this scope - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr deleted file mode 100644 index 6a107d7beb8f..000000000000 --- a/tests/ui/async-await/in-trait/return-type-suggestion.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/return-type-suggestion.rs:9:9 - | -LL | Ok(()) - | ^^^^^^- help: consider using a semicolon here: `;` - | | - | expected `()`, found `Result<(), _>` - | - = note: expected unit type `()` - found enum `Result<(), _>` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr b/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr deleted file mode 100644 index 6a107d7beb8f..000000000000 --- a/tests/ui/async-await/in-trait/return-type-suggestion.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/return-type-suggestion.rs:9:9 - | -LL | Ok(()) - | ^^^^^^- help: consider using a semicolon here: `;` - | | - | expected `()`, found `Result<(), _>` - | - = note: expected unit type `()` - found enum `Result<(), _>` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/deep-match.current.stderr b/tests/ui/impl-trait/in-trait/deep-match.current.stderr deleted file mode 100644 index 400db20c79c9..000000000000 --- a/tests/ui/impl-trait/in-trait/deep-match.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0053]: method `bar` has an incompatible return type for trait - --> $DIR/deep-match.rs:14:17 - | -LL | fn bar() -> i32 { - | ^^^ - | | - | expected `Wrapper<_>`, found `i32` - | return type in trait - | - = note: expected struct `Wrapper<_>` - found type `i32` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/deep-match.next.stderr b/tests/ui/impl-trait/in-trait/deep-match.next.stderr deleted file mode 100644 index 400db20c79c9..000000000000 --- a/tests/ui/impl-trait/in-trait/deep-match.next.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0053]: method `bar` has an incompatible return type for trait - --> $DIR/deep-match.rs:14:17 - | -LL | fn bar() -> i32 { - | ^^^ - | | - | expected `Wrapper<_>`, found `i32` - | return type in trait - | - = note: expected struct `Wrapper<_>` - found type `i32` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr deleted file mode 100644 index 85450e3b0a0b..000000000000 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/default-body-type-err-2.rs:10:9 - | -LL | 42 - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr deleted file mode 100644 index 85450e3b0a0b..000000000000 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/default-body-type-err-2.rs:10:9 - | -LL | 42 - | ^^- help: try using a conversion method: `.to_string()` - | | - | expected `String`, found integer - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr deleted file mode 100644 index c949168a3778..000000000000 --- a/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String` - --> $DIR/default-body-type-err.rs:10:22 - | -LL | fn lol(&self) -> impl Deref { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String` -LL | -LL | &1i32 - | ----- return type was inferred to be `&i32` here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr deleted file mode 100644 index c949168a3778..000000000000 --- a/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String` - --> $DIR/default-body-type-err.rs:10:22 - | -LL | fn lol(&self) -> impl Deref { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String` -LL | -LL | &1i32 - | ----- return type was inferred to be `&i32` here - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr deleted file mode 100644 index 3c24eff9ae30..000000000000 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.current.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/default-body-with-rpit.rs:13:9 - | -LL | "" - | ^^ expected `impl Debug`, got `&'static str` - | -note: previous use here - --> $DIR/default-body-with-rpit.rs:12:39 - | -LL | async fn baz(&self) -> impl Debug { - | _______________________________________^ -LL | | "" -LL | | } - | |_____^ - -error[E0720]: cannot resolve opaque type - --> $DIR/default-body-with-rpit.rs:12:28 - | -LL | async fn baz(&self) -> impl Debug { - | ^^^^^^^^^^ cannot resolve opaque type - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr b/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr deleted file mode 100644 index 3c24eff9ae30..000000000000 --- a/tests/ui/impl-trait/in-trait/default-body-with-rpit.next.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error: concrete type differs from previous defining opaque type use - --> $DIR/default-body-with-rpit.rs:13:9 - | -LL | "" - | ^^ expected `impl Debug`, got `&'static str` - | -note: previous use here - --> $DIR/default-body-with-rpit.rs:12:39 - | -LL | async fn baz(&self) -> impl Debug { - | _______________________________________^ -LL | | "" -LL | | } - | |_____^ - -error[E0720]: cannot resolve opaque type - --> $DIR/default-body-with-rpit.rs:12:28 - | -LL | async fn baz(&self) -> impl Debug { - | ^^^^^^^^^^ cannot resolve opaque type - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr deleted file mode 100644 index 653016cf009a..000000000000 --- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/doesnt-satisfy.rs:12:17 - | -LL | fn bar() -> () {} - | ^^ `()` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `()` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -note: required by a bound in `Foo::bar::{opaque#0}` - --> $DIR/doesnt-satisfy.rs:8:22 - | -LL | fn bar() -> impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{opaque#0}` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr deleted file mode 100644 index f0cd43bcf921..000000000000 --- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/doesnt-satisfy.rs:12:17 - | -LL | fn bar() -> () {} - | ^^ `()` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `()` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -note: required by a bound in `Foo::{opaque#0}` - --> $DIR/doesnt-satisfy.rs:8:22 - | -LL | fn bar() -> impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr deleted file mode 100644 index d4d0124a6599..000000000000 --- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/dont-project-to-rpitit-with-no-value.rs:11:1 - | -LL | fn foo(&self) -> impl Sized; - | ---------------------------- `foo` from trait -... -LL | impl MyTrait for i32 { - | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr b/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr deleted file mode 100644 index d4d0124a6599..000000000000 --- a/tests/ui/impl-trait/in-trait/dont-project-to-rpitit-with-no-value.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0046]: not all trait items implemented, missing: `foo` - --> $DIR/dont-project-to-rpitit-with-no-value.rs:11:1 - | -LL | fn foo(&self) -> impl Sized; - | ---------------------------- `foo` from trait -... -LL | impl MyTrait for i32 { - | ^^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr b/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr deleted file mode 100644 index 310edbcb6cd1..000000000000 --- a/tests/ui/impl-trait/in-trait/generics-mismatch.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters - --> $DIR/generics-mismatch.rs:14:12 - | -LL | fn bar(&self) -> impl Sized; - | - expected 0 type parameters -... -LL | fn bar(&self) {} - | ^ found 1 type parameter - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr b/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr deleted file mode 100644 index 310edbcb6cd1..000000000000 --- a/tests/ui/impl-trait/in-trait/generics-mismatch.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters - --> $DIR/generics-mismatch.rs:14:12 - | -LL | fn bar(&self) -> impl Sized; - | - expected 0 type parameters -... -LL | fn bar(&self) {} - | ^ found 1 type parameter - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/impl-trait/in-trait/issue-102140.current.stderr b/tests/ui/impl-trait/in-trait/issue-102140.current.stderr deleted file mode 100644 index 7aa7880e2588..000000000000 --- a/tests/ui/impl-trait/in-trait/issue-102140.current.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:26:22 - | -LL | MyTrait::foo(&self) - | ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` - | | - | required by a bound introduced by this call - | -help: consider removing the leading `&`-reference - | -LL - MyTrait::foo(&self) -LL + MyTrait::foo(self) - | - -error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:26:9 - | -LL | MyTrait::foo(&self) - | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` - | - = help: the trait `MyTrait` is implemented for `Outer` - -error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:26:9 - | -LL | MyTrait::foo(&self) - | ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` - | - = help: the trait `MyTrait` is implemented for `Outer` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/issue-102140.next.stderr b/tests/ui/impl-trait/in-trait/issue-102140.next.stderr deleted file mode 100644 index 94893c9e7b49..000000000000 --- a/tests/ui/impl-trait/in-trait/issue-102140.next.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:26:22 - | -LL | MyTrait::foo(&self) - | ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` - | | - | required by a bound introduced by this call - | - = help: the trait `MyTrait` is implemented for `Outer` - -error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:26:9 - | -LL | MyTrait::foo(&self) - | ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` - | - = help: the trait `MyTrait` is implemented for `Outer` - -error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied - --> $DIR/issue-102140.rs:26:9 - | -LL | MyTrait::foo(&self) - | ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait` - | - = help: the trait `MyTrait` is implemented for `Outer` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/issue-102571.current.stderr b/tests/ui/impl-trait/in-trait/issue-102571.current.stderr deleted file mode 100644 index cac9a29f6440..000000000000 --- a/tests/ui/impl-trait/in-trait/issue-102571.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-102571.rs:23:9 - | -LL | let () = t.bar(); - | ^^ ------- this expression has type `impl Deref` - | | - | expected associated type, found `()` - | - = note: expected associated type `impl Deref` - found unit type `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/issue-102571.next.stderr b/tests/ui/impl-trait/in-trait/issue-102571.next.stderr deleted file mode 100644 index cac9a29f6440..000000000000 --- a/tests/ui/impl-trait/in-trait/issue-102571.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-102571.rs:23:9 - | -LL | let () = t.bar(); - | ^^ ------- this expression has type `impl Deref` - | | - | expected associated type, found `()` - | - = note: expected associated type `impl Deref` - found unit type `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/object-safety.current.stderr b/tests/ui/impl-trait/in-trait/object-safety.current.stderr deleted file mode 100644 index 2c340a02319b..000000000000 --- a/tests/ui/impl-trait/in-trait/object-safety.current.stderr +++ /dev/null @@ -1,49 +0,0 @@ -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:33 - | -LL | let i = Box::new(42_u32) as Box; - | ^^^^^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:10:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:23:13 - | -LL | let s = i.baz(); - | ^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:10:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:13 - | -LL | let i = Box::new(42_u32) as Box; - | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:10:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - = note: required for the cast from `Box` to `Box` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/in-trait/object-safety.next.stderr b/tests/ui/impl-trait/in-trait/object-safety.next.stderr deleted file mode 100644 index 2c340a02319b..000000000000 --- a/tests/ui/impl-trait/in-trait/object-safety.next.stderr +++ /dev/null @@ -1,49 +0,0 @@ -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:33 - | -LL | let i = Box::new(42_u32) as Box; - | ^^^^^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:10:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:23:13 - | -LL | let s = i.baz(); - | ^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:10:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety.rs:20:13 - | -LL | let i = Box::new(42_u32) as Box; - | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/object-safety.rs:10:22 - | -LL | trait Foo { - | --- this trait cannot be made into an object... -LL | fn baz(&self) -> impl Debug; - | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type - = help: consider moving `baz` to another trait - = note: required for the cast from `Box` to `Box` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr deleted file mode 100644 index a57653b2c9ed..000000000000 --- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.current.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/opaque-in-impl-is-opaque.rs:20:19 - | -LL | fn bar(&self) -> impl Display { - | ------------ the found opaque type -... -LL | let x: &str = ().bar(); - | ---- ^^^^^^^^ expected `&str`, found opaque type - | | - | expected due to this - | - = note: expected reference `&str` - found opaque type `impl std::fmt::Display` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr b/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr deleted file mode 100644 index a57653b2c9ed..000000000000 --- a/tests/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/opaque-in-impl-is-opaque.rs:20:19 - | -LL | fn bar(&self) -> impl Display { - | ------------ the found opaque type -... -LL | let x: &str = ().bar(); - | ---- ^^^^^^^^ expected `&str`, found opaque type - | | - | expected due to this - | - = note: expected reference `&str` - found opaque type `impl std::fmt::Display` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr deleted file mode 100644 index ff30103b771d..000000000000 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.current.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0277]: the trait bound `impl Foo: Foo` is not satisfied - --> $DIR/return-dont-satisfy-bounds.rs:13:34 - | -LL | fn foo>(self) -> impl Foo { - | ^^^^^^^^^^^^ the trait `Foo` is not implemented for `impl Foo` - | - = help: the trait `Foo` is implemented for `Bar` -note: required by a bound in `Foo::foo::{opaque#0}` - --> $DIR/return-dont-satisfy-bounds.rs:7:30 - | -LL | fn foo(self) -> impl Foo; - | ^^^^^^ required by this bound in `Foo::foo::{opaque#0}` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr deleted file mode 100644 index 7c7f7feaa550..000000000000 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.next.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0277]: the trait bound `impl Foo: Foo` is not satisfied - --> $DIR/return-dont-satisfy-bounds.rs:13:34 - | -LL | fn foo>(self) -> impl Foo { - | ^^^^^^^^^^^^ the trait `Foo` is not implemented for `impl Foo` - | - = help: the trait `Foo` is implemented for `Bar` -note: required by a bound in `Foo::{opaque#0}` - --> $DIR/return-dont-satisfy-bounds.rs:7:30 - | -LL | fn foo(self) -> impl Foo; - | ^^^^^^ required by this bound in `Foo::{opaque#0}` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr deleted file mode 100644 index 8c9dd403174b..000000000000 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.current.stderr +++ /dev/null @@ -1,61 +0,0 @@ -error: return type captures more lifetimes than trait definition - --> $DIR/signature-mismatch.rs:36:47 - | -LL | fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future> + 'a { - | -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: hidden type must only reference lifetimes captured by this impl trait - --> $DIR/signature-mismatch.rs:17:40 - | -LL | fn async_fn(&self, buff: &[u8]) -> impl Future>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: hidden type inferred to be `impl Future> + 'a` - -error: return type captures more lifetimes than trait definition - --> $DIR/signature-mismatch.rs:41:57 - | -LL | fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future> + 'a { - | -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: hidden type must only reference lifetimes captured by this impl trait - --> $DIR/signature-mismatch.rs:18:57 - | -LL | fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: hidden type inferred to be `impl Future> + 'a` - -error: return type captures more lifetimes than trait definition - --> $DIR/signature-mismatch.rs:49:10 - | -LL | fn async_fn_multiple<'a, 'b>( - | -- this lifetime was captured -... -LL | ) -> impl Future> + Captures2<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: hidden type must only reference lifetimes captured by this impl trait - --> $DIR/signature-mismatch.rs:20:12 - | -LL | -> impl Future> + Captures<'a>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: hidden type inferred to be `impl Future> + Captures2<'a, 'b>` - -error[E0309]: the parameter type `T` may not live long enough - --> $DIR/signature-mismatch.rs:58:10 - | -LL | ) -> impl Future> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `impl Future>` will meet its required lifetime bounds... - | -note: ...that is required by this bound - --> $DIR/signature-mismatch.rs:25:42 - | -LL | ) -> impl Future> + 'a; - | ^^ -help: consider adding an explicit lifetime bound... - | -LL | fn async_fn_reduce_outlive<'a, 'b, T: 'a>( - | ++++ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr deleted file mode 100644 index 8c9dd403174b..000000000000 --- a/tests/ui/impl-trait/in-trait/signature-mismatch.next.stderr +++ /dev/null @@ -1,61 +0,0 @@ -error: return type captures more lifetimes than trait definition - --> $DIR/signature-mismatch.rs:36:47 - | -LL | fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future> + 'a { - | -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: hidden type must only reference lifetimes captured by this impl trait - --> $DIR/signature-mismatch.rs:17:40 - | -LL | fn async_fn(&self, buff: &[u8]) -> impl Future>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: hidden type inferred to be `impl Future> + 'a` - -error: return type captures more lifetimes than trait definition - --> $DIR/signature-mismatch.rs:41:57 - | -LL | fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future> + 'a { - | -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: hidden type must only reference lifetimes captured by this impl trait - --> $DIR/signature-mismatch.rs:18:57 - | -LL | fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: hidden type inferred to be `impl Future> + 'a` - -error: return type captures more lifetimes than trait definition - --> $DIR/signature-mismatch.rs:49:10 - | -LL | fn async_fn_multiple<'a, 'b>( - | -- this lifetime was captured -... -LL | ) -> impl Future> + Captures2<'a, 'b> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: hidden type must only reference lifetimes captured by this impl trait - --> $DIR/signature-mismatch.rs:20:12 - | -LL | -> impl Future> + Captures<'a>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: hidden type inferred to be `impl Future> + Captures2<'a, 'b>` - -error[E0309]: the parameter type `T` may not live long enough - --> $DIR/signature-mismatch.rs:58:10 - | -LL | ) -> impl Future> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `impl Future>` will meet its required lifetime bounds... - | -note: ...that is required by this bound - --> $DIR/signature-mismatch.rs:25:42 - | -LL | ) -> impl Future> + 'a; - | ^^ -help: consider adding an explicit lifetime bound... - | -LL | fn async_fn_reduce_outlive<'a, 'b, T: 'a>( - | ++++ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr deleted file mode 100644 index f48e7a1ed140..000000000000 --- a/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/specialization-broken.rs:19:22 - | -LL | default impl Foo for U - | - this type parameter -... -LL | fn bar(&self) -> U { - | ^ - | | - | expected associated type, found type parameter `U` - | help: change the output type to match the trait: `impl Sized` - | -note: type in trait - --> $DIR/specialization-broken.rs:12:22 - | -LL | fn bar(&self) -> impl Sized; - | ^^^^^^^^^^ - = note: expected signature `fn(&U) -> impl Sized` - found signature `fn(&U) -> U` - -error: method with return-position `impl Trait` in trait cannot be specialized - --> $DIR/specialization-broken.rs:19:5 - | -LL | fn bar(&self) -> U { - | ^^^^^^^^^^^^^^^^^^ - | - = note: specialization behaves in inconsistent and surprising ways with `#![feature(return_position_impl_trait_in_trait)]`, and for now is disallowed - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr deleted file mode 100644 index f48e7a1ed140..000000000000 --- a/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/specialization-broken.rs:19:22 - | -LL | default impl Foo for U - | - this type parameter -... -LL | fn bar(&self) -> U { - | ^ - | | - | expected associated type, found type parameter `U` - | help: change the output type to match the trait: `impl Sized` - | -note: type in trait - --> $DIR/specialization-broken.rs:12:22 - | -LL | fn bar(&self) -> impl Sized; - | ^^^^^^^^^^ - = note: expected signature `fn(&U) -> impl Sized` - found signature `fn(&U) -> U` - -error: method with return-position `impl Trait` in trait cannot be specialized - --> $DIR/specialization-broken.rs:19:5 - | -LL | fn bar(&self) -> U { - | ^^^^^^^^^^^^^^^^^^ - | - = note: specialization behaves in inconsistent and surprising ways with `#![feature(return_position_impl_trait_in_trait)]`, and for now is disallowed - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr deleted file mode 100644 index 64c942705cf8..000000000000 --- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.current.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter - --> $DIR/trait-more-generics-than-impl.rs:14:11 - | -LL | fn bar() -> impl Sized; - | - expected 1 type parameter -... -LL | fn bar() -> impl Sized {} - | ^ found 0 type parameters - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr b/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr deleted file mode 100644 index 64c942705cf8..000000000000 --- a/tests/ui/impl-trait/in-trait/trait-more-generics-than-impl.next.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter - --> $DIR/trait-more-generics-than-impl.rs:14:11 - | -LL | fn bar() -> impl Sized; - | - expected 1 type parameter -... -LL | fn bar() -> impl Sized {} - | ^ found 0 type parameters - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0049`. diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr deleted file mode 100644 index bf088ae8b25c..000000000000 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.current.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-lt.rs:10:6 - | -LL | impl<'a, T> Foo for T { - | ^^ unconstrained lifetime parameter - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr b/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr deleted file mode 100644 index bf088ae8b25c..000000000000 --- a/tests/ui/impl-trait/in-trait/unconstrained-lt.next.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained-lt.rs:10:6 - | -LL | impl<'a, T> Foo for T { - | ^^ unconstrained lifetime parameter - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr deleted file mode 100644 index 74c84c012b1b..000000000000 --- a/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:17:22 - | -LL | fn nya() -> impl Wf>; - | ^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:20:23 - | -LL | fn nya2() -> impl Wf<[u8]>; - | ^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Wf` - --> $DIR/wf-bounds.rs:10:10 - | -LL | trait Wf { - | ^ required by this bound in `Wf` -help: consider relaxing the implicit `Sized` restriction - | -LL | trait Wf { - | ++++++++ - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:23:44 - | -LL | fn nya3() -> impl Wf<(), Output = impl Wf>>; - | ^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error[E0277]: `T` doesn't implement `std::fmt::Display` - --> $DIR/wf-bounds.rs:26:26 - | -LL | fn nya4() -> impl Wf>; - | ^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter - | - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -note: required by a bound in `NeedsDisplay` - --> $DIR/wf-bounds.rs:14:24 - | -LL | struct NeedsDisplay(T); - | ^^^^^^^ required by this bound in `NeedsDisplay` -help: consider restricting type parameter `T` - | -LL | fn nya4() -> impl Wf>; - | +++++++++++++++++++ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr deleted file mode 100644 index 74c84c012b1b..000000000000 --- a/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:17:22 - | -LL | fn nya() -> impl Wf>; - | ^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:20:23 - | -LL | fn nya2() -> impl Wf<[u8]>; - | ^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Wf` - --> $DIR/wf-bounds.rs:10:10 - | -LL | trait Wf { - | ^ required by this bound in `Wf` -help: consider relaxing the implicit `Sized` restriction - | -LL | trait Wf { - | ++++++++ - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:23:44 - | -LL | fn nya3() -> impl Wf<(), Output = impl Wf>>; - | ^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Vec` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error[E0277]: `T` doesn't implement `std::fmt::Display` - --> $DIR/wf-bounds.rs:26:26 - | -LL | fn nya4() -> impl Wf>; - | ^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter - | - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -note: required by a bound in `NeedsDisplay` - --> $DIR/wf-bounds.rs:14:24 - | -LL | struct NeedsDisplay(T); - | ^^^^^^^ required by this bound in `NeedsDisplay` -help: consider restricting type parameter `T` - | -LL | fn nya4() -> impl Wf>; - | +++++++++++++++++++ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0277`. From a22b9bf2e699b67f060142af4d26728ee9020f36 Mon Sep 17 00:00:00 2001 From: Alyssa Haroldsen Date: Tue, 8 Aug 2023 15:52:52 -0700 Subject: [PATCH 60/76] Rename copying `ascii::Char` methods from `as_` to `to_` Tracking issue: #110998. The [API guidelines][naming] describe `as` as used for borrowed -> borrowed operations, and `to_` for owned -> owned operations on `Copy` types. [naming]: https://rust-lang.github.io/api-guidelines/naming.html --- library/core/src/ascii/ascii_char.rs | 4 ++-- library/core/src/escape.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index f093a0990d1a..5378b210e673 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -518,14 +518,14 @@ pub const fn digit(d: u8) -> Option { /// Gets this ASCII character as a byte. #[unstable(feature = "ascii_char", issue = "110998")] #[inline] - pub const fn as_u8(self) -> u8 { + pub const fn to_u8(self) -> u8 { self as u8 } /// Gets this ASCII character as a `char` Unicode Scalar Value. #[unstable(feature = "ascii_char", issue = "110998")] #[inline] - pub const fn as_char(self) -> char { + pub const fn to_char(self) -> char { self as u8 as char } diff --git a/library/core/src/escape.rs b/library/core/src/escape.rs index 3d471419bb8f..24bb9ad1ad1a 100644 --- a/library/core/src/escape.rs +++ b/library/core/src/escape.rs @@ -95,11 +95,11 @@ pub fn len(&self) -> usize { } pub fn next(&mut self) -> Option { - self.alive.next().map(|i| self.data[usize::from(i)].as_u8()) + self.alive.next().map(|i| self.data[usize::from(i)].to_u8()) } pub fn next_back(&mut self) -> Option { - self.alive.next_back().map(|i| self.data[usize::from(i)].as_u8()) + self.alive.next_back().map(|i| self.data[usize::from(i)].to_u8()) } pub fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { From 31ddea6e988ba34bcca97c700a6297657331964a Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Sun, 16 Apr 2023 23:16:52 +0000 Subject: [PATCH 61/76] rustdoc-json: Add tests for field/variant ordering. --- tests/rustdoc-json/enums/field_order.rs | 40 +++++++++++++++++++++++ tests/rustdoc-json/enums/variant_order.rs | 38 +++++++++++++++++++++ tests/rustdoc-json/structs/field_order.rs | 38 +++++++++++++++++++++ tests/rustdoc-json/unions/field_order.rs | 38 +++++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 tests/rustdoc-json/enums/field_order.rs create mode 100644 tests/rustdoc-json/enums/variant_order.rs create mode 100644 tests/rustdoc-json/structs/field_order.rs create mode 100644 tests/rustdoc-json/unions/field_order.rs diff --git a/tests/rustdoc-json/enums/field_order.rs b/tests/rustdoc-json/enums/field_order.rs new file mode 100644 index 000000000000..e89add9cbbde --- /dev/null +++ b/tests/rustdoc-json/enums/field_order.rs @@ -0,0 +1,40 @@ +// Check that the order of fields is preserved. + +pub enum Whatever { + Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + ews_0: i32, + dik_1: i32, + hsk_2: i32, + djt_3: i32, + jnr_4: i32, + dfs_5: i32, + bja_6: i32, + lyc_7: i32, + yqd_8: i32, + vll_9: i32, + }, +} + +// @set 0 = '$.index[*][?(@.name == "ews_0")].id' +// @set 1 = '$.index[*][?(@.name == "dik_1")].id' +// @set 2 = '$.index[*][?(@.name == "hsk_2")].id' +// @set 3 = '$.index[*][?(@.name == "djt_3")].id' +// @set 4 = '$.index[*][?(@.name == "jnr_4")].id' +// @set 5 = '$.index[*][?(@.name == "dfs_5")].id' +// @set 6 = '$.index[*][?(@.name == "bja_6")].id' +// @set 7 = '$.index[*][?(@.name == "lyc_7")].id' +// @set 8 = '$.index[*][?(@.name == "yqd_8")].id' +// @set 9 = '$.index[*][?(@.name == "vll_9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[9]' $9 diff --git a/tests/rustdoc-json/enums/variant_order.rs b/tests/rustdoc-json/enums/variant_order.rs new file mode 100644 index 000000000000..17ca96213de9 --- /dev/null +++ b/tests/rustdoc-json/enums/variant_order.rs @@ -0,0 +1,38 @@ +// Check that the order of variants is preserved. + +pub enum Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + Ews0, + Dik1, + Hsk2, + Djt3, + Jnr4, + Dfs5, + Bja6, + Lyc7, + Yqd8, + Vll9, +} + +// @set 0 = '$.index[*][?(@.name == "Ews0")].id' +// @set 1 = '$.index[*][?(@.name == "Dik1")].id' +// @set 2 = '$.index[*][?(@.name == "Hsk2")].id' +// @set 3 = '$.index[*][?(@.name == "Djt3")].id' +// @set 4 = '$.index[*][?(@.name == "Jnr4")].id' +// @set 5 = '$.index[*][?(@.name == "Dfs5")].id' +// @set 6 = '$.index[*][?(@.name == "Bja6")].id' +// @set 7 = '$.index[*][?(@.name == "Lyc7")].id' +// @set 8 = '$.index[*][?(@.name == "Yqd8")].id' +// @set 9 = '$.index[*][?(@.name == "Vll9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.enum.variants[9]' $9 diff --git a/tests/rustdoc-json/structs/field_order.rs b/tests/rustdoc-json/structs/field_order.rs new file mode 100644 index 000000000000..a8c18323d527 --- /dev/null +++ b/tests/rustdoc-json/structs/field_order.rs @@ -0,0 +1,38 @@ +// Check that the order of fields is preserved. + +pub struct Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + pub ews_0: i32, + pub dik_1: i32, + pub hsk_2: i32, + pub djt_3: i32, + pub jnr_4: i32, + pub dfs_5: i32, + pub bja_6: i32, + pub lyc_7: i32, + pub yqd_8: i32, + pub vll_9: i32, +} + +// @set 0 = '$.index[*][?(@.name == "ews_0")].id' +// @set 1 = '$.index[*][?(@.name == "dik_1")].id' +// @set 2 = '$.index[*][?(@.name == "hsk_2")].id' +// @set 3 = '$.index[*][?(@.name == "djt_3")].id' +// @set 4 = '$.index[*][?(@.name == "jnr_4")].id' +// @set 5 = '$.index[*][?(@.name == "dfs_5")].id' +// @set 6 = '$.index[*][?(@.name == "bja_6")].id' +// @set 7 = '$.index[*][?(@.name == "lyc_7")].id' +// @set 8 = '$.index[*][?(@.name == "yqd_8")].id' +// @set 9 = '$.index[*][?(@.name == "vll_9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[9]' $9 diff --git a/tests/rustdoc-json/unions/field_order.rs b/tests/rustdoc-json/unions/field_order.rs new file mode 100644 index 000000000000..8a40bda03999 --- /dev/null +++ b/tests/rustdoc-json/unions/field_order.rs @@ -0,0 +1,38 @@ +// Check that the order of fields is preserved. + +pub union Foo { + // Important: random prefixes are used here to ensure that + // sorting fields by name would cause this test to fail. + pub ews_0: i32, + pub dik_1: i32, + pub hsk_2: i32, + pub djt_3: i32, + pub jnr_4: i32, + pub dfs_5: i32, + pub bja_6: i32, + pub lyc_7: i32, + pub yqd_8: i32, + pub vll_9: i32, +} + +// @set 0 = '$.index[*][?(@.name == "ews_0")].id' +// @set 1 = '$.index[*][?(@.name == "dik_1")].id' +// @set 2 = '$.index[*][?(@.name == "hsk_2")].id' +// @set 3 = '$.index[*][?(@.name == "djt_3")].id' +// @set 4 = '$.index[*][?(@.name == "jnr_4")].id' +// @set 5 = '$.index[*][?(@.name == "dfs_5")].id' +// @set 6 = '$.index[*][?(@.name == "bja_6")].id' +// @set 7 = '$.index[*][?(@.name == "lyc_7")].id' +// @set 8 = '$.index[*][?(@.name == "yqd_8")].id' +// @set 9 = '$.index[*][?(@.name == "vll_9")].id' + +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[0]' $0 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[1]' $1 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[2]' $2 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[3]' $3 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[4]' $4 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[5]' $5 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[6]' $6 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[7]' $7 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[8]' $8 +// @is '$.index[*][?(@.name == "Foo")].inner.union.fields[9]' $9 From 897c7bb23bfd29b94de4b390cdc3c5c38be84990 Mon Sep 17 00:00:00 2001 From: Seth Pellegrino Date: Tue, 23 May 2023 15:08:23 -0700 Subject: [PATCH 62/76] feat: `riscv-interrupt-{m,s}` calling conventions Similar to prior support added for the mips430, avr, and x86 targets this change implements the rough equivalent of clang's [`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling e.g. ```rust static mut CNT: usize = 0; pub extern "riscv-interrupt-m" fn isr_m() { unsafe { CNT += 1; } } ``` to produce highly effective assembly like: ```asm pub extern "riscv-interrupt-m" fn isr_m() { 420003a0: 1141 addi sp,sp,-16 unsafe { CNT += 1; 420003a2: c62a sw a0,12(sp) 420003a4: c42e sw a1,8(sp) 420003a6: 3fc80537 lui a0,0x3fc80 420003aa: 63c52583 lw a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0> 420003ae: 0585 addi a1,a1,1 420003b0: 62b52e23 sw a1,1596(a0) } } 420003b4: 4532 lw a0,12(sp) 420003b6: 45a2 lw a1,8(sp) 420003b8: 0141 addi sp,sp,16 420003ba: 30200073 mret ``` (disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`) This outcome is superior to hand-coded interrupt routines which, lacking visibility into any non-assembly body of the interrupt handler, have to be very conservative and save the [entire CPU state to the stack frame][full-frame-save]. By instead asking LLVM to only save the registers that it uses, we defer the decision to the tool with the best context: it can more accurately account for the cost of spills if it knows that every additional register used is already at the cost of an implicit spill. At the LLVM level, this is apparently [implemented by] marking every register as "[callee-save]," matching the semantics of an interrupt handler nicely (it has to leave the CPU state just as it found it after its `{m|s}ret`). This approach is not suitable for every interrupt handler, as it makes no attempt to e.g. save the state in a user-accessible stack frame. For a full discussion of those challenges and tradeoffs, please refer to [the interrupt calling conventions RFC][rfc]. Inside rustc, this implementation differs from prior art because LLVM does not expose the "all-saved" function flavor as a calling convention directly, instead preferring to use an attribute that allows for differentiating between "machine-mode" and "superivsor-mode" interrupts. Finally, some effort has been made to guide those who may not yet be aware of the differences between machine-mode and supervisor-mode interrupts as to why no `riscv-interrupt` calling convention is exposed through rustc, and similarly for why `riscv-interrupt-u` makes no appearance (as it would complicate future LLVM upgrades). [clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v [full-frame-save]: https://github.com/esp-rs/esp-riscv-rt/blob/9281af2ecffe13e40992917316f36920c26acaf3/src/lib.rs#L440-L469 [implemented by]: https://github.com/llvm/llvm-project/blob/b7fb2a3fec7c187d58a6d338ab512d9173bca987/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp#L61-L67 [callee-save]: https://github.com/llvm/llvm-project/blob/973f1fe7a8591c7af148e573491ab68cc15b6ecf/llvm/lib/Target/RISCV/RISCVCallingConv.td#L30-L37 [rfc]: https://github.com/rust-lang/rfcs/pull/3246 --- compiler/rustc_ast_lowering/src/errors.rs | 17 ++++++ compiler/rustc_ast_lowering/src/item.rs | 12 ++-- .../rustc_codegen_cranelift/src/abi/mod.rs | 4 +- compiler/rustc_codegen_llvm/src/abi.rs | 9 ++- compiler/rustc_feature/src/active.rs | 2 + compiler/rustc_middle/src/ty/layout.rs | 2 + .../src/ffi_unwind_calls.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/abi/call/mod.rs | 25 ++++++++ compiler/rustc_target/src/json.rs | 5 ++ compiler/rustc_target/src/spec/abi.rs | 30 ++++++++- compiler/rustc_target/src/spec/abi/tests.rs | 6 +- compiler/rustc_target/src/spec/mod.rs | 3 +- compiler/rustc_ty_utils/src/abi.rs | 3 + .../src/completions/extern_abi.rs | 2 + ...cv-discoverability-guidance.riscv32.stderr | 27 ++++++++ ...cv-discoverability-guidance.riscv64.stderr | 27 ++++++++ .../ui/abi/riscv-discoverability-guidance.rs | 27 ++++++++ tests/ui/abi/unsupported.aarch64.stderr | 26 +++++--- tests/ui/abi/unsupported.arm.stderr | 24 +++++--- tests/ui/abi/unsupported.i686.stderr | 20 +++--- tests/ui/abi/unsupported.riscv32.stderr | 61 +++++++++++++++++++ tests/ui/abi/unsupported.riscv64.stderr | 61 +++++++++++++++++++ tests/ui/abi/unsupported.rs | 40 +++++++++--- tests/ui/abi/unsupported.x64.stderr | 24 +++++--- .../feature-gate-abi-riscv-interrupt.rs | 33 ++++++++++ .../feature-gate-abi-riscv-interrupt.stderr | 57 +++++++++++++++++ 27 files changed, 492 insertions(+), 58 deletions(-) create mode 100644 tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr create mode 100644 tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr create mode 100644 tests/ui/abi/riscv-discoverability-guidance.rs create mode 100644 tests/ui/abi/unsupported.riscv32.stderr create mode 100644 tests/ui/abi/unsupported.riscv64.stderr create mode 100644 tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs create mode 100644 tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 72dc52a63299..a63bd4f8a025 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -31,9 +31,26 @@ pub struct InvalidAbi { pub abi: Symbol, pub command: String, #[subdiagnostic] + pub explain: Option, + #[subdiagnostic] pub suggestion: Option, } +pub struct InvalidAbiReason(pub &'static str); + +impl rustc_errors::AddToDiagnostic for InvalidAbiReason { + fn add_to_diagnostic_with(self, diag: &mut rustc_errors::Diagnostic, _: F) + where + F: Fn( + &mut rustc_errors::Diagnostic, + rustc_errors::SubdiagnosticMessage, + ) -> rustc_errors::SubdiagnosticMessage, + { + #[allow(rustc::untranslatable_diagnostic)] + diag.note(self.0); + } +} + #[derive(Subdiagnostic)] #[suggestion( ast_lowering_invalid_abi_suggestion, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7954297900f9..a59c83de0f46 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1,4 +1,4 @@ -use super::errors::{InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound}; +use super::errors::{InvalidAbi, InvalidAbiReason, InvalidAbiSuggestion, MisplacedRelaxTraitBound}; use super::ResolverAstLoweringExt; use super::{AstOwner, ImplTraitContext, ImplTraitPosition}; use super::{FnDeclKind, LoweringContext, ParamMode}; @@ -1271,8 +1271,8 @@ fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader { } pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi { - abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| { - self.error_on_invalid_abi(abi); + abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|err| { + self.error_on_invalid_abi(abi, err); abi::Abi::Rust }) } @@ -1285,7 +1285,7 @@ pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi { } } - fn error_on_invalid_abi(&self, abi: StrLit) { + fn error_on_invalid_abi(&self, abi: StrLit, err: abi::AbiUnsupported) { let abi_names = abi::enabled_names(self.tcx.features(), abi.span) .iter() .map(|s| Symbol::intern(s)) @@ -1294,6 +1294,10 @@ fn error_on_invalid_abi(&self, abi: StrLit) { self.tcx.sess.emit_err(InvalidAbi { abi: abi.symbol_unescaped, span: abi.span, + explain: match err { + abi::AbiUnsupported::Reason { explain } => Some(InvalidAbiReason(explain)), + _ => None, + }, suggestion: suggested_name.map(|suggested_name| InvalidAbiSuggestion { span: abi.span, suggestion: format!("\"{suggested_name}\""), diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 2c038f22ca99..b7f56a2986cf 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -48,7 +48,9 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call default_call_conv } - Conv::X86Intr => sess.fatal("x86-interrupt call conv not yet implemented"), + Conv::X86Intr | Conv::RiscvInterrupt { .. } => { + sess.fatal(format!("interrupt call conv {c:?} not yet implemented")) + } Conv::ArmAapcs => sess.fatal("aapcs call conv not yet implemented"), Conv::CCmseNonSecureCall => { diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index e02b457fd0b1..c6a7dc95d77a 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -383,13 +383,16 @@ fn llvm_cconv(&self) -> llvm::CallConv { } fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) { - let mut func_attrs = SmallVec::<[_; 2]>::new(); + let mut func_attrs = SmallVec::<[_; 3]>::new(); if self.ret.layout.abi.is_uninhabited() { func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx)); } if !self.can_unwind { func_attrs.push(llvm::AttributeKind::NoUnwind.create_attr(cx.llcx)); } + if let Conv::RiscvInterrupt { kind } = self.conv { + func_attrs.push(llvm::CreateAttrStringValue(cx.llcx, "interrupt", kind.as_str())); + } attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &{ func_attrs }); let mut i = 0; @@ -565,7 +568,9 @@ fn get_param(&mut self, index: usize) -> Self::Value { impl From for llvm::CallConv { fn from(conv: Conv) -> Self { match conv { - Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv, + Conv::C | Conv::Rust | Conv::CCmseNonSecureCall | Conv::RiscvInterrupt { .. } => { + llvm::CCallConv + } Conv::RustCold => llvm::ColdCallConv, Conv::AmdGpuKernel => llvm::AmdGpuKernel, Conv::AvrInterrupt => llvm::AvrInterrupt, diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index ede3570510ac..898f5fd3b709 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -313,6 +313,8 @@ pub fn set(&self, features: &mut Features, span: Span) { (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), /// Allows `extern "ptx-*" fn()`. (active, abi_ptx, "1.15.0", Some(38788), None), + /// Allows `extern "riscv-interrupt-m" fn()` and `extern "riscv-interrupt-s" fn()`. + (active, abi_riscv_interrupt, "CURRENT_RUSTC_VERSION", Some(111889), None), /// Allows `extern "x86-interrupt" fn()`. (active, abi_x86_interrupt, "1.17.0", Some(40180), None), /// Allows additional const parameter types, such as `&'static str` or user defined types diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index df39103bc197..e362b3477c9f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1239,6 +1239,8 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option, abi: SpecAbi) -> | EfiApi | AvrInterrupt | AvrNonBlockingInterrupt + | RiscvInterruptM + | RiscvInterruptS | CCmseNonSecureCall | Wasm | PlatformIntrinsic diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 58cc161ddcc4..d202860840c2 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -30,6 +30,8 @@ fn abi_can_unwind(abi: Abi) -> bool { | EfiApi | AvrInterrupt | AvrNonBlockingInterrupt + | RiscvInterruptM + | RiscvInterruptS | CCmseNonSecureCall | Wasm | RustIntrinsic diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9ea9efb047c2..745a3590720a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -326,6 +326,7 @@ abi_efiapi, abi_msp430_interrupt, abi_ptx, + abi_riscv_interrupt, abi_sysv64, abi_thiscall, abi_unadjusted, diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 3d2ea017d8f1..e4989bdfbcd6 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -603,6 +603,25 @@ pub enum Conv { AmdGpuKernel, AvrInterrupt, AvrNonBlockingInterrupt, + + RiscvInterrupt { + kind: RiscvInterruptKind, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] +pub enum RiscvInterruptKind { + Machine, + Supervisor, +} + +impl RiscvInterruptKind { + pub fn as_str(&self) -> &'static str { + match self { + Self::Machine => "machine", + Self::Supervisor => "supervisor", + } + } } /// Metadata describing how the arguments to a native function @@ -753,6 +772,12 @@ fn from_str(s: &str) -> Result { "AmdGpuKernel" => Ok(Conv::AmdGpuKernel), "AvrInterrupt" => Ok(Conv::AvrInterrupt), "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt), + "RiscvInterrupt(machine)" => { + Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine }) + } + "RiscvInterrupt(supervisor)" => { + Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor }) + } _ => Err(format!("'{s}' is not a valid value for entry function call convention.")), } } diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs index 75bb76a9de08..af455b6432f5 100644 --- a/compiler/rustc_target/src/json.rs +++ b/compiler/rustc_target/src/json.rs @@ -92,6 +92,7 @@ fn to_json(&self) -> Json { impl ToJson for crate::abi::call::Conv { fn to_json(&self) -> Json { + let buf: String; let s = match self { Self::C => "C", Self::Rust => "Rust", @@ -110,6 +111,10 @@ fn to_json(&self) -> Json { Self::AmdGpuKernel => "AmdGpuKernel", Self::AvrInterrupt => "AvrInterrupt", Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt", + Self::RiscvInterrupt { kind } => { + buf = format!("RiscvInterrupt({})", kind.as_str()); + &buf + } }; Json::String(s.to_owned()) } diff --git a/compiler/rustc_target/src/spec/abi.rs b/compiler/rustc_target/src/spec/abi.rs index dc233121f666..550cdf6bda6f 100644 --- a/compiler/rustc_target/src/spec/abi.rs +++ b/compiler/rustc_target/src/spec/abi.rs @@ -38,6 +38,8 @@ pub enum Abi { PlatformIntrinsic, Unadjusted, RustCold, + RiscvInterruptM, + RiscvInterruptS, } impl Abi { @@ -107,11 +109,29 @@ pub struct AbiData { AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" }, AbiData { abi: Abi::Unadjusted, name: "unadjusted" }, AbiData { abi: Abi::RustCold, name: "rust-cold" }, + AbiData { abi: Abi::RiscvInterruptM, name: "riscv-interrupt-m" }, + AbiData { abi: Abi::RiscvInterruptS, name: "riscv-interrupt-s" }, ]; +#[derive(Copy, Clone, Debug)] +pub enum AbiUnsupported { + Unrecognized, + Reason { explain: &'static str }, +} + /// Returns the ABI with the given name (if any). -pub fn lookup(name: &str) -> Option { - AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi) +pub fn lookup(name: &str) -> Result { + AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi).ok_or_else(|| match name { + "riscv-interrupt" => AbiUnsupported::Reason { + explain: "please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively", + }, + "riscv-interrupt-u" => AbiUnsupported::Reason { + explain: "user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314", + }, + + _ => AbiUnsupported::Unrecognized, + + }) } pub fn all_names() -> Vec<&'static str> { @@ -200,6 +220,10 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> { feature: sym::abi_avr_interrupt, explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change", }), + "riscv-interrupt-m" | "riscv-interrupt-s" => Err(AbiDisabled::Unstable { + feature: sym::abi_riscv_interrupt, + explain: "riscv-interrupt ABIs are experimental and subject to change", + }), "C-cmse-nonsecure-call" => Err(AbiDisabled::Unstable { feature: sym::abi_c_cmse_nonsecure_call, explain: "C-cmse-nonsecure-call ABI is experimental and subject to change", @@ -260,6 +284,8 @@ pub fn index(self) -> usize { PlatformIntrinsic => 32, Unadjusted => 33, RustCold => 34, + RiscvInterruptM => 35, + RiscvInterruptS => 36, }; debug_assert!( AbiDatas diff --git a/compiler/rustc_target/src/spec/abi/tests.rs b/compiler/rustc_target/src/spec/abi/tests.rs index 8bea5e5efe3b..251a12fe7aa6 100644 --- a/compiler/rustc_target/src/spec/abi/tests.rs +++ b/compiler/rustc_target/src/spec/abi/tests.rs @@ -4,19 +4,19 @@ #[test] fn lookup_Rust() { let abi = lookup("Rust"); - assert!(abi.is_some() && abi.unwrap().data().name == "Rust"); + assert!(abi.is_ok() && abi.unwrap().data().name == "Rust"); } #[test] fn lookup_cdecl() { let abi = lookup("cdecl"); - assert!(abi.is_some() && abi.unwrap().data().name == "cdecl"); + assert!(abi.is_ok() && abi.unwrap().data().name == "cdecl"); } #[test] fn lookup_baz() { let abi = lookup("baz"); - assert!(abi.is_none()); + assert!(matches!(abi, Err(AbiUnsupported::Unrecognized))) } #[test] diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index c215a7c4b6e0..523a64441c79 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2267,6 +2267,7 @@ pub fn is_abi_supported(&self, abi: Abi) -> Option { PtxKernel => self.arch == "nvptx64", Msp430Interrupt => self.arch == "msp430", AmdGpuKernel => self.arch == "amdgcn", + RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]), AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr", Wasm => ["wasm32", "wasm64"].contains(&&self.arch[..]), Thiscall { .. } => self.arch == "x86", @@ -2698,7 +2699,7 @@ macro_rules! key { let name = (stringify!($key_name)).replace("_", "-"); obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { match lookup_abi(s) { - Some(abi) => base.$key_name = Some(abi), + Ok(abi) => base.$key_name = Some(abi), _ => return Some(Err(format!("'{}' is not a valid value for abi", s))), } Some(Ok(())) diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index d0a7414b4ff6..4d0b847533b8 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -9,6 +9,7 @@ use rustc_span::def_id::DefId; use rustc_target::abi::call::{ ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind, + RiscvInterruptKind, }; use rustc_target::abi::*; use rustc_target::spec::abi::Abi as SpecAbi; @@ -193,6 +194,8 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { AmdGpuKernel => Conv::AmdGpuKernel, AvrInterrupt => Conv::AvrInterrupt, AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt, + RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine }, + RiscvInterruptS => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor }, Wasm => Conv::C, // These API constants ought to be more specific... diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs index c717a9cb55b8..e411c1c869c5 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs @@ -30,6 +30,8 @@ "efiapi", "avr-interrupt", "avr-non-blocking-interrupt", + "riscv-interrupt-m", + "riscv-interrupt-s", "C-cmse-nonsecure-call", "wasm", "system", diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr new file mode 100644 index 000000000000..02082c13f91a --- /dev/null +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr @@ -0,0 +1,27 @@ +error[E0703]: invalid ABI: found `riscv-interrupt` + --> $DIR/riscv-discoverability-guidance.rs:17:8 + | +LL | extern "riscv-interrupt" fn isr() {} + | ^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively + +error[E0703]: invalid ABI: found `riscv-interrupt-u` + --> $DIR/riscv-discoverability-guidance.rs:23:8 + | +LL | extern "riscv-interrupt-u" fn isr_U() {} + | ^^^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr new file mode 100644 index 000000000000..02082c13f91a --- /dev/null +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr @@ -0,0 +1,27 @@ +error[E0703]: invalid ABI: found `riscv-interrupt` + --> $DIR/riscv-discoverability-guidance.rs:17:8 + | +LL | extern "riscv-interrupt" fn isr() {} + | ^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively + +error[E0703]: invalid ABI: found `riscv-interrupt-u` + --> $DIR/riscv-discoverability-guidance.rs:23:8 + | +LL | extern "riscv-interrupt-u" fn isr_U() {} + | ^^^^^^^^^^^^^^^^^^^ + | | + | invalid ABI + | help: did you mean: `"riscv-interrupt-m"` + | + = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions. + = note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0703`. diff --git a/tests/ui/abi/riscv-discoverability-guidance.rs b/tests/ui/abi/riscv-discoverability-guidance.rs new file mode 100644 index 000000000000..f57fcd6044ff --- /dev/null +++ b/tests/ui/abi/riscv-discoverability-guidance.rs @@ -0,0 +1,27 @@ +// ignore-tidy-linelength +// revisions: riscv32 riscv64 +// +// [riscv32] needs-llvm-components: riscv +// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib +// [riscv64] needs-llvm-components: riscv +// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib +#![no_core] +#![feature( + no_core, + lang_items, + abi_riscv_interrupt +)] +#[lang = "sized"] +trait Sized {} + +extern "riscv-interrupt" fn isr() {} +//~^ ERROR invalid ABI +//~^^ NOTE invalid ABI +//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +//~^^^^ NOTE please use one of riscv-interrupt-m or riscv-interrupt-s + +extern "riscv-interrupt-u" fn isr_U() {} +//~^ ERROR invalid ABI +//~^^ NOTE invalid ABI +//~^^^ NOTE invoke `rustc --print=calling-conventions` for a full list of supported calling conventions +//~^^^^ NOTE user-mode interrupt handlers have been removed from LLVM pending standardization diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index 980457eeab5b..d7b4e6150ff3 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,53 +1,59 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:31:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:1 + --> $DIR/unsupported.rs:51:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:56:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:62:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,6 +62,6 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -error: aborting due to 8 previous errors; 1 warning emitted +error: aborting due to 9 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index 450abd948863..3a3ed2dd9c56 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,47 +1,53 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:39:1 + --> $DIR/unsupported.rs:51:1 | LL | extern "x86-interrupt" fn x86() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:56:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:62:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 8 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 0340382a4526..31b7d030bd3b 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,39 +1,45 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:31:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr new file mode 100644 index 000000000000..1966e18f0a06 --- /dev/null +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -0,0 +1,61 @@ +error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:30:1 + | +LL | extern "ptx-kernel" fn ptx() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:32:1 + | +LL | extern "amdgpu-kernel" fn amdgpu() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"wasm"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:34:1 + | +LL | extern "wasm" fn wasm() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"aapcs"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:36:1 + | +LL | extern "aapcs" fn aapcs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:42:1 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:44:1 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:51:1 + | +LL | extern "x86-interrupt" fn x86() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"thiscall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:56:1 + | +LL | extern "thiscall" fn thiscall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:62:1 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #87678 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +error: aborting due to 8 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr new file mode 100644 index 000000000000..1966e18f0a06 --- /dev/null +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -0,0 +1,61 @@ +error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:30:1 + | +LL | extern "ptx-kernel" fn ptx() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:32:1 + | +LL | extern "amdgpu-kernel" fn amdgpu() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"wasm"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:34:1 + | +LL | extern "wasm" fn wasm() {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"aapcs"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:36:1 + | +LL | extern "aapcs" fn aapcs() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:42:1 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:44:1 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"x86-interrupt"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:51:1 + | +LL | extern "x86-interrupt" fn x86() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0570]: `"thiscall"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:56:1 + | +LL | extern "thiscall" fn thiscall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: use of calling convention not supported on this target + --> $DIR/unsupported.rs:62:1 + | +LL | extern "stdcall" fn stdcall() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #87678 + = note: `#[warn(unsupported_calling_conventions)]` on by default + +error: aborting due to 8 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index bcd95f1ed4cd..57278e664b51 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -1,4 +1,4 @@ -// revisions: x64 i686 aarch64 arm +// revisions: x64 i686 aarch64 arm riscv32 riscv64 // // [x64] needs-llvm-components: x86 // [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -8,6 +8,10 @@ // [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu --crate-type=rlib // [arm] needs-llvm-components: arm // [arm] compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib +// [riscv32] needs-llvm-components: riscv +// [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib +// [riscv64] needs-llvm-components: riscv +// [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib #![no_core] #![feature( no_core, @@ -17,10 +21,11 @@ abi_avr_interrupt, abi_amdgpu_kernel, wasm_abi, - abi_x86_interrupt + abi_x86_interrupt, + abi_riscv_interrupt )] -#[lang="sized"] -trait Sized { } +#[lang = "sized"] +trait Sized {} extern "ptx-kernel" fn ptx() {} //~^ ERROR is not a supported ABI @@ -32,21 +37,36 @@ extern "aapcs" fn aapcs() {} //[x64]~^ ERROR is not a supported ABI //[i686]~^^ ERROR is not a supported ABI //[aarch64]~^^^ ERROR is not a supported ABI +//[riscv32]~^^^^ ERROR is not a supported ABI +//[riscv64]~^^^^^ ERROR is not a supported ABI extern "msp430-interrupt" fn msp430() {} //~^ ERROR is not a supported ABI extern "avr-interrupt" fn avr() {} //~^ ERROR is not a supported ABI +extern "riscv-interrupt-m" fn riscv() {} +//[arm]~^ ERROR is not a supported ABI +//[x64]~^^ ERROR is not a supported ABI +//[i686]~^^^ ERROR is not a supported ABI +//[aarch64]~^^^^ ERROR is not a supported ABI extern "x86-interrupt" fn x86() {} //[aarch64]~^ ERROR is not a supported ABI //[arm]~^^ ERROR is not a supported ABI +//[riscv32]~^^^ ERROR is not a supported ABI +//[riscv64]~^^^^ ERROR is not a supported ABI extern "thiscall" fn thiscall() {} //[x64]~^ ERROR is not a supported ABI -//[aarch64]~^^ ERROR is not a supported ABI -//[arm]~^^^ ERROR is not a supported ABI +//[arm]~^^ ERROR is not a supported ABI +//[aarch64]~^^^ ERROR is not a supported ABI +//[riscv32]~^^^^ ERROR is not a supported ABI +//[riscv64]~^^^^^ ERROR is not a supported ABI extern "stdcall" fn stdcall() {} //[x64]~^ WARN use of calling convention not supported //[x64]~^^ WARN this was previously accepted -//[aarch64]~^^^ WARN use of calling convention not supported -//[aarch64]~^^^^ WARN this was previously accepted -//[arm]~^^^^^ WARN use of calling convention not supported -//[arm]~^^^^^^ WARN this was previously accepted +//[arm]~^^^ WARN use of calling convention not supported +//[arm]~^^^^ WARN this was previously accepted +//[aarch64]~^^^^^ WARN use of calling convention not supported +//[aarch64]~^^^^^^ WARN this was previously accepted +//[riscv32]~^^^^^^^ WARN use of calling convention not supported +//[riscv32]~^^^^^^^^ WARN this was previously accepted +//[riscv64]~^^^^^^^^^ WARN use of calling convention not supported +//[riscv64]~^^^^^^^^^^ WARN this was previously accepted diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 29eed8505b9b..ea62cb151480 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,47 +1,53 @@ error[E0570]: `"ptx-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:25:1 + --> $DIR/unsupported.rs:30:1 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"amdgpu-kernel"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:27:1 + --> $DIR/unsupported.rs:32:1 | LL | extern "amdgpu-kernel" fn amdgpu() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"wasm"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:29:1 + --> $DIR/unsupported.rs:34:1 | LL | extern "wasm" fn wasm() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"aapcs"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:31:1 + --> $DIR/unsupported.rs:36:1 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"msp430-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:35:1 + --> $DIR/unsupported.rs:42:1 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: `"avr-interrupt"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:37:1 + --> $DIR/unsupported.rs:44:1 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0570]: `"riscv-interrupt-m"` is not a supported ABI for the current target + --> $DIR/unsupported.rs:46:1 + | +LL | extern "riscv-interrupt-m" fn riscv() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0570]: `"thiscall"` is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:1 + --> $DIR/unsupported.rs:56:1 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of calling convention not supported on this target - --> $DIR/unsupported.rs:46:1 + --> $DIR/unsupported.rs:62:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,6 +56,6 @@ LL | extern "stdcall" fn stdcall() {} = note: for more information, see issue #87678 = note: `#[warn(unsupported_calling_conventions)]` on by default -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 8 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs new file mode 100644 index 000000000000..7755a46da3b5 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.rs @@ -0,0 +1,33 @@ +// needs-llvm-components: riscv +// compile-flags: --target=riscv32imc-unknown-none-elf --crate-type=rlib +#![no_core] +#![feature(no_core, lang_items)] +#[lang = "sized"] +trait Sized {} + +// Test that the riscv interrupt ABIs cannot be used when riscv_interrupt +// feature gate is not used. + +extern "riscv-interrupt-m" fn f() {} +//~^ ERROR riscv-interrupt ABIs are experimental +extern "riscv-interrupt-s" fn f_s() {} +//~^ ERROR riscv-interrupt ABIs are experimental + +trait T { + extern "riscv-interrupt-m" fn m(); + //~^ ERROR riscv-interrupt ABIs are experimental +} + +struct S; +impl T for S { + extern "riscv-interrupt-m" fn m() {} + //~^ ERROR riscv-interrupt ABIs are experimental +} + +impl S { + extern "riscv-interrupt-m" fn im() {} + //~^ ERROR riscv-interrupt ABIs are experimental +} + +type TA = extern "riscv-interrupt-m" fn(); +//~^ ERROR riscv-interrupt ABIs are experimental diff --git a/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr new file mode 100644 index 000000000000..60c7fa0ea67b --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-abi-riscv-interrupt.stderr @@ -0,0 +1,57 @@ +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:11:8 + | +LL | extern "riscv-interrupt-m" fn f() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:13:8 + | +LL | extern "riscv-interrupt-s" fn f_s() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:17:12 + | +LL | extern "riscv-interrupt-m" fn m(); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:23:12 + | +LL | extern "riscv-interrupt-m" fn m() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:28:12 + | +LL | extern "riscv-interrupt-m" fn im() {} + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error[E0658]: riscv-interrupt ABIs are experimental and subject to change + --> $DIR/feature-gate-abi-riscv-interrupt.rs:32:18 + | +LL | type TA = extern "riscv-interrupt-m" fn(); + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #111889 for more information + = help: add `#![feature(abi_riscv_interrupt)]` to the crate attributes to enable + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0658`. From d88ab223c5ef946c2fa5f756e7b6937a470f3dfc Mon Sep 17 00:00:00 2001 From: Seth Pellegrino Date: Sat, 29 Jul 2023 10:56:07 -0700 Subject: [PATCH 63/76] fix: add RiscvInterrupt* cconv to smir These new interrupt calling conventions are not themselves stabilized, but there are other unstable calling conventions present in the SMIR mapping (e.g. AVR interrupts) and the mapping appears to be "complete" so far, with no obvious way to represent unstable conventions separately from the stable ones. --- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 ++ compiler/rustc_smir/src/stable_mir/ty.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index d12de92db8a6..3d9a0b9def45 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -877,6 +877,8 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic, abi::Abi::Unadjusted => Abi::Unadjusted, abi::Abi::RustCold => Abi::RustCold, + abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM, + abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS, }, } } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index c487db5b732a..7aecbec4963a 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -178,6 +178,8 @@ pub enum Abi { PlatformIntrinsic, Unadjusted, RustCold, + RiscvInterruptM, + RiscvInterruptS, } #[derive(Clone, Debug)] From 26bd86d3d92c6d221a3cbae8fe93c464b75a622b Mon Sep 17 00:00:00 2001 From: Seth Pellegrino Date: Sat, 29 Jul 2023 14:44:17 -0700 Subject: [PATCH 64/76] fix(test): improve sensitivity of hygene tests The change in 07f855d7817aa53af8adbb385407f6c2cacc2702 introduced a trailing numeral of some kind after the `extern crate compiler_builtins`, which appears to have caused at least two false negatives (654b924 and 657fd24). Instead, this change normalizes the test output to ignore the number (of symbols rustc recognizes?) to avoid needing to re-`--bless` these two tests for unrelated changes. --- tests/ui/proc-macro/meta-macro-hygiene.rs | 4 +++- tests/ui/proc-macro/meta-macro-hygiene.stdout | 8 +++++--- tests/ui/proc-macro/nonterminal-token-hygiene.rs | 3 ++- .../ui/proc-macro/nonterminal-token-hygiene.stdout | 13 +++++++------ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tests/ui/proc-macro/meta-macro-hygiene.rs b/tests/ui/proc-macro/meta-macro-hygiene.rs index 70b8d8da19b3..72fd88e119fd 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.rs +++ b/tests/ui/proc-macro/meta-macro-hygiene.rs @@ -3,8 +3,10 @@ // edition:2018 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no // check-pass +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout @@ -22,7 +24,7 @@ macro_rules! produce_it { // the fact that `print_def_site` is produced by a // `macro_rules!` macro in `make_macro`). meta_macro::print_def_site!($crate::dummy!()); - } + }; } fn main() { diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index ac65ba075123..eeb7179e6fdb 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -1,5 +1,5 @@ Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) -Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#3) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:44 (#3) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:44: 24:45 (#3) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#3) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#3) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#3) }] +Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:26:37: 26:43 (#3) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:26:43: 26:44 (#3) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:44: 26:45 (#3) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:26:45: 26:50 (#3) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:26:50: 26:51 (#3) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:26:51: 26:53 (#3) }] Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#4) }] #![feature /* 0#0 */(prelude_import)] // aux-build:make-macro.rs @@ -7,8 +7,10 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro // edition:2018 // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene -Z trim-diagnostic-paths=no // check-pass +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // // We don't care about symbol ids, so we set them all to 0 // in the stdout @@ -18,7 +20,7 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*; #[macro_use /* 0#1 */] extern crate core /* 0#1 */; -extern crate compiler_builtins /* 445 */ as _ /* 0#1 */; +extern crate compiler_builtins /* NNN */ as _ /* 0#1 */; // Don't load unnecessary hygiene information from std extern crate std /* 0#0 */; @@ -36,7 +38,7 @@ macro_rules! produce_it // relative to `meta_macro`, *not* `make_macro` (despite // the fact that `print_def_site` is produced by a // `macro_rules!` macro in `make_macro`). - } + } ; } fn main /* 0#0 */() { ; } diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.rs b/tests/ui/proc-macro/nonterminal-token-hygiene.rs index fa52a975bca8..1e9e90a6b6f0 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.rs +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.rs @@ -3,12 +3,13 @@ // check-pass // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene // compile-flags: -Z trim-diagnostic-paths=no +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // aux-build:test-macros.rs #![feature(decl_macro)] - #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index 4031eb98a38d..c437853ac728 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -6,19 +6,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "struct", - span: $DIR/nonterminal-token-hygiene.rs:31:5: 31:11 (#4), + span: $DIR/nonterminal-token-hygiene.rs:32:5: 32:11 (#4), }, Ident { ident: "S", - span: $DIR/nonterminal-token-hygiene.rs:31:12: 31:13 (#4), + span: $DIR/nonterminal-token-hygiene.rs:32:12: 32:13 (#4), }, Punct { ch: ';', spacing: Alone, - span: $DIR/nonterminal-token-hygiene.rs:31:13: 31:14 (#4), + span: $DIR/nonterminal-token-hygiene.rs:32:13: 32:14 (#4), }, ], - span: $DIR/nonterminal-token-hygiene.rs:21:27: 21:32 (#5), + span: $DIR/nonterminal-token-hygiene.rs:22:27: 22:32 (#5), }, ] #![feature /* 0#0 */(prelude_import)] @@ -28,18 +28,19 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ // check-pass // compile-flags: -Z span-debug -Z macro-backtrace -Z unpretty=expanded,hygiene // compile-flags: -Z trim-diagnostic-paths=no +// ignore-tidy-linelength // normalize-stdout-test "\d+#" -> "0#" // normalize-stdout-test "expn\d{3,}" -> "expnNNN" +// normalize-stdout-test "extern crate compiler_builtins /\* \d+ \*/" -> "extern crate compiler_builtins /* NNN */" // aux-build:test-macros.rs #![feature /* 0#0 */(decl_macro)] - #![no_std /* 0#0 */] #[prelude_import /* 0#1 */] use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*; #[macro_use /* 0#1 */] extern crate core /* 0#2 */; -extern crate compiler_builtins /* 445 */ as _ /* 0#2 */; +extern crate compiler_builtins /* NNN */ as _ /* 0#2 */; // Don't load unnecessary hygiene information from std extern crate std /* 0#0 */; From 6b4ec09cab1f72a17285285c356acc0afdcd47e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 9 Aug 2023 09:31:22 +0200 Subject: [PATCH 65/76] Remove usage of `--use-old-text` for BOLT --- src/tools/opt-dist/src/bolt.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/tools/opt-dist/src/bolt.rs b/src/tools/opt-dist/src/bolt.rs index e44b8a4db920..cf9f4fabcec1 100644 --- a/src/tools/opt-dist/src/bolt.rs +++ b/src/tools/opt-dist/src/bolt.rs @@ -65,8 +65,13 @@ pub fn bolt_optimize(path: &Utf8Path, profile: &LlvmBoltProfile) -> anyhow::Resu .arg("-jump-tables=move") // Fold functions with identical code .arg("-icf=1") + // The following flag saves about 50 MiB of libLLVM.so size. + // However, it succeeds very non-deterministically. To avoid frequent artifact size swings, + // it is kept disabled for now. + // FIXME(kobzol): try to re-enable this once BOLT in-place rewriting is merged or after + // we bump LLVM. // Try to reuse old text segments to reduce binary size - .arg("--use-old-text") + // .arg("--use-old-text") // Update DWARF debug info in the final binary .arg("-update-debug-sections") // Print optimization statistics From 3deb6c69e0ea8665ec4453cfde67491a62683116 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 9 Aug 2023 10:05:36 +0000 Subject: [PATCH 66/76] Rustup to rustc 1.73.0-nightly (03a119b0b 2023-08-07) --- example/mini_core.rs | 2 +- example/mini_core_hello_world.rs | 2 +- ...ortable-simd-Allow-internal-features.patch | 24 +++++++++++++++++++ patches/stdlib-lock.toml | 4 ++-- rust-toolchain | 2 +- 5 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 patches/0001-portable-simd-Allow-internal-features.patch diff --git a/example/mini_core.rs b/example/mini_core.rs index 9ecc4c5dd5b6..34c7e44b2881 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -11,7 +11,7 @@ thread_local )] #![no_core] -#![allow(dead_code)] +#![allow(dead_code, internal_features)] #[lang = "sized"] pub trait Sized {} diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 5937866dea10..58670b33c7bd 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,6 +1,6 @@ #![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)] #![no_core] -#![allow(dead_code, non_camel_case_types)] +#![allow(dead_code, non_camel_case_types, internal_features)] extern crate mini_core; diff --git a/patches/0001-portable-simd-Allow-internal-features.patch b/patches/0001-portable-simd-Allow-internal-features.patch new file mode 100644 index 000000000000..87252df1eabe --- /dev/null +++ b/patches/0001-portable-simd-Allow-internal-features.patch @@ -0,0 +1,24 @@ +From fcf75306d88e533b83eaff3f8d0ab9f307e8a84d Mon Sep 17 00:00:00 2001 +From: bjorn3 <17426603+bjorn3@users.noreply.github.com> +Date: Wed, 9 Aug 2023 10:01:17 +0000 +Subject: [PATCH] Allow internal features + +--- + crates/core_simd/src/lib.rs | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs +index fde406b..b386116 100644 +--- a/crates/core_simd/src/lib.rs ++++ b/crates/core_simd/src/lib.rs +@@ -19,6 +19,7 @@ + #![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really + #![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)] + #![unstable(feature = "portable_simd", issue = "86656")] ++#![allow(internal_features)] + //! Portable SIMD module. + + #[path = "mod.rs"] +-- +2.34.1 + diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index aea47bdfba26..fa175edcae60 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.95" +version = "0.1.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6866e0f3638013234db3c89ead7a14d278354338e7237257407500009012b23f" +checksum = "d6c0f24437059853f0fa64afc51f338f93647a3de4cf3358ba1bb4171a199775" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/rust-toolchain b/rust-toolchain index 34514658359c..5689bdee64d2 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-07-22" +channel = "nightly-2023-08-08" components = ["rust-src", "rustc-dev", "llvm-tools"] From 843549e4786a88fcd120d083bd98f8046469e054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 9 Aug 2023 10:28:53 +0000 Subject: [PATCH 67/76] review comments --- compiler/rustc_hir_typeck/src/expr.rs | 4 +- compiler/rustc_hir_typeck/src/method/mod.rs | 2 +- .../rustc_hir_typeck/src/method/suggest.rs | 56 +++++++++++++------ 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9de4c28190ee..fbf45ee99fe6 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -13,7 +13,7 @@ YieldExprOutsideOfGenerator, }; use crate::fatally_break_rust; -use crate::method::SelfSource; +use crate::method::{MethodCallComponents, SelfSource}; use crate::type_error_struct; use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation}; use crate::{ @@ -1293,7 +1293,7 @@ fn check_method_call( segment.ident, SelfSource::MethodCall(rcvr), error, - Some((rcvr, args, expr)), + Some(MethodCallComponents { receiver: rcvr, args, full_expr: expr }), expected, false, ) { diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 356e7022aea1..e9a9489af35c 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -7,7 +7,7 @@ pub mod probe; mod suggest; -pub use self::suggest::SelfSource; +pub use self::suggest::{MethodCallComponents, SelfSource}; pub use self::MethodError::*; use crate::errors::OpMethodGenericParams; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 9418624debc2..ea08a0aa4892 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -50,6 +50,15 @@ use std::cmp::{self, Ordering}; use std::iter; +/// After identifying that `full_expr` is a method call, we use this type to keep the expression's +/// components readily available to us to point at the right place in diagnostics. +#[derive(Debug, Clone, Copy)] +pub struct MethodCallComponents<'tcx> { + pub receiver: &'tcx hir::Expr<'tcx>, + pub args: &'tcx [hir::Expr<'tcx>], + pub full_expr: &'tcx hir::Expr<'tcx>, +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool { let tcx = self.tcx; @@ -115,7 +124,7 @@ pub fn report_method_error( item_name: Ident, source: SelfSource<'tcx>, error: MethodError<'tcx>, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, + args: Option>, expected: Expectation<'tcx>, trait_missing_method: bool, ) -> Option> { @@ -257,18 +266,23 @@ pub fn report_method_error( fn suggest_missing_writer( &self, rcvr_ty: Ty<'tcx>, - args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>), + args: MethodCallComponents<'tcx>, ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty); - let mut err = - struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str); + let mut err = struct_span_err!( + self.tcx.sess, + args.receiver.span, + E0599, + "cannot write into `{}`", + ty_str + ); err.span_note( - args.0.span, + args.receiver.span, "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method", ); - if let ExprKind::Lit(_) = args.0.kind { + if let ExprKind::Lit(_) = args.receiver.kind { err.span_help( - args.0.span.shrink_to_lo(), + args.receiver.span.shrink_to_lo(), "a writer is needed before this format string", ); }; @@ -282,7 +296,7 @@ pub fn report_no_match_method_error( rcvr_ty: Ty<'tcx>, item_name: Ident, source: SelfSource<'tcx>, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, + args: Option>, sugg_span: Span, no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, @@ -953,7 +967,7 @@ trait bound{s}", unsatisfied_bounds = true; } - } else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some((rcvr, _, expr)) = args { + } else if let ty::Adt(def, targs) = rcvr_ty.kind() && let Some(args) = args { // This is useful for methods on arbitrary self types that might have a simple // mutability difference, like calling a method on `Pin<&mut Self>` that is on // `Pin<&Self>`. @@ -972,7 +986,13 @@ trait bound{s}", }) ); let rcvr_ty = Ty::new_adt(tcx, *def, new_args); - if let Ok(method) = self.lookup_method_for_diagnostic(rcvr_ty, &item_segment, span, expr, rcvr) { + if let Ok(method) = self.lookup_method_for_diagnostic( + rcvr_ty, + &item_segment, + span, + args.full_expr, + args.receiver, + ) { err.span_note( tcx.def_span(method.def_id), format!("{item_kind} is available for `{rcvr_ty}`"), @@ -1138,7 +1158,7 @@ trait bound{s}", span, rcvr_ty, item_name, - args.map(|(_, args, _)| args.len() + 1), + args.map(|MethodCallComponents { args, .. }| args.len() + 1), source, no_match_data.out_of_scope_traits.clone(), &unsatisfied_predicates, @@ -1219,7 +1239,7 @@ fn note_candidates_on_method_error( &self, rcvr_ty: Ty<'tcx>, item_name: Ident, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, + args: Option>, span: Span, err: &mut Diagnostic, sources: &mut Vec, @@ -1370,7 +1390,7 @@ fn suggest_associated_call_syntax( rcvr_ty: Ty<'tcx>, source: SelfSource<'tcx>, item_name: Ident, - args: Option<(&hir::Expr<'tcx>, &[hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, + args: Option>, sugg_span: Span, ) { let mut has_unsuggestable_args = false; @@ -1442,7 +1462,7 @@ fn suggest_associated_call_syntax( None }; let mut applicability = Applicability::MachineApplicable; - let args = if let Some((receiver, args, _)) = args { + let args = if let Some(MethodCallComponents { receiver, args, .. }) = args { // The first arg is the same kind as the receiver let explicit_args = if first_arg.is_some() { std::iter::once(receiver).chain(args.iter()).collect::>() @@ -3022,7 +3042,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec { fn print_disambiguation_help<'tcx>( item_name: Ident, - args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], &'tcx hir::Expr<'tcx>)>, + args: Option>, err: &mut Diagnostic, trait_name: String, rcvr_ty: Ty<'_>, @@ -3034,7 +3054,11 @@ fn print_disambiguation_help<'tcx>( fn_has_self_parameter: bool, ) { let mut applicability = Applicability::MachineApplicable; - let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args, _))) = (kind, args) { + let (span, sugg) = if let ( + ty::AssocKind::Fn, + Some(MethodCallComponents { receiver, args, .. }), + ) = (kind, args) + { let args = format!( "({}{})", rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()), From 716dcb77931935264847f55cd20f581a5a25afa8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 9 Aug 2023 10:33:57 +0000 Subject: [PATCH 68/76] Fix rustc test suite --- scripts/test_rustc_tests.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 83cbe0db6334..c163b8543848 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -49,6 +49,8 @@ rm tests/ui/proc-macro/allowed-signatures.rs # vendor intrinsics rm tests/ui/sse2.rs # cpuid not supported, so sse2 not detected rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant" +rm tests/ui/simd/intrinsic/generic-bswap-byte.rs # simd_bswap not yet implemented +rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # many missing simd intrinsics # exotic linkages rm tests/ui/issues/issue-33992.rs # unsupported linkages @@ -124,6 +126,8 @@ rm tests/ui/typeck/issue-46112.rs # same rm tests/ui/consts/const_cmp_type_id.rs # same rm tests/ui/consts/issue-73976-monomorphic.rs # same rm tests/ui/rfcs/rfc-3348-c-string-literals/non-ascii.rs # same +rm tests/ui/consts/const-eval/nonnull_as_ref_ub.rs # same +rm tests/ui/consts/issue-94675.rs # same # rustdoc-clif passes extra args, suppressing the help message when no args are passed rm -r tests/run-make/issue-88756-default-output @@ -158,8 +162,6 @@ rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd -rm tests/ui/panic-handler/weak-lang-item-2.rs # Will be fixed by #113568 - cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist # prevent $(RUSTDOC) from picking up the sysroot built by x.py. It conflicts with the one used by @@ -172,7 +174,7 @@ index ea06b620c4c..b969d0009c6 100644 @@ -9,7 +9,7 @@ RUSTC_ORIGINAL := \$(RUSTC) BARE_RUSTC := \$(HOST_RPATH_ENV) '\$(RUSTC)' BARE_RUSTDOC := \$(HOST_RPATH_ENV) '\$(RUSTDOC)' - RUSTC := \$(BARE_RUSTC) --out-dir \$(TMPDIR) -L \$(TMPDIR) \$(RUSTFLAGS) + RUSTC := \$(BARE_RUSTC) --out-dir \$(TMPDIR) -L \$(TMPDIR) \$(RUSTFLAGS) -Ainternal_features -RUSTDOC := \$(BARE_RUSTDOC) -L \$(TARGET_RPATH_DIR) +RUSTDOC := \$(BARE_RUSTDOC) ifdef RUSTC_LINKER From 8f9ac9c22d6594cf059d8e6c71d414cc5ccd7975 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 9 Aug 2023 10:47:49 +0000 Subject: [PATCH 69/76] Fix MinGW --- build_system/build_sysroot.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs index 6623a713719f..31a4b209826f 100644 --- a/build_system/build_sysroot.rs +++ b/build_system/build_sysroot.rs @@ -306,6 +306,7 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { let obj = RTSTARTUP_SYSROOT.to_path(dirs).join(format!("{file}.o")); let mut build_rtstartup_cmd = Command::new(&compiler.rustc); build_rtstartup_cmd + .arg("-Ainternal_features") // Missing #[allow(internal_features)] .arg("--target") .arg(&compiler.triple) .arg("--emit=obj") From c41339a52f1e2f46663153e9e30fa3ac8368b532 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Mon, 7 Aug 2023 18:29:12 +0300 Subject: [PATCH 70/76] Convert Const to Allocation in smir --- .../src/mir/interpret/allocation.rs | 3 + compiler/rustc_smir/src/rustc_internal/mod.rs | 4 + compiler/rustc_smir/src/rustc_smir/mod.rs | 31 ++++- compiler/rustc_smir/src/stable_mir/ty.rs | 114 +++++++++++++++++- 4 files changed, 149 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 2567170f39af..c787481bfbec 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -329,6 +329,9 @@ pub fn try_uninit<'tcx>(size: Size, align: Align) -> InterpResult<'tcx, Self> { /// Try to create an Allocation of `size` bytes, panics if there is not enough memory /// available to the compiler to do so. + /// + /// Example use case: To obtain an Allocation filled with specific data, + /// first call this function and then call write_scalar to fill in the right data. pub fn uninit(size: Size, align: Align) -> Self { match Self::uninit_inner(size, align, || { panic!("Allocation::uninit called with panic_on_fail had allocation failure"); diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 39541c845b39..0d9157940f82 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -112,6 +112,10 @@ pub fn trait_def(&mut self, did: DefId) -> stable_mir::ty::TraitDef { stable_mir::ty::TraitDef(self.create_def_id(did)) } + pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef { + stable_mir::ty::ConstDef(self.create_def_id(did)) + } + fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId { // FIXME: this becomes inefficient when we have too many ids for (i, &d) in self.def_ids.iter().enumerate() { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index d12de92db8a6..c760fd8b69a6 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,11 +9,11 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy}; +use crate::stable_mir::ty::{new_allocation, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy}; use crate::stable_mir::{self, Context}; use rustc_hir as hir; use rustc_middle::mir::coverage::CodeRegion; -use rustc_middle::mir::{self}; +use rustc_middle::mir::{self, ConstantKind}; use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; @@ -1145,3 +1145,30 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { } } } + +impl<'tcx> Stable<'tcx> for rustc_middle::mir::ConstantKind<'tcx> { + type T = stable_mir::ty::ConstantKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + ConstantKind::Ty(c) => match c.kind() { + ty::Value(val) => { + let const_val = tables.tcx.valtree_to_const_val((c.ty(), val)); + stable_mir::ty::ConstantKind::Allocated(new_allocation(self, const_val, tables)) + } + _ => todo!(), + }, + ConstantKind::Unevaluated(unev_const, ty) => { + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + ty: tables.intern_ty(*ty), + def: tables.const_def(unev_const.def), + args: unev_const.args.stable(tables), + promoted: unev_const.promoted.map(|u| u.as_u32()), + }) + } + ConstantKind::Val(val, _) => { + stable_mir::ty::ConstantKind::Allocated(new_allocation(self, *val, tables)) + } + } + } +} diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index c487db5b732a..c8bf861be793 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,5 +1,10 @@ +use rustc_middle::mir::interpret::{alloc_range, ConstValue, Pointer}; + use super::{mir::Mutability, mir::Safety, with, DefId}; -use crate::rustc_internal::Opaque; +use crate::{ + rustc_internal::Opaque, + rustc_smir::{Stable, Tables}, +}; #[derive(Copy, Clone, Debug)] pub struct Ty(pub usize); @@ -105,6 +110,9 @@ pub enum Movability { #[derive(Clone, PartialEq, Eq, Debug)] pub struct TraitDef(pub(crate) DefId); +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct ConstDef(pub(crate) DefId); + impl TraitDef { pub fn trait_decl(&self) -> TraitDecl { with(|cx| cx.trait_decl(self)) @@ -248,6 +256,7 @@ pub struct BoundTy { pub type Size = usize; pub type Prov = Opaque; pub type Align = u64; +pub type Promoted = u32; pub type InitMaskMaterialized = Vec; /// Stores the provenance information of pointers stored in memory. @@ -266,6 +275,109 @@ pub struct Allocation { pub mutability: Mutability, } +impl Allocation { + /// Creates new empty `Allocation` from given `Align`. + fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { + Allocation { + bytes: Vec::new(), + provenance: ProvenanceMap { ptrs: Vec::new() }, + align: align.bytes(), + mutability: Mutability::Not, + } + } +} + +// We need this method instead of a Stable implementation +// because we need to get `Ty` of the const we are trying to create, to do that +// we need to have access to `ConstantKind` but we can't access that inside Stable impl. +pub fn new_allocation<'tcx>( + const_kind: &rustc_middle::mir::ConstantKind<'tcx>, + const_value: ConstValue<'tcx>, + tables: &mut Tables<'tcx>, +) -> Allocation { + match const_value { + ConstValue::Scalar(scalar) => { + let size = scalar.size(); + let align = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) + .unwrap() + .align; + let mut allocation = rustc_middle::mir::interpret::Allocation::uninit(size, align.abi); + allocation + .write_scalar(&tables.tcx, alloc_range(rustc_target::abi::Size::ZERO, size), scalar) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ZeroSized => { + let align = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::empty().and(const_kind.ty())) + .unwrap() + .align; + Allocation::new_empty_allocation(align.abi) + } + ConstValue::Slice { data, start, end } => { + let alloc_id = tables.tcx.create_memory_alloc(data); + let ptr = Pointer::new(alloc_id, rustc_target::abi::Size::from_bytes(start)); + let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); + let scalar_len = rustc_middle::mir::interpret::Scalar::from_target_usize( + (end - start) as u64, + &tables.tcx, + ); + let layout = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) + .unwrap(); + let mut allocation = + rustc_middle::mir::interpret::Allocation::uninit(layout.size, layout.align.abi); + allocation + .write_scalar( + &tables.tcx, + alloc_range(rustc_target::abi::Size::ZERO, tables.tcx.data_layout.pointer_size), + scalar_ptr, + ) + .unwrap(); + allocation + .write_scalar( + &tables.tcx, + alloc_range(tables.tcx.data_layout.pointer_size, scalar_len.size()), + scalar_len, + ) + .unwrap(); + allocation.stable(tables) + } + ConstValue::ByRef { alloc, offset } => { + let ty_size = tables + .tcx + .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) + .unwrap() + .size; + let bytes = alloc.0.get_bytes_unchecked(alloc_range(offset, ty_size)); + let offset_allocation = rustc_middle::mir::interpret::Allocation::from_bytes( + bytes, + alloc.0.align, + alloc.0.mutability, + ); + offset_allocation.stable(tables) + } + } +} + +#[derive(Clone, Debug)] +pub enum ConstantKind { + Allocated(Allocation), + Unevaluated(UnevaluatedConst), +} + +#[derive(Clone, Debug)] +pub struct UnevaluatedConst { + pub ty: Ty, + pub def: ConstDef, + pub args: GenericArgs, + pub promoted: Option, +} + pub enum TraitSpecializationKind { None, Marker, From 9de1a472b68ed85f396b2e2cc79c3ef17584d6e1 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 14 Sep 2021 15:44:08 +0000 Subject: [PATCH 71/76] Suggest using `Arc` on `!Send`/`!Sync` types --- .../src/traits/error_reporting/suggestions.rs | 6 ++++++ library/core/src/marker.rs | 10 ++++++++-- .../bad-bounds-on-assoc-in-trait.stderr | 2 ++ .../return-type-notation/basic.without.stderr | 1 + .../async-await-let-else.drop_tracking.stderr | 4 ++++ .../async-await-let-else.drop_tracking_mir.stderr | 4 ++++ .../async-await-let-else.no_drop_tracking.stderr | 4 ++++ .../async-fn-nonsend.drop_tracking.stderr | 2 ++ .../async-fn-nonsend.drop_tracking_mir.stderr | 2 ++ .../async-fn-nonsend.no_drop_tracking.stderr | 5 +++++ ...p-track-field-assign-nonsend.drop_tracking.stderr | 1 + ...ack-field-assign-nonsend.drop_tracking_mir.stderr | 1 + ...rack-field-assign-nonsend.no_drop_tracking.stderr | 1 + .../field-assign-nonsend.drop_tracking.stderr | 1 + .../field-assign-nonsend.drop_tracking_mir.stderr | 1 + .../field-assign-nonsend.no_drop_tracking.stderr | 1 + .../async-await/in-trait/missing-send-bound.stderr | 1 + .../issue-64130-1-sync.drop_tracking.stderr | 1 + .../issue-64130-1-sync.drop_tracking_mir.stderr | 1 + .../issue-64130-1-sync.no_drop_tracking.stderr | 1 + .../issue-64130-4-async-move.no_drop_tracking.stderr | 1 + .../issue-64130-non-send-future-diags.stderr | 1 + .../issue-67252-unnamed-future.drop_tracking.stderr | 1 + ...sue-67252-unnamed-future.drop_tracking_mir.stderr | 1 + ...ssue-67252-unnamed-future.no_drop_tracking.stderr | 1 + .../ui/async-await/issue-70818.drop_tracking.stderr | 1 + .../async-await/issue-70818.drop_tracking_mir.stderr | 1 + .../async-await/issue-70818.no_drop_tracking.stderr | 1 + .../issue-70935-complex-spans.drop_tracking.stderr | 1 + ...ssue-70935-complex-spans.drop_tracking_mir.stderr | 1 + ...issue-70935-complex-spans.no_drop_tracking.stderr | 1 + tests/ui/async-await/issue-71137.stderr | 1 + .../ui/async-await/issue-86507.drop_tracking.stderr | 1 + .../async-await/issue-86507.drop_tracking_mir.stderr | 1 + .../async-await/issue-86507.no_drop_tracking.stderr | 1 + ...ue-65436-raw-ptr-not-send.no_drop_tracking.stderr | 1 + tests/ui/async-await/issues/issue-67893.stderr | 1 + .../partial-drop-partial-reinit.drop_tracking.stderr | 5 +++-- ...rtial-drop-partial-reinit.no_drop_tracking.stderr | 5 +++-- tests/ui/async-await/partial-drop-partial-reinit.rs | 1 + tests/ui/auto-traits/issue-83857-ub.stderr | 1 + .../builtin-superkinds-double-superkind.stderr | 2 ++ .../builtin-superkinds-in-metadata.stderr | 1 + .../builtin-superkinds-simple.stderr | 1 + .../builtin-superkinds-typaram-not-send.stderr | 1 + ...re-bounds-cant-promote-superkind-in-struct.stderr | 1 + tests/ui/closures/closure-bounds-subtype.stderr | 1 + tests/ui/closures/closure-move-sync.stderr | 1 + tests/ui/error-codes/E0277-2.stderr | 1 + tests/ui/extern/extern-type-diag-not-similar.stderr | 1 + tests/ui/extern/extern-types-not-sync-send.stderr | 2 ++ tests/ui/fmt/send-sync.stderr | 2 ++ ...p-tracking-parent-expression.drop_tracking.stderr | 3 +++ ...acking-parent-expression.drop_tracking_mir.stderr | 3 +++ ...racking-parent-expression.no_drop_tracking.stderr | 8 ++++++++ tests/ui/generator/drop-yield-twice.stderr | 1 + .../ui/generator/issue-57017.no_drop_tracking.stderr | 6 ++++++ .../ui/generator/issue-57478.no_drop_tracking.stderr | 1 + .../ui/generator/not-send-sync.drop_tracking.stderr | 2 ++ .../generator/not-send-sync.drop_tracking_mir.stderr | 2 ++ .../generator/not-send-sync.no_drop_tracking.stderr | 2 ++ .../generator/parent-expression.drop_tracking.stderr | 3 +++ .../parent-expression.drop_tracking_mir.stderr | 3 +++ .../parent-expression.no_drop_tracking.stderr | 8 ++++++++ tests/ui/generator/partial-drop.drop_tracking.stderr | 2 ++ .../generator/partial-drop.no_drop_tracking.stderr | 2 ++ .../generator-print-verbose-2.drop_tracking.stderr | 2 ++ ...enerator-print-verbose-2.drop_tracking_mir.stderr | 2 ++ ...generator-print-verbose-2.no_drop_tracking.stderr | 2 ++ tests/ui/generator/ref-upvar-not-send.rs | 2 ++ tests/ui/generator/ref-upvar-not-send.stderr | 12 ++++++++---- tests/ui/impl-trait/auto-trait-leak2.rs | 2 ++ tests/ui/impl-trait/auto-trait-leak2.stderr | 8 +++++--- .../in-trait/check-wf-on-non-defaulted-rpitit.stderr | 1 + tests/ui/issues/issue-21763.stderr | 1 + tests/ui/issues/issue-24446.stderr | 1 + tests/ui/issues/issue-40827.stderr | 2 ++ tests/ui/kindck/kindck-impl-type-params.stderr | 2 ++ tests/ui/kindck/kindck-nonsendable-1.stderr | 1 + tests/ui/kindck/kindck-send-object.stderr | 2 ++ tests/ui/kindck/kindck-send-object1.stderr | 2 ++ tests/ui/kindck/kindck-send-object2.stderr | 2 ++ tests/ui/kindck/kindck-send-owned.stderr | 1 + tests/ui/kindck/kindck-send-unsafe.stderr | 2 ++ tests/ui/mut/mutable-enum-indirect.stderr | 1 + tests/ui/no-send-res-ports.stderr | 1 + tests/ui/no_send-enum.stderr | 1 + tests/ui/no_send-rc.stderr | 1 + tests/ui/no_share-enum.stderr | 1 + tests/ui/no_share-struct.stderr | 1 + tests/ui/phantom-auto-trait.stderr | 2 ++ tests/ui/recursion/recursive-requirements.stderr | 2 ++ tests/ui/statics/issue-17718-static-sync.stderr | 1 + tests/ui/stdlib-unit-tests/not-sync.stderr | 3 +++ ...impl-trait-with-missing-bounds-on-async-fn.stderr | 2 ++ tests/ui/suggestions/issue-84973-blacklist.stderr | 1 + tests/ui/suggestions/restrict-type-argument.stderr | 6 ++++++ tests/ui/traits/alias/cross-crate.stderr | 2 ++ tests/ui/traits/bad-method-typaram-kind.stderr | 1 + tests/ui/traits/inductive-overflow/two-traits.stderr | 1 + tests/ui/traits/issue-7013.stderr | 1 + .../negative-impls/negated-auto-traits-error.stderr | 6 ++++++ .../auto-with-drop_tracking_mir.fail.stderr | 1 + tests/ui/traits/no_send-struct.stderr | 1 + tests/ui/traits/non_lifetime_binders/fail.stderr | 1 + tests/ui/traits/unsend-future.stderr | 1 + .../ui/type-alias-impl-trait/auto-trait-leakage2.rs | 1 + .../type-alias-impl-trait/auto-trait-leakage2.stderr | 1 + .../typeck-default-trait-impl-assoc-type.stderr | 1 + .../typeck-default-trait-impl-negation-send.stderr | 1 + .../typeck-default-trait-impl-negation-sync.stderr | 3 +++ .../typeck-default-trait-impl-send-param.stderr | 1 + tests/ui/typeck/typeck-unsafe-always-share.stderr | 4 ++++ 113 files changed, 223 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 2b8571796df7..d071cf76fd3a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2743,6 +2743,12 @@ fn note_obligation_cause_code( } ObligationCauseCode::BindingObligation(item_def_id, span) | ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => { + if self.tcx.is_diagnostic_item(sym::Send, item_def_id) + || self.tcx.lang_items().sync_trait() == Some(item_def_id) + { + return; + } + let item_name = tcx.def_path_str(item_def_id); let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id)); let mut multispan = MultiSpan::from(span); diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5ec751e5168b..aec287226a05 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -76,8 +76,11 @@ #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "Send")] #[rustc_on_unimplemented( + on(_Self = "std::rc::Rc", note = "use `std::sync::Arc` instead of `std::rc::Rc`"), message = "`{Self}` cannot be sent between threads safely", - label = "`{Self}` cannot be sent between threads safely" + label = "`{Self}` cannot be sent between threads safely", + note = "consider using `std::sync::Arc<{Self}>`; for more information visit \ + " )] pub unsafe auto trait Send { // empty. @@ -628,8 +631,11 @@ impl Copy for &T {} any(_Self = "core::cell::RefCell", _Self = "std::cell::RefCell"), note = "if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead", ), + on(_Self = "std::rc::Rc", note = "use `std::sync::Arc` instead of `std::rc::Rc`"), message = "`{Self}` cannot be shared between threads safely", - label = "`{Self}` cannot be shared between threads safely" + label = "`{Self}` cannot be shared between threads safely", + note = "consider using `std::sync::Arc<{Self}>`; for more information visit \ + " )] pub unsafe auto trait Sync { // FIXME(estebank): once support to add notes in `rustc_on_unimplemented` diff --git a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr index c23e54594ee3..e7e7eac68a72 100644 --- a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr +++ b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -5,6 +5,7 @@ LL | type C: Clone + Iterator Lam<&'a u8 | ^^^^ `<::C as Iterator>::Item` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `<::C as Iterator>::Item` + = note: consider using `std::sync::Arc<<::C as Iterator>::Item>`; for more information visit help: consider further restricting the associated type | LL | trait Case1 where <::C as Iterator>::Item: Send { @@ -29,6 +30,7 @@ LL | type C: Clone + Iterator Lam<&'a u8 | ^^^^ `<::C as Iterator>::Item` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `<::C as Iterator>::Item` + = note: consider using `std::sync::Arc<<::C as Iterator>::Item>`; for more information visit help: consider further restricting the associated type | LL | trait Case1 where <::C as Iterator>::Item: Sync { diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr index c2da4f57696f..c34a51612991 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr @@ -14,6 +14,7 @@ LL | is_send(foo::()); | ^^^^^^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future>`, the trait `Send` is not implemented for `impl Future>` + = note: consider using `std::sync::Arc>>`; for more information visit note: future is not `Send` as it awaits another future which is not `Send` --> $DIR/basic.rs:13:5 | diff --git a/tests/ui/async-await/async-await-let-else.drop_tracking.stderr b/tests/ui/async-await/async-await-let-else.drop_tracking.stderr index dee90262fd44..b74dec64de38 100644 --- a/tests/ui/async-await/async-await-let-else.drop_tracking.stderr +++ b/tests/ui/async-await/async-await-let-else.drop_tracking.stderr @@ -5,6 +5,7 @@ LL | is_send(foo(Some(true))); | ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:11:15 | @@ -32,6 +33,7 @@ LL | is_send(foo2(Some(true))); | required by a bound introduced by this call | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it's used within this `async fn` body --> $DIR/async-await-let-else.rs:27:29 | @@ -64,6 +66,7 @@ LL | is_send(foo3(Some(true))); | ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:33:29 | @@ -85,6 +88,7 @@ LL | is_send(foo4(Some(true))); | ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:41:15 | diff --git a/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr b/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr index e3fcceaa3921..26881781c956 100644 --- a/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr +++ b/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | is_send(foo(Some(true))); | ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:11:15 | @@ -30,6 +31,7 @@ LL | is_send(foo2(Some(true))); | required by a bound introduced by this call | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it's used within this `async fn` body --> $DIR/async-await-let-else.rs:27:29 | @@ -62,6 +64,7 @@ LL | is_send(foo3(Some(true))); | ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:33:29 | @@ -82,6 +85,7 @@ LL | is_send(foo4(Some(true))); | ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:41:15 | diff --git a/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr b/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr index ece4e51ecff1..8a1215159e5a 100644 --- a/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr +++ b/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | is_send(foo(Some(true))); | ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:11:15 | @@ -27,6 +28,7 @@ LL | is_send(foo2(Some(true))); | ^^^^^^^^^^^^^^^^ future returned by `foo2` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:23:27 | @@ -49,6 +51,7 @@ LL | is_send(foo3(Some(true))); | ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:33:29 | @@ -70,6 +73,7 @@ LL | is_send(foo4(Some(true))); | ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-await-let-else.rs:41:15 | diff --git a/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr b/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr index 0515edaeda34..6677b4d9bac2 100644 --- a/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr +++ b/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr @@ -5,6 +5,7 @@ LL | assert_send(non_send_temporary_in_match()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:36:26 | @@ -28,6 +29,7 @@ LL | assert_send(non_sync_with_method_call()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `dyn std::fmt::Write` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:49:15 | diff --git a/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr index 219945e0971b..c03e9e56f3e4 100644 --- a/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr +++ b/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | assert_send(non_send_temporary_in_match()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:36:26 | @@ -25,6 +26,7 @@ LL | assert_send(non_sync_with_method_call()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `dyn std::fmt::Write` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:49:15 | diff --git a/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr index b29d2e192f4f..b182cf0c9665 100644 --- a/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr +++ b/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | assert_send(local_dropped_before_await()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `local_dropped_before_await` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:27:11 | @@ -28,6 +29,7 @@ LL | assert_send(non_send_temporary_in_match()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:36:26 | @@ -51,6 +53,7 @@ LL | assert_send(non_sync_with_method_call()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `dyn std::fmt::Write` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:49:15 | @@ -75,6 +78,7 @@ LL | assert_send(non_sync_with_method_call_panic()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call_panic` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `dyn std::fmt::Write` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:56:15 | @@ -99,6 +103,7 @@ LL | assert_send(non_sync_with_method_call_infinite_loop()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call_infinite_loop` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `dyn std::fmt::Write` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:63:15 | diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr index 80402d8424de..90e97e7438e7 100644 --- a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr +++ b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr @@ -5,6 +5,7 @@ LL | assert_send(agent.handle()); | ^^^^^^^^^^^^^^ future returned by `handle` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/drop-track-field-assign-nonsend.rs:23:39 | diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr index d9141cf4e364..42dcd65609d4 100644 --- a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr +++ b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | assert_send(agent.handle()); | ^^^^^^^^^^^^^^ future returned by `handle` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/drop-track-field-assign-nonsend.rs:23:39 | diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr index 80402d8424de..90e97e7438e7 100644 --- a/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr +++ b/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | assert_send(agent.handle()); | ^^^^^^^^^^^^^^ future returned by `handle` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/drop-track-field-assign-nonsend.rs:23:39 | diff --git a/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr b/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr index e2e64c9ae0c4..b6ff839aefae 100644 --- a/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr +++ b/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr @@ -5,6 +5,7 @@ LL | assert_send(agent.handle()); | ^^^^^^^^^^^^^^ future returned by `handle` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/field-assign-nonsend.rs:23:39 | diff --git a/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr index d1df8e91afa2..c9888636e3cc 100644 --- a/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr +++ b/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | assert_send(agent.handle()); | ^^^^^^^^^^^^^^ future returned by `handle` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/field-assign-nonsend.rs:23:39 | diff --git a/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr index e2e64c9ae0c4..b6ff839aefae 100644 --- a/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr +++ b/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | assert_send(agent.handle()); | ^^^^^^^^^^^^^^ future returned by `handle` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: future is not `Send` as this value is used across an await --> $DIR/field-assign-nonsend.rs:23:39 | diff --git a/tests/ui/async-await/in-trait/missing-send-bound.stderr b/tests/ui/async-await/in-trait/missing-send-bound.stderr index 18185b75554a..330dbef3978a 100644 --- a/tests/ui/async-await/in-trait/missing-send-bound.stderr +++ b/tests/ui/async-await/in-trait/missing-send-bound.stderr @@ -5,6 +5,7 @@ LL | assert_is_send(test::()); | ^^^^^^^^^^^ future returned by `test` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `impl Future` + = note: consider using `std::sync::Arc>`; for more information visit note: future is not `Send` as it awaits another future which is not `Send` --> $DIR/missing-send-bound.rs:10:5 | diff --git a/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr b/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr index 56aa035f44ba..a65ec664eaba 100644 --- a/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr +++ b/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr @@ -5,6 +5,7 @@ LL | is_sync(bar()); | ^^^^^ future returned by `bar` is not `Sync` | = help: within `impl Future`, the trait `Sync` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Sync` as this value is used across an await --> $DIR/issue-64130-1-sync.rs:18:11 | diff --git a/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr b/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr index ea1bfb9f9ac2..159be3215e74 100644 --- a/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr +++ b/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | is_sync(bar()); | ^^^^^ future returned by `bar` is not `Sync` | = help: within `impl Future`, the trait `Sync` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Sync` as this value is used across an await --> $DIR/issue-64130-1-sync.rs:18:11 | diff --git a/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr index 56aa035f44ba..a65ec664eaba 100644 --- a/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | is_sync(bar()); | ^^^^^ future returned by `bar` is not `Sync` | = help: within `impl Future`, the trait `Sync` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: future is not `Sync` as this value is used across an await --> $DIR/issue-64130-1-sync.rs:18:11 | diff --git a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr index 60b7551ff8ad..5b60b3c3ae3a 100644 --- a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | pub fn foo() -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)` + = note: consider using `std::sync::Arc<(dyn Any + Send + 'static)>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-64130-4-async-move.rs:27:23 | diff --git a/tests/ui/async-await/issue-64130-non-send-future-diags.stderr b/tests/ui/async-await/issue-64130-non-send-future-diags.stderr index e044e2ca011f..d906d63fa31d 100644 --- a/tests/ui/async-await/issue-64130-non-send-future-diags.stderr +++ b/tests/ui/async-await/issue-64130-non-send-future-diags.stderr @@ -5,6 +5,7 @@ LL | is_send(foo()); | ^^^^^ future returned by `foo` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, u32>` + = note: consider using `std::sync::Arc>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-64130-non-send-future-diags.rs:17:11 | diff --git a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr index fa22298658b3..3c788ef8c4d3 100644 --- a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr +++ b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr @@ -10,6 +10,7 @@ LL | | }); | |_____^ future created by async block is not `Send` | = help: within `[async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6]`, the trait `Send` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-67252-unnamed-future.rs:23:17 | diff --git a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr index 8cf7bb8d9179..03916f7e3f8f 100644 --- a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr +++ b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | spawn(async { | ^^^^^ future created by async block is not `Send` | = help: within `[async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6]`, the trait `Send` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-67252-unnamed-future.rs:23:17 | diff --git a/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr b/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr index fa22298658b3..3c788ef8c4d3 100644 --- a/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr @@ -10,6 +10,7 @@ LL | | }); | |_____^ future created by async block is not `Send` | = help: within `[async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6]`, the trait `Send` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-67252-unnamed-future.rs:23:17 | diff --git a/tests/ui/async-await/issue-70818.drop_tracking.stderr b/tests/ui/async-await/issue-70818.drop_tracking.stderr index ab0698c3ec21..cf90d727efbb 100644 --- a/tests/ui/async-await/issue-70818.drop_tracking.stderr +++ b/tests/ui/async-await/issue-70818.drop_tracking.stderr @@ -4,6 +4,7 @@ error: future cannot be sent between threads safely LL | fn foo(ty: T, ty1: U) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | + = note: consider using `std::sync::Arc`; for more information visit note: captured value is not `Send` --> $DIR/issue-70818.rs:9:18 | diff --git a/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr b/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr index ab0698c3ec21..cf90d727efbb 100644 --- a/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr +++ b/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr @@ -4,6 +4,7 @@ error: future cannot be sent between threads safely LL | fn foo(ty: T, ty1: U) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | + = note: consider using `std::sync::Arc`; for more information visit note: captured value is not `Send` --> $DIR/issue-70818.rs:9:18 | diff --git a/tests/ui/async-await/issue-70818.no_drop_tracking.stderr b/tests/ui/async-await/issue-70818.no_drop_tracking.stderr index ab0698c3ec21..cf90d727efbb 100644 --- a/tests/ui/async-await/issue-70818.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-70818.no_drop_tracking.stderr @@ -4,6 +4,7 @@ error: future cannot be sent between threads safely LL | fn foo(ty: T, ty1: U) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | + = note: consider using `std::sync::Arc`; for more information visit note: captured value is not `Send` --> $DIR/issue-70818.rs:9:18 | diff --git a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr index f80bb4242aa7..1e78befee830 100644 --- a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr +++ b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr @@ -5,6 +5,7 @@ LL | fn foo(x: NotSync) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely | = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: required because it appears within the type `PhantomData<*mut ()>` --> $SRC_DIR/core/src/marker.rs:LL:COL note: required because it appears within the type `NotSync` diff --git a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr index eb9d93e229fb..b91630138705 100644 --- a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr +++ b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | fn foo(x: NotSync) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely | = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: required because it appears within the type `PhantomData<*mut ()>` --> $SRC_DIR/core/src/marker.rs:LL:COL note: required because it appears within the type `NotSync` diff --git a/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr b/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr index d8ef6a5eedb7..1bbd8b76c1fa 100644 --- a/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr @@ -5,6 +5,7 @@ LL | fn foo(x: NotSync) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-70935-complex-spans.rs:24:12 | diff --git a/tests/ui/async-await/issue-71137.stderr b/tests/ui/async-await/issue-71137.stderr index a344246d6bff..dba713dd36f5 100644 --- a/tests/ui/async-await/issue-71137.stderr +++ b/tests/ui/async-await/issue-71137.stderr @@ -5,6 +5,7 @@ LL | fake_spawn(wrong_mutex()); | ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, i32>` + = note: consider using `std::sync::Arc>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-71137.rs:14:26 | diff --git a/tests/ui/async-await/issue-86507.drop_tracking.stderr b/tests/ui/async-await/issue-86507.drop_tracking.stderr index adb7b9bf4bf8..00b71f10e1a5 100644 --- a/tests/ui/async-await/issue-86507.drop_tracking.stderr +++ b/tests/ui/async-await/issue-86507.drop_tracking.stderr @@ -8,6 +8,7 @@ LL | | } LL | | ) | |_____________^ future created by async block is not `Send` | + = note: consider using `std::sync::Arc`; for more information visit note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> $DIR/issue-86507.rs:22:29 | diff --git a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr index adb7b9bf4bf8..00b71f10e1a5 100644 --- a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr +++ b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr @@ -8,6 +8,7 @@ LL | | } LL | | ) | |_____________^ future created by async block is not `Send` | + = note: consider using `std::sync::Arc`; for more information visit note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> $DIR/issue-86507.rs:22:29 | diff --git a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr index adb7b9bf4bf8..00b71f10e1a5 100644 --- a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr +++ b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr @@ -8,6 +8,7 @@ LL | | } LL | | ) | |_____________^ future created by async block is not `Send` | + = note: consider using `std::sync::Arc`; for more information visit note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> $DIR/issue-86507.rs:22:29 | diff --git a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr index 53d32620241c..5840e68f3a56 100644 --- a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr +++ b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr @@ -9,6 +9,7 @@ LL | | }) | |_____^ future created by async block is not `Send` | = help: within `[async block@$DIR/issue-65436-raw-ptr-not-send.rs:17:17: 20:6]`, the trait `Send` is not implemented for `*const u8` + = note: consider using `std::sync::Arc<*const u8>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/issue-65436-raw-ptr-not-send.rs:19:36 | diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr index c941b9eeb29a..5b6015c31358 100644 --- a/tests/ui/async-await/issues/issue-67893.stderr +++ b/tests/ui/async-await/issues/issue-67893.stderr @@ -5,6 +5,7 @@ LL | g(issue_67893::run()) | ^^^^^^^^^^^^^^^^^^ future is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>` + = note: consider using `std::sync::Arc>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/auxiliary/issue_67893.rs:12:27 | diff --git a/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr b/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr index 17b4ef7bdc67..f8a14798696e 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr +++ b/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr @@ -10,10 +10,11 @@ LL | async fn foo() { | - within this `impl Future` | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit = note: required because it appears within the type `(NotSend,)` = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `()`, `impl Future` note: required because it's used within this `async fn` body - --> $DIR/partial-drop-partial-reinit.rs:31:16 + --> $DIR/partial-drop-partial-reinit.rs:32:16 | LL | async fn foo() { | ________________^ @@ -25,7 +26,7 @@ LL | | bar().await; LL | | } | |_^ note: required by a bound in `gimme_send` - --> $DIR/partial-drop-partial-reinit.rs:17:18 + --> $DIR/partial-drop-partial-reinit.rs:18:18 | LL | fn gimme_send(t: T) { | ^^^^ required by this bound in `gimme_send` diff --git a/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr b/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr index 34d8a159f106..5a1ff62dcdf8 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr +++ b/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr @@ -10,10 +10,11 @@ LL | async fn foo() { | - within this `impl Future` | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit = note: required because it appears within the type `(NotSend,)` = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future`, `()` note: required because it's used within this `async fn` body - --> $DIR/partial-drop-partial-reinit.rs:31:16 + --> $DIR/partial-drop-partial-reinit.rs:32:16 | LL | async fn foo() { | ________________^ @@ -25,7 +26,7 @@ LL | | bar().await; LL | | } | |_^ note: required by a bound in `gimme_send` - --> $DIR/partial-drop-partial-reinit.rs:17:18 + --> $DIR/partial-drop-partial-reinit.rs:18:18 | LL | fn gimme_send(t: T) { | ^^^^ required by this bound in `gimme_send` diff --git a/tests/ui/async-await/partial-drop-partial-reinit.rs b/tests/ui/async-await/partial-drop-partial-reinit.rs index 7d097e72fb49..50ba247c81bb 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.rs +++ b/tests/ui/async-await/partial-drop-partial-reinit.rs @@ -12,6 +12,7 @@ fn main() { //~| NOTE bound introduced by //~| NOTE appears within the type //~| NOTE captures the following types + //~| NOTE consider using `std::sync::Arc` } fn gimme_send(t: T) { diff --git a/tests/ui/auto-traits/issue-83857-ub.stderr b/tests/ui/auto-traits/issue-83857-ub.stderr index 23a2f62d9057..72b92b49c016 100644 --- a/tests/ui/auto-traits/issue-83857-ub.stderr +++ b/tests/ui/auto-traits/issue-83857-ub.stderr @@ -5,6 +5,7 @@ LL | fn generic(v: Foo, f: fn( as WithAssoc>::Output) -> i | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc>`; for more information visit note: required for `Foo` to implement `WithAssoc` --> $DIR/issue-83857-ub.rs:15:15 | diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr index 592aa4369ce0..beb336b2963b 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-double-superkind.stderr @@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely LL | impl Foo for (T,) { } | ^^^^ `T` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit = note: required because it appears within the type `(T,)` note: required by a bound in `Foo` --> $DIR/builtin-superkinds-double-superkind.rs:4:13 @@ -21,6 +22,7 @@ error[E0277]: `T` cannot be shared between threads safely LL | impl Foo for (T,T) { } | ^^^^^ `T` cannot be shared between threads safely | + = note: consider using `std::sync::Arc`; for more information visit = note: required because it appears within the type `(T, T)` note: required by a bound in `Foo` --> $DIR/builtin-superkinds-double-superkind.rs:4:18 diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr index f9d548bb8fbe..9929452ab791 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata.stderr @@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely LL | impl RequiresRequiresShareAndSend for X { } | ^^^^ `T` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required because it appears within the type `X` --> $DIR/builtin-superkinds-in-metadata.rs:9:8 | diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr index 8b19170b0f10..8d740df97083 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-simple.stderr @@ -5,6 +5,7 @@ LL | impl Foo for std::rc::Rc { } | ^^^^^^^^^^^^^^^ `Rc` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required by a bound in `Foo` --> $DIR/builtin-superkinds-simple.rs:4:13 | diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr b/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr index 0cfea72d5f18..481c524a9aea 100644 --- a/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr +++ b/tests/ui/builtin-superkinds/builtin-superkinds-typaram-not-send.stderr @@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely LL | impl Foo for T { } | ^ `T` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `Foo` --> $DIR/builtin-superkinds-typaram-not-send.rs:3:13 | diff --git a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr index bf6ec5c36e48..ca2daffde272 100644 --- a/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr +++ b/tests/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr @@ -4,6 +4,7 @@ error[E0277]: `F` cannot be sent between threads safely LL | fn foo(blk: F) -> X where F: FnOnce() + 'static { | ^^^^ `F` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `X` --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:1:43 | diff --git a/tests/ui/closures/closure-bounds-subtype.stderr b/tests/ui/closures/closure-bounds-subtype.stderr index 8ad8273fc2b9..818ad6a4a0c7 100644 --- a/tests/ui/closures/closure-bounds-subtype.stderr +++ b/tests/ui/closures/closure-bounds-subtype.stderr @@ -6,6 +6,7 @@ LL | take_const_owned(f); | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `take_const_owned` --> $DIR/closure-bounds-subtype.rs:4:50 | diff --git a/tests/ui/closures/closure-move-sync.stderr b/tests/ui/closures/closure-move-sync.stderr index aee903ac9504..f2fa7c0c7a46 100644 --- a/tests/ui/closures/closure-move-sync.stderr +++ b/tests/ui/closures/closure-move-sync.stderr @@ -11,6 +11,7 @@ LL | | }); | |_____^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>` + = note: consider using `std::sync::Arc>`; for more information visit = note: required for `&std::sync::mpsc::Receiver<()>` to implement `Send` note: required because it's used within this closure --> $DIR/closure-move-sync.rs:6:27 diff --git a/tests/ui/error-codes/E0277-2.stderr b/tests/ui/error-codes/E0277-2.stderr index a2abf37931a4..38ae0aa6aa59 100644 --- a/tests/ui/error-codes/E0277-2.stderr +++ b/tests/ui/error-codes/E0277-2.stderr @@ -5,6 +5,7 @@ LL | is_send::(); | ^^^ `*const u8` cannot be sent between threads safely | = help: within `Foo`, the trait `Send` is not implemented for `*const u8` + = note: consider using `std::sync::Arc<*const u8>`; for more information visit note: required because it appears within the type `Baz` --> $DIR/E0277-2.rs:9:8 | diff --git a/tests/ui/extern/extern-type-diag-not-similar.stderr b/tests/ui/extern/extern-type-diag-not-similar.stderr index 75836f7eca19..90e944f02b52 100644 --- a/tests/ui/extern/extern-type-diag-not-similar.stderr +++ b/tests/ui/extern/extern-type-diag-not-similar.stderr @@ -5,6 +5,7 @@ LL | assert_send::() | ^^^ `Foo` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `assert_send` --> $DIR/extern-type-diag-not-similar.rs:17:19 | diff --git a/tests/ui/extern/extern-types-not-sync-send.stderr b/tests/ui/extern/extern-types-not-sync-send.stderr index 7865ddeda34f..5edfa5b51c47 100644 --- a/tests/ui/extern/extern-types-not-sync-send.stderr +++ b/tests/ui/extern/extern-types-not-sync-send.stderr @@ -5,6 +5,7 @@ LL | assert_sync::(); | ^ `A` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `A` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `assert_sync` --> $DIR/extern-types-not-sync-send.rs:9:28 | @@ -18,6 +19,7 @@ LL | assert_send::(); | ^ `A` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `A` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `assert_send` --> $DIR/extern-types-not-sync-send.rs:10:28 | diff --git a/tests/ui/fmt/send-sync.stderr b/tests/ui/fmt/send-sync.stderr index e3ebe6cdcb81..e431501e9f8a 100644 --- a/tests/ui/fmt/send-sync.stderr +++ b/tests/ui/fmt/send-sync.stderr @@ -7,6 +7,7 @@ LL | send(format_args!("{:?}", c)); | required by a bound introduced by this call | = help: within `[core::fmt::rt::Argument<'_>]`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque` + = note: consider using `std::sync::Arc`; for more information visit = note: required because it appears within the type `&core::fmt::rt::Opaque` note: required because it appears within the type `Argument<'_>` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL @@ -29,6 +30,7 @@ LL | sync(format_args!("{:?}", c)); | required by a bound introduced by this call | = help: within `Arguments<'_>`, the trait `Sync` is not implemented for `core::fmt::rt::Opaque` + = note: consider using `std::sync::Arc`; for more information visit = note: required because it appears within the type `&core::fmt::rt::Opaque` note: required because it appears within the type `Argument<'_>` --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL diff --git a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr index c07906ec37d3..0038ed0ac1c1 100644 --- a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr +++ b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr @@ -14,6 +14,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -56,6 +57,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -98,6 +100,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | diff --git a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr index 35698a98dbd6..2e684636432c 100644 --- a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr +++ b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr @@ -14,6 +14,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -54,6 +55,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -94,6 +96,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | diff --git a/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr b/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr index 1a05bfe4f0e6..30f1546c6e35 100644 --- a/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr +++ b/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr @@ -14,6 +14,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `copy::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -56,6 +57,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `copy::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:38:22 | @@ -97,6 +99,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -139,6 +142,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:38:22 | @@ -180,6 +184,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -222,6 +227,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:38:22 | @@ -263,6 +269,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:25:22 | @@ -305,6 +312,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:38:22 | diff --git a/tests/ui/generator/drop-yield-twice.stderr b/tests/ui/generator/drop-yield-twice.stderr index 0808a2c85ee1..468d9a809b42 100644 --- a/tests/ui/generator/drop-yield-twice.stderr +++ b/tests/ui/generator/drop-yield-twice.stderr @@ -11,6 +11,7 @@ LL | | }) | |_____^ generator is not `Send` | = help: within `[generator@$DIR/drop-yield-twice.rs:7:17: 7:19]`, the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/drop-yield-twice.rs:9:9 | diff --git a/tests/ui/generator/issue-57017.no_drop_tracking.stderr b/tests/ui/generator/issue-57017.no_drop_tracking.stderr index f7b8e198cc4b..7dd9980635af 100644 --- a/tests/ui/generator/issue-57017.no_drop_tracking.stderr +++ b/tests/ui/generator/issue-57017.no_drop_tracking.stderr @@ -14,6 +14,7 @@ LL | | ); | |_____- in this macro invocation | = help: the trait `Sync` is not implemented for `copy::unsync::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/issue-57017.rs:30:28 | @@ -55,6 +56,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `copy::unsend::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/issue-57017.rs:42:28 | @@ -96,6 +98,7 @@ LL | | ); | |_____- in this macro invocation | = help: the trait `Sync` is not implemented for `derived_drop::unsync::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/issue-57017.rs:30:28 | @@ -137,6 +140,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/issue-57017.rs:42:28 | @@ -178,6 +182,7 @@ LL | | ); | |_____- in this macro invocation | = help: the trait `Sync` is not implemented for `significant_drop::unsync::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/issue-57017.rs:30:28 | @@ -219,6 +224,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/issue-57017.rs:42:28 | diff --git a/tests/ui/generator/issue-57478.no_drop_tracking.stderr b/tests/ui/generator/issue-57478.no_drop_tracking.stderr index 612dd9c37f70..91f30ef1ef62 100644 --- a/tests/ui/generator/issue-57478.no_drop_tracking.stderr +++ b/tests/ui/generator/issue-57478.no_drop_tracking.stderr @@ -11,6 +11,7 @@ LL | | }) | |_____^ generator is not `Send` | = help: within `[generator@$DIR/issue-57478.rs:13:17: 13:19]`, the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/issue-57478.rs:17:9 | diff --git a/tests/ui/generator/not-send-sync.drop_tracking.stderr b/tests/ui/generator/not-send-sync.drop_tracking.stderr index 718fd42245ad..3cbfcf436c57 100644 --- a/tests/ui/generator/not-send-sync.drop_tracking.stderr +++ b/tests/ui/generator/not-send-sync.drop_tracking.stderr @@ -11,6 +11,7 @@ LL | | }); | |_____^ generator is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:17:17: 17:19]`, the trait `Sync` is not implemented for `NotSync` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Sync` as this value is used across a yield --> $DIR/not-send-sync.rs:20:9 | @@ -40,6 +41,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[generator@$DIR/not-send-sync.rs:24:17: 24:19]`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/not-send-sync.rs:27:9 | diff --git a/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr b/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr index 66f01ae37d81..6647adff5281 100644 --- a/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr +++ b/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | assert_sync(|| { | ^^^^^^^^^^^ generator is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:17:17: 17:19]`, the trait `Sync` is not implemented for `NotSync` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Sync` as this value is used across a yield --> $DIR/not-send-sync.rs:20:9 | @@ -25,6 +26,7 @@ LL | assert_send(|| { | ^^^^^^^^^^^ generator is not `Send` | = help: within `[generator@$DIR/not-send-sync.rs:24:17: 24:19]`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/not-send-sync.rs:27:9 | diff --git a/tests/ui/generator/not-send-sync.no_drop_tracking.stderr b/tests/ui/generator/not-send-sync.no_drop_tracking.stderr index 718fd42245ad..3cbfcf436c57 100644 --- a/tests/ui/generator/not-send-sync.no_drop_tracking.stderr +++ b/tests/ui/generator/not-send-sync.no_drop_tracking.stderr @@ -11,6 +11,7 @@ LL | | }); | |_____^ generator is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:17:17: 17:19]`, the trait `Sync` is not implemented for `NotSync` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Sync` as this value is used across a yield --> $DIR/not-send-sync.rs:20:9 | @@ -40,6 +41,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[generator@$DIR/not-send-sync.rs:24:17: 24:19]`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/not-send-sync.rs:27:9 | diff --git a/tests/ui/generator/parent-expression.drop_tracking.stderr b/tests/ui/generator/parent-expression.drop_tracking.stderr index ef489088bf85..e30ace31719d 100644 --- a/tests/ui/generator/parent-expression.drop_tracking.stderr +++ b/tests/ui/generator/parent-expression.drop_tracking.stderr @@ -14,6 +14,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -56,6 +57,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -98,6 +100,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | diff --git a/tests/ui/generator/parent-expression.drop_tracking_mir.stderr b/tests/ui/generator/parent-expression.drop_tracking_mir.stderr index bf814456427e..82a29b29d2e3 100644 --- a/tests/ui/generator/parent-expression.drop_tracking_mir.stderr +++ b/tests/ui/generator/parent-expression.drop_tracking_mir.stderr @@ -14,6 +14,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -54,6 +55,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -94,6 +96,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | diff --git a/tests/ui/generator/parent-expression.no_drop_tracking.stderr b/tests/ui/generator/parent-expression.no_drop_tracking.stderr index 2e1313a80048..23fa90edfb55 100644 --- a/tests/ui/generator/parent-expression.no_drop_tracking.stderr +++ b/tests/ui/generator/parent-expression.no_drop_tracking.stderr @@ -14,6 +14,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `copy::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -56,6 +57,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `copy::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:38:22 | @@ -97,6 +99,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -139,6 +142,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `derived_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:38:22 | @@ -180,6 +184,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -222,6 +227,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `significant_drop::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:38:22 | @@ -263,6 +269,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:21:21: 21:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:25:22 | @@ -305,6 +312,7 @@ LL | | ); | |_____- in this macro invocation | = help: within `[generator@$DIR/parent-expression.rs:37:21: 37:28]`, the trait `Send` is not implemented for `insignificant_dtor::Client` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:38:22 | diff --git a/tests/ui/generator/partial-drop.drop_tracking.stderr b/tests/ui/generator/partial-drop.drop_tracking.stderr index f1b25cb8c34e..018f1c05ad95 100644 --- a/tests/ui/generator/partial-drop.drop_tracking.stderr +++ b/tests/ui/generator/partial-drop.drop_tracking.stderr @@ -11,6 +11,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:17:17: 17:19]`, the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/partial-drop.rs:21:9 | @@ -41,6 +42,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:24:17: 24:19]`, the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/partial-drop.rs:29:9 | diff --git a/tests/ui/generator/partial-drop.no_drop_tracking.stderr b/tests/ui/generator/partial-drop.no_drop_tracking.stderr index 91152b5ea6f3..bd74ae6ac3ae 100644 --- a/tests/ui/generator/partial-drop.no_drop_tracking.stderr +++ b/tests/ui/generator/partial-drop.no_drop_tracking.stderr @@ -11,6 +11,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:17:17: 17:19]`, the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/partial-drop.rs:21:9 | @@ -41,6 +42,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[generator@$DIR/partial-drop.rs:24:17: 24:19]`, the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/partial-drop.rs:29:9 | diff --git a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr index 1f2e530f6f57..ff7a6885b8ea 100644 --- a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr +++ b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr @@ -11,6 +11,7 @@ LL | | }); | |_____^ generator is not `Sync` | = help: within `[main::{closure#0} upvar_tys=() {NotSync, ()}]`, the trait `Sync` is not implemented for `NotSync` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Sync` as this value is used across a yield --> $DIR/generator-print-verbose-2.rs:23:9 | @@ -40,6 +41,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[main::{closure#1} upvar_tys=() {NotSend, ()}]`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/generator-print-verbose-2.rs:30:9 | diff --git a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr index 354369f19540..6dc8e68a7087 100644 --- a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr +++ b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr @@ -5,6 +5,7 @@ LL | assert_sync(|| { | ^^^^^^^^^^^ generator is not `Sync` | = help: within `[main::{closure#0} upvar_tys=() [main::{closure#0}]]`, the trait `Sync` is not implemented for `NotSync` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Sync` as this value is used across a yield --> $DIR/generator-print-verbose-2.rs:23:9 | @@ -25,6 +26,7 @@ LL | assert_send(|| { | ^^^^^^^^^^^ generator is not `Send` | = help: within `[main::{closure#1} upvar_tys=() [main::{closure#1}]]`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/generator-print-verbose-2.rs:30:9 | diff --git a/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr index 1f2e530f6f57..ff7a6885b8ea 100644 --- a/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr +++ b/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr @@ -11,6 +11,7 @@ LL | | }); | |_____^ generator is not `Sync` | = help: within `[main::{closure#0} upvar_tys=() {NotSync, ()}]`, the trait `Sync` is not implemented for `NotSync` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Sync` as this value is used across a yield --> $DIR/generator-print-verbose-2.rs:23:9 | @@ -40,6 +41,7 @@ LL | | }); | |_____^ generator is not `Send` | = help: within `[main::{closure#1} upvar_tys=() {NotSend, ()}]`, the trait `Send` is not implemented for `NotSend` + = note: consider using `std::sync::Arc`; for more information visit note: generator is not `Send` as this value is used across a yield --> $DIR/generator-print-verbose-2.rs:30:9 | diff --git a/tests/ui/generator/ref-upvar-not-send.rs b/tests/ui/generator/ref-upvar-not-send.rs index eb9ef63ecfcb..53ded21b6214 100644 --- a/tests/ui/generator/ref-upvar-not-send.rs +++ b/tests/ui/generator/ref-upvar-not-send.rs @@ -15,6 +15,7 @@ fn main() { assert_send(move || { //~^ ERROR generator cannot be sent between threads safely //~| NOTE generator is not `Send` + //~| NOTE consider using `std::sync::Arc yield; let _x = x; }); @@ -23,6 +24,7 @@ fn main() { assert_send(move || { //~^ ERROR generator cannot be sent between threads safely //~| NOTE generator is not `Send` + //~| NOTE consider using `std::sync::Arc yield; let _y = y; }); diff --git a/tests/ui/generator/ref-upvar-not-send.stderr b/tests/ui/generator/ref-upvar-not-send.stderr index 689ace67e34e..0a5289544b8b 100644 --- a/tests/ui/generator/ref-upvar-not-send.stderr +++ b/tests/ui/generator/ref-upvar-not-send.stderr @@ -5,14 +5,16 @@ LL | assert_send(move || { | _________________^ LL | | LL | | +LL | | LL | | yield; LL | | let _x = x; LL | | }); | |_____^ generator is not `Send` | = help: the trait `Sync` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` - --> $DIR/ref-upvar-not-send.rs:19:18 + --> $DIR/ref-upvar-not-send.rs:20:18 | LL | let _x = x; | ^ has type `&*mut ()` which is not `Send`, because `*mut ()` is not `Sync` @@ -23,20 +25,22 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: generator cannot be sent between threads safely - --> $DIR/ref-upvar-not-send.rs:23:17 + --> $DIR/ref-upvar-not-send.rs:24:17 | LL | assert_send(move || { | _________________^ LL | | LL | | +LL | | LL | | yield; LL | | let _y = y; LL | | }); | |_____^ generator is not `Send` | - = help: within `[generator@$DIR/ref-upvar-not-send.rs:23:17: 23:24]`, the trait `Send` is not implemented for `*mut ()` + = help: within `[generator@$DIR/ref-upvar-not-send.rs:24:17: 24:24]`, the trait `Send` is not implemented for `*mut ()` + = note: consider using `std::sync::Arc<*mut ()>`; for more information visit note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send` - --> $DIR/ref-upvar-not-send.rs:27:18 + --> $DIR/ref-upvar-not-send.rs:29:18 | LL | let _y = y; | ^ has type `&mut *mut ()` which is not `Send`, because `*mut ()` is not `Send` diff --git a/tests/ui/impl-trait/auto-trait-leak2.rs b/tests/ui/impl-trait/auto-trait-leak2.rs index 09450089adaa..bbad0df1f66f 100644 --- a/tests/ui/impl-trait/auto-trait-leak2.rs +++ b/tests/ui/impl-trait/auto-trait-leak2.rs @@ -21,11 +21,13 @@ fn main() { //~^ ERROR `Rc>` cannot be sent between threads safely //~| NOTE `Rc>` cannot be sent between threads safely //~| NOTE required by a bound + //~| NOTE use `std::sync::Arc` instead send(after()); //~^ ERROR `Rc>` cannot be sent between threads safely //~| NOTE `Rc>` cannot be sent between threads safely //~| NOTE required by a bound + //~| NOTE use `std::sync::Arc` instead } // Deferred path, main has to wait until typeck finishes, diff --git a/tests/ui/impl-trait/auto-trait-leak2.stderr b/tests/ui/impl-trait/auto-trait-leak2.stderr index 52fa28145d66..f2f88215a39b 100644 --- a/tests/ui/impl-trait/auto-trait-leak2.stderr +++ b/tests/ui/impl-trait/auto-trait-leak2.stderr @@ -10,6 +10,7 @@ LL | send(before()); | required by a bound introduced by this call | = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it's used within this closure --> $DIR/auto-trait-leak2.rs:10:5 | @@ -27,7 +28,7 @@ LL | fn send(_: T) {} | ^^^^ required by this bound in `send` error[E0277]: `Rc>` cannot be sent between threads safely - --> $DIR/auto-trait-leak2.rs:25:10 + --> $DIR/auto-trait-leak2.rs:26:10 | LL | send(after()); | ---- ^^^^^^^ `Rc>` cannot be sent between threads safely @@ -38,13 +39,14 @@ LL | fn after() -> impl Fn(i32) { | ------------ within this `impl Fn(i32)` | = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it's used within this closure - --> $DIR/auto-trait-leak2.rs:38:5 + --> $DIR/auto-trait-leak2.rs:40:5 | LL | move |x| p.set(x) | ^^^^^^^^ note: required because it appears within the type `impl Fn(i32)` - --> $DIR/auto-trait-leak2.rs:33:15 + --> $DIR/auto-trait-leak2.rs:35:15 | LL | fn after() -> impl Fn(i32) { | ^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr index dee87d082386..687c811a5d54 100644 --- a/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr +++ b/tests/ui/impl-trait/in-trait/check-wf-on-non-defaulted-rpitit.stderr @@ -5,6 +5,7 @@ LL | fn bar() -> Wrapper; | ^^^^^^^^^^^^^^^^^^^ `impl Sized` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `impl Sized` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `Wrapper` --> $DIR/check-wf-on-non-defaulted-rpitit.rs:3:19 | diff --git a/tests/ui/issues/issue-21763.stderr b/tests/ui/issues/issue-21763.stderr index df50118ac477..9bd96723d817 100644 --- a/tests/ui/issues/issue-21763.stderr +++ b/tests/ui/issues/issue-21763.stderr @@ -5,6 +5,7 @@ LL | foo::, Rc<()>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely | = help: within `(Rc<()>, Rc<()>)`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` = note: required because it appears within the type `(Rc<()>, Rc<()>)` = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` note: required because it appears within the type `HashMap, Rc<()>, RandomState>` diff --git a/tests/ui/issues/issue-24446.stderr b/tests/ui/issues/issue-24446.stderr index 4afb87c48254..b40e73116e36 100644 --- a/tests/ui/issues/issue-24446.stderr +++ b/tests/ui/issues/issue-24446.stderr @@ -13,6 +13,7 @@ LL | static foo: dyn Fn() -> u32 = || -> u32 { | ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)` + = note: consider using `std::sync::Arc<(dyn Fn() -> u32 + 'static)>`; for more information visit = note: shared static variables must have a type that implements `Sync` error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-40827.stderr b/tests/ui/issues/issue-40827.stderr index 7f5c578ae4ff..67a5394bee98 100644 --- a/tests/ui/issues/issue-40827.stderr +++ b/tests/ui/issues/issue-40827.stderr @@ -7,6 +7,7 @@ LL | f(Foo(Arc::new(Bar::B(None)))); | required by a bound introduced by this call | = help: within `Bar`, the trait `Sync` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it appears within the type `Bar` --> $DIR/issue-40827.rs:6:6 | @@ -33,6 +34,7 @@ LL | f(Foo(Arc::new(Bar::B(None)))); | required by a bound introduced by this call | = help: within `Bar`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it appears within the type `Bar` --> $DIR/issue-40827.rs:6:6 | diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr index 53c1940491f8..37c7a2938919 100644 --- a/tests/ui/kindck/kindck-impl-type-params.stderr +++ b/tests/ui/kindck/kindck-impl-type-params.stderr @@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely LL | let a = &t as &dyn Gettable; | ^^ `T` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required for `S` to implement `Gettable` --> $DIR/kindck-impl-type-params.rs:12:32 | @@ -42,6 +43,7 @@ error[E0277]: `T` cannot be sent between threads safely LL | let a: &dyn Gettable = &t; | ^^ `T` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required for `S` to implement `Gettable` --> $DIR/kindck-impl-type-params.rs:12:32 | diff --git a/tests/ui/kindck/kindck-nonsendable-1.stderr b/tests/ui/kindck/kindck-nonsendable-1.stderr index cc6e1f59c778..37c8e10c82c5 100644 --- a/tests/ui/kindck/kindck-nonsendable-1.stderr +++ b/tests/ui/kindck/kindck-nonsendable-1.stderr @@ -9,6 +9,7 @@ LL | bar(move|| foo(x)); | required by a bound introduced by this call | = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:15]`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it's used within this closure --> $DIR/kindck-nonsendable-1.rs:9:9 | diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr index 284d5dcec310..27eebe273679 100644 --- a/tests/ui/kindck/kindck-send-object.stderr +++ b/tests/ui/kindck/kindck-send-object.stderr @@ -5,6 +5,7 @@ LL | assert_send::<&'static (dyn Dummy + 'static)>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` + = note: consider using `std::sync::Arc<(dyn Dummy + 'static)>`; for more information visit = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` note: required by a bound in `assert_send` --> $DIR/kindck-send-object.rs:5:18 @@ -19,6 +20,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` + = note: consider using `std::sync::Arc`; for more information visit = note: required for `Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr index 269193f73b47..62e0c5794d38 100644 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ b/tests/ui/kindck/kindck-send-object1.stderr @@ -5,6 +5,7 @@ LL | assert_send::<&'a dyn Dummy>(); | ^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)` + = note: consider using `std::sync::Arc<(dyn Dummy + 'a)>`; for more information visit = note: required for `&'a (dyn Dummy + 'a)` to implement `Send` note: required by a bound in `assert_send` --> $DIR/kindck-send-object1.rs:5:18 @@ -19,6 +20,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` + = note: consider using `std::sync::Arc<(dyn Dummy + 'a)>`; for more information visit = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr index 6b8df60227f5..4608e88c1d1a 100644 --- a/tests/ui/kindck/kindck-send-object2.stderr +++ b/tests/ui/kindck/kindck-send-object2.stderr @@ -5,6 +5,7 @@ LL | assert_send::<&'static dyn Dummy>(); | ^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)` + = note: consider using `std::sync::Arc<(dyn Dummy + 'static)>`; for more information visit = note: required for `&'static (dyn Dummy + 'static)` to implement `Send` note: required by a bound in `assert_send` --> $DIR/kindck-send-object2.rs:3:18 @@ -19,6 +20,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` + = note: consider using `std::sync::Arc`; for more information visit = note: required for `Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/tests/ui/kindck/kindck-send-owned.stderr b/tests/ui/kindck/kindck-send-owned.stderr index dc1bb6206afc..3f18667f97b8 100644 --- a/tests/ui/kindck/kindck-send-owned.stderr +++ b/tests/ui/kindck/kindck-send-owned.stderr @@ -5,6 +5,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut u8` + = note: consider using `std::sync::Arc<*mut u8>`; for more information visit = note: required for `Unique<*mut u8>` to implement `Send` note: required because it appears within the type `Box<*mut u8>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/tests/ui/kindck/kindck-send-unsafe.stderr b/tests/ui/kindck/kindck-send-unsafe.stderr index f1a5054abbc4..75230519c791 100644 --- a/tests/ui/kindck/kindck-send-unsafe.stderr +++ b/tests/ui/kindck/kindck-send-unsafe.stderr @@ -5,6 +5,7 @@ LL | assert_send::<*mut isize>(); | ^^^^^^^^^^ `*mut isize` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut isize` + = note: consider using `std::sync::Arc<*mut isize>`; for more information visit note: required by a bound in `assert_send` --> $DIR/kindck-send-unsafe.rs:3:19 | @@ -18,6 +19,7 @@ LL | assert_send::<*mut &'a isize>(); | ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut &'a isize` + = note: consider using `std::sync::Arc<*mut &'a isize>`; for more information visit note: required by a bound in `assert_send` --> $DIR/kindck-send-unsafe.rs:3:19 | diff --git a/tests/ui/mut/mutable-enum-indirect.stderr b/tests/ui/mut/mutable-enum-indirect.stderr index 9e1f4e1fe4ea..0aa2f29160dd 100644 --- a/tests/ui/mut/mutable-enum-indirect.stderr +++ b/tests/ui/mut/mutable-enum-indirect.stderr @@ -7,6 +7,7 @@ LL | bar(&x); | required by a bound introduced by this call | = help: within `&Foo`, the trait `Sync` is not implemented for `NoSync` + = note: consider using `std::sync::Arc`; for more information visit note: required because it appears within the type `Foo` --> $DIR/mutable-enum-indirect.rs:11:6 | diff --git a/tests/ui/no-send-res-ports.stderr b/tests/ui/no-send-res-ports.stderr index 75561f4119aa..6fe1f2a1c84a 100644 --- a/tests/ui/no-send-res-ports.stderr +++ b/tests/ui/no-send-res-ports.stderr @@ -14,6 +14,7 @@ LL | | }); | |_____^ `Rc<()>` cannot be sent between threads safely | = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 25:25]`, the trait `Send` is not implemented for `Rc<()>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it appears within the type `Port<()>` --> $DIR/no-send-res-ports.rs:5:8 | diff --git a/tests/ui/no_send-enum.stderr b/tests/ui/no_send-enum.stderr index b5a14b551dc2..7cd83b6b2cb6 100644 --- a/tests/ui/no_send-enum.stderr +++ b/tests/ui/no_send-enum.stderr @@ -7,6 +7,7 @@ LL | bar(x); | required by a bound introduced by this call | = help: within `Foo`, the trait `Send` is not implemented for `NoSend` + = note: consider using `std::sync::Arc`; for more information visit note: required because it appears within the type `Foo` --> $DIR/no_send-enum.rs:8:6 | diff --git a/tests/ui/no_send-rc.stderr b/tests/ui/no_send-rc.stderr index ce25da559da3..67bed5ba7506 100644 --- a/tests/ui/no_send-rc.stderr +++ b/tests/ui/no_send-rc.stderr @@ -7,6 +7,7 @@ LL | bar(x); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `Rc<{integer}>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required by a bound in `bar` --> $DIR/no_send-rc.rs:3:11 | diff --git a/tests/ui/no_share-enum.stderr b/tests/ui/no_share-enum.stderr index 5b453e0da3bb..03451413b2fe 100644 --- a/tests/ui/no_share-enum.stderr +++ b/tests/ui/no_share-enum.stderr @@ -7,6 +7,7 @@ LL | bar(x); | required by a bound introduced by this call | = help: within `Foo`, the trait `Sync` is not implemented for `NoSync` + = note: consider using `std::sync::Arc`; for more information visit note: required because it appears within the type `Foo` --> $DIR/no_share-enum.rs:8:6 | diff --git a/tests/ui/no_share-struct.stderr b/tests/ui/no_share-struct.stderr index 9ce3a318f1d3..e40d8f3e4b66 100644 --- a/tests/ui/no_share-struct.stderr +++ b/tests/ui/no_share-struct.stderr @@ -7,6 +7,7 @@ LL | bar(x); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `bar` --> $DIR/no_share-struct.rs:8:11 | diff --git a/tests/ui/phantom-auto-trait.stderr b/tests/ui/phantom-auto-trait.stderr index 5af648f6a0cf..43ff20d47190 100644 --- a/tests/ui/phantom-auto-trait.stderr +++ b/tests/ui/phantom-auto-trait.stderr @@ -6,6 +6,7 @@ LL | is_zen(x) | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required for `&T` to implement `Zen` --> $DIR/phantom-auto-trait.rs:10:24 | @@ -36,6 +37,7 @@ LL | is_zen(x) | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required for `&T` to implement `Zen` --> $DIR/phantom-auto-trait.rs:10:24 | diff --git a/tests/ui/recursion/recursive-requirements.stderr b/tests/ui/recursion/recursive-requirements.stderr index bb63f7cd0dce..ceb03c4cdbed 100644 --- a/tests/ui/recursion/recursive-requirements.stderr +++ b/tests/ui/recursion/recursive-requirements.stderr @@ -5,6 +5,7 @@ LL | let _: AssertSync = unimplemented!(); | ^^^^^^^^^^^^^^^ `*const Bar` cannot be shared between threads safely | = help: within `Foo`, the trait `Sync` is not implemented for `*const Bar` + = note: consider using `std::sync::Arc<*const Bar>`; for more information visit note: required because it appears within the type `Foo` --> $DIR/recursive-requirements.rs:5:12 | @@ -23,6 +24,7 @@ LL | let _: AssertSync = unimplemented!(); | ^^^^^^^^^^^^^^^ `*const Foo` cannot be shared between threads safely | = help: within `Foo`, the trait `Sync` is not implemented for `*const Foo` + = note: consider using `std::sync::Arc<*const Foo>`; for more information visit note: required because it appears within the type `Bar` --> $DIR/recursive-requirements.rs:10:12 | diff --git a/tests/ui/statics/issue-17718-static-sync.stderr b/tests/ui/statics/issue-17718-static-sync.stderr index bc6e45e59258..24e598280deb 100644 --- a/tests/ui/statics/issue-17718-static-sync.stderr +++ b/tests/ui/statics/issue-17718-static-sync.stderr @@ -5,6 +5,7 @@ LL | static BAR: Foo = Foo; | ^^^ `Foo` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit = note: shared static variables must have a type that implements `Sync` error: aborting due to previous error diff --git a/tests/ui/stdlib-unit-tests/not-sync.stderr b/tests/ui/stdlib-unit-tests/not-sync.stderr index b9a266e4eb9b..2ea08b8b4f4e 100644 --- a/tests/ui/stdlib-unit-tests/not-sync.stderr +++ b/tests/ui/stdlib-unit-tests/not-sync.stderr @@ -33,6 +33,7 @@ LL | test::>(); | ^^^^^^^ `Rc` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required by a bound in `test` --> $DIR/not-sync.rs:5:12 | @@ -46,6 +47,7 @@ LL | test::>(); | ^^^^^^^^^ `std::rc::Weak` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `std::rc::Weak` + = note: consider using `std::sync::Arc>`; for more information visit note: required by a bound in `test` --> $DIR/not-sync.rs:5:12 | @@ -59,6 +61,7 @@ LL | test::>(); | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver` + = note: consider using `std::sync::Arc>`; for more information visit note: required by a bound in `test` --> $DIR/not-sync.rs:5:12 | diff --git a/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr b/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr index a3ab0b8efb06..86e044ac00a9 100644 --- a/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr +++ b/tests/ui/suggestions/issue-79843-impl-trait-with-missing-bounds-on-async-fn.stderr @@ -7,6 +7,7 @@ LL | assert_is_send(&bar); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `::Bar` + = note: consider using `std::sync::Arc<::Bar>`; for more information visit note: required by a bound in `assert_is_send` --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:30:22 | @@ -26,6 +27,7 @@ LL | assert_is_send(&bar); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `::Bar` + = note: consider using `std::sync::Arc<::Bar>`; for more information visit note: required by a bound in `assert_is_send` --> $DIR/issue-79843-impl-trait-with-missing-bounds-on-async-fn.rs:30:22 | diff --git a/tests/ui/suggestions/issue-84973-blacklist.stderr b/tests/ui/suggestions/issue-84973-blacklist.stderr index 4de9da89c9bc..a3b7805c0720 100644 --- a/tests/ui/suggestions/issue-84973-blacklist.stderr +++ b/tests/ui/suggestions/issue-84973-blacklist.stderr @@ -71,6 +71,7 @@ LL | f_send(rc); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `Rc<{integer}>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required by a bound in `f_send` --> $DIR/issue-84973-blacklist.rs:10:14 | diff --git a/tests/ui/suggestions/restrict-type-argument.stderr b/tests/ui/suggestions/restrict-type-argument.stderr index 01c2de798641..205634a8d682 100644 --- a/tests/ui/suggestions/restrict-type-argument.stderr +++ b/tests/ui/suggestions/restrict-type-argument.stderr @@ -6,6 +6,7 @@ LL | is_send(val); | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/restrict-type-argument.rs:1:15 | @@ -24,6 +25,7 @@ LL | is_send(val); | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/restrict-type-argument.rs:1:15 | @@ -42,6 +44,7 @@ LL | is_send(val); | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/restrict-type-argument.rs:1:15 | @@ -60,6 +63,7 @@ LL | is_send(val); | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/restrict-type-argument.rs:1:15 | @@ -78,6 +82,7 @@ LL | is_send(val); | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/restrict-type-argument.rs:1:15 | @@ -96,6 +101,7 @@ LL | is_send(val); | | | required by a bound introduced by this call | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/restrict-type-argument.rs:1:15 | diff --git a/tests/ui/traits/alias/cross-crate.stderr b/tests/ui/traits/alias/cross-crate.stderr index ae9d7d0a9b4a..bccdd3da04ef 100644 --- a/tests/ui/traits/alias/cross-crate.stderr +++ b/tests/ui/traits/alias/cross-crate.stderr @@ -5,6 +5,7 @@ LL | use_alias::>(); | ^^^^^^^ `Rc` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` = note: required for `Rc` to implement `SendSync` note: required by a bound in `use_alias` --> $DIR/cross-crate.rs:10:17 @@ -19,6 +20,7 @@ LL | use_alias::>(); | ^^^^^^^ `Rc` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` = note: required for `Rc` to implement `SendSync` note: required by a bound in `use_alias` --> $DIR/cross-crate.rs:10:17 diff --git a/tests/ui/traits/bad-method-typaram-kind.stderr b/tests/ui/traits/bad-method-typaram-kind.stderr index 56acfbe80d03..074284cbdd41 100644 --- a/tests/ui/traits/bad-method-typaram-kind.stderr +++ b/tests/ui/traits/bad-method-typaram-kind.stderr @@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely LL | 1.bar::(); | ^ `T` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `Bar::bar` --> $DIR/bad-method-typaram-kind.rs:6:14 | diff --git a/tests/ui/traits/inductive-overflow/two-traits.stderr b/tests/ui/traits/inductive-overflow/two-traits.stderr index 0d0bf88616c8..d2f809f3577d 100644 --- a/tests/ui/traits/inductive-overflow/two-traits.stderr +++ b/tests/ui/traits/inductive-overflow/two-traits.stderr @@ -4,6 +4,7 @@ error[E0277]: `T` cannot be shared between threads safely LL | type X = Self; | ^^^^ `T` cannot be shared between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `Magic::X` --> $DIR/two-traits.rs:8:13 | diff --git a/tests/ui/traits/issue-7013.stderr b/tests/ui/traits/issue-7013.stderr index 1c0e8bcf1851..335c7cd24851 100644 --- a/tests/ui/traits/issue-7013.stderr +++ b/tests/ui/traits/issue-7013.stderr @@ -5,6 +5,7 @@ LL | let a = A {v: Box::new(B{v: None}) as Box}; | ^^^^^^^^^^^^^^^^^^^^ `Rc>` cannot be sent between threads safely | = help: within `B`, the trait `Send` is not implemented for `Rc>` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it appears within the type `Option>>` --> $SRC_DIR/core/src/option.rs:LL:COL note: required because it appears within the type `B` diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr index a53879657f5a..b61ad52a67a8 100644 --- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -7,6 +7,7 @@ LL | Outer(TestType); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `dummy::TestType` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `Outer` --> $DIR/negated-auto-traits-error.rs:10:17 | @@ -20,6 +21,7 @@ LL | Outer(TestType); | ^^^^^^^^^^^^^^^ `dummy::TestType` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dummy::TestType` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `Outer` --> $DIR/negated-auto-traits-error.rs:10:17 | @@ -35,6 +37,7 @@ LL | is_send(TestType); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `dummy1b::TestType` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 | @@ -50,6 +53,7 @@ LL | is_send((8, TestType)); | required by a bound introduced by this call | = help: within `({integer}, dummy1c::TestType)`, the trait `Send` is not implemented for `dummy1c::TestType` + = note: consider using `std::sync::Arc`; for more information visit = note: required because it appears within the type `({integer}, TestType)` note: required by a bound in `is_send` --> $DIR/negated-auto-traits-error.rs:16:15 @@ -88,6 +92,7 @@ LL | is_send(Box::new(Outer2(TestType))); | required by a bound introduced by this call | = help: within `Outer2`, the trait `Send` is not implemented for `dummy3::TestType` + = note: consider using `std::sync::Arc`; for more information visit note: required because it appears within the type `Outer2` --> $DIR/negated-auto-traits-error.rs:12:8 | @@ -111,6 +116,7 @@ LL | is_sync(Outer2(TestType)); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `main::TestType` + = note: consider using `std::sync::Arc`; for more information visit note: required for `Outer2` to implement `Sync` --> $DIR/negated-auto-traits-error.rs:14:22 | diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr index 4aefdd6bb073..ee260ca11b64 100644 --- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr @@ -7,6 +7,7 @@ LL | is_send(foo()); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `impl Future` + = note: consider using `std::sync::Arc>`; for more information visit note: required by a bound in `is_send` --> $DIR/auto-with-drop_tracking_mir.rs:24:24 | diff --git a/tests/ui/traits/no_send-struct.stderr b/tests/ui/traits/no_send-struct.stderr index ee7bdf282b74..a13ef0901549 100644 --- a/tests/ui/traits/no_send-struct.stderr +++ b/tests/ui/traits/no_send-struct.stderr @@ -7,6 +7,7 @@ LL | bar(x); | required by a bound introduced by this call | = help: the trait `Send` is not implemented for `Foo` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `bar` --> $DIR/no_send-struct.rs:11:11 | diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr index 7bd02550fb38..c0773ecec6ca 100644 --- a/tests/ui/traits/non_lifetime_binders/fail.stderr +++ b/tests/ui/traits/non_lifetime_binders/fail.stderr @@ -29,6 +29,7 @@ LL | auto_trait(); | ^^^^^^^^^^ `T` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `T` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `auto_trait` --> $DIR/fail.rs:15:15 | diff --git a/tests/ui/traits/unsend-future.stderr b/tests/ui/traits/unsend-future.stderr index 6ce1cf452f45..004c657c3782 100644 --- a/tests/ui/traits/unsend-future.stderr +++ b/tests/ui/traits/unsend-future.stderr @@ -5,6 +5,7 @@ LL | require_handler(handler) | ^^^^^^^ future returned by `handler` is not `Send` | = help: within `impl Future`, the trait `Send` is not implemented for `*const i32` + = note: consider using `std::sync::Arc<*const i32>`; for more information visit note: future is not `Send` as this value is used across an await --> $DIR/unsend-future.rs:15:14 | diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs index fc89b0e870e3..40f6f83f235e 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.rs @@ -22,4 +22,5 @@ fn main() { //~^ ERROR: `Rc` cannot be sent between threads safely [E0277] //~| NOTE cannot be sent //~| NOTE required by a bound + //~| NOTE use `std::sync::Arc` instead } diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr index d7247302dd1e..38c78c02bc51 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage2.stderr @@ -10,6 +10,7 @@ LL | is_send(m::foo()); | required by a bound introduced by this call | = help: within `Foo`, the trait `Send` is not implemented for `Rc` + = note: use `std::sync::Arc` instead of `std::rc::Rc` note: required because it appears within the type `Foo` --> $DIR/auto-trait-leakage2.rs:7:16 | diff --git a/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr b/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr index 468a14762c0d..39c8f4173abf 100644 --- a/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr +++ b/tests/ui/typeck/typeck-default-trait-impl-assoc-type.stderr @@ -5,6 +5,7 @@ LL | is_send::(); | ^^^^^^^^^^^^ `::AssocType` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `::AssocType` + = note: consider using `std::sync::Arc<::AssocType>`; for more information visit note: required by a bound in `is_send` --> $DIR/typeck-default-trait-impl-assoc-type.rs:14:14 | diff --git a/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr b/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr index 2ce32990e55d..3b5dc4565605 100644 --- a/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr +++ b/tests/ui/typeck/typeck-default-trait-impl-negation-send.stderr @@ -5,6 +5,7 @@ LL | is_send::(); | ^^^^^^^^^^^^^ `MyNotSendable` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `MyNotSendable` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/typeck-default-trait-impl-negation-send.rs:15:15 | diff --git a/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr index b9fca1a1b54b..a6bfecbe1df7 100644 --- a/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr +++ b/tests/ui/typeck/typeck-default-trait-impl-negation-sync.stderr @@ -5,6 +5,7 @@ LL | is_sync::(); | ^^^^^^^^^ `MyNotSync` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `MyNotSync` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_sync` --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:15 | @@ -18,6 +19,7 @@ LL | is_sync::(); | ^^^^^^^^^^^^^ `UnsafeCell` cannot be shared between threads safely | = help: within `MyTypeWUnsafe`, the trait `Sync` is not implemented for `UnsafeCell` + = note: consider using `std::sync::Arc>`; for more information visit note: required because it appears within the type `MyTypeWUnsafe` --> $DIR/typeck-default-trait-impl-negation-sync.rs:21:8 | @@ -36,6 +38,7 @@ LL | is_sync::(); | ^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely | = help: within `MyTypeManaged`, the trait `Sync` is not implemented for `Managed` + = note: consider using `std::sync::Arc`; for more information visit note: required because it appears within the type `MyTypeManaged` --> $DIR/typeck-default-trait-impl-negation-sync.rs:25:8 | diff --git a/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr b/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr index 887a1ddbb692..2797d995e5be 100644 --- a/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr +++ b/tests/ui/typeck/typeck-default-trait-impl-send-param.stderr @@ -4,6 +4,7 @@ error[E0277]: `T` cannot be sent between threads safely LL | is_send::() | ^ `T` cannot be sent between threads safely | + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `is_send` --> $DIR/typeck-default-trait-impl-send-param.rs:8:14 | diff --git a/tests/ui/typeck/typeck-unsafe-always-share.stderr b/tests/ui/typeck/typeck-unsafe-always-share.stderr index 154e504996bc..e3d26790f5e6 100644 --- a/tests/ui/typeck/typeck-unsafe-always-share.stderr +++ b/tests/ui/typeck/typeck-unsafe-always-share.stderr @@ -7,6 +7,7 @@ LL | test(us); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `UnsafeCell>` + = note: consider using `std::sync::Arc>>`; for more information visit note: required by a bound in `test` --> $DIR/typeck-unsafe-always-share.rs:15:12 | @@ -22,6 +23,7 @@ LL | test(uns); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `UnsafeCell` + = note: consider using `std::sync::Arc>`; for more information visit note: required by a bound in `test` --> $DIR/typeck-unsafe-always-share.rs:15:12 | @@ -37,6 +39,7 @@ LL | test(ms); | required by a bound introduced by this call | = help: within `MySync`, the trait `Sync` is not implemented for `UnsafeCell` + = note: consider using `std::sync::Arc>`; for more information visit note: required because it appears within the type `MySync` --> $DIR/typeck-unsafe-always-share.rs:8:8 | @@ -57,6 +60,7 @@ LL | test(NoSync); | required by a bound introduced by this call | = help: the trait `Sync` is not implemented for `NoSync` + = note: consider using `std::sync::Arc`; for more information visit note: required by a bound in `test` --> $DIR/typeck-unsafe-always-share.rs:15:12 | From 214d78daecdda209a4e0a3bc56dcb18c1eb00292 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 9 Aug 2023 17:00:59 +0000 Subject: [PATCH 72/76] Only resolve in new solver --- compiler/rustc_hir_typeck/src/coercion.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index b2b3f4355053..d9b17a2e2b77 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1007,15 +1007,17 @@ pub fn try_coerce( &self, expr: &hir::Expr<'_>, expr_ty: Ty<'tcx>, - target: Ty<'tcx>, + mut target: Ty<'tcx>, allow_two_phase: AllowTwoPhase, cause: Option>, ) -> RelateResult<'tcx, Ty<'tcx>> { let source = self.try_structurally_resolve_type(expr.span, expr_ty); - let target = self.try_structurally_resolve_type( - cause.as_ref().map_or(expr.span, |cause| cause.span), - target, - ); + if self.next_trait_solver() { + target = self.try_structurally_resolve_type( + cause.as_ref().map_or(expr.span, |cause| cause.span), + target, + ); + } debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target); let cause = From 8f1ea576b769d1d8a518d20eabbaf60343c03d81 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Wed, 9 Aug 2023 21:05:03 +0300 Subject: [PATCH 73/76] only allocate bytes within AllocRange --- compiler/rustc_smir/src/rustc_smir/mod.rs | 30 +++---------- compiler/rustc_smir/src/stable_mir/ty.rs | 51 +++++++++++++++++++---- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index c760fd8b69a6..07ef53ca3045 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,10 +9,13 @@ use crate::rustc_internal::{self, opaque}; use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{new_allocation, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy}; +use crate::stable_mir::ty::{ + allocation_filter, new_allocation, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy, +}; use crate::stable_mir::{self, Context}; use rustc_hir as hir; use rustc_middle::mir::coverage::CodeRegion; +use rustc_middle::mir::interpret::alloc_range; use rustc_middle::mir::{self, ConstantKind}; use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -1080,30 +1083,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { type T = stable_mir::ty::Allocation; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let size = self.size(); - let mut bytes: Vec> = self - .inspect_with_uninit_and_ptr_outside_interpreter(0..size.bytes_usize()) - .iter() - .copied() - .map(Some) - .collect(); - for (i, b) in bytes.iter_mut().enumerate() { - if !self.init_mask().get(rustc_target::abi::Size::from_bytes(i)) { - *b = None; - } - } - stable_mir::ty::Allocation { - bytes: bytes, - provenance: { - let mut ptrs = Vec::new(); - for (size, prov) in self.provenance().ptrs().iter() { - ptrs.push((size.bytes_usize(), opaque(prov))); - } - stable_mir::ty::ProvenanceMap { ptrs } - }, - align: self.align.bytes(), - mutability: self.mutability.stable(tables), - } + allocation_filter(self, alloc_range(rustc_target::abi::Size::ZERO, self.size()), tables) } } diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index c8bf861be793..14b841a46703 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,8 +1,8 @@ -use rustc_middle::mir::interpret::{alloc_range, ConstValue, Pointer}; +use rustc_middle::mir::interpret::{alloc_range, AllocRange, ConstValue, Pointer}; use super::{mir::Mutability, mir::Safety, with, DefId}; use crate::{ - rustc_internal::Opaque, + rustc_internal::{opaque, Opaque}, rustc_smir::{Stable, Tables}, }; @@ -353,17 +353,50 @@ pub fn new_allocation<'tcx>( .layout_of(rustc_middle::ty::ParamEnv::reveal_all().and(const_kind.ty())) .unwrap() .size; - let bytes = alloc.0.get_bytes_unchecked(alloc_range(offset, ty_size)); - let offset_allocation = rustc_middle::mir::interpret::Allocation::from_bytes( - bytes, - alloc.0.align, - alloc.0.mutability, - ); - offset_allocation.stable(tables) + allocation_filter(&alloc.0, alloc_range(offset, ty_size), tables) } } } +/// Creates an `Allocation` only from information within the `AllocRange`. +pub fn allocation_filter<'tcx>( + alloc: &rustc_middle::mir::interpret::Allocation, + alloc_range: AllocRange, + tables: &mut Tables<'tcx>, +) -> Allocation { + let mut bytes: Vec> = alloc + .inspect_with_uninit_and_ptr_outside_interpreter( + alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), + ) + .iter() + .copied() + .map(Some) + .collect(); + for (i, b) in bytes.iter_mut().enumerate() { + if !alloc + .init_mask() + .get(rustc_target::abi::Size::from_bytes(i + alloc_range.start.bytes_usize())) + { + *b = None; + } + } + let mut ptrs = Vec::new(); + for (offset, prov) in alloc + .provenance() + .ptrs() + .iter() + .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) + { + ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), opaque(prov))); + } + Allocation { + bytes: bytes, + provenance: ProvenanceMap { ptrs }, + align: alloc.align.bytes(), + mutability: alloc.mutability.stable(tables), + } +} + #[derive(Clone, Debug)] pub enum ConstantKind { Allocated(Allocation), From d8e3986d4214612ce7992da2b9b3269785e3ea40 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 9 Aug 2023 20:00:07 +0000 Subject: [PATCH 74/76] Don't use type_of to determine if item has intrinsic shim --- compiler/rustc_ty_utils/src/instance.rs | 65 +++++++++---------- .../instance-doesnt-depend-on-type.rs | 10 +++ 2 files changed, 40 insertions(+), 35 deletions(-) create mode 100644 tests/ui/inline-const/instance-doesnt-depend-on-type.rs diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index a21b5ef05e60..e1a15b5cf9ff 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,4 +1,5 @@ use rustc_errors::ErrorGuaranteed; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; @@ -15,54 +16,48 @@ fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, (DefId, GenericArgsRef<'tcx>)>, ) -> Result>, ErrorGuaranteed> { - let (param_env, (def, args)) = key.into_parts(); + let (param_env, (def_id, args)) = key.into_parts(); - let result = if let Some(trait_def_id) = tcx.trait_of_item(def) { + let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) { debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); resolve_associated_item( tcx, - def, + def_id, param_env, trait_def_id, tcx.normalize_erasing_regions(param_env, args), ) } else { - let ty = tcx.type_of(def); - let item_type = tcx.subst_and_normalize_erasing_regions(args, param_env, ty); + let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.is_intrinsic(def_id) { + debug!(" => intrinsic"); + ty::InstanceDef::Intrinsic(def_id) + } else if Some(def_id) == tcx.lang_items().drop_in_place_fn() { + let ty = args.type_at(0); - let def = match *item_type.kind() { - ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { - debug!(" => intrinsic"); - ty::InstanceDef::Intrinsic(def) - } - ty::FnDef(def_id, args) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => { - let ty = args.type_at(0); - - if ty.needs_drop(tcx, param_env) { - debug!(" => nontrivial drop glue"); - match *ty.kind() { - ty::Closure(..) - | ty::Generator(..) - | ty::Tuple(..) - | ty::Adt(..) - | ty::Dynamic(..) - | ty::Array(..) - | ty::Slice(..) => {} - // Drop shims can only be built from ADTs. - _ => return Ok(None), - } - - ty::InstanceDef::DropGlue(def_id, Some(ty)) - } else { - debug!(" => trivial drop glue"); - ty::InstanceDef::DropGlue(def_id, None) + if ty.needs_drop(tcx, param_env) { + debug!(" => nontrivial drop glue"); + match *ty.kind() { + ty::Closure(..) + | ty::Generator(..) + | ty::Tuple(..) + | ty::Adt(..) + | ty::Dynamic(..) + | ty::Array(..) + | ty::Slice(..) => {} + // Drop shims can only be built from ADTs. + _ => return Ok(None), } + + ty::InstanceDef::DropGlue(def_id, Some(ty)) + } else { + debug!(" => trivial drop glue"); + ty::InstanceDef::DropGlue(def_id, None) } - _ => { - debug!(" => free item"); - ty::InstanceDef::Item(def) - } + } else { + debug!(" => free item"); + ty::InstanceDef::Item(def_id) }; + Ok(Some(Instance { def, args })) }; debug!("inner_resolve_instance: result={:?}", result); diff --git a/tests/ui/inline-const/instance-doesnt-depend-on-type.rs b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs new file mode 100644 index 000000000000..bc739785c8bb --- /dev/null +++ b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs @@ -0,0 +1,10 @@ +// check-pass +// issue: 114660 + +#![feature(inline_const)] + +fn main() { + const { core::mem::transmute:: }; + // Don't resolve the instance of this inline constant to be an intrinsic, + // even if the type of the constant is `extern "intrinsic" fn(u8) -> u8`. +} From a549de1588f114a0400e21911806a124cd69fcc8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 10 Aug 2023 19:06:43 +0200 Subject: [PATCH 75/76] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index d577448dfb31..22a3d439861f 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -8e7fd551311d424e4e63fa45906a2a928fce96a7 +9fa6bdd764a1f7bdf69eccceeace6d13f38cb2e1 From 9281ddc64423c967a5c12280a1a6b84773ca46a3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 10 Aug 2023 19:31:08 +0200 Subject: [PATCH 76/76] add gamma function shims --- src/tools/miri/src/lib.rs | 1 + src/tools/miri/src/shims/foreign_items.rs | 24 ++++++++++++++++++++ src/tools/miri/tests/pass/intrinsics-math.rs | 19 ++++++++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 5327c2f24e06..39d30024a274 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -1,4 +1,5 @@ #![feature(rustc_private)] +#![feature(float_gamma)] #![feature(map_try_insert)] #![feature(never_type)] #![feature(try_blocks)] diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 167d1fd45188..efb62609fa9f 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -815,6 +815,7 @@ fn emulate_foreign_item_by_name( | "atanf" | "log1pf" | "expm1f" + | "tgammaf" => { let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; // FIXME: Using host floats. @@ -830,6 +831,7 @@ fn emulate_foreign_item_by_name( "atanf" => f.atan(), "log1pf" => f.ln_1p(), "expm1f" => f.exp_m1(), + "tgammaf" => f.gamma(), _ => bug!(), }; this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?; @@ -866,6 +868,7 @@ fn emulate_foreign_item_by_name( | "atan" | "log1p" | "expm1" + | "tgamma" => { let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; // FIXME: Using host floats. @@ -881,6 +884,7 @@ fn emulate_foreign_item_by_name( "atan" => f.atan(), "log1p" => f.ln_1p(), "expm1" => f.exp_m1(), + "tgamma" => f.gamma(), _ => bug!(), }; this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?; @@ -917,6 +921,26 @@ fn emulate_foreign_item_by_name( let res = x.scalbn(exp); this.write_scalar(Scalar::from_f64(res), dest)?; } + "lgammaf_r" => { + let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + // FIXME: Using host floats. + let x = f32::from_bits(this.read_scalar(x)?.to_u32()?); + let signp = this.deref_pointer(signp)?; + + let (res, sign) = x.ln_gamma(); + this.write_int(sign, &signp)?; + this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?; + } + "lgamma_r" => { + let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + // FIXME: Using host floats. + let x = f64::from_bits(this.read_scalar(x)?.to_u64()?); + let signp = this.deref_pointer(signp)?; + + let (res, sign) = x.ln_gamma(); + this.write_int(sign, &signp)?; + this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?; + } // Architecture-specific shims "llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => { diff --git a/src/tools/miri/tests/pass/intrinsics-math.rs b/src/tools/miri/tests/pass/intrinsics-math.rs index 9f2dc333f33e..e0e4f5654d6a 100644 --- a/src/tools/miri/tests/pass/intrinsics-math.rs +++ b/src/tools/miri/tests/pass/intrinsics-math.rs @@ -1,5 +1,4 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -// SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org) +#![feature(float_gamma)] macro_rules! assert_approx_eq { ($a:expr, $b:expr) => {{ @@ -130,4 +129,20 @@ pub fn main() { ); assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32); assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64); + + assert_approx_eq!(5.0f32.gamma(), 24.0); + assert_approx_eq!(5.0f64.gamma(), 24.0); + // These fail even on the host, precision seems to be terrible. + //assert_approx_eq!(-0.5f32.gamma(), -2.0 * f32::consts::PI.sqrt()); + //assert_approx_eq!(-0.5f64.gamma(), -2.0 * f64::consts::PI.sqrt()); + + assert_eq!(2.0f32.ln_gamma(), (0.0, 1)); + assert_eq!(2.0f64.ln_gamma(), (0.0, 1)); + // Gamma(-0.5) = -2*sqrt(π) + let (val, sign) = (-0.5f32).ln_gamma(); + assert_approx_eq!(val, (2.0 * f32::consts::PI.sqrt()).ln()); + assert_eq!(sign, -1); + let (val, sign) = (-0.5f64).ln_gamma(); + assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln()); + assert_eq!(sign, -1); }