Suggest named lifetime in ADT with hrtb
This commit is contained in:
parent
24be307b53
commit
bde96776a1
3 changed files with 87 additions and 10 deletions
|
@ -364,14 +364,52 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
match self.node() {
|
match self.node() {
|
||||||
hir::Node::Field(_)
|
hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => {
|
||||||
| hir::Node::Variant(_)
|
let item =
|
||||||
| hir::Node::Ctor(_)
|
self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(self.hir_id()));
|
||||||
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Struct(..), .. })
|
match &item.kind {
|
||||||
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(..), .. })
|
hir::ItemKind::Enum(_, generics)
|
||||||
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Union(..), .. }) => {
|
| hir::ItemKind::Struct(_, generics)
|
||||||
// The suggestion is only valid if this is not an ADT.
|
| hir::ItemKind::Union(_, generics) => {
|
||||||
|
// FIXME: look for an appropriate lt name if `'a` is already used
|
||||||
|
let (lt_sp, sugg) = match &generics.params[..] {
|
||||||
|
[] => (generics.span, "<'a>".to_string()),
|
||||||
|
[bound, ..] => (bound.span.shrink_to_lo(), "'a, ".to_string()),
|
||||||
|
};
|
||||||
|
let suggestions = vec![
|
||||||
|
(lt_sp, sugg),
|
||||||
|
(
|
||||||
|
span,
|
||||||
|
format!(
|
||||||
|
"{}::{}",
|
||||||
|
// Replace the existing lifetimes with a new named lifetime.
|
||||||
|
self.tcx
|
||||||
|
.replace_late_bound_regions(&poly_trait_ref, |_| {
|
||||||
|
self.tcx.mk_region(ty::ReEarlyBound(
|
||||||
|
ty::EarlyBoundRegion {
|
||||||
|
def_id: item_def_id,
|
||||||
|
index: 0,
|
||||||
|
name: Symbol::intern("'a"),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.0,
|
||||||
|
item_segment.ident
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
err.multipart_suggestion(
|
||||||
|
"use a fully qualified path with explicit lifetimes",
|
||||||
|
suggestions,
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::Struct(..), .. })
|
||||||
|
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(..), .. })
|
||||||
|
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Union(..), .. }) => {}
|
||||||
hir::Node::Item(_)
|
hir::Node::Item(_)
|
||||||
| hir::Node::ForeignItem(_)
|
| hir::Node::ForeignItem(_)
|
||||||
| hir::Node::TraitItem(_)
|
| hir::Node::TraitItem(_)
|
||||||
|
|
|
@ -12,6 +12,13 @@ struct SomeStruct<I : for<'x> Foo<&'x isize>> {
|
||||||
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
|
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SomeEnum<I: for<'x> Foo<&'x isize>> {
|
||||||
|
TupleVariant(I::A),
|
||||||
|
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
|
||||||
|
StructVariant { field: I::A },
|
||||||
|
//~^ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME(eddyb) This one doesn't even compile because of the unsupported syntax.
|
// FIXME(eddyb) This one doesn't even compile because of the unsupported syntax.
|
||||||
|
|
||||||
// struct AnotherStruct<I : for<'x> Foo<&'x isize>> {
|
// struct AnotherStruct<I : for<'x> Foo<&'x isize>> {
|
||||||
|
|
|
@ -3,6 +3,38 @@ error[E0212]: cannot extract an associated type from a higher-ranked trait bound
|
||||||
|
|
|
|
||||||
LL | field: I::A
|
LL | field: I::A
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
||||||
|
help: use a fully qualified path with explicit lifetimes
|
||||||
|
|
|
||||||
|
LL | struct SomeStruct<'a, I: for<'x> Foo<&'x isize>> {
|
||||||
|
LL | field: <I as Foo<&'a isize>>::A
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
|
||||||
|
--> $DIR/associated-types-project-from-hrtb-in-struct.rs:16:18
|
||||||
|
|
|
||||||
|
LL | TupleVariant(I::A),
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
help: use a fully qualified path with explicit lifetimes
|
||||||
|
|
|
||||||
|
LL | enum SomeEnum<'a, I: for<'x> Foo<&'x isize>> {
|
||||||
|
LL | TupleVariant(<I as Foo<&'a isize>>::A),
|
||||||
|
|
|
||||||
|
|
||||||
|
error[E0212]: cannot extract an associated type from a higher-ranked trait bound in this context
|
||||||
|
--> $DIR/associated-types-project-from-hrtb-in-struct.rs:18:28
|
||||||
|
|
|
||||||
|
LL | StructVariant { field: I::A },
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
help: use a fully qualified path with explicit lifetimes
|
||||||
|
|
|
||||||
|
LL | enum SomeEnum<'a, I: for<'x> Foo<&'x isize>> {
|
||||||
|
LL | TupleVariant(I::A),
|
||||||
|
LL |
|
||||||
|
LL | StructVariant { field: <I as Foo<&'a isize>>::A },
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue