1
Fork 0

Combine projection and opaque into alias

This commit is contained in:
Michael Goulet 2022-11-26 21:51:55 +00:00
parent c13bd83528
commit 61adaf8187
104 changed files with 387 additions and 381 deletions

View file

@ -579,14 +579,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
match ty.kind() {
ty::Param(_) => true,
ty::Projection(p) => self.is_of_param(p.self_ty()),
ty::Alias(ty::Projection, p) => self.is_of_param(p.self_ty()),
_ => false,
}
}
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
if let Some(ty) = p.term().skip_binder().ty() {
matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_ty)
} else {
false
}

View file

@ -659,7 +659,7 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
| ty::RawPtr(..)
| ty::Never
| ty::Tuple(..)
| ty::Projection(..) => self.found_non_local_ty(ty),
| ty::Alias(ty::Projection, ..) => self.found_non_local_ty(ty),
ty::Param(..) => self.found_param_ty(ty),
@ -704,7 +704,7 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
);
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
}
ty::Opaque(..) => {
ty::Alias(ty::Opaque, ..) => {
// This merits some explanation.
// Normally, opaque types are not involved when performing
// coherence checking, since it is illegal to directly

View file

@ -1787,8 +1787,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::Closure(..) => Some(9),
ty::Tuple(..) => Some(10),
ty::Param(..) => Some(11),
ty::Projection(..) => Some(12),
ty::Opaque(..) => Some(13),
ty::Alias(ty::Projection, ..) => Some(12),
ty::Alias(ty::Opaque, ..) => Some(13),
ty::Never => Some(14),
ty::Adt(..) => Some(15),
ty::Generator(..) => Some(16),

View file

@ -495,7 +495,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let self_ty = trait_pred.skip_binder().self_ty();
let (param_ty, projection) = match self_ty.kind() {
ty::Param(_) => (true, None),
ty::Projection(projection) => (false, Some(projection)),
ty::Alias(ty::Projection, projection) => (false, Some(projection)),
_ => (false, None),
};
@ -855,7 +855,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
))
}
ty::Opaque(ty::AliasTy { def_id, substs }) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
@ -2644,7 +2644,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
Some(ident) => err.span_note(ident.span, &msg),
None => err.note(&msg),
},
ty::Opaque(ty::AliasTy { def_id, substs: _ }) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) => {
// Avoid printing the future from `core::future::identity_future`, it's not helpful
if tcx.parent(*def_id) == identity_future {
break 'print;
@ -3221,7 +3221,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
for diff in &type_diffs {
let Sorts(expected_found) = diff else { continue; };
let ty::Projection(proj) = expected_found.expected.kind() else { continue; };
let ty::Alias(ty::Projection, proj) = expected_found.expected.kind() else { continue; };
let origin =
TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };

View file

@ -794,13 +794,13 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
ControlFlow::CONTINUE
}
}
ty::Projection(ref data)
ty::Alias(ty::Projection, ref data)
if self.tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder =>
{
// We'll deny these later in their own pass
ControlFlow::CONTINUE
}
ty::Projection(ref data) => {
ty::Alias(ty::Projection, ref data) => {
// This is a projected type `<Foo as SomeTrait>::X`.
// Compute supertraits of current trait lazily.
@ -861,7 +861,7 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
// FIXME(RPITIT): Perhaps we should use a visitor here?
ty.skip_binder().walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
&& let ty::Alias(ty::Projection, proj) = ty.kind()
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
{
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id)))

View file

@ -496,7 +496,9 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
// This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark.
ty::Opaque(ty::AliasTy { def_id, substs }) if !substs.has_escaping_bound_vars() => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs })
if !substs.has_escaping_bound_vars() =>
{
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.super_fold_with(self),
@ -523,7 +525,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
}
}
ty::Projection(data) if !data.has_escaping_bound_vars() => {
ty::Alias(ty::Projection, data) if !data.has_escaping_bound_vars() => {
// This branch is *mostly* just an optimization: when we don't
// have escaping bound vars, we don't need to replace them with
// placeholders (see branch below). *Also*, we know that we can
@ -562,7 +564,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
normalized_ty.ty().unwrap()
}
ty::Projection(data) => {
ty::Alias(ty::Projection, data) => {
// If there are escaping bound vars, we temporarily replace the
// bound vars with placeholders. Note though, that in the case
// that we still can't project for whatever reason (e.g. self
@ -1375,8 +1377,10 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
// Check whether the self-type is itself a projection.
// If so, extract what we know from the trait and try to come up with a good answer.
let bounds = match *obligation.predicate.self_ty().kind() {
ty::Projection(ref data) => tcx.bound_item_bounds(data.def_id).subst(tcx, data.substs),
ty::Opaque(ty::AliasTy { def_id, substs }) => {
ty::Alias(ty::Projection, ref data) => {
tcx.bound_item_bounds(data.def_id).subst(tcx, data.substs)
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
tcx.bound_item_bounds(def_id).subst(tcx, substs)
}
ty::Infer(ty::TyVar(_)) => {
@ -1616,8 +1620,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// type parameters, opaques, and unnormalized projections have pointer
// metadata if they're known (e.g. by the param_env) to be sized
ty::Param(_)
| ty::Projection(..)
| ty::Opaque(..)
| ty::Alias(ty::Projection, ..)
| ty::Alias(ty::Opaque, ..)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(..)
@ -1671,7 +1675,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// type parameters, opaques, and unnormalized projections have pointer
// metadata if they're known (e.g. by the param_env) to be sized
ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
ty::Param(_) | ty::Alias(ty::Projection, ..) | ty::Alias(ty::Opaque, ..)
if selcx.infcx.predicate_must_hold_modulo_regions(
&obligation.with(
selcx.tcx(),
@ -1687,8 +1691,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
ty::Param(_)
| ty::Projection(..)
| ty::Opaque(..)
| ty::Alias(ty::Projection, ..)
| ty::Alias(ty::Opaque, ..)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(..)

View file

@ -62,9 +62,9 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
// The following *might* require a destructor: needs deeper inspection.
ty::Dynamic(..)
| ty::Projection(..)
| ty::Alias(ty::Projection, ..)
| ty::Param(_)
| ty::Opaque(..)
| ty::Alias(ty::Opaque, ..)
| ty::Placeholder(..)
| ty::Infer(_)
| ty::Bound(..)

View file

@ -205,7 +205,9 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark.
ty::Opaque(ty::AliasTy { def_id, substs }) if !substs.has_escaping_bound_vars() => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs })
if !substs.has_escaping_bound_vars() =>
{
// Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.try_super_fold_with(self),
@ -242,7 +244,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
}
}
ty::Projection(data) if !data.has_escaping_bound_vars() => {
ty::Alias(ty::Projection, data) if !data.has_escaping_bound_vars() => {
// This branch is just an optimization: when we don't have escaping bound vars,
// we don't need to replace them with placeholders (see branch below).
@ -291,7 +293,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
}
}
ty::Projection(data) => {
ty::Alias(ty::Projection, data) => {
// See note in `rustc_trait_selection::traits::project`
let tcx = self.infcx.tcx;

View file

@ -138,7 +138,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Before we go into the whole placeholder thing, just
// quickly check if the self-type is a projection at all.
match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
ty::Projection(_) | ty::Opaque(..) => {}
ty::Alias(ty::Projection, _) | ty::Alias(ty::Opaque, ..) => {}
ty::Infer(ty::TyVar(_)) => {
span_bug!(
obligation.cause.span,
@ -394,7 +394,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// still be provided by a manual implementation for
// this trait and type.
}
ty::Param(..) | ty::Projection(..) => {
ty::Param(..) | ty::Alias(ty::Projection, ..) => {
// In these cases, we don't know what the actual
// type is. Therefore, we cannot break it down
// into its constituent types. So we don't
@ -734,13 +734,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
match self_ty.skip_binder().kind() {
ty::Opaque(..)
ty::Alias(ty::Opaque, ..)
| ty::Dynamic(..)
| ty::Error(_)
| ty::Bound(..)
| ty::Param(_)
| ty::Placeholder(_)
| ty::Projection(_) => {
| ty::Alias(ty::Projection, _) => {
// We don't know if these are `~const Destruct`, at least
// not structurally... so don't push a candidate.
}
@ -826,8 +826,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)
| ty::Never
| ty::Projection(_)
| ty::Opaque(ty::AliasTy { def_id: _, substs: _ })
| ty::Alias(ty::Projection, _)
| ty::Alias(ty::Opaque, ty::AliasTy { def_id: _, substs: _ })
| ty::Param(_)
| ty::Bound(_, _)
| ty::Error(_)

View file

@ -155,8 +155,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let placeholder_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let (def_id, substs) = match *placeholder_self_ty.kind() {
ty::Projection(proj) => (proj.def_id, proj.substs),
ty::Opaque(ty::AliasTy { def_id, substs }) => (def_id, substs),
ty::Alias(ty::Projection, proj) => (proj.def_id, proj.substs),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => (def_id, substs),
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
};
@ -184,7 +184,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map_err(|_| Unimplemented)
})?);
if let ty::Projection(..) = placeholder_self_ty.kind() {
if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates;
debug!(?predicates, "projection predicates");
for predicate in predicates {
@ -1279,7 +1279,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable
ty::Projection(..) => {
ty::Alias(ty::Projection, ..) => {
let predicate = normalize_with_depth_to(
self,
obligation.param_env,

View file

@ -1595,8 +1595,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tcx = self.infcx.tcx;
let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
ty::Projection(ref data) => (data.def_id, data.substs),
ty::Opaque(ty::AliasTy { def_id, substs }) => (def_id, substs),
ty::Alias(ty::Projection, ref data) => (data.def_id, data.substs),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => (def_id, substs),
_ => {
span_bug!(
obligation.cause.span,
@ -2067,7 +2067,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}))
}
ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None,
ty::Alias(ty::Projection, _) | ty::Param(_) | ty::Alias(ty::Opaque, ..) => None,
ty::Infer(ty::TyVar(_)) => Ambiguous,
ty::Placeholder(..)
@ -2167,7 +2167,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::Adt(..) | ty::Projection(..) | ty::Param(..) | ty::Opaque(..) => {
ty::Adt(..)
| ty::Alias(ty::Projection, ..)
| ty::Param(..)
| ty::Alias(ty::Opaque, ..) => {
// Fallback to whatever user-defined impls exist in this case.
None
}
@ -2220,7 +2223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Dynamic(..)
| ty::Param(..)
| ty::Foreign(..)
| ty::Projection(..)
| ty::Alias(ty::Projection, ..)
| ty::Bound(..)
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("asked to assemble constituent types of unexpected type: {:?}", t);
@ -2260,7 +2263,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
}
ty::Opaque(ty::AliasTy { def_id, substs }) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.

View file

@ -95,10 +95,10 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
ty::Foreign(_) => {
return ControlFlow::Break(ty);
}
ty::Opaque(..) => {
ty::Alias(ty::Opaque, ..) => {
return ControlFlow::Break(ty);
}
ty::Projection(..) => {
ty::Alias(ty::Projection, ..) => {
return ControlFlow::Break(ty);
}
ty::Closure(..) => {

View file

@ -234,7 +234,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
// projection coming from another associated type. See
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
// `traits-assoc-type-in-supertrait-bad.rs`.
if let Some(ty::Projection(projection_ty)) = proj.term.ty().map(|ty| ty.kind())
if let Some(ty::Alias(ty::Projection, projection_ty)) = proj.term.ty().map(|ty| ty.kind())
&& let Some(&impl_item_id) =
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
&& let Some(impl_item_span) = items
@ -249,7 +249,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
// An associated item obligation born out of the `trait` failed to be met. An example
// can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
if let ty::Projection(ty::AliasTy { def_id, .. }) = *pred.self_ty().kind()
if let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = *pred.self_ty().kind()
&& let Some(&impl_item_id) =
tcx.impl_item_implementor_ids(impl_def_id).get(&def_id)
&& let Some(impl_item_span) = items
@ -556,7 +556,7 @@ impl<'tcx> WfPredicates<'tcx> {
// Simple cases that are WF if their type args are WF.
}
ty::Projection(data) => {
ty::Alias(ty::Projection, data) => {
walker.skip_current_subtree(); // Subtree handled by compute_projection.
self.compute_projection(data);
}
@ -648,7 +648,7 @@ impl<'tcx> WfPredicates<'tcx> {
// types appearing in the fn signature
}
ty::Opaque(ty::AliasTy { def_id, substs }) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
// All of the requirements on type parameters
// have already been checked for `impl Trait` in
// return position. We do need to check type-alias-impl-trait though.