diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 8b8cff0dbbe64..e33035381e0a9 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>, + origin: Option>, 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 5af76b5d610db..229b69b92e68e 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 0000000000000..6c2505177fef8 --- /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 016d7c3b7ef21..bce35cbdd0d38 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::{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 c9b3f61254484..a32004cda1a6f 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::{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