Auto merge of #104986 - compiler-errors:opaques, r=oli-obk
Combine `ty::Projection` and `ty::Opaque` into `ty::Alias` Implements https://github.com/rust-lang/types-team/issues/79. This PR consolidates `ty::Projection` and `ty::Opaque` into a single `ty::Alias`, with an `AliasKind` and `AliasTy` type (renamed from `ty::ProjectionTy`, which is the inner data of `ty::Projection`) defined as so: ``` enum AliasKind { Projection, Opaque, } struct AliasTy<'tcx> { def_id: DefId, substs: SubstsRef<'tcx>, } ``` Since we don't have access to `TyCtxt` in type flags computation, and because repeatedly calling `DefKind` on the def-id is expensive, these two types are distinguished with `ty::AliasKind`, conveniently glob-imported into `ty::{Projection, Opaque}`. For example: ```diff match ty.kind() { - ty::Opaque(..) => + ty::Alias(ty::Opaque, ..) => {} _ => {} } ``` This PR also consolidates match arms that treated `ty::Opaque` and `ty::Projection` identically. r? `@ghost`
This commit is contained in:
commit
918d0ac38e
115 changed files with 632 additions and 674 deletions
|
@ -1146,10 +1146,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
debug!(?substs_trait_ref_and_assoc_item);
|
||||
|
||||
ty::ProjectionTy {
|
||||
item_def_id: assoc_item.def_id,
|
||||
substs: substs_trait_ref_and_assoc_item,
|
||||
}
|
||||
ty::AliasTy { def_id: assoc_item.def_id, substs: substs_trait_ref_and_assoc_item }
|
||||
});
|
||||
|
||||
if !speculative {
|
||||
|
@ -1195,7 +1192,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// the "projection predicate" for:
|
||||
//
|
||||
// `<T as Iterator>::Item = u32`
|
||||
let assoc_item_def_id = projection_ty.skip_binder().item_def_id;
|
||||
let assoc_item_def_id = projection_ty.skip_binder().def_id;
|
||||
let def_kind = tcx.def_kind(assoc_item_def_id);
|
||||
match (def_kind, term.unpack()) {
|
||||
(hir::def::DefKind::AssocTy, ty::TermKind::Ty(_))
|
||||
|
@ -1244,7 +1241,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
//
|
||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
let param_ty = tcx.mk_ty(ty::Projection(projection_ty.skip_binder()));
|
||||
let param_ty = tcx.mk_ty(ty::Alias(ty::Projection, projection_ty.skip_binder()));
|
||||
self.add_bounds(param_ty, ast_bounds.iter(), bounds, candidate.bound_vars());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1440,7 +1440,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E
|
|||
impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypeCollector {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match *t.kind() {
|
||||
ty::Opaque(def, _) => {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, substs: _ }) => {
|
||||
self.0.push(def);
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
|
|
|
@ -571,10 +571,10 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if let ty::Projection(proj) = ty.kind()
|
||||
&& self.tcx().def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
|
||||
if let ty::Alias(ty::Projection, proj) = ty.kind()
|
||||
&& self.tcx().def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
if let Some((ty, _)) = self.types.get(&proj.item_def_id) {
|
||||
if let Some((ty, _)) = self.types.get(&proj.def_id) {
|
||||
return *ty;
|
||||
}
|
||||
//FIXME(RPITIT): Deny nested RPITIT in substs too
|
||||
|
@ -586,9 +586,9 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
|||
span: self.span,
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
});
|
||||
self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
|
||||
self.types.insert(proj.def_id, (infer_ty, proj.substs));
|
||||
// Recurse into bounds
|
||||
for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.item_def_id).subst_iter_copied(self.tcx(), proj.substs) {
|
||||
for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.tcx(), proj.substs) {
|
||||
let pred = pred.fold_with(self);
|
||||
let pred = self.ocx.normalize(
|
||||
&ObligationCause::misc(self.span, self.body_id),
|
||||
|
@ -601,7 +601,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
|||
ObligationCause::new(
|
||||
self.span,
|
||||
self.body_id,
|
||||
ObligationCauseCode::BindingObligation(proj.item_def_id, pred_span),
|
||||
ObligationCauseCode::BindingObligation(proj.def_id, pred_span),
|
||||
),
|
||||
self.param_env,
|
||||
pred,
|
||||
|
@ -1734,8 +1734,8 @@ pub fn check_type_bounds<'tcx>(
|
|||
let normalize_param_env = {
|
||||
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
|
||||
match impl_ty_value.kind() {
|
||||
ty::Projection(proj)
|
||||
if proj.item_def_id == trait_ty.def_id && proj.substs == rebased_substs =>
|
||||
ty::Alias(ty::Projection, proj)
|
||||
if proj.def_id == trait_ty.def_id && proj.substs == rebased_substs =>
|
||||
{
|
||||
// Don't include this predicate if the projected type is
|
||||
// exactly the same as the projection. This can occur in
|
||||
|
@ -1746,8 +1746,8 @@ pub fn check_type_bounds<'tcx>(
|
|||
_ => predicates.push(
|
||||
ty::Binder::bind_with_vars(
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
item_def_id: trait_ty.def_id,
|
||||
projection_ty: ty::AliasTy {
|
||||
def_id: trait_ty.def_id,
|
||||
substs: rebased_substs,
|
||||
},
|
||||
term: impl_ty_value.into(),
|
||||
|
|
|
@ -352,11 +352,7 @@ fn bounds_from_generic_predicates<'tcx>(
|
|||
// insert the associated types where they correspond, but for now let's be "lazy" and
|
||||
// propose this instead of the following valid resugaring:
|
||||
// `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
|
||||
where_clauses.push(format!(
|
||||
"{} = {}",
|
||||
tcx.def_path_str(p.projection_ty.item_def_id),
|
||||
p.term,
|
||||
));
|
||||
where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.def_id), p.term));
|
||||
}
|
||||
let where_clauses = if where_clauses.is_empty() {
|
||||
String::new()
|
||||
|
|
|
@ -759,7 +759,7 @@ impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
|
|||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match t.kind() {
|
||||
ty::Projection(p) if p.item_def_id == self.gat => {
|
||||
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
|
||||
for (idx, subst) in p.substs.iter().enumerate() {
|
||||
match subst.unpack() {
|
||||
GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
|
||||
|
@ -1592,12 +1592,12 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
|
|||
{
|
||||
for arg in fn_output.walk() {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Projection(proj) = ty.kind()
|
||||
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
|
||||
&& tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
|
||||
&& let ty::Alias(ty::Projection, proj) = ty.kind()
|
||||
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
|
||||
&& tcx.impl_trait_in_trait_parent(proj.def_id) == fn_def_id.to_def_id()
|
||||
{
|
||||
let span = tcx.def_span(proj.item_def_id);
|
||||
let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
|
||||
let span = tcx.def_span(proj.def_id);
|
||||
let bounds = wfcx.tcx().explicit_item_bounds(proj.def_id);
|
||||
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
|
||||
let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs);
|
||||
let normalized_bound = wfcx.normalize(span, None, bound);
|
||||
|
|
|
@ -223,7 +223,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
|||
| ty::Tuple(..) => {
|
||||
self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span)
|
||||
}
|
||||
ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
|
||||
ty::Alias(..) | ty::Param(_) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
ty.span,
|
||||
|
|
|
@ -1749,7 +1749,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
|
|||
ty::Param(param_ty) => {
|
||||
self.arg_is_constrained[param_ty.index as usize] = true;
|
||||
}
|
||||
ty::Projection(_) => return ControlFlow::Continue(()),
|
||||
ty::Alias(ty::Projection, _) => return ControlFlow::Continue(()),
|
||||
_ => (),
|
||||
}
|
||||
t.super_visit_with(self)
|
||||
|
|
|
@ -408,9 +408,9 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||
// identity substs of the trait.
|
||||
// * It must be an associated type for this trait (*not* a
|
||||
// supertrait).
|
||||
if let ty::Projection(projection) = ty.kind() {
|
||||
if let ty::Alias(ty::Projection, projection) = ty.kind() {
|
||||
projection.substs == trait_identity_substs
|
||||
&& tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id
|
||||
&& tcx.associated_item(projection.def_id).container_id(tcx) == def_id
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
|
|||
// Using the ItemCtxt convert the HIR for the unresolved assoc type into a
|
||||
// ty which is a fully resolved projection.
|
||||
// For the code example above, this would mean converting Self::Assoc<3>
|
||||
// into a ty::Projection(<Self as Foo>::Assoc<3>)
|
||||
// into a ty::Alias(ty::Projection, <Self as Foo>::Assoc<3>)
|
||||
let item_hir_id = tcx
|
||||
.hir()
|
||||
.parent_iter(hir_id)
|
||||
|
@ -68,8 +68,8 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
|
|||
// the def_id that this query was called with. We filter to only type and const args here
|
||||
// as a precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't
|
||||
// but it can't hurt to be safe ^^
|
||||
if let ty::Projection(projection) = ty.kind() {
|
||||
let generics = tcx.generics_of(projection.item_def_id);
|
||||
if let ty::Alias(ty::Projection, projection) = ty.kind() {
|
||||
let generics = tcx.generics_of(projection.def_id);
|
||||
|
||||
let arg_index = segment
|
||||
.args
|
||||
|
@ -666,7 +666,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
|
|||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
let scope = tcx.hir().get_defining_scope(hir_id);
|
||||
let mut locator = ConstraintLocator { def_id: def_id, tcx, found: None, typeck_types: vec![] };
|
||||
let mut locator = ConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] };
|
||||
|
||||
debug!(?scope);
|
||||
|
||||
|
@ -803,7 +803,7 @@ fn find_opaque_ty_constraints_for_rpit(
|
|||
if let Some(concrete) = concrete {
|
||||
let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id);
|
||||
debug!(?scope);
|
||||
let mut locator = ConstraintChecker { def_id: def_id, tcx, found: concrete };
|
||||
let mut locator = ConstraintChecker { def_id, tcx, found: concrete };
|
||||
|
||||
match tcx.hir().get(scope) {
|
||||
Node::Item(it) => intravisit::walk_item(&mut locator, it),
|
||||
|
|
|
@ -59,7 +59,7 @@ struct ParameterCollector {
|
|||
impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match *t.kind() {
|
||||
ty::Projection(..) if !self.include_nonconstraining => {
|
||||
ty::Alias(ty::Projection, ..) if !self.include_nonconstraining => {
|
||||
// projections are not injective
|
||||
return ControlFlow::CONTINUE;
|
||||
}
|
||||
|
|
|
@ -196,13 +196,13 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
ty::Projection(obj) => {
|
||||
ty::Alias(ty::Projection, obj) => {
|
||||
// This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
|
||||
// explicit predicates as well.
|
||||
debug!("Projection");
|
||||
check_explicit_predicates(
|
||||
tcx,
|
||||
tcx.parent(obj.item_def_id),
|
||||
tcx.parent(obj.def_id),
|
||||
obj.substs,
|
||||
required_predicates,
|
||||
explicit_map,
|
||||
|
|
|
@ -90,7 +90,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
|
|||
// ```
|
||||
//
|
||||
// Here we want to add an explicit `where <T as Iterator>::Item: 'a`.
|
||||
let ty: Ty<'tcx> = tcx.mk_projection(proj_ty.item_def_id, proj_ty.substs);
|
||||
let ty: Ty<'tcx> = tcx.mk_projection(proj_ty.def_id, proj_ty.substs);
|
||||
required_predicates
|
||||
.entry(ty::OutlivesPredicate(ty.into(), outlived_region))
|
||||
.or_insert(span);
|
||||
|
|
|
@ -249,14 +249,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
self.add_constraints_from_substs(current, def.did(), substs, variance);
|
||||
}
|
||||
|
||||
ty::Projection(ref data) => {
|
||||
ty::Alias(_, ref data) => {
|
||||
self.add_constraints_from_invariant_substs(current, data.substs, variance);
|
||||
}
|
||||
|
||||
ty::Opaque(_, substs) => {
|
||||
self.add_constraints_from_invariant_substs(current, substs, variance);
|
||||
}
|
||||
|
||||
ty::Dynamic(data, r, _) => {
|
||||
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
|
||||
let contra = self.contravariant(variance);
|
||||
|
|
|
@ -111,11 +111,13 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match t.kind() {
|
||||
ty::Opaque(def_id, substs) => self.visit_opaque(*def_id, substs),
|
||||
ty::Projection(proj)
|
||||
if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder =>
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs })
|
||||
if matches!(
|
||||
self.tcx.def_kind(*def_id),
|
||||
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder
|
||||
) =>
|
||||
{
|
||||
self.visit_opaque(proj.item_def_id, proj.substs)
|
||||
self.visit_opaque(*def_id, substs)
|
||||
}
|
||||
_ => t.super_visit_with(self),
|
||||
}
|
||||
|
@ -167,7 +169,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||
}
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::Clause::Projection(ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: _ },
|
||||
projection_ty: ty::AliasTy { substs, def_id: _ },
|
||||
term,
|
||||
})) => {
|
||||
for subst in &substs[1..] {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue