1
Fork 0

best_blame_constraint: add a special case to recover object lifetime default notes

This commit is contained in:
dianne 2024-12-12 08:45:32 -08:00
parent ac922245f0
commit 2864906fce
6 changed files with 51 additions and 38 deletions

View file

@ -1945,7 +1945,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
target_test: impl Fn(RegionVid) -> bool, target_test: impl Fn(RegionVid) -> bool,
) -> (BlameConstraint<'tcx>, Vec<OutlivesConstraint<'tcx>>) { ) -> (BlameConstraint<'tcx>, Vec<OutlivesConstraint<'tcx>>) {
// Find all paths // Find all paths
let (path, _) = self let (path, target_region) = self
.find_constraint_paths_between_regions(from_region, target_test) .find_constraint_paths_between_regions(from_region, target_test)
.or_else(|| { .or_else(|| {
self.find_constraint_paths_between_regions(from_region, |r| { 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], Some(i) => path[i],
None => { None => {

View file

@ -2,87 +2,83 @@ error[E0597]: `o2` does not live long enough
--> $DIR/dropck_trait_cycle_checked.rs:111:13 --> $DIR/dropck_trait_cycle_checked.rs:111:13
| |
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new()); LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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); LL | o1.set0(&o2);
| ^^^ borrowed value does not live long enough | ^^^ borrowed value does not live long enough
... ...
LL | o3.set0(&o1);
| ------------ argument requires that `o2` is borrowed for `'static`
LL | o3.set1(&o2);
LL | } LL | }
| - `o2` dropped here while still borrowed | - `o2` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
error[E0597]: `o3` does not live long enough error[E0597]: `o3` does not live long enough
--> $DIR/dropck_trait_cycle_checked.rs:112:13 --> $DIR/dropck_trait_cycle_checked.rs:112:13
| |
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new()); LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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.set0(&o2);
LL | o1.set1(&o3); LL | o1.set1(&o3);
| ^^^ borrowed value does not live long enough | ^^^ borrowed value does not live long enough
... ...
LL | o3.set0(&o1);
| ------------ argument requires that `o3` is borrowed for `'static`
LL | o3.set1(&o2);
LL | } LL | }
| - `o3` dropped here while still borrowed | - `o3` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
error[E0597]: `o2` does not live long enough error[E0597]: `o2` does not live long enough
--> $DIR/dropck_trait_cycle_checked.rs:113:13 --> $DIR/dropck_trait_cycle_checked.rs:113:13
| |
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new()); LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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); ...
| ------------ argument requires that `o2` is borrowed for `'static`
LL | o1.set1(&o3);
LL | o2.set0(&o2); LL | o2.set0(&o2);
| ^^^ borrowed value does not live long enough | ^^^ borrowed value does not live long enough
... ...
LL | } LL | }
| - `o2` dropped here while still borrowed | - `o2` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
error[E0597]: `o3` does not live long enough error[E0597]: `o3` does not live long enough
--> $DIR/dropck_trait_cycle_checked.rs:114:13 --> $DIR/dropck_trait_cycle_checked.rs:114:13
| |
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new()); LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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);
| ------------ argument requires that `o3` is borrowed for `'static`
... ...
LL | o2.set1(&o3); LL | o2.set1(&o3);
| ^^^ borrowed value does not live long enough | ^^^ borrowed value does not live long enough
... ...
LL | } LL | }
| - `o3` dropped here while still borrowed | - `o3` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
error[E0597]: `o1` does not live long enough error[E0597]: `o1` does not live long enough
--> $DIR/dropck_trait_cycle_checked.rs:115:13 --> $DIR/dropck_trait_cycle_checked.rs:115:13
| |
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new()); LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
| -- binding `o1` declared here | -- binding `o1` declared here -------- coercion requires that `o1` is borrowed for `'static`
LL | o1.set0(&o2);
LL | o1.set1(&o3);
| ------------ argument requires that `o1` is borrowed for `'static`
... ...
LL | o3.set0(&o1); LL | o3.set0(&o1);
| ^^^ borrowed value does not live long enough | ^^^ borrowed value does not live long enough
LL | o3.set1(&o2); LL | o3.set1(&o2);
LL | } LL | }
| - `o1` dropped here while still borrowed | - `o1` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
error[E0597]: `o2` does not live long enough error[E0597]: `o2` does not live long enough
--> $DIR/dropck_trait_cycle_checked.rs:116:13 --> $DIR/dropck_trait_cycle_checked.rs:116:13
| |
LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new()); LL | let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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);
LL | o1.set1(&o3);
| ------------ argument requires that `o2` is borrowed for `'static`
... ...
LL | o3.set1(&o2); LL | o3.set1(&o2);
| ^^^ borrowed value does not live long enough | ^^^ borrowed value does not live long enough
LL | } LL | }
| - `o2` dropped here while still borrowed | - `o2` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn Obj<'_>>` actually means `Box<(dyn Obj<'_> + 'static)>`
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -29,7 +29,7 @@ impl DebugWith<dyn DebugContext> for Foo {
fmt: &mut std::fmt::Formatter<'_>, fmt: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result { ) -> std::fmt::Result {
let Foo { bar } = self; 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(()) Ok(())
} }
} }

View file

@ -1,17 +1,11 @@
error[E0521]: borrowed data escapes outside of method error: lifetime may not live long enough
--> $DIR/issue-54779-anon-static-lifetime.rs:32:9 --> $DIR/issue-54779-anon-static-lifetime.rs:32:24
| |
LL | cx: &dyn DebugContext, LL | cx: &dyn DebugContext,
| -- - let's call the lifetime of this reference `'1` | - let's call the lifetime of this reference `'1`
| |
| `cx` is a reference that is only valid in the method body
... ...
LL | bar.debug_with(cx); LL | bar.debug_with(cx);
| ^^^^^^^^^^^^^^^^^^ | ^^ coercion requires that `'1` must outlive `'static`
| |
| `cx` escapes the method body here
| argument requires that `'1` must outlive `'static`
error: aborting due to 1 previous error error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0521`.

View file

@ -6,8 +6,9 @@ fn main() {
let local = 0; //~ NOTE binding `local` declared here let local = 0; //~ NOTE binding `local` declared here
let r = &local; //~ ERROR `local` does not live long enough let r = &local; //~ ERROR `local` does not live long enough
//~| NOTE borrowed value does not live long enough //~| NOTE borrowed value does not live long enough
//~| NOTE due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
require_box(Box::new(r)); 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; let _ = 0;
} //~ NOTE `local` dropped here while still borrowed } //~ NOTE `local` dropped here while still borrowed

View file

@ -5,12 +5,14 @@ LL | let local = 0;
| ----- binding `local` declared here | ----- binding `local` declared here
LL | let r = &local; LL | let r = &local;
| ^^^^^^ borrowed value does not live long enough | ^^^^^^ borrowed value does not live long enough
LL | ...
LL | require_box(Box::new(r)); LL | require_box(Box::new(r));
| ------------------------ argument requires that `local` is borrowed for `'static` | ----------- coercion requires that `local` is borrowed for `'static`
... ...
LL | } LL | }
| - `local` dropped here while still borrowed | - `local` dropped here while still borrowed
|
= note: due to object lifetime defaults, `Box<dyn A>` actually means `Box<(dyn A + 'static)>`
error: aborting due to 1 previous error error: aborting due to 1 previous error