Replace RPITIT current impl with new strategy that lowers as a GAT
This commit is contained in:
parent
d1389b9b48
commit
20429af7a3
146 changed files with 1106 additions and 586 deletions
|
@ -109,8 +109,6 @@ pub enum DefKind {
|
|||
InlineConst,
|
||||
/// Opaque type, aka `impl Trait`.
|
||||
OpaqueTy,
|
||||
/// A return-position `impl Trait` in a trait definition
|
||||
ImplTraitPlaceholder,
|
||||
Field,
|
||||
/// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
|
||||
LifetimeParam,
|
||||
|
@ -143,7 +141,6 @@ impl DefKind {
|
|||
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
|
||||
DefKind::OpaqueTy => "opaque type",
|
||||
DefKind::ImplTraitPlaceholder => "opaque type in trait",
|
||||
DefKind::TyAlias => "type alias",
|
||||
DefKind::TraitAlias => "trait alias",
|
||||
DefKind::AssocTy => "associated type",
|
||||
|
@ -227,8 +224,7 @@ impl DefKind {
|
|||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::ImplTraitPlaceholder => None,
|
||||
| DefKind::Impl { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +258,6 @@ impl DefKind {
|
|||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Field
|
||||
| DefKind::TyParam
|
||||
|
|
|
@ -36,7 +36,6 @@ pub enum Target {
|
|||
GlobalAsm,
|
||||
TyAlias,
|
||||
OpaqueTy,
|
||||
ImplTraitPlaceholder,
|
||||
Enum,
|
||||
Variant,
|
||||
Struct,
|
||||
|
@ -80,13 +79,7 @@ impl Target {
|
|||
ItemKind::ForeignMod { .. } => Target::ForeignMod,
|
||||
ItemKind::GlobalAsm(..) => Target::GlobalAsm,
|
||||
ItemKind::TyAlias(..) => Target::TyAlias,
|
||||
ItemKind::OpaqueTy(ref opaque) => {
|
||||
if opaque.in_trait {
|
||||
Target::ImplTraitPlaceholder
|
||||
} else {
|
||||
Target::OpaqueTy
|
||||
}
|
||||
}
|
||||
ItemKind::OpaqueTy(..) => Target::OpaqueTy,
|
||||
ItemKind::Enum(..) => Target::Enum,
|
||||
ItemKind::Struct(..) => Target::Struct,
|
||||
ItemKind::Union(..) => Target::Union,
|
||||
|
@ -110,7 +103,6 @@ impl Target {
|
|||
DefKind::GlobalAsm => Target::GlobalAsm,
|
||||
DefKind::TyAlias => Target::TyAlias,
|
||||
DefKind::OpaqueTy => Target::OpaqueTy,
|
||||
DefKind::ImplTraitPlaceholder => Target::ImplTraitPlaceholder,
|
||||
DefKind::Enum => Target::Enum,
|
||||
DefKind::Struct => Target::Struct,
|
||||
DefKind::Union => Target::Union,
|
||||
|
@ -165,7 +157,6 @@ impl Target {
|
|||
Target::GlobalAsm => "global asm",
|
||||
Target::TyAlias => "type alias",
|
||||
Target::OpaqueTy => "opaque type",
|
||||
Target::ImplTraitPlaceholder => "opaque type in trait",
|
||||
Target::Enum => "enum",
|
||||
Target::Variant => "enum variant",
|
||||
Target::Struct => "struct",
|
||||
|
|
|
@ -2128,7 +2128,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
let span = path.span;
|
||||
match path.res {
|
||||
Res::Def(DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder, did) => {
|
||||
Res::Def(DefKind::OpaqueTy, did) => {
|
||||
// Check for desugared `impl Trait`.
|
||||
assert!(tcx.is_type_alias_impl_trait(did));
|
||||
let item_segment = path.segments.split_last().unwrap();
|
||||
|
@ -2439,7 +2439,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
|
||||
// generate the def_id of an associated type for the trait and return as
|
||||
// type a projection.
|
||||
let def_id = if in_trait && tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
let def_id = if in_trait {
|
||||
tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id()
|
||||
} else {
|
||||
local_def_id.to_def_id()
|
||||
|
|
|
@ -302,16 +302,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
|||
|
||||
if let ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
|
||||
in_trait,
|
||||
..
|
||||
}) = item.kind
|
||||
{
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let opaque_identity_ty = if in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
Ty::new_projection(tcx, def_id.to_def_id(), substs)
|
||||
} else {
|
||||
Ty::new_opaque(tcx, def_id.to_def_id(), substs)
|
||||
};
|
||||
let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
||||
let mut visitor = ProhibitOpaqueVisitor {
|
||||
opaque_identity_ty,
|
||||
parent_count: tcx.generics_of(def_id).parent_count as u32,
|
||||
|
@ -576,17 +571,6 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
|
|||
check_opaque(tcx, id);
|
||||
}
|
||||
}
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
let parent = tcx.impl_trait_in_trait_parent_fn(id.owner_id.to_def_id());
|
||||
// Only check the validity of this opaque type if the function has a default body
|
||||
if let hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
|
||||
..
|
||||
}) = tcx.hir().get_by_def_id(parent.expect_local())
|
||||
{
|
||||
check_opaque(tcx, id);
|
||||
}
|
||||
}
|
||||
DefKind::TyAlias => {
|
||||
let pty_ty = tcx.type_of(id.owner_id).subst_identity();
|
||||
let generics = tcx.generics_of(id.owner_id);
|
||||
|
|
|
@ -113,16 +113,12 @@ pub(super) fn explicit_item_bounds(
|
|||
..
|
||||
}) => associated_type_bounds(tcx, def_id, bounds, *span),
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }),
|
||||
span,
|
||||
..
|
||||
}) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let item_ty = if *in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
Ty::new_projection(tcx, def_id.to_def_id(), substs)
|
||||
} else {
|
||||
Ty::new_opaque(tcx, def_id.to_def_id(), substs)
|
||||
};
|
||||
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), substs);
|
||||
opaque_type_bounds(tcx, def_id, bounds, item_ty, *span)
|
||||
}
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||
|
|
|
@ -109,20 +109,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
|
|||
vec![]
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Fn => {
|
||||
if !tcx.lower_impl_trait_in_trait_to_assoc_ty()
|
||||
&& item.defaultness(tcx).has_value()
|
||||
&& tcx.impl_method_has_trait_impl_trait_tys(item.def_id)
|
||||
&& let Ok(table) = tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
{
|
||||
table.values().copied().flat_map(|ty| {
|
||||
cgp::parameters_for(&ty.subst_identity(), true)
|
||||
}).collect()
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
ty::AssocKind::Const => vec![],
|
||||
ty::AssocKind::Fn | ty::AssocKind::Const => vec![],
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
|
|
@ -56,7 +56,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
|
|||
let crate_map = tcx.crate_variances(());
|
||||
return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
|
||||
}
|
||||
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => {
|
||||
DefKind::OpaqueTy => {
|
||||
return variance_of_opaque(tcx, item_def_id);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -115,14 +115,6 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||
{
|
||||
self.visit_opaque(*def_id, substs)
|
||||
}
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary
|
||||
// at all for RPITITs.
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs, .. })
|
||||
if self.tcx.is_impl_trait_in_trait(*def_id)
|
||||
&& !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() =>
|
||||
{
|
||||
self.visit_opaque(*def_id, substs)
|
||||
}
|
||||
_ => t.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -824,7 +824,6 @@ fn should_encode_span(def_kind: DefKind) -> bool {
|
|||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Closure
|
||||
|
@ -867,7 +866,6 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
|
|||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Generator => false,
|
||||
|
@ -902,7 +900,6 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool {
|
|||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
@ -939,7 +936,6 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
|
|||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Closure
|
||||
|
@ -966,7 +962,6 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
|
|||
| DefKind::ForeignMod
|
||||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Enum
|
||||
| DefKind::Union
|
||||
| DefKind::Impl { .. }
|
||||
|
@ -1033,7 +1028,6 @@ fn should_encode_variances(def_kind: DefKind) -> bool {
|
|||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Fn
|
||||
| DefKind::Ctor(..)
|
||||
| DefKind::AssocFn => true,
|
||||
|
@ -1083,7 +1077,6 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
|
|||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Field
|
||||
| DefKind::TyParam
|
||||
|
@ -1134,19 +1127,6 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
|||
}
|
||||
}
|
||||
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
let parent_def_id = tcx.impl_trait_in_trait_parent_fn(def_id.to_def_id());
|
||||
let assoc_item = tcx.associated_item(parent_def_id);
|
||||
match assoc_item.container {
|
||||
// Always encode an RPIT in an impl fn, since it always has a body
|
||||
ty::AssocItemContainer::ImplContainer => true,
|
||||
ty::AssocItemContainer::TraitContainer => {
|
||||
// Encode an RPIT for a trait only if the trait has a default body
|
||||
assoc_item.defaultness(tcx).has_value()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefKind::AssocTy => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
match assoc_item.container {
|
||||
|
@ -1192,7 +1172,6 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool {
|
|||
| DefKind::Ctor(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::AssocConst
|
||||
|
@ -1235,7 +1214,6 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
|
|||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::Impl { of_trait: false }
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Generator
|
||||
| DefKind::ConstParam
|
||||
|
@ -1268,7 +1246,6 @@ fn should_encode_const(def_kind: DefKind) -> bool {
|
|||
| DefKind::Static(..)
|
||||
| DefKind::TyAlias
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::AssocFn
|
||||
|
@ -1289,11 +1266,8 @@ fn should_encode_const(def_kind: DefKind) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
// We only encode impl trait in trait when using `lower-impl-trait-in-trait-to-assoc-ty` unstable
|
||||
// option.
|
||||
fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
|
||||
if tcx.lower_impl_trait_in_trait_to_assoc_ty()
|
||||
&& let Some(assoc_item) = tcx.opt_associated_item(def_id)
|
||||
if let Some(assoc_item) = tcx.opt_associated_item(def_id)
|
||||
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
|
||||
&& assoc_item.kind == ty::AssocKind::Fn
|
||||
{
|
||||
|
@ -1447,9 +1421,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||
.is_type_alias_impl_trait
|
||||
.set(def_id.index, self.tcx.is_type_alias_impl_trait(def_id));
|
||||
}
|
||||
if let DefKind::ImplTraitPlaceholder = def_kind {
|
||||
self.encode_explicit_item_bounds(def_id);
|
||||
}
|
||||
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
|
||||
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
{
|
||||
|
|
|
@ -142,7 +142,6 @@ fixed_size_enum! {
|
|||
( AnonConst )
|
||||
( InlineConst )
|
||||
( OpaqueTy )
|
||||
( ImplTraitPlaceholder )
|
||||
( Field )
|
||||
( LifetimeParam )
|
||||
( GlobalAsm )
|
||||
|
|
|
@ -195,13 +195,7 @@ impl<'hir> Map<'hir> {
|
|||
ItemKind::Fn(..) => DefKind::Fn,
|
||||
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
|
||||
ItemKind::Mod(..) => DefKind::Mod,
|
||||
ItemKind::OpaqueTy(ref opaque) => {
|
||||
if opaque.in_trait && !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
DefKind::ImplTraitPlaceholder
|
||||
} else {
|
||||
DefKind::OpaqueTy
|
||||
}
|
||||
}
|
||||
ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
|
||||
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
||||
ItemKind::Enum(..) => DefKind::Enum,
|
||||
ItemKind::Struct(..) => DefKind::Struct,
|
||||
|
|
|
@ -1036,7 +1036,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
scope_def_id: LocalDefId,
|
||||
) -> Vec<&'tcx hir::Ty<'tcx>> {
|
||||
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
|
||||
let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id) else {
|
||||
let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) =
|
||||
self.hir().fn_decl_by_hir_id(hir_id)
|
||||
else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
|
@ -2002,16 +2004,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn lower_impl_trait_in_trait_to_assoc_ty(self) -> bool {
|
||||
self.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty
|
||||
}
|
||||
|
||||
pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
|
||||
if self.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
self.opt_rpitit_info(def_id).is_some()
|
||||
} else {
|
||||
self.def_kind(def_id) == DefKind::ImplTraitPlaceholder
|
||||
}
|
||||
self.opt_rpitit_info(def_id).is_some()
|
||||
}
|
||||
|
||||
/// Named module children from all kinds of items, including imports.
|
||||
|
|
|
@ -2688,7 +2688,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
| Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) => fn_def_id,
|
||||
None => {
|
||||
while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn {
|
||||
debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder);
|
||||
def_id = self.parent(def_id);
|
||||
}
|
||||
def_id
|
||||
|
@ -2720,26 +2719,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
let Some(trait_item_def_id) = item.trait_item_def_id else { return false; };
|
||||
|
||||
if self.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
return !self
|
||||
.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
|
||||
.is_empty();
|
||||
}
|
||||
|
||||
// FIXME(RPITIT): This does a somewhat manual walk through the signature
|
||||
// of the trait fn to look for any RPITITs, but that's kinda doing a lot
|
||||
// of work. We can probably remove this when we refactor RPITITs to be
|
||||
// associated types.
|
||||
self.fn_sig(trait_item_def_id).subst_identity().skip_binder().output().walk().any(|arg| {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Alias(ty::Projection, data) = ty.kind()
|
||||
&& self.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
return !self
|
||||
.associated_types_for_impl_traits_in_associated_fn(trait_item_def_id)
|
||||
.is_empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -567,15 +567,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
|
|||
|
||||
// Alias tend to mostly already be handled downstream due to normalization.
|
||||
(&ty::Alias(a_kind, a_data), &ty::Alias(b_kind, b_data)) => {
|
||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): This if can be removed
|
||||
// and the assert uncommented once the new desugaring is stable.
|
||||
if a_kind == b_kind {
|
||||
let alias_ty = relation.relate(a_data, b_data)?;
|
||||
// assert_eq!(a_kind, b_kind);
|
||||
Ok(Ty::new_alias(tcx, a_kind, alias_ty))
|
||||
} else {
|
||||
Err(TypeError::Sorts(expected_found(relation, a, b)))
|
||||
}
|
||||
let alias_ty = relation.relate(a_data, b_data)?;
|
||||
assert_eq!(a_kind, b_kind);
|
||||
Ok(Ty::new_alias(tcx, a_kind, alias_ty))
|
||||
}
|
||||
|
||||
_ => Err(TypeError::Sorts(expected_found(relation, a, b))),
|
||||
|
|
|
@ -1237,7 +1237,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind {
|
||||
match tcx.def_kind(self.def_id) {
|
||||
DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
|
||||
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection,
|
||||
DefKind::AssocTy => ty::Projection,
|
||||
DefKind::OpaqueTy => ty::Opaque,
|
||||
DefKind::TyAlias => ty::Weak,
|
||||
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
|
||||
|
@ -1265,9 +1265,6 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
|
||||
match tcx.def_kind(self.def_id) {
|
||||
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
|
||||
DefKind::ImplTraitPlaceholder => {
|
||||
tcx.parent(tcx.impl_trait_in_trait_parent_fn(self.def_id))
|
||||
}
|
||||
kind => bug!("expected a projection AliasTy; found {kind:?}"),
|
||||
}
|
||||
}
|
||||
|
@ -1970,7 +1967,6 @@ impl<'tcx> Ty<'tcx> {
|
|||
(kind, tcx.def_kind(alias_ty.def_id)),
|
||||
(ty::Opaque, DefKind::OpaqueTy)
|
||||
| (ty::Projection | ty::Inherent, DefKind::AssocTy)
|
||||
| (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder)
|
||||
| (ty::Weak, DefKind::TyAlias)
|
||||
);
|
||||
Ty::new(tcx, Alias(kind, alias_ty))
|
||||
|
|
|
@ -163,7 +163,6 @@ fn mark_used_by_default_parameters<'tcx>(
|
|||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
|
|
@ -694,7 +694,6 @@ impl CheckAttrVisitor<'_> {
|
|||
| Target::GlobalAsm
|
||||
| Target::TyAlias
|
||||
| Target::OpaqueTy
|
||||
| Target::ImplTraitPlaceholder
|
||||
| Target::Enum
|
||||
| Target::Variant
|
||||
| Target::Struct
|
||||
|
|
|
@ -136,19 +136,7 @@ where
|
|||
|
||||
fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
|
||||
let tcx = self.def_id_visitor.tcx();
|
||||
let (trait_ref, assoc_substs) = if tcx.def_kind(projection.def_id)
|
||||
!= DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
projection.trait_ref_and_own_substs(tcx)
|
||||
} else {
|
||||
// HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
|
||||
let def_id = tcx.impl_trait_in_trait_parent_fn(projection.def_id);
|
||||
let trait_generics = tcx.generics_of(def_id);
|
||||
(
|
||||
ty::TraitRef::new(tcx, def_id, projection.substs.truncate_to(tcx, trait_generics)),
|
||||
&projection.substs[trait_generics.count()..],
|
||||
)
|
||||
};
|
||||
let (trait_ref, assoc_substs) = projection.trait_ref_and_own_substs(tcx);
|
||||
self.visit_trait(trait_ref)?;
|
||||
if V::SHALLOW {
|
||||
ControlFlow::Continue(())
|
||||
|
@ -651,7 +639,6 @@ impl<'tcx> EmbargoVisitor<'tcx> {
|
|||
| DefKind::ForeignTy
|
||||
| DefKind::Fn
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::AssocFn
|
||||
| DefKind::Trait
|
||||
| DefKind::TyParam
|
||||
|
|
|
@ -949,7 +949,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
|||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::AssocTy,
|
||||
_,
|
||||
|
|
|
@ -1583,9 +1583,6 @@ options! {
|
|||
"what location details should be tracked when using caller_location, either \
|
||||
`none`, or a comma separated list of location details, for which \
|
||||
valid options are `file`, `line`, and `column` (default: `file,line,column`)"),
|
||||
lower_impl_trait_in_trait_to_assoc_ty: bool = (false, parse_bool, [TRACKED],
|
||||
"modify the lowering strategy for `impl Trait` in traits so that they are lowered to \
|
||||
generic associated types"),
|
||||
ls: bool = (false, parse_bool, [UNTRACKED],
|
||||
"list the symbols defined by a library crate (default: no)"),
|
||||
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
|
||||
|
|
|
@ -131,8 +131,6 @@ enum ProjectionCandidate<'tcx> {
|
|||
|
||||
/// From an "impl" (or a "pseudo-impl" returned by select)
|
||||
Select(Selection<'tcx>),
|
||||
|
||||
ImplTraitInTrait(ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>),
|
||||
}
|
||||
|
||||
enum ProjectionCandidateSet<'tcx> {
|
||||
|
@ -1472,8 +1470,6 @@ fn project<'cx, 'tcx>(
|
|||
|
||||
let mut candidates = ProjectionCandidateSet::None;
|
||||
|
||||
assemble_candidate_for_impl_trait_in_trait(selcx, obligation, &mut candidates);
|
||||
|
||||
// Make sure that the following procedures are kept in order. ParamEnv
|
||||
// needs to be first because it has highest priority, and Select checks
|
||||
// the return value of push_candidate which assumes it's ran at last.
|
||||
|
@ -1499,7 +1495,7 @@ fn project<'cx, 'tcx>(
|
|||
ProjectionCandidateSet::None => {
|
||||
let tcx = selcx.tcx();
|
||||
let term = match tcx.def_kind(obligation.predicate.def_id) {
|
||||
DefKind::AssocTy | DefKind::ImplTraitPlaceholder => Ty::new_projection(
|
||||
DefKind::AssocTy => Ty::new_projection(
|
||||
tcx,
|
||||
obligation.predicate.def_id,
|
||||
obligation.predicate.substs,
|
||||
|
@ -1530,47 +1526,6 @@ fn project<'cx, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
/// If the predicate's item is an `ImplTraitPlaceholder`, we do a select on the
|
||||
/// corresponding trait ref. If this yields an `impl`, then we're able to project
|
||||
/// to a concrete type, since we have an `impl`'s method to provide the RPITIT.
|
||||
fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||
) {
|
||||
let tcx = selcx.tcx();
|
||||
if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
|
||||
|
||||
let trait_def_id = tcx.parent(trait_fn_def_id);
|
||||
let trait_substs =
|
||||
obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
|
||||
let trait_predicate = ty::TraitRef::new(tcx, trait_def_id, trait_substs);
|
||||
|
||||
let _ = selcx.infcx.commit_if_ok(|_| {
|
||||
match selcx.select(&obligation.with(tcx, trait_predicate)) {
|
||||
Ok(Some(super::ImplSource::UserDefined(data))) => {
|
||||
candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(data));
|
||||
Ok(())
|
||||
}
|
||||
Ok(None) => {
|
||||
candidate_set.mark_ambiguous();
|
||||
Err(())
|
||||
}
|
||||
Ok(Some(_)) => {
|
||||
// Don't know enough about the impl to provide a useful signature
|
||||
Err(())
|
||||
}
|
||||
Err(e) => {
|
||||
debug!(error = ?e, "selection error");
|
||||
candidate_set.mark_error(e);
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// The first thing we have to do is scan through the parameter
|
||||
/// environment to see whether there are any projection predicates
|
||||
/// there that can answer this question.
|
||||
|
@ -1739,11 +1694,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||
) {
|
||||
// Can't assemble candidate from impl for RPITIT
|
||||
if selcx.tcx().def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are resolving `<T as TraitRef<...>>::Item == Type`,
|
||||
// start out by selecting the predicate `T as TraitRef<...>`:
|
||||
let trait_ref = obligation.predicate.trait_ref(selcx.tcx());
|
||||
|
@ -2012,9 +1962,6 @@ fn confirm_candidate<'cx, 'tcx>(
|
|||
ProjectionCandidate::Select(impl_source) => {
|
||||
confirm_select_candidate(selcx, obligation, impl_source)
|
||||
}
|
||||
ProjectionCandidate::ImplTraitInTrait(data) => {
|
||||
confirm_impl_trait_in_trait_candidate(selcx, obligation, data)
|
||||
}
|
||||
};
|
||||
|
||||
// When checking for cycle during evaluation, we compare predicates with
|
||||
|
@ -2240,8 +2187,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
|
|||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
nested: Vec<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let ty::Closure(_, substs) =
|
||||
selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
|
||||
let ty::Closure(_, substs) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
|
||||
else {
|
||||
unreachable!()
|
||||
};
|
||||
|
@ -2419,103 +2365,6 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
selcx: &mut SelectionContext<'_, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
data: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
let mut obligations = data.nested;
|
||||
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id);
|
||||
let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) {
|
||||
Ok(assoc_ty) => assoc_ty,
|
||||
Err(guar) => return Progress::error(tcx, guar),
|
||||
};
|
||||
// We don't support specialization for RPITITs anyways... yet.
|
||||
// Also don't try to project to an RPITIT that has no value
|
||||
if !leaf_def.is_final() || !leaf_def.item.defaultness(tcx).has_value() {
|
||||
return Progress { term: Ty::new_misc_error(tcx).into(), obligations };
|
||||
}
|
||||
|
||||
// Use the default `impl Trait` for the trait, e.g., for a default trait body
|
||||
if leaf_def.item.container == ty::AssocItemContainer::TraitContainer {
|
||||
return Progress {
|
||||
term: Ty::new_opaque(tcx, obligation.predicate.def_id, obligation.predicate.substs)
|
||||
.into(),
|
||||
obligations,
|
||||
};
|
||||
}
|
||||
|
||||
// Rebase from {trait}::{fn}::{opaque} to {impl}::{fn}::{opaque},
|
||||
// since `data.substs` are the impl substs.
|
||||
let impl_fn_substs =
|
||||
obligation.predicate.substs.rebase_onto(tcx, tcx.parent(trait_fn_def_id), data.substs);
|
||||
let impl_fn_substs = translate_substs(
|
||||
selcx.infcx,
|
||||
obligation.param_env,
|
||||
data.impl_def_id,
|
||||
impl_fn_substs,
|
||||
leaf_def.defining_node,
|
||||
);
|
||||
|
||||
if !check_substs_compatible(tcx, leaf_def.item, impl_fn_substs) {
|
||||
let err = Ty::new_error_with_message(
|
||||
tcx,
|
||||
obligation.cause.span,
|
||||
"impl method and trait method have different parameters",
|
||||
);
|
||||
return Progress { term: err.into(), obligations };
|
||||
}
|
||||
|
||||
let impl_fn_def_id = leaf_def.item.def_id;
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
super::ItemObligation(impl_fn_def_id),
|
||||
);
|
||||
let predicates = normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs),
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.extend(predicates.into_iter().map(|(pred, span)| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
if span.is_dummy() {
|
||||
super::ItemObligation(impl_fn_def_id)
|
||||
} else {
|
||||
super::BindingObligation(impl_fn_def_id, span)
|
||||
},
|
||||
),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
pred,
|
||||
)
|
||||
}));
|
||||
|
||||
let ty = normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
tcx.collect_return_position_impl_trait_in_trait_tys(impl_fn_def_id).map_or_else(
|
||||
|guar| Ty::new_error(tcx, guar),
|
||||
|tys| tys[&obligation.predicate.def_id].subst(tcx, impl_fn_substs),
|
||||
),
|
||||
&mut obligations,
|
||||
);
|
||||
|
||||
Progress { term: ty.into(), obligations }
|
||||
}
|
||||
|
||||
// Get obligations corresponding to the predicates from the where-clause of the
|
||||
// associated type itself.
|
||||
fn assoc_ty_own_obligations<'cx, 'tcx>(
|
||||
|
|
|
@ -24,70 +24,54 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
|
|||
let item = tcx.hir().expect_item(def_id);
|
||||
match item.kind {
|
||||
hir::ItemKind::Trait(.., ref trait_item_refs) => {
|
||||
if tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
// We collect RPITITs for each trait method's return type and create a
|
||||
// corresponding associated item using associated_types_for_impl_traits_in_associated_fn
|
||||
// query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
|
||||
.chain(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.filter(|trait_item_ref| {
|
||||
matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|trait_item_ref| {
|
||||
let trait_fn_def_id =
|
||||
trait_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
trait_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
tcx.arena.alloc_from_iter(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id()),
|
||||
)
|
||||
}
|
||||
// We collect RPITITs for each trait method's return type and create a
|
||||
// corresponding associated item using associated_types_for_impl_traits_in_associated_fn
|
||||
// query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
|
||||
.chain(
|
||||
trait_item_refs
|
||||
.iter()
|
||||
.filter(|trait_item_ref| {
|
||||
matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|trait_item_ref| {
|
||||
let trait_fn_def_id = trait_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
trait_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id),
|
||||
),
|
||||
)
|
||||
}
|
||||
hir::ItemKind::Impl(ref impl_) => {
|
||||
if tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
// We collect RPITITs for each trait method's return type, on the impl side too and
|
||||
// create a corresponding associated item using
|
||||
// associated_types_for_impl_traits_in_associated_fn query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id())
|
||||
.chain(impl_.of_trait.iter().flat_map(|_| {
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.filter(|impl_item_ref| {
|
||||
matches!(impl_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|impl_item_ref| {
|
||||
let impl_fn_def_id =
|
||||
impl_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
impl_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id)
|
||||
})),
|
||||
)
|
||||
} else {
|
||||
tcx.arena.alloc_from_iter(
|
||||
impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()),
|
||||
)
|
||||
}
|
||||
// We collect RPITITs for each trait method's return type, on the impl side too and
|
||||
// create a corresponding associated item using
|
||||
// associated_types_for_impl_traits_in_associated_fn query.
|
||||
tcx.arena.alloc_from_iter(
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id())
|
||||
.chain(impl_.of_trait.iter().flat_map(|_| {
|
||||
impl_
|
||||
.items
|
||||
.iter()
|
||||
.filter(|impl_item_ref| {
|
||||
matches!(impl_item_ref.kind, hir::AssocItemKind::Fn { .. })
|
||||
})
|
||||
.flat_map(|impl_item_ref| {
|
||||
let impl_fn_def_id = impl_item_ref.id.owner_id.def_id.to_def_id();
|
||||
tcx.associated_types_for_impl_traits_in_associated_fn(
|
||||
impl_fn_def_id,
|
||||
)
|
||||
})
|
||||
.map(|def_id| *def_id)
|
||||
})),
|
||||
)
|
||||
}
|
||||
_ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
|
||||
}
|
||||
|
|
|
@ -75,7 +75,6 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
|||
| DefKind::ForeignMod
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
|
|
@ -318,7 +318,6 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
|
|||
| DefKind::ExternCrate
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
|
|
|
@ -282,11 +282,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
|||
// If we're lowering to associated item, install the opaque type which is just
|
||||
// the `type_of` of the trait's associated item. If we're using the old lowering
|
||||
// strategy, then just reinterpret the associated type like an opaque :^)
|
||||
let default_ty = if self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
self.tcx.type_of(shifted_alias_ty.def_id).subst(self.tcx, shifted_alias_ty.substs)
|
||||
} else {
|
||||
Ty::new_alias(self.tcx,ty::Opaque, shifted_alias_ty)
|
||||
};
|
||||
let default_ty = self.tcx.type_of(shifted_alias_ty.def_id).subst(self.tcx, shifted_alias_ty.substs);
|
||||
|
||||
self.predicates.push(
|
||||
ty::Binder::bind_with_vars(
|
||||
|
@ -408,9 +404,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet<u32
|
|||
};
|
||||
|
||||
// The last field of the structure has to exist and contain type/const parameters.
|
||||
let Some((tail_field, prefix_fields)) =
|
||||
def.non_enum_variant().fields.raw.split_last() else
|
||||
{
|
||||
let Some((tail_field, prefix_fields)) = def.non_enum_variant().fields.raw.split_last() else {
|
||||
return BitSet::new_empty(num_params);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue