1
Fork 0

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:
bors 2022-12-14 01:19:24 +00:00
commit 918d0ac38e
115 changed files with 632 additions and 674 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

@ -1636,8 +1636,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let normalized_ty = ocx.normalize(
&obligation.cause,
obligation.param_env,
self.tcx
.mk_projection(data.projection_ty.item_def_id, data.projection_ty.substs),
self.tcx.mk_projection(data.projection_ty.def_id, data.projection_ty.substs),
);
debug!(?obligation.cause, ?obligation.param_env);
@ -1688,10 +1687,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let secondary_span = match predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self
.tcx
.opt_associated_item(proj.projection_ty.item_def_id)
.opt_associated_item(proj.projection_ty.def_id)
.and_then(|trait_assoc_item| {
self.tcx
.trait_of_item(proj.projection_ty.item_def_id)
.trait_of_item(proj.projection_ty.def_id)
.map(|id| (trait_assoc_item, id))
})
.and_then(|(trait_assoc_item, id)| {
@ -1747,7 +1746,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_def_id = pred.projection_ty.trait_def_id(self.tcx);
let self_ty = pred.projection_ty.self_ty();
if Some(pred.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output() {
if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() {
Some(format!(
"expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it returns `{normalized_ty}`",
fn_kind = self_ty.prefix_string(self.tcx)
@ -1790,8 +1789,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

@ -371,7 +371,7 @@ fn suggest_restriction<'tcx>(
msg: &str,
err: &mut Diagnostic,
fn_sig: Option<&hir::FnSig<'_>>,
projection: Option<&ty::ProjectionTy<'_>>,
projection: Option<&ty::AliasTy<'_>>,
trait_pred: ty::PolyTraitPredicate<'tcx>,
// When we are dealing with a trait, `super_traits` will be `Some`:
// Given `trait T: A + B + C {}`
@ -497,7 +497,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),
};
@ -857,10 +857,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
))
}
ty::Opaque(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.item_def_id) == self.tcx.lang_items().fn_once_output()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
{
@ -877,7 +877,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::Dynamic(data, _, ty::Dyn) => {
data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
&& Some(proj.item_def_id) == self.tcx.lang_items().fn_once_output()
&& Some(proj.def_id) == self.tcx.lang_items().fn_once_output()
// for existential projection, substs are shifted over by 1
&& let ty::Tuple(args) = proj.substs.type_at(0).kind()
{
@ -894,7 +894,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::Param(_) => {
obligation.param_env.caller_bounds().iter().find_map(|pred| {
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
&& proj.projection_ty.self_ty() == found
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
@ -2641,7 +2641,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
Some(ident) => err.span_note(ident.span, &msg),
None => err.note(&msg),
},
ty::Opaque(def_id, _) => {
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;
@ -3218,7 +3218,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 };
@ -3245,7 +3245,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// This corresponds to `<ExprTy as Iterator>::Item = _`.
let trait_ref = ty::Binder::dummy(ty::PredicateKind::Clause(
ty::Clause::Projection(ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy { substs, item_def_id: proj.item_def_id },
projection_ty: ty::AliasTy { substs, def_id: proj.def_id },
term: ty_var.into(),
}),
));
@ -3260,7 +3260,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if ocx.select_where_possible().is_empty() {
// `ty_var` now holds the type that `Item` is for `ExprTy`.
let ty_var = self.resolve_vars_if_possible(ty_var);
assocs_in_this_method.push(Some((span, (proj.item_def_id, ty_var))));
assocs_in_this_method.push(Some((span, (proj.def_id, ty_var))));
} else {
// `<ExprTy as Iterator>` didn't select, so likely we've
// reached the end of the iterator chain, like the originating

View file

@ -589,7 +589,7 @@ fn object_ty_for_trait<'tcx>(
let pred = obligation.predicate.to_opt_poly_projection_pred()?;
Some(pred.map_bound(|p| {
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
item_def_id: p.projection_ty.item_def_id,
def_id: p.projection_ty.def_id,
substs: p.projection_ty.substs,
term: p.term,
})
@ -794,13 +794,13 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
ControlFlow::CONTINUE
}
}
ty::Projection(ref data)
if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder =>
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,10 +861,10 @@ 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()
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
&& let ty::Alias(ty::Projection, proj) = ty.kind()
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
{
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.item_def_id)))
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id)))
} else {
None
}

View file

@ -45,7 +45,7 @@ pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPre
pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>;
pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>;
pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>;
pub(super) struct InProgress;
@ -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(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
@ -957,7 +959,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
pub fn normalize_projection_type<'a, 'b, 'tcx>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
projection_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>,
depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>,
@ -995,7 +997,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
fn opt_normalize_projection_type<'a, 'b, 'tcx>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
projection_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>,
depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>,
@ -1177,7 +1179,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
fn normalize_to_error<'a, 'tcx>(
selcx: &mut SelectionContext<'a, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
projection_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>,
depth: usize,
) -> NormalizedTy<'tcx> {
@ -1189,10 +1191,9 @@ fn normalize_to_error<'a, 'tcx>(
predicate: trait_ref.without_const().to_predicate(selcx.tcx()),
};
let tcx = selcx.infcx.tcx;
let def_id = projection_ty.item_def_id;
let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::NormalizeProjectionType,
span: tcx.def_span(def_id),
span: tcx.def_span(projection_ty.def_id),
});
Normalized { value: new_value, obligations: vec![trait_obligation] }
}
@ -1270,7 +1271,7 @@ fn project<'cx, 'tcx>(
// need to investigate whether or not this is fine.
selcx
.tcx()
.mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs)
.mk_projection(obligation.predicate.def_id, obligation.predicate.substs)
.into(),
)),
// Error occurred while trying to processing impls.
@ -1290,13 +1291,12 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
candidate_set: &mut ProjectionCandidateSet<'tcx>,
) {
let tcx = selcx.tcx();
if tcx.def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
// If we are trying to project an RPITIT with trait's default `Self` parameter,
// then we must be within a default trait body.
if obligation.predicate.self_ty()
== ty::InternalSubsts::identity_for_item(tcx, obligation.predicate.item_def_id)
.type_at(0)
== ty::InternalSubsts::identity_for_item(tcx, obligation.predicate.def_id).type_at(0)
&& tcx.associated_item(trait_fn_def_id).defaultness(tcx).has_value()
{
candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(
@ -1377,8 +1377,7 @@ 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.item_def_id).subst(tcx, data.substs),
ty::Opaque(def_id, substs) => tcx.bound_item_bounds(def_id).subst(tcx, substs),
ty::Alias(_, ref data) => tcx.bound_item_bounds(data.def_id).subst(tcx, data.substs),
ty::Infer(ty::TyVar(_)) => {
// If the self-type is an inference variable, then it MAY wind up
// being a projected type, so induce an ambiguity.
@ -1430,7 +1429,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
};
let env_predicates = data
.projection_bounds()
.filter(|bound| bound.item_def_id() == obligation.predicate.item_def_id)
.filter(|bound| bound.item_def_id() == obligation.predicate.def_id)
.map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx));
assemble_candidates_from_predicates(
@ -1462,7 +1461,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
predicate.kind().skip_binder()
{
let data = bound_predicate.rebind(data);
if data.projection_def_id() != obligation.predicate.item_def_id {
if data.projection_def_id() != obligation.predicate.def_id {
continue;
}
@ -1503,7 +1502,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
candidate_set: &mut ProjectionCandidateSet<'tcx>,
) {
// Can't assemble candidate from impl for RPITIT
if selcx.tcx().def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
if selcx.tcx().def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
return;
}
@ -1555,7 +1554,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// NOTE: This should be kept in sync with the similar code in
// `rustc_ty_utils::instance::resolve_associated_item()`.
let node_item =
assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id)
assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.def_id)
.map_err(|ErrorGuaranteed { .. }| ())?;
if node_item.is_final() {
@ -1616,8 +1615,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::Alias(..)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(..)
@ -1671,7 +1669,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(..)
if selcx.infcx.predicate_must_hold_modulo_regions(
&obligation.with(
selcx.tcx(),
@ -1687,8 +1685,7 @@ 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::Bound(..)
| ty::Placeholder(..)
| ty::Infer(..)
@ -1788,7 +1785,7 @@ fn confirm_candidate<'cx, 'tcx>(
ProjectionCandidate::ImplTraitInTrait(ImplTraitInTraitCandidate::Trait) => Progress {
term: selcx
.tcx()
.mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs)
.mk_opaque(obligation.predicate.def_id, obligation.predicate.substs)
.into(),
obligations: vec![],
},
@ -1860,7 +1857,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
gen_sig,
)
.map_bound(|(trait_ref, yield_ty, return_ty)| {
let name = tcx.associated_item(obligation.predicate.item_def_id).name;
let name = tcx.associated_item(obligation.predicate.def_id).name;
let ty = if name == sym::Return {
return_ty
} else if name == sym::Yield {
@ -1870,9 +1867,9 @@ fn confirm_generator_candidate<'cx, 'tcx>(
};
ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy {
projection_ty: ty::AliasTy {
substs: trait_ref.substs,
item_def_id: obligation.predicate.item_def_id,
def_id: obligation.predicate.def_id,
},
term: ty.into(),
}
@ -1909,12 +1906,12 @@ fn confirm_future_candidate<'cx, 'tcx>(
gen_sig,
)
.map_bound(|(trait_ref, return_ty)| {
debug_assert_eq!(tcx.associated_item(obligation.predicate.item_def_id).name, sym::Output);
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output);
ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy {
projection_ty: ty::AliasTy {
substs: trait_ref.substs,
item_def_id: obligation.predicate.item_def_id,
def_id: obligation.predicate.def_id,
},
term: return_ty.into(),
}
@ -1934,7 +1931,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
let self_ty = obligation.predicate.self_ty();
let substs = tcx.mk_substs([self_ty.into()].iter());
let lang_items = tcx.lang_items();
let item_def_id = obligation.predicate.item_def_id;
let item_def_id = obligation.predicate.def_id;
let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
@ -1968,8 +1965,10 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
};
let predicate =
ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term };
let predicate = ty::ProjectionPredicate {
projection_ty: ty::AliasTy { substs, def_id: item_def_id },
term,
};
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
.with_addl_obligations(obligations)
@ -2038,10 +2037,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
flag,
)
.map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy {
substs: trait_ref.substs,
item_def_id: fn_once_output_def_id,
},
projection_ty: ty::AliasTy { substs: trait_ref.substs, def_id: fn_once_output_def_id },
term: ret_type.into(),
});
@ -2122,7 +2118,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
let tcx = selcx.tcx();
let ImplSourceUserDefinedData { impl_def_id, substs, mut nested } = impl_impl_source;
let assoc_item_id = obligation.predicate.item_def_id;
let assoc_item_id = obligation.predicate.def_id;
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
let param_env = obligation.param_env;
@ -2222,7 +2218,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
let tcx = selcx.tcx();
let mut obligations = data.nested;
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
return Progress { term: tcx.ty_error().into(), obligations };
};
@ -2233,9 +2229,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
// 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: tcx
.mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs)
.into(),
term: tcx.mk_opaque(obligation.predicate.def_id, obligation.predicate.substs).into(),
obligations,
};
}
@ -2302,7 +2296,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
obligation.recursion_depth + 1,
tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
.map_bound(|tys| {
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.def_id])
})
.subst(tcx, impl_fn_substs),
&mut obligations,
@ -2320,7 +2314,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
) {
let tcx = selcx.tcx();
let own = tcx
.predicates_of(obligation.predicate.item_def_id)
.predicates_of(obligation.predicate.def_id)
.instantiate_own(tcx, obligation.predicate.substs);
for (predicate, span) in std::iter::zip(own.predicates, own.spans) {
let normalized = normalize_with_depth_to(
@ -2343,13 +2337,13 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
ObligationCause::new(
obligation.cause.span,
obligation.cause.body_id,
super::ItemObligation(obligation.predicate.item_def_id),
super::ItemObligation(obligation.predicate.def_id),
)
} else {
ObligationCause::new(
obligation.cause.span,
obligation.cause.body_id,
super::BindingObligation(obligation.predicate.item_def_id, span),
super::BindingObligation(obligation.predicate.def_id, span),
)
};
nested.push(Obligation::with_depth(

View file

@ -62,9 +62,8 @@ 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::Param(_)
| 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(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::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
@ -536,10 +536,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let ty = traits::normalize_projection_type(
self,
param_env,
ty::ProjectionTy {
item_def_id: tcx.lang_items().deref_target()?,
substs: trait_ref.substs,
},
ty::AliasTy { def_id: tcx.lang_items().deref_target()?, substs: trait_ref.substs },
cause.clone(),
0,
// We're *intentionally* throwing these away,
@ -737,13 +734,12 @@ 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::Dynamic(..)
| ty::Error(_)
| ty::Bound(..)
| ty::Param(_)
| ty::Placeholder(_)
| ty::Projection(_) => {
| ty::Placeholder(_) => {
// We don't know if these are `~const Destruct`, at least
// not structurally... so don't push a candidate.
}
@ -829,8 +825,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)
| ty::Never
| ty::Projection(_)
| ty::Opaque(_, _)
| ty::Alias(..)
| ty::Param(_)
| ty::Bound(_, _)
| ty::Error(_)

View file

@ -155,8 +155,7 @@ 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.item_def_id, proj.substs),
ty::Opaque(def_id, substs) => (def_id, substs),
ty::Alias(_, ty::AliasTy { def_id, substs }) => (def_id, substs),
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
};
@ -184,7 +183,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 +1278,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,7 @@ 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.item_def_id, data.substs),
ty::Opaque(def_id, substs) => (def_id, substs),
ty::Alias(_, ty::AliasTy { def_id, substs }) => (def_id, substs),
_ => {
span_bug!(
obligation.cause.span,
@ -1745,7 +1744,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
});
if is_match {
let generics = self.tcx().generics_of(obligation.predicate.item_def_id);
let generics = self.tcx().generics_of(obligation.predicate.def_id);
// FIXME(generic-associated-types): Addresses aggressive inference in #92917.
// If this type is a GAT, and of the GAT substs resolve to something new,
// that means that we must have newly inferred something about the GAT.
@ -2067,7 +2066,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}))
}
ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None,
ty::Alias(..) | ty::Param(_) => None,
ty::Infer(ty::TyVar(_)) => Ambiguous,
ty::Placeholder(..)
@ -2167,7 +2166,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::Adt(..) | ty::Projection(..) | ty::Param(..) | ty::Opaque(..) => {
ty::Adt(..) | ty::Alias(..) | ty::Param(..) => {
// Fallback to whatever user-defined impls exist in this case.
None
}
@ -2220,7 +2219,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 +2259,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
}
ty::Opaque(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,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
ty::Foreign(_) => {
return ControlFlow::Break(ty);
}
ty::Opaque(..) => {
return ControlFlow::Break(ty);
}
ty::Projection(..) => {
ty::Alias(..) => {
return ControlFlow::Break(ty);
}
ty::Closure(..) => {

View file

@ -234,9 +234,9 @@ 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.item_def_id)
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
&& let Some(impl_item_span) = items
.iter()
.find(|item| item.id.owner_id.to_def_id() == impl_item_id)
@ -249,9 +249,9 @@ 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::ProjectionTy { item_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(&item_def_id)
tcx.impl_item_implementor_ids(impl_def_id).get(&def_id)
&& let Some(impl_item_span) = items
.iter()
.find(|item| item.id.owner_id.to_def_id() == impl_item_id)
@ -369,7 +369,7 @@ impl<'tcx> WfPredicates<'tcx> {
/// Pushes the obligations required for `trait_ref::Item` to be WF
/// into `self.out`.
fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) {
fn compute_projection(&mut self, data: ty::AliasTy<'tcx>) {
// A projection is well-formed if
//
// (a) its predicates hold (*)
@ -392,7 +392,7 @@ impl<'tcx> WfPredicates<'tcx> {
// `i32: Copy`
// ]
// Projection types do not require const predicates.
let obligations = self.nominal_obligations_without_const(data.item_def_id, data.substs);
let obligations = self.nominal_obligations_without_const(data.def_id, data.substs);
self.out.extend(obligations);
let tcx = self.tcx();
@ -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,12 +648,12 @@ impl<'tcx> WfPredicates<'tcx> {
// types appearing in the fn signature
}
ty::Opaque(did, 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.
if ty::is_impl_trait_defn(self.tcx, did).is_none() {
let obligations = self.nominal_obligations(did, substs);
if ty::is_impl_trait_defn(self.tcx, def_id).is_none() {
let obligations = self.nominal_obligations(def_id, substs);
self.out.extend(obligations);
}
}