1
Fork 0

Require impl Trait in associated types to appear in method signatures

This commit is contained in:
Oli Scherer 2023-04-17 10:19:41 +00:00
parent 699a862a3d
commit f08b517597
20 changed files with 242 additions and 53 deletions

View file

@ -305,7 +305,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
}
Some(ty) => this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy),
Some(ty) => this.lower_ty(
ty,
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
),
},
);
hir::ItemKind::TyAlias(ty, generics)
@ -852,7 +855,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Type(ty)
}
Some(ty) => {
let ty = this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy);
let ty = this.lower_ty(
ty,
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
);
hir::ImplItemKind::Type(ty)
}
},

View file

@ -247,7 +247,7 @@ enum ImplTraitContext {
in_trait: bool,
},
/// Impl trait in type aliases.
TypeAliasesOpaqueTy,
TypeAliasesOpaqueTy { in_assoc_ty: bool },
/// `impl Trait` is unstably accepted in this position.
FeatureGated(ImplTraitPosition, Symbol),
/// `impl Trait` is not accepted in this position.
@ -1407,14 +1407,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
*in_trait,
itctx,
),
ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait(
span,
hir::OpaqueTyOrigin::TyAlias,
*def_node_id,
bounds,
false,
itctx,
),
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
.lower_opaque_impl_trait(
span,
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
*def_node_id,
bounds,
false,
itctx,
),
ImplTraitContext::Universal => {
let span = t.span;
self.create_def(
@ -1534,13 +1535,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
// to capture the lifetimes that appear in the bounds. So visit the bounds to find out
// exactly which ones those are.
let lifetimes_to_remap = if origin == hir::OpaqueTyOrigin::TyAlias {
// in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
Vec::new()
} else {
// in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
// we only keep the lifetimes that appear in the `impl Debug` itself:
lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
let lifetimes_to_remap = match origin {
hir::OpaqueTyOrigin::TyAlias { .. } => {
// in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
Vec::new()
}
hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..) => {
// in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
// we only keep the lifetimes that appear in the `impl Debug` itself:
lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
}
};
debug!(?lifetimes_to_remap);