Report diagnostics at the actually actionable site
This commit is contained in:
parent
e237aaef25
commit
59e285ff34
@ -2314,7 +2314,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
generic_param_scope: LocalDefId,
|
generic_param_scope: LocalDefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
mut origin: Option<SubregionOrigin<'tcx>>,
|
origin: Option<SubregionOrigin<'tcx>>,
|
||||||
bound_kind: GenericKind<'tcx>,
|
bound_kind: GenericKind<'tcx>,
|
||||||
sub: Region<'tcx>,
|
sub: Region<'tcx>,
|
||||||
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||||
@ -2349,14 +2349,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
None
|
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,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -336,6 +336,7 @@ where
|
|||||||
GenericKind::Opaque(def_id, substs),
|
GenericKind::Opaque(def_id, substs),
|
||||||
def_id,
|
def_id,
|
||||||
substs,
|
substs,
|
||||||
|
true,
|
||||||
|ty| match *ty.kind() {
|
|ty| match *ty.kind() {
|
||||||
ty::Opaque(def_id, substs) => (def_id, substs),
|
ty::Opaque(def_id, substs) => (def_id, substs),
|
||||||
_ => bug!("expected only projection types from env, not {:?}", ty),
|
_ => bug!("expected only projection types from env, not {:?}", ty),
|
||||||
@ -356,6 +357,7 @@ where
|
|||||||
GenericKind::Projection(projection_ty),
|
GenericKind::Projection(projection_ty),
|
||||||
projection_ty.item_def_id,
|
projection_ty.item_def_id,
|
||||||
projection_ty.substs,
|
projection_ty.substs,
|
||||||
|
false,
|
||||||
|ty| match ty.kind() {
|
|ty| match ty.kind() {
|
||||||
ty::Projection(projection_ty) => (projection_ty.item_def_id, projection_ty.substs),
|
ty::Projection(projection_ty) => (projection_ty.item_def_id, projection_ty.substs),
|
||||||
_ => bug!("expected only projection types from env, not {:?}", ty),
|
_ => bug!("expected only projection types from env, not {:?}", ty),
|
||||||
@ -371,6 +373,7 @@ where
|
|||||||
generic: GenericKind<'tcx>,
|
generic: GenericKind<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
|
is_opaque: bool,
|
||||||
filter: impl Fn(Ty<'tcx>) -> (DefId, SubstsRef<'tcx>),
|
filter: impl Fn(Ty<'tcx>) -> (DefId, SubstsRef<'tcx>),
|
||||||
) {
|
) {
|
||||||
// An optimization for a common case with opaque types.
|
// An optimization for a common case with opaque types.
|
||||||
@ -437,7 +440,7 @@ where
|
|||||||
// inference variables, we use a verify constraint instead of adding
|
// inference variables, we use a verify constraint instead of adding
|
||||||
// edges, which winds up enforcing the same condition.
|
// edges, which winds up enforcing the same condition.
|
||||||
let needs_infer = substs.needs_infer();
|
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");
|
debug!("no declared bounds");
|
||||||
|
|
||||||
self.substs_must_outlive(substs, origin, region);
|
self.substs_must_outlive(substs, origin, region);
|
||||||
|
25
src/test/ui/impl-trait/unactionable_diagnostic.fixed
Normal file
25
src/test/ui/impl-trait/unactionable_diagnostic.fixed
Normal file
@ -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() {}
|
@ -1,23 +1,25 @@
|
|||||||
trait Trait {}
|
// run-rustfix
|
||||||
|
|
||||||
struct Foo;
|
pub trait Trait {}
|
||||||
|
|
||||||
|
pub struct Foo;
|
||||||
|
|
||||||
impl Trait for Foo {}
|
impl Trait for Foo {}
|
||||||
|
|
||||||
fn foo<'x, P>(
|
fn foo<'x, P>(
|
||||||
post: P,
|
_post: P,
|
||||||
x: &'x Foo,
|
x: &'x Foo,
|
||||||
) -> &'x impl Trait {
|
) -> &'x impl Trait {
|
||||||
//~^ HELP: consider adding an explicit lifetime bound...
|
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bar<'t, T>(
|
pub fn bar<'t, T>(
|
||||||
|
//~^ HELP: consider adding an explicit lifetime bound...
|
||||||
post: T,
|
post: T,
|
||||||
x: &'t Foo,
|
x: &'t Foo,
|
||||||
) -> &'t impl Trait {
|
) -> &'t impl Trait {
|
||||||
foo(post, x)
|
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() {}
|
fn main() {}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
error[E0309]: the opaque type `foo<T>::{opaque#0}` may not live long enough
|
error[E0309]: the parameter type `T` may not live long enough
|
||||||
--> $DIR/unactionable_diagnostic.rs:19:5
|
--> $DIR/unactionable_diagnostic.rs:21:5
|
||||||
|
|
|
|
||||||
LL | foo(post, x)
|
LL | foo(post, x)
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
||||||
|
|
|
|
||||||
help: consider adding an explicit lifetime bound...
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user