diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 4c2aeace67e..7ec692d36b1 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1945,7 +1945,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { target_test: impl Fn(RegionVid) -> bool, ) -> (BlameConstraint<'tcx>, Vec>) { // Find all paths - let (path, _) = self + let (path, target_region) = self .find_constraint_paths_between_regions(from_region, target_test) .or_else(|| { self.find_constraint_paths_between_regions(from_region, |r| { @@ -2071,6 +2071,26 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + Some(_) + if target_region == self.universal_regions().fr_static + && let Some(old_best) = path.iter().min_by_key(|p| p.category) + && matches!(old_best.category, ConstraintCategory::Cast { + is_implicit_coercion: true, + unsize_to: Some(_) + }) => + { + // FIXME(dianne): This is a hack in order to emit the subdiagnostic + // `BorrowExplanation::add_object_lifetime_default_note` more often, e.g. on + // `tests/ui/traits/trait-object-lifetime-default-note.rs`. The subdiagnostic + // depends on a coercion being blamed, so we fall back to an earlier version of this + // function's blaming logic to keep the test result the same. A proper fix will + // require rewriting the subdiagnostic not to rely on a coercion being blamed. + // For examples of where notes are missing, see #131008 and + // `tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs`. + // As part of fixing those, this case should be removed. + *old_best + } + Some(i) => path[i], None => { diff --git a/tests/ui/dropck/dropck_trait_cycle_checked.stderr b/tests/ui/dropck/dropck_trait_cycle_checked.stderr index e595e98fa2e..f32736f1a67 100644 --- a/tests/ui/dropck/dropck_trait_cycle_checked.stderr +++ b/tests/ui/dropck/dropck_trait_cycle_checked.stderr @@ -2,87 +2,83 @@ 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 + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` LL | o1.set0(&o2); | ^^^ borrowed value does not live long enough ... -LL | o3.set0(&o1); - | ------------ argument requires that `o2` is borrowed for `'static` -LL | o3.set1(&o2); LL | } | - `o2` dropped here while still borrowed + | + = note: due to object lifetime defaults, `Box>` actually means `Box<(dyn Obj<'_> + 'static)>` 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 + | -- 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 ... -LL | o3.set0(&o1); - | ------------ argument requires that `o3` is borrowed for `'static` -LL | o3.set1(&o2); LL | } | - `o3` dropped here while still borrowed + | + = note: due to object lifetime defaults, `Box>` actually means `Box<(dyn Obj<'_> + 'static)>` 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 -LL | o1.set0(&o2); - | ------------ argument requires that `o2` is borrowed for `'static` -LL | o1.set1(&o3); + | -- binding `o2` declared here -------- coercion requires that `o2` is borrowed for `'static` +... LL | o2.set0(&o2); | ^^^ borrowed value does not live long enough ... LL | } | - `o2` dropped here while still borrowed + | + = note: due to object lifetime defaults, `Box>` actually means `Box<(dyn Obj<'_> + 'static)>` 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 -LL | o1.set0(&o2); - | ------------ argument 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 ... LL | } | - `o3` dropped here while still borrowed + | + = note: due to object lifetime defaults, `Box>` actually means `Box<(dyn Obj<'_> + 'static)>` 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 -LL | o1.set0(&o2); -LL | o1.set1(&o3); - | ------------ argument 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 LL | o3.set1(&o2); LL | } | - `o1` dropped here while still borrowed + | + = note: due to object lifetime defaults, `Box>` actually means `Box<(dyn Obj<'_> + 'static)>` 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 -LL | o1.set0(&o2); -LL | o1.set1(&o3); - | ------------ argument 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 LL | } | - `o2` dropped here while still borrowed + | + = note: due to object lifetime defaults, `Box>` actually means `Box<(dyn Obj<'_> + 'static)>` error: aborting due to 6 previous errors diff --git a/tests/ui/nll/issue-54779-anon-static-lifetime.rs b/tests/ui/nll/issue-54779-anon-static-lifetime.rs index 3a92b9709a1..1dab7c1712a 100644 --- a/tests/ui/nll/issue-54779-anon-static-lifetime.rs +++ b/tests/ui/nll/issue-54779-anon-static-lifetime.rs @@ -29,7 +29,7 @@ impl DebugWith for Foo { fmt: &mut std::fmt::Formatter<'_>, ) -> std::fmt::Result { let Foo { bar } = self; - bar.debug_with(cx); //~ ERROR borrowed data escapes outside of method [E0521] + bar.debug_with(cx); //~ lifetime may not live long enough Ok(()) } } diff --git a/tests/ui/nll/issue-54779-anon-static-lifetime.stderr b/tests/ui/nll/issue-54779-anon-static-lifetime.stderr index 03a55906614..a454ed26568 100644 --- a/tests/ui/nll/issue-54779-anon-static-lifetime.stderr +++ b/tests/ui/nll/issue-54779-anon-static-lifetime.stderr @@ -1,17 +1,11 @@ -error[E0521]: borrowed data escapes outside of method - --> $DIR/issue-54779-anon-static-lifetime.rs:32:9 +error: lifetime may not live long enough + --> $DIR/issue-54779-anon-static-lifetime.rs:32:24 | LL | cx: &dyn DebugContext, - | -- - let's call the lifetime of this reference `'1` - | | - | `cx` is a reference that is only valid in the method body + | - let's call the lifetime of this reference `'1` ... LL | bar.debug_with(cx); - | ^^^^^^^^^^^^^^^^^^ - | | - | `cx` escapes the method body here - | argument requires that `'1` must outlive `'static` + | ^^ coercion requires that `'1` must outlive `'static` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/traits/trait-object-lifetime-default-note.rs b/tests/ui/traits/trait-object-lifetime-default-note.rs index 5d8d2c53919..275411ff61c 100644 --- a/tests/ui/traits/trait-object-lifetime-default-note.rs +++ b/tests/ui/traits/trait-object-lifetime-default-note.rs @@ -6,8 +6,9 @@ fn main() { let local = 0; //~ NOTE binding `local` declared here let r = &local; //~ ERROR `local` does not live long enough //~| 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 argument 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 9a97704f493..8cb9bc0d800 100644 --- a/tests/ui/traits/trait-object-lifetime-default-note.stderr +++ b/tests/ui/traits/trait-object-lifetime-default-note.stderr @@ -5,12 +5,14 @@ LL | let local = 0; | ----- binding `local` declared here LL | let r = &local; | ^^^^^^ borrowed value does not live long enough -LL | +... LL | require_box(Box::new(r)); - | ------------------------ argument requires that `local` is borrowed for `'static` + | ----------- coercion requires that `local` is borrowed for `'static` ... LL | } | - `local` dropped here while still borrowed + | + = note: due to object lifetime defaults, `Box` actually means `Box<(dyn A + 'static)>` error: aborting due to 1 previous error