diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 7077d78f459..63b653bc9f4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -333,7 +333,9 @@ pub(crate) fn add_explanation_to_diagnostic( } } - if let ConstraintCategory::Cast { unsize_to: Some(unsize_ty) } = category { + if let ConstraintCategory::Cast { is_coercion: true, unsize_to: Some(unsize_ty) } = + category + { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index ca0a3c66130..a4a9734de3f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -47,7 +47,8 @@ fn description(&self) -> &'static str { ConstraintCategory::Yield => "yielding this value ", ConstraintCategory::UseAsConst => "using this value as a constant ", ConstraintCategory::UseAsStatic => "using this value as a static ", - ConstraintCategory::Cast { .. } => "cast ", + ConstraintCategory::Cast { is_coercion: false, .. } => "cast ", + ConstraintCategory::Cast { is_coercion: true, .. } => "coercion ", ConstraintCategory::CallArgument(_) => "argument ", ConstraintCategory::TypeAnnotation => "type annotation ", ConstraintCategory::ClosureBounds => "closure body ", diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 29a0c5bdf57..db69f48e515 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2007,7 +2007,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); let src_ty = self.normalize(src_ty, location); @@ -2015,7 +2015,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2036,7 +2036,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); // The type that we see in the fcx is like @@ -2049,7 +2049,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2074,7 +2074,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2103,7 +2103,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2128,6 +2128,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L trait_ref, location.to_locations(), ConstraintCategory::Cast { + is_coercion: true, unsize_to: Some(tcx.fold_regions(ty, |r, _| { if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased @@ -2155,7 +2156,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L .iter() .map(|predicate| predicate.with_self_ty(tcx, self_ty)), location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); let outlives_predicate = tcx.mk_predicate(Binder::dummy( @@ -2166,7 +2167,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L self.prove_predicate( outlives_predicate, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ); } @@ -2184,7 +2185,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L *ty_from, *ty_to, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2246,7 +2247,7 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L *ty_elem, *ty_to, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { is_coercion: true, unsize_to: None }, ) { span_mirbug!( self, @@ -2427,7 +2428,10 @@ fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: L src_obj, dst_obj, location.to_locations(), - ConstraintCategory::Cast { unsize_to: None }, + ConstraintCategory::Cast { + is_coercion: false, + unsize_to: None, + }, ) .unwrap(); } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 1002f64f849..47fea6f6d90 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -234,7 +234,9 @@ pub enum ConstraintCategory<'tcx> { UseAsStatic, TypeAnnotation, Cast { - /// Whether this is an unsizing cast and if yes, this contains the target type. + /// Whether this cast is a coercion. + is_coercion: bool, + /// Whether this is an unsizing coercion and if yes, this contains the target type. /// Region variables are erased to ReErased. #[derive_where(skip)] unsize_to: Option>, diff --git a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr index b3bf2f924fc..89b15a7a659 100644 --- a/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr +++ b/tests/ui/borrowck/two-phase-surprise-no-conflict.stderr @@ -75,7 +75,7 @@ LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut))); | ^^^^^^^^^^^^^^^^^^-----------------------------------------^ | | | | | | | immutable borrow occurs here - | | cast requires that `reg.sess_mut` is borrowed for `'a` + | | coercion requires that `reg.sess_mut` is borrowed for `'a` | mutable borrow occurs here | = note: due to object lifetime defaults, `Box LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>` @@ -119,7 +119,7 @@ LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut))); | ^^^^^^^^^^^^^^^^^^-------------------------------------------------^ | | | | | | | first mutable borrow occurs here - | | cast requires that `reg.sess_mut` is borrowed for `'a` + | | coercion requires that `reg.sess_mut` is borrowed for `'a` | second mutable borrow occurs here | = note: due to object lifetime defaults, `Box LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>` diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index 4a699780c64..6069f4f3b55 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -138,7 +138,7 @@ error: lifetime may not live long enough LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) { | -- lifetime `'a` defined here LL | require_static(ptr as _) - | ^^^ cast requires that `'a` must outlive `'static` + | ^^^^^^^^ cast requires that `'a` must outlive `'static` error: aborting due to 9 previous errors diff --git a/tests/ui/dropck/dropck_trait_cycle_checked.stderr b/tests/ui/dropck/dropck_trait_cycle_checked.stderr index 63fd07a9163..f32736f1a67 100644 --- a/tests/ui/dropck/dropck_trait_cycle_checked.stderr +++ b/tests/ui/dropck/dropck_trait_cycle_checked.stderr @@ -2,7 +2,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:111:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` LL | o1.set0(&o2); | ^^^ borrowed value does not live long enough ... @@ -15,7 +15,7 @@ error[E0597]: `o3` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:112:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o3` declared here -------- cast requires that `o3` is borrowed for `'static` + | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` LL | o1.set0(&o2); LL | o1.set1(&o3); | ^^^ borrowed value does not live long enough @@ -29,7 +29,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:113:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` ... LL | o2.set0(&o2); | ^^^ borrowed value does not live long enough @@ -43,7 +43,7 @@ error[E0597]: `o3` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:114:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o3` declared here -------- cast requires that `o3` is borrowed for `'static` + | -- binding `o3` declared here -------- coercion requires that `o3` is borrowed for `'static` ... LL | o2.set1(&o3); | ^^^ borrowed value does not live long enough @@ -57,7 +57,7 @@ error[E0597]: `o1` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:115:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o1` declared here -------- cast requires that `o1` is borrowed for `'static` + | -- binding `o1` declared here -------- coercion requires that `o1` is borrowed for `'static` ... LL | o3.set0(&o1); | ^^^ borrowed value does not live long enough @@ -71,7 +71,7 @@ error[E0597]: `o2` does not live long enough --> $DIR/dropck_trait_cycle_checked.rs:116:13 | LL | let (o1, o2, o3): (Box, Box, Box) = (O::new(), O::new(), O::new()); - | -- binding `o2` declared here -------- cast requires that `o2` is borrowed for `'static` + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` ... LL | o3.set1(&o2); | ^^^ borrowed value does not live long enough diff --git a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr index 598f1424191..6bd6a0584c9 100644 --- a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr +++ b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr @@ -7,7 +7,7 @@ LL | let refcell = RefCell::new(&mut foo); | ^^^^^^^^ borrowed value does not live long enough LL | LL | let read = &refcell as &RefCell; - | -------- cast requires that `foo` is borrowed for `'static` + | -------- coercion requires that `foo` is borrowed for `'static` ... LL | } | - `foo` dropped here while still borrowed @@ -19,7 +19,7 @@ LL | fn inner(mut foo: &[u8]) { | - let's call the lifetime of this reference `'1` ... LL | let read = &refcell as &RefCell; - | ^^^^^^^^ cast requires that `'1` must outlive `'static` + | ^^^^^^^^ coercion requires that `'1` must outlive `'static` error: aborting due to 2 previous errors diff --git a/tests/ui/nll/issue-54779-anon-static-lifetime.stderr b/tests/ui/nll/issue-54779-anon-static-lifetime.stderr index 92298c6617f..a454ed26568 100644 --- a/tests/ui/nll/issue-54779-anon-static-lifetime.stderr +++ b/tests/ui/nll/issue-54779-anon-static-lifetime.stderr @@ -5,7 +5,7 @@ LL | cx: &dyn DebugContext, | - let's call the lifetime of this reference `'1` ... LL | bar.debug_with(cx); - | ^^ cast requires that `'1` must outlive `'static` + | ^^ coercion requires that `'1` must outlive `'static` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr b/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr index 73fa5ddb146..050ef7da9b9 100644 --- a/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr +++ b/tests/ui/suggestions/lifetimes/suggest-using-tick-underscore-lifetime-in-return-trait-object.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | fn foo(value: &T) -> Box { | - let's call the lifetime of this reference `'1` LL | Box::new(value) as Box - | ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static` + | ^^^^^^^^^^^^^^^ coercion requires that `'1` must outlive `'static` | help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | diff --git a/tests/ui/traits/trait-object-lifetime-default-note.rs b/tests/ui/traits/trait-object-lifetime-default-note.rs index 31e3eb4ba41..275411ff61c 100644 --- a/tests/ui/traits/trait-object-lifetime-default-note.rs +++ b/tests/ui/traits/trait-object-lifetime-default-note.rs @@ -8,7 +8,7 @@ fn main() { //~| NOTE borrowed value does not live long enough //~| NOTE due to object lifetime defaults, `Box` actually means `Box<(dyn A + 'static)>` require_box(Box::new(r)); - //~^ NOTE cast requires that `local` is borrowed for `'static` + //~^ NOTE coercion requires that `local` is borrowed for `'static` let _ = 0; } //~ NOTE `local` dropped here while still borrowed diff --git a/tests/ui/traits/trait-object-lifetime-default-note.stderr b/tests/ui/traits/trait-object-lifetime-default-note.stderr index 4244e34873a..8cb9bc0d800 100644 --- a/tests/ui/traits/trait-object-lifetime-default-note.stderr +++ b/tests/ui/traits/trait-object-lifetime-default-note.stderr @@ -7,7 +7,7 @@ LL | let r = &local; | ^^^^^^ borrowed value does not live long enough ... LL | require_box(Box::new(r)); - | ----------- cast requires that `local` is borrowed for `'static` + | ----------- coercion requires that `local` is borrowed for `'static` ... LL | } | - `local` dropped here while still borrowed