about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs22
-rw-r--r--tests/ui/dropck/dropck_trait_cycle_checked.stderr42
-rw-r--r--tests/ui/nll/issue-54779-anon-static-lifetime.rs2
-rw-r--r--tests/ui/nll/issue-54779-anon-static-lifetime.stderr14
-rw-r--r--tests/ui/traits/trait-object-lifetime-default-note.rs3
-rw-r--r--tests/ui/traits/trait-object-lifetime-default-note.stderr6
6 files changed, 51 insertions, 38 deletions
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<OutlivesConstraint<'tcx>>) {
         // 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<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);
    |             ^^^ 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<dyn Obj<'_>>` 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<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.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<dyn Obj<'_>>` 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<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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<dyn Obj<'_>>` 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<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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<dyn Obj<'_>>` 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<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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<dyn Obj<'_>>` 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<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (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<dyn Obj<'_>>` 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<dyn DebugContext> 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<dyn A>` 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<dyn A>` actually means `Box<(dyn A + 'static)>`
 
 error: aborting due to 1 previous error