about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs10
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs5
-rw-r--r--src/test/ui/impl-trait/unactionable_diagnostic.fixed25
-rw-r--r--src/test/ui/impl-trait/unactionable_diagnostic.rs14
-rw-r--r--src/test/ui/impl-trait/unactionable_diagnostic.stderr10
5 files changed, 43 insertions, 21 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 8b8cff0dbbe..e33035381e0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2314,7 +2314,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         &self,
         generic_param_scope: LocalDefId,
         span: Span,
-        mut origin: Option<SubregionOrigin<'tcx>>,
+        origin: Option<SubregionOrigin<'tcx>>,
         bound_kind: GenericKind<'tcx>,
         sub: Region<'tcx>,
     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
@@ -2349,14 +2349,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     None
                 }
             }
-            GenericKind::Opaque(def_id, _substs) => {
-                // Avoid emitting a `... so that the type` message at the error site.
-                // It would be out of order for return position impl trait
-                origin = None;
-                // Make sure the lifetime suggestion is on the RPIT instead of proposing
-                // to add a bound for opaque types (which isn't possible)
-                Some((self.tcx.def_span(def_id).shrink_to_hi(), true))
-            }
             _ => None,
         };
 
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 5af76b5d610..229b69b92e6 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -336,6 +336,7 @@ where
             GenericKind::Opaque(def_id, substs),
             def_id,
             substs,
+            true,
             |ty| match *ty.kind() {
                 ty::Opaque(def_id, substs) => (def_id, substs),
                 _ => bug!("expected only projection types from env, not {:?}", ty),
@@ -356,6 +357,7 @@ where
             GenericKind::Projection(projection_ty),
             projection_ty.item_def_id,
             projection_ty.substs,
+            false,
             |ty| match ty.kind() {
                 ty::Projection(projection_ty) => (projection_ty.item_def_id, projection_ty.substs),
                 _ => bug!("expected only projection types from env, not {:?}", ty),
@@ -371,6 +373,7 @@ where
         generic: GenericKind<'tcx>,
         def_id: DefId,
         substs: SubstsRef<'tcx>,
+        is_opaque: bool,
         filter: impl Fn(Ty<'tcx>) -> (DefId, SubstsRef<'tcx>),
     ) {
         // An optimization for a common case with opaque types.
@@ -437,7 +440,7 @@ where
         // inference variables, we use a verify constraint instead of adding
         // edges, which winds up enforcing the same condition.
         let needs_infer = substs.needs_infer();
-        if approx_env_bounds.is_empty() && trait_bounds.is_empty() && needs_infer {
+        if approx_env_bounds.is_empty() && trait_bounds.is_empty() && (needs_infer || is_opaque) {
             debug!("no declared bounds");
 
             self.substs_must_outlive(substs, origin, region);
diff --git a/src/test/ui/impl-trait/unactionable_diagnostic.fixed b/src/test/ui/impl-trait/unactionable_diagnostic.fixed
new file mode 100644
index 00000000000..6c2505177fe
--- /dev/null
+++ b/src/test/ui/impl-trait/unactionable_diagnostic.fixed
@@ -0,0 +1,25 @@
+// run-rustfix
+
+pub trait Trait {}
+
+pub struct Foo;
+
+impl Trait for Foo {}
+
+fn foo<'x, P>(
+    _post: P,
+    x: &'x Foo,
+) -> &'x impl Trait {
+    x
+}
+
+pub fn bar<'t, T: 't>(
+    //~^ HELP: consider adding an explicit lifetime bound...
+    post: T,
+    x: &'t Foo,
+) -> &'t impl Trait {
+    foo(post, x)
+    //~^ ERROR: the parameter type `T` may not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/unactionable_diagnostic.rs b/src/test/ui/impl-trait/unactionable_diagnostic.rs
index 016d7c3b7ef..bce35cbdd0d 100644
--- a/src/test/ui/impl-trait/unactionable_diagnostic.rs
+++ b/src/test/ui/impl-trait/unactionable_diagnostic.rs
@@ -1,23 +1,25 @@
-trait Trait {}
+// run-rustfix
 
-struct Foo;
+pub trait Trait {}
+
+pub struct Foo;
 
 impl Trait for Foo {}
 
 fn foo<'x, P>(
-    post: P,
+    _post: P,
     x: &'x Foo,
 ) -> &'x impl Trait {
-    //~^ HELP: consider adding an explicit lifetime bound...
     x
 }
 
-fn bar<'t, T>(
+pub fn bar<'t, T>(
+    //~^ HELP: consider adding an explicit lifetime bound...
     post: T,
     x: &'t Foo,
 ) -> &'t impl Trait {
     foo(post, x)
-    //~^ ERROR: the opaque type `foo<T>::{opaque#0}` may not live long enough
+    //~^ ERROR: the parameter type `T` may not live long enough
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/unactionable_diagnostic.stderr b/src/test/ui/impl-trait/unactionable_diagnostic.stderr
index c9b3f612544..a32004cda1a 100644
--- a/src/test/ui/impl-trait/unactionable_diagnostic.stderr
+++ b/src/test/ui/impl-trait/unactionable_diagnostic.stderr
@@ -1,13 +1,13 @@
-error[E0309]: the opaque type `foo<T>::{opaque#0}` may not live long enough
-  --> $DIR/unactionable_diagnostic.rs:19:5
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/unactionable_diagnostic.rs:21:5
    |
 LL |     foo(post, x)
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
    |
 help: consider adding an explicit lifetime bound...
    |
-LL | ) -> &'x impl Trait + 't {
-   |                     ++++
+LL | pub fn bar<'t, T: 't>(
+   |                 ++++
 
 error: aborting due to previous error