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

@ -697,8 +697,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.map_bound(|p| p.predicates), .map_bound(|p| p.predicates),
None, None,
), ),
ty::Opaque(did, substs) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*did), Some(*substs)) find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*def_id), Some(*substs))
} }
ty::Closure(_, substs) => match substs.as_closure().kind() { ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not), ty::ClosureKind::Fn => Some(hir::Mutability::Not),

View file

@ -504,7 +504,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty; let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
if let ty::Opaque(def_id, _) = *output_ty.kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) = *output_ty.kind() {
output_ty = self.infcx.tcx.type_of(def_id) output_ty = self.infcx.tcx.type_of(def_id)
}; };

View file

@ -235,7 +235,7 @@ fn push_debuginfo_type_name<'tcx>(
let projection_bounds: SmallVec<[_; 4]> = trait_data let projection_bounds: SmallVec<[_; 4]> = trait_data
.projection_bounds() .projection_bounds()
.map(|bound| { .map(|bound| {
let ExistentialProjection { item_def_id, term, .. } = let ExistentialProjection { def_id: item_def_id, term, .. } =
tcx.erase_late_bound_regions(bound); tcx.erase_late_bound_regions(bound);
// FIXME(associated_const_equality): allow for consts here // FIXME(associated_const_equality): allow for consts here
(item_def_id, term.ty().unwrap()) (item_def_id, term.ty().unwrap())
@ -411,9 +411,8 @@ fn push_debuginfo_type_name<'tcx>(
ty::Error(_) ty::Error(_)
| ty::Infer(_) | ty::Infer(_)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Projection(..) | ty::Alias(..)
| ty::Bound(..) | ty::Bound(..)
| ty::Opaque(..)
| ty::GeneratorWitness(..) => { | ty::GeneratorWitness(..) => {
bug!( bug!(
"debuginfo: Trying to create type name for \ "debuginfo: Trying to create type name for \

View file

@ -142,12 +142,11 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
| ty::Foreign(..) | ty::Foreign(..)
| ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_)) | ty::Infer(ty::FreshFloatTy(_))
| ty::Projection(..) // FIXME(oli-obk): we could look behind opaque types
| ty::Alias(..)
| ty::Param(_) | ty::Param(_)
| ty::Bound(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Placeholder(..)
// FIXME(oli-obk): we could look behind opaque types
| ty::Opaque(..)
| ty::Infer(_) | ty::Infer(_)
// FIXME(oli-obk): we can probably encode closures just like structs // FIXME(oli-obk): we can probably encode closures just like structs
| ty::Closure(..) | ty::Closure(..)
@ -307,11 +306,10 @@ pub fn valtree_to_const_value<'tcx>(
| ty::Foreign(..) | ty::Foreign(..)
| ty::Infer(ty::FreshIntTy(_)) | ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_)) | ty::Infer(ty::FreshFloatTy(_))
| ty::Projection(..) | ty::Alias(..)
| ty::Param(_) | ty::Param(_)
| ty::Bound(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Opaque(..)
| ty::Infer(_) | ty::Infer(_)
| ty::Closure(..) | ty::Closure(..)
| ty::Generator(..) | ty::Generator(..)

View file

@ -82,11 +82,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
ty::Adt(ref adt, _) => { ty::Adt(ref adt, _) => {
ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx) ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx)
} }
ty::Projection(_) ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
| ty::Opaque(_, _) throw_inval!(TooGeneric)
| ty::Param(_) }
| ty::Placeholder(_)
| ty::Infer(_) => throw_inval!(TooGeneric),
ty::Bound(_, _) => bug!("bound ty during ctfe"), ty::Bound(_, _) => bug!("bound ty during ctfe"),
ty::Bool ty::Bool
| ty::Char | ty::Char

View file

@ -601,8 +601,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Bound(..) | ty::Bound(..)
| ty::Param(..) | ty::Param(..)
| ty::Opaque(..) | ty::Alias(..)
| ty::Projection(..)
| ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty), | ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
} }
} }

View file

@ -241,7 +241,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}; };
let kind = match parent_ty.ty.kind() { let kind = match parent_ty.ty.kind() {
&ty::Opaque(def_id, substs) => { &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind() self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind()
} }
kind => kind, kind => kind,
@ -652,7 +652,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation"); self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
} }
let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind(); let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
if !matches!(pty, ty::Adt(..) | ty::Generator(..) | ty::Opaque(..)) { if !matches!(pty, ty::Adt(..) | ty::Generator(..) | ty::Alias(ty::Opaque, ..)) {
self.fail( self.fail(
location, location,
format!( format!(

View file

@ -58,8 +58,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
// Types with identity (print the module path). // Types with identity (print the module path).
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs) ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
| ty::FnDef(def_id, substs) | ty::FnDef(def_id, substs)
| ty::Opaque(def_id, substs) | ty::Alias(_, ty::AliasTy { def_id, substs })
| ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
| ty::Closure(def_id, substs) | ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
ty::Foreign(def_id) => self.print_def_path(def_id, &[]), ty::Foreign(def_id) => self.print_def_path(def_id, &[]),

View file

@ -1146,10 +1146,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
debug!(?substs_trait_ref_and_assoc_item); debug!(?substs_trait_ref_and_assoc_item);
ty::ProjectionTy { ty::AliasTy { def_id: assoc_item.def_id, substs: substs_trait_ref_and_assoc_item }
item_def_id: assoc_item.def_id,
substs: substs_trait_ref_and_assoc_item,
}
}); });
if !speculative { if !speculative {
@ -1195,7 +1192,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// the "projection predicate" for: // the "projection predicate" for:
// //
// `<T as Iterator>::Item = u32` // `<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); let def_kind = tcx.def_kind(assoc_item_def_id);
match (def_kind, term.unpack()) { match (def_kind, term.unpack()) {
(hir::def::DefKind::AssocTy, ty::TermKind::Ty(_)) (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` // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
// parameter to have a skipped binder. // 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()); self.add_bounds(param_ty, ast_bounds.iter(), bounds, candidate.bound_vars());
} }
} }

View file

@ -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 { impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypeCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match *t.kind() { match *t.kind() {
ty::Opaque(def, _) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, substs: _ }) => {
self.0.push(def); self.0.push(def);
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }

View file

@ -571,10 +571,10 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
} }
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Projection(proj) = ty.kind() if let ty::Alias(ty::Projection, proj) = ty.kind()
&& self.tcx().def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder && 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; return *ty;
} }
//FIXME(RPITIT): Deny nested RPITIT in substs too //FIXME(RPITIT): Deny nested RPITIT in substs too
@ -586,9 +586,9 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
span: self.span, span: self.span,
kind: TypeVariableOriginKind::MiscVariable, 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 // 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 = pred.fold_with(self);
let pred = self.ocx.normalize( let pred = self.ocx.normalize(
&ObligationCause::misc(self.span, self.body_id), &ObligationCause::misc(self.span, self.body_id),
@ -601,7 +601,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
ObligationCause::new( ObligationCause::new(
self.span, self.span,
self.body_id, self.body_id,
ObligationCauseCode::BindingObligation(proj.item_def_id, pred_span), ObligationCauseCode::BindingObligation(proj.def_id, pred_span),
), ),
self.param_env, self.param_env,
pred, pred,
@ -1734,8 +1734,8 @@ pub fn check_type_bounds<'tcx>(
let normalize_param_env = { let normalize_param_env = {
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>(); let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
match impl_ty_value.kind() { match impl_ty_value.kind() {
ty::Projection(proj) ty::Alias(ty::Projection, proj)
if proj.item_def_id == trait_ty.def_id && proj.substs == rebased_substs => if proj.def_id == trait_ty.def_id && proj.substs == rebased_substs =>
{ {
// Don't include this predicate if the projected type is // Don't include this predicate if the projected type is
// exactly the same as the projection. This can occur in // exactly the same as the projection. This can occur in
@ -1746,8 +1746,8 @@ pub fn check_type_bounds<'tcx>(
_ => predicates.push( _ => predicates.push(
ty::Binder::bind_with_vars( ty::Binder::bind_with_vars(
ty::ProjectionPredicate { ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy { projection_ty: ty::AliasTy {
item_def_id: trait_ty.def_id, def_id: trait_ty.def_id,
substs: rebased_substs, substs: rebased_substs,
}, },
term: impl_ty_value.into(), term: impl_ty_value.into(),

View file

@ -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 // insert the associated types where they correspond, but for now let's be "lazy" and
// propose this instead of the following valid resugaring: // propose this instead of the following valid resugaring:
// `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>` // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
where_clauses.push(format!( where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.def_id), p.term));
"{} = {}",
tcx.def_path_str(p.projection_ty.item_def_id),
p.term,
));
} }
let where_clauses = if where_clauses.is_empty() { let where_clauses = if where_clauses.is_empty() {
String::new() String::new()

View file

@ -759,7 +759,7 @@ impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() { 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() { for (idx, subst) in p.substs.iter().enumerate() {
match subst.unpack() { match subst.unpack() {
GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => { 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() { for arg in fn_output.walk() {
if let ty::GenericArgKind::Type(ty) = arg.unpack() 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.item_def_id) == DefKind::ImplTraitPlaceholder && tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
&& tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id() && 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 span = tcx.def_span(proj.def_id);
let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id); let bounds = wfcx.tcx().explicit_item_bounds(proj.def_id);
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs); let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs);
let normalized_bound = wfcx.normalize(span, None, bound); let normalized_bound = wfcx.normalize(span, None, bound);

View file

@ -223,7 +223,7 @@ impl<'tcx> InherentCollect<'tcx> {
| ty::Tuple(..) => { | ty::Tuple(..) => {
self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span) 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!( let mut err = struct_span_err!(
self.tcx.sess, self.tcx.sess,
ty.span, ty.span,

View file

@ -1749,7 +1749,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
ty::Param(param_ty) => { ty::Param(param_ty) => {
self.arg_is_constrained[param_ty.index as usize] = true; 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) t.super_visit_with(self)

View file

@ -408,9 +408,9 @@ pub(super) fn explicit_predicates_of<'tcx>(
// identity substs of the trait. // identity substs of the trait.
// * It must be an associated type for this trait (*not* a // * It must be an associated type for this trait (*not* a
// supertrait). // supertrait).
if let ty::Projection(projection) = ty.kind() { if let ty::Alias(ty::Projection, projection) = ty.kind() {
projection.substs == trait_identity_substs 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 { } else {
false false
} }

View file

@ -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 // Using the ItemCtxt convert the HIR for the unresolved assoc type into a
// ty which is a fully resolved projection. // ty which is a fully resolved projection.
// For the code example above, this would mean converting Self::Assoc<3> // 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 let item_hir_id = tcx
.hir() .hir()
.parent_iter(hir_id) .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 // 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 // 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 ^^ // but it can't hurt to be safe ^^
if let ty::Projection(projection) = ty.kind() { if let ty::Alias(ty::Projection, projection) = ty.kind() {
let generics = tcx.generics_of(projection.item_def_id); let generics = tcx.generics_of(projection.def_id);
let arg_index = segment let arg_index = segment
.args .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 hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let scope = tcx.hir().get_defining_scope(hir_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); debug!(?scope);
@ -803,7 +803,7 @@ fn find_opaque_ty_constraints_for_rpit(
if let Some(concrete) = concrete { if let Some(concrete) = concrete {
let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id); let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id);
debug!(?scope); 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) { match tcx.hir().get(scope) {
Node::Item(it) => intravisit::walk_item(&mut locator, it), Node::Item(it) => intravisit::walk_item(&mut locator, it),

View file

@ -59,7 +59,7 @@ struct ParameterCollector {
impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match *t.kind() { match *t.kind() {
ty::Projection(..) if !self.include_nonconstraining => { ty::Alias(ty::Projection, ..) if !self.include_nonconstraining => {
// projections are not injective // projections are not injective
return ControlFlow::CONTINUE; return ControlFlow::CONTINUE;
} }

View file

@ -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 // This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
// explicit predicates as well. // explicit predicates as well.
debug!("Projection"); debug!("Projection");
check_explicit_predicates( check_explicit_predicates(
tcx, tcx,
tcx.parent(obj.item_def_id), tcx.parent(obj.def_id),
obj.substs, obj.substs,
required_predicates, required_predicates,
explicit_map, explicit_map,

View file

@ -90,7 +90,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
// ``` // ```
// //
// Here we want to add an explicit `where <T as Iterator>::Item: 'a`. // 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 required_predicates
.entry(ty::OutlivesPredicate(ty.into(), outlived_region)) .entry(ty::OutlivesPredicate(ty.into(), outlived_region))
.or_insert(span); .or_insert(span);

View file

@ -249,14 +249,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_substs(current, def.did(), substs, variance); 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); 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, _) => { ty::Dynamic(data, r, _) => {
// The type `Foo<T+'a>` is contravariant w/r/t `'a`: // The type `Foo<T+'a>` is contravariant w/r/t `'a`:
let contra = self.contravariant(variance); let contra = self.contravariant(variance);

View file

@ -111,11 +111,13 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
#[instrument(level = "trace", skip(self), ret)] #[instrument(level = "trace", skip(self), ret)]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() { match t.kind() {
ty::Opaque(def_id, substs) => self.visit_opaque(*def_id, substs), ty::Alias(_, ty::AliasTy { def_id, substs })
ty::Projection(proj) if matches!(
if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder => 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), _ => 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 { ty::PredicateKind::Clause(ty::Clause::Projection(ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy { substs, item_def_id: _ }, projection_ty: ty::AliasTy { substs, def_id: _ },
term, term,
})) => { })) => {
for subst in &substs[1..] { for subst in &substs[1..] {

View file

@ -212,7 +212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.can_coerce(arm_ty, ret_ty) self.can_coerce(arm_ty, ret_ty)
&& prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty)) && prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty))
// The match arms need to unify for the case of `impl Trait`. // The match arms need to unify for the case of `impl Trait`.
&& !matches!(ret_ty.kind(), ty::Opaque(..)) && !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..))
} }
_ => false, _ => false,
}; };
@ -518,7 +518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let substs = sig.output().walk().find_map(|arg| { let substs = sig.output().walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack() if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Opaque(def_id, substs) = *ty.kind() && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) = *ty.kind()
&& def_id == rpit_def_id && def_id == rpit_def_id
{ {
Some(substs) Some(substs)

View file

@ -38,7 +38,6 @@ use rustc_middle::mir::Mutability;
use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::adjustment::AllowTwoPhase;
use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::cast::{CastKind, CastTy};
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable, VariantDef}; use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable, VariantDef};
use rustc_session::lint; use rustc_session::lint;
use rustc_session::Session; use rustc_session::Session;
@ -75,10 +74,8 @@ enum PointerKind<'tcx> {
VTable(Option<DefId>), VTable(Option<DefId>),
/// Slice /// Slice
Length, Length,
/// The unsize info of this projection /// The unsize info of this projection or opaque type
OfProjection(ty::ProjectionTy<'tcx>), OfAlias(ty::AliasTy<'tcx>),
/// The unsize info of this opaque ty
OfOpaque(DefId, SubstsRef<'tcx>),
/// The unsize info of this parameter /// The unsize info of this parameter
OfParam(ty::ParamTy), OfParam(ty::ParamTy),
} }
@ -118,8 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Pointers to foreign types are thin, despite being unsized // Pointers to foreign types are thin, despite being unsized
ty::Foreign(..) => Some(PointerKind::Thin), ty::Foreign(..) => Some(PointerKind::Thin),
// We should really try to normalize here. // We should really try to normalize here.
ty::Projection(pi) => Some(PointerKind::OfProjection(pi)), ty::Alias(_, pi) => Some(PointerKind::OfAlias(pi)),
ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)),
ty::Param(p) => Some(PointerKind::OfParam(p)), ty::Param(p) => Some(PointerKind::OfParam(p)),
// Insufficient type information. // Insufficient type information.
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None, ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,
@ -976,11 +972,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
Some(PointerKind::Thin) => Ok(CastKind::AddrPtrCast), Some(PointerKind::Thin) => Ok(CastKind::AddrPtrCast),
Some(PointerKind::VTable(_)) => Err(CastError::IntToFatCast(Some("a vtable"))), Some(PointerKind::VTable(_)) => Err(CastError::IntToFatCast(Some("a vtable"))),
Some(PointerKind::Length) => Err(CastError::IntToFatCast(Some("a length"))), Some(PointerKind::Length) => Err(CastError::IntToFatCast(Some("a length"))),
Some( Some(PointerKind::OfAlias(_) | PointerKind::OfParam(_)) => {
PointerKind::OfProjection(_) Err(CastError::IntToFatCast(None))
| PointerKind::OfOpaque(_, _) }
| PointerKind::OfParam(_),
) => Err(CastError::IntToFatCast(None)),
} }
} }

View file

@ -167,7 +167,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) { ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
match *expected_ty.kind() { match *expected_ty.kind() {
ty::Opaque(def_id, substs) => self.deduce_signature_from_predicates( ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => self
.deduce_signature_from_predicates(
self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs), self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs),
), ),
ty::Dynamic(ref object_type, ..) => { ty::Dynamic(ref object_type, ..) => {
@ -677,17 +678,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
get_future_output(obligation.predicate, obligation.cause.span) get_future_output(obligation.predicate, obligation.cause.span)
})? })?
} }
ty::Opaque(def_id, substs) => self ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => self
.tcx .tcx
.bound_explicit_item_bounds(def_id) .bound_explicit_item_bounds(def_id)
.subst_iter_copied(self.tcx, substs) .subst_iter_copied(self.tcx, substs)
.find_map(|(p, s)| get_future_output(p, s))?, .find_map(|(p, s)| get_future_output(p, s))?,
ty::Error(_) => return None, ty::Error(_) => return None,
ty::Projection(proj) ty::Alias(ty::Projection, proj)
if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder => if self.tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder =>
{ {
self.tcx self.tcx
.bound_explicit_item_bounds(proj.item_def_id) .bound_explicit_item_bounds(proj.def_id)
.subst_iter_copied(self.tcx, proj.substs) .subst_iter_copied(self.tcx, proj.substs)
.find_map(|(p, s)| get_future_output(p, s))? .find_map(|(p, s)| get_future_output(p, s))?
} }
@ -743,11 +744,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// The `Future` trait has only one associated item, `Output`, // The `Future` trait has only one associated item, `Output`,
// so check that this is what we see. // so check that this is what we see.
let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0]; let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0];
if output_assoc_item != predicate.projection_ty.item_def_id { if output_assoc_item != predicate.projection_ty.def_id {
span_bug!( span_bug!(
cause_span, cause_span,
"projecting associated item `{:?}` from future, which is not Output `{:?}`", "projecting associated item `{:?}` from future, which is not Output `{:?}`",
predicate.projection_ty.item_def_id, predicate.projection_ty.def_id,
output_assoc_item, output_assoc_item,
); );
} }

View file

@ -1805,7 +1805,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
{ {
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty); let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty);
// Get the `impl Trait`'s `DefId`. // Get the `impl Trait`'s `DefId`.
if let ty::Opaque(def_id, _) = ty.kind() if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) = ty.kind()
// Get the `impl Trait`'s `Item` so that we can get its trait bounds and // Get the `impl Trait`'s `Item` so that we can get its trait bounds and
// get the `Trait`'s `DefId`. // get the `Trait`'s `DefId`.
&& let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) = && let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) =

View file

@ -2391,7 +2391,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Param(param_ty) => { ty::Param(param_ty) => {
self.point_at_param_definition(&mut err, param_ty); self.point_at_param_definition(&mut err, param_ty);
} }
ty::Opaque(_, _) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id: _, substs: _ }) => {
self.suggest_await_on_field_access(&mut err, ident, base, base_ty.peel_refs()); self.suggest_await_on_field_access(&mut err, ident, base, base_ty.peel_refs());
} }
_ => {} _ => {}

View file

@ -716,7 +716,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if formal_ret.has_infer_types() { if formal_ret.has_infer_types() {
for ty in ret_ty.walk() { for ty in ret_ty.walk() {
if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() if let ty::subst::GenericArgKind::Type(ty) = ty.unpack()
&& let ty::Opaque(def_id, _) = *ty.kind() && let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) = *ty.kind()
&& let Some(def_id) = def_id.as_local() && let Some(def_id) = def_id.as_local()
&& self.opaque_type_origin(def_id, DUMMY_SP).is_some() { && self.opaque_type_origin(def_id, DUMMY_SP).is_some() {
return None; return None;

View file

@ -2124,7 +2124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
} }
ty::Opaque(new_def_id, _) ty::Alias(ty::Opaque, ty::AliasTy { def_id: new_def_id, substs: _ })
| ty::Closure(new_def_id, _) | ty::Closure(new_def_id, _)
| ty::FnDef(new_def_id, _) => { | ty::FnDef(new_def_id, _) => {
def_id = new_def_id; def_id = new_def_id;
@ -2217,7 +2217,7 @@ fn find_param_in_ty<'tcx>(ty: Ty<'tcx>, param_to_point_at: ty::GenericArg<'tcx>)
if arg == param_to_point_at { if arg == param_to_point_at {
return true; return true;
} else if let ty::GenericArgKind::Type(ty) = arg.unpack() } else if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(..) = ty.kind() && let ty::Alias(ty::Projection, ..) = ty.kind()
{ {
// This logic may seem a bit strange, but typically when // This logic may seem a bit strange, but typically when
// we have a projection type in a function signature, the // we have a projection type in a function signature, the

View file

@ -174,10 +174,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let fn_sig = substs.as_closure().sig(); let fn_sig = substs.as_closure().sig();
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs().map_bound(|inputs| &inputs[1..]))) Some((DefIdOrName::DefId(def_id), fn_sig.output(), 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| { 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() 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] // args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind() && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
{ {
@ -194,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Dynamic(data, _, ty::Dyn) => { ty::Dynamic(data, _, ty::Dyn) => {
data.iter().find_map(|pred| { data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder() 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 // for existential projection, substs are shifted over by 1
&& let ty::Tuple(args) = proj.substs.type_at(0).kind() && let ty::Tuple(args) = proj.substs.type_at(0).kind()
{ {
@ -212,7 +212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let def_id = self.tcx.generics_of(self.body_id.owner).type_param(&param, self.tcx).def_id; let def_id = self.tcx.generics_of(self.body_id.owner).type_param(&param, self.tcx).def_id;
self.tcx.predicates_of(self.body_id.owner).predicates.iter().find_map(|(pred, _)| { self.tcx.predicates_of(self.body_id.owner).predicates.iter().find_map(|(pred, _)| {
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder() 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 && proj.projection_ty.self_ty() == found
// args tuple will always be substs[1] // args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind() && let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()

View file

@ -563,7 +563,7 @@ fn check_must_not_suspend_ty<'tcx>(
} }
ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did(), hir_id, data), ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did(), hir_id, data),
// FIXME: support adding the attribute to TAITs // FIXME: support adding the attribute to TAITs
ty::Opaque(def, _) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, substs: _ }) => {
let mut has_emitted = false; let mut has_emitted = false;
for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) { for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) {
// We only look at the `DefId`, so it is safe to skip the binder here. // We only look at the `DefId`, so it is safe to skip the binder here.

View file

@ -557,9 +557,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.chain(projection_ty.substs.iter().skip(1)), .chain(projection_ty.substs.iter().skip(1)),
); );
let quiet_projection_ty = ty::ProjectionTy { let quiet_projection_ty = ty::AliasTy {
substs: substs_with_infer_self, substs: substs_with_infer_self,
item_def_id: projection_ty.item_def_id, def_id: projection_ty.def_id,
}; };
let term = pred.skip_binder().term; let term = pred.skip_binder().term;
@ -1982,7 +1982,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Float(_) | ty::Float(_)
| ty::Adt(_, _) | ty::Adt(_, _)
| ty::Str | ty::Str
| ty::Projection(_) | ty::Alias(ty::Projection, _)
| ty::Param(_) => format!("{deref_ty}"), | ty::Param(_) => format!("{deref_ty}"),
// we need to test something like <&[_]>::len or <(&[u32])>::len // we need to test something like <&[_]>::len or <(&[u32])>::len
// and Vec::function(); // and Vec::function();
@ -2282,7 +2282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
t.def_id() == info.def_id t.def_id() == info.def_id
} }
ty::PredicateKind::Clause(ty::Clause::Projection(p)) => { ty::PredicateKind::Clause(ty::Clause::Projection(p)) => {
p.projection_ty.item_def_id == info.def_id p.projection_ty.def_id == info.def_id
} }
_ => false, _ => false,
} }

View file

@ -546,7 +546,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
impl<'tcx> ty::TypeVisitor<'tcx> for RecursionChecker { impl<'tcx> ty::TypeVisitor<'tcx> for RecursionChecker {
type BreakTy = (); type BreakTy = ();
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::Opaque(def_id, _) = *t.kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) = *t.kind() {
if def_id == self.def_id.to_def_id() { if def_id == self.def_id.to_def_id() {
return ControlFlow::Break(()); return ControlFlow::Break(());
} }

View file

@ -411,7 +411,7 @@ impl<'tcx> ToTrace<'tcx> for ty::PolyTraitRef<'tcx> {
} }
} }
impl<'tcx> ToTrace<'tcx> for ty::ProjectionTy<'tcx> { impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> {
fn to_trace( fn to_trace(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
@ -419,8 +419,8 @@ impl<'tcx> ToTrace<'tcx> for ty::ProjectionTy<'tcx> {
a: Self, a: Self,
b: Self, b: Self,
) -> TypeTrace<'tcx> { ) -> TypeTrace<'tcx> {
let a_ty = tcx.mk_projection(a.item_def_id, a.substs); let a_ty = tcx.mk_projection(a.def_id, a.substs);
let b_ty = tcx.mk_projection(b.item_def_id, b.substs); let b_ty = tcx.mk_projection(b.def_id, b.substs);
TypeTrace { TypeTrace {
cause: cause.clone(), cause: cause.clone(),
values: Terms(ExpectedFound::new(a_is_expected, a_ty.into(), b_ty.into())), values: Terms(ExpectedFound::new(a_is_expected, a_ty.into(), b_ty.into())),

View file

@ -453,10 +453,9 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
| ty::Dynamic(..) | ty::Dynamic(..)
| ty::Never | ty::Never
| ty::Tuple(..) | ty::Tuple(..)
| ty::Projection(..) | ty::Alias(..)
| ty::Foreign(..) | ty::Foreign(..)
| ty::Param(..) | ty::Param(..) => {
| ty::Opaque(..) => {
if t.flags().intersects(self.needs_canonical_flags) { if t.flags().intersects(self.needs_canonical_flags) {
t.super_fold_with(self) t.super_fold_with(self)
} else { } else {

View file

@ -675,7 +675,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
// relatable. // relatable.
Ok(t) Ok(t)
} }
ty::Opaque(def_id, substs) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
let s = self.relate(substs, substs)?; let s = self.relate(substs, substs)?;
Ok(if s == substs { t } else { self.infcx.tcx.mk_opaque(def_id, s) }) Ok(if s == substs { t } else { self.infcx.tcx.mk_opaque(def_id, s) })
} }

View file

@ -100,11 +100,15 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?; self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
} }
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { (
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: _ }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: _ }),
) if a_def_id == b_def_id => {
self.fields.infcx.super_combine_tys(self, a, b)?; self.fields.infcx.super_combine_tys(self, a, b)?;
} }
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }), _)
if self.fields.define_opaque_types && did.is_local() => | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }))
if self.fields.define_opaque_types && def_id.is_local() =>
{ {
self.fields.obligations.extend( self.fields.obligations.extend(
infcx infcx

View file

@ -339,11 +339,13 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>(
impl<'tcx> InferCtxt<'tcx> { impl<'tcx> InferCtxt<'tcx> {
pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> { pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
let (def_id, substs) = match *ty.kind() { let (def_id, substs) = match *ty.kind() {
ty::Opaque(def_id, substs) => (def_id, substs), ty::Alias(_, ty::AliasTy { def_id, substs })
ty::Projection(data) if matches!(
if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder => self.tcx.def_kind(def_id),
DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder
) =>
{ {
(data.item_def_id, data.substs) (def_id, substs)
} }
_ => return None, _ => return None,
}; };
@ -357,7 +359,7 @@ impl<'tcx> InferCtxt<'tcx> {
.kind() .kind()
.map_bound(|kind| match kind { .map_bound(|kind| match kind {
ty::PredicateKind::Clause(ty::Clause::Projection(projection_predicate)) ty::PredicateKind::Clause(ty::Clause::Projection(projection_predicate))
if projection_predicate.projection_ty.item_def_id == item_def_id => if projection_predicate.projection_ty.def_id == item_def_id =>
{ {
projection_predicate.term.ty() projection_predicate.term.ty()
} }
@ -1730,7 +1732,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let extra = expected == found; let extra = expected == found;
let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| { let sort_string = |ty: Ty<'tcx>, path: Option<PathBuf>| {
let mut s = match (extra, ty.kind()) { let mut s = match (extra, ty.kind()) {
(true, ty::Opaque(def_id, _)) => { (true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
let sm = self.tcx.sess.source_map(); let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
format!( format!(
@ -1740,12 +1742,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
pos.col.to_usize() + 1, pos.col.to_usize() + 1,
) )
} }
(true, ty::Projection(proj)) (true, ty::Alias(ty::Projection, proj))
if self.tcx.def_kind(proj.item_def_id) if self.tcx.def_kind(proj.def_id)
== DefKind::ImplTraitPlaceholder => == DefKind::ImplTraitPlaceholder =>
{ {
let sm = self.tcx.sess.source_map(); let sm = self.tcx.sess.source_map();
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.item_def_id).lo()); let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
format!( format!(
" (trait associated opaque type at <{}:{}:{}>)", " (trait associated opaque type at <{}:{}:{}>)",
sm.filename_for_diagnostics(&pos.file.name), sm.filename_for_diagnostics(&pos.file.name),
@ -2383,7 +2385,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ // fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
// suggest: // suggest:
// fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
ty::Closure(_, _substs) | ty::Opaque(_, _substs) if return_impl_trait => { ty::Closure(..) | ty::Alias(ty::Opaque, ..) if return_impl_trait => {
new_binding_suggestion(&mut err, type_param_span); new_binding_suggestion(&mut err, type_param_span);
} }
_ => { _ => {
@ -2765,7 +2767,9 @@ impl TyCategory {
pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> { pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> {
match *ty.kind() { match *ty.kind() {
ty::Closure(def_id, _) => Some((Self::Closure, def_id)), ty::Closure(def_id, _) => Some((Self::Closure, def_id)),
ty::Opaque(def_id, _) => Some((Self::Opaque, def_id)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) => {
Some((Self::Opaque, def_id))
}
ty::Generator(def_id, ..) => { ty::Generator(def_id, ..) => {
Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), def_id)) Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), def_id))
} }

View file

@ -852,7 +852,10 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
match inner.unpack() { match inner.unpack() {
GenericArgKind::Lifetime(_) => {} GenericArgKind::Lifetime(_) => {}
GenericArgKind::Type(ty) => { GenericArgKind::Type(ty) => {
if matches!(ty.kind(), ty::Opaque(..) | ty::Closure(..) | ty::Generator(..)) { if matches!(
ty.kind(),
ty::Alias(ty::Opaque, ..) | ty::Closure(..) | ty::Generator(..)
) {
// Opaque types can't be named by the user right now. // Opaque types can't be named by the user right now.
// //
// Both the generic arguments of closures and generators can // Both the generic arguments of closures and generators can

View file

@ -486,12 +486,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
_ if self.same_type_modulo_infer(last_expr_ty, expected_ty) => { _ if self.same_type_modulo_infer(last_expr_ty, expected_ty) => {
StatementAsExpression::CorrectType StatementAsExpression::CorrectType
} }
(ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _)) (
if last_def_id == exp_def_id => ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, substs: _ }),
{ ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, substs: _ }),
StatementAsExpression::CorrectType ) if last_def_id == exp_def_id => StatementAsExpression::CorrectType,
} (
(ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, substs: last_bounds }),
ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, substs: exp_bounds }),
) => {
debug!( debug!(
"both opaque, likely future {:?} {:?} {:?} {:?}", "both opaque, likely future {:?} {:?} {:?} {:?}",
last_def_id, last_bounds, exp_def_id, exp_bounds last_def_id, last_bounds, exp_def_id, exp_bounds

View file

@ -205,12 +205,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
| ty::Dynamic(..) | ty::Dynamic(..)
| ty::Never | ty::Never
| ty::Tuple(..) | ty::Tuple(..)
| ty::Projection(..) | ty::Alias(..)
| ty::Foreign(..) | ty::Foreign(..)
| ty::Param(..) | ty::Param(..)
| ty::Closure(..) | ty::Closure(..)
| ty::GeneratorWitness(..) | ty::GeneratorWitness(..) => t.super_fold_with(self),
| ty::Opaque(..) => t.super_fold_with(self),
ty::Placeholder(..) | ty::Bound(..) => bug!("unexpected type {:?}", t), ty::Placeholder(..) | ty::Bound(..) => bug!("unexpected type {:?}", t),
} }

View file

@ -105,11 +105,13 @@ where
Ok(v) Ok(v)
} }
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { (
infcx.super_combine_tys(this, a, b) &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: _ }),
} &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: _ }),
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) ) if a_def_id == b_def_id => infcx.super_combine_tys(this, a, b),
if this.define_opaque_types() && did.is_local() => (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }), _)
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }))
if this.define_opaque_types() && def_id.is_local() =>
{ {
this.add_obligations( this.add_obligations(
infcx infcx

View file

@ -275,13 +275,13 @@ where
/// `ProjectionEq(projection = ?U)`, `ProjectionEq(other_projection = ?U)`. /// `ProjectionEq(projection = ?U)`, `ProjectionEq(other_projection = ?U)`.
fn relate_projection_ty( fn relate_projection_ty(
&mut self, &mut self,
projection_ty: ty::ProjectionTy<'tcx>, projection_ty: ty::AliasTy<'tcx>,
value_ty: Ty<'tcx>, value_ty: Ty<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
use rustc_span::DUMMY_SP; use rustc_span::DUMMY_SP;
match *value_ty.kind() { match *value_ty.kind() {
ty::Projection(other_projection_ty) => { ty::Alias(ty::Projection, other_projection_ty) => {
let var = self.infcx.next_ty_var(TypeVariableOrigin { let var = self.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable, kind: TypeVariableOriginKind::MiscVariable,
span: DUMMY_SP, span: DUMMY_SP,
@ -335,7 +335,9 @@ where
return Ok(value_ty); return Ok(value_ty);
} }
ty::Projection(projection_ty) if D::normalization() == NormalizationStrategy::Lazy => { ty::Alias(ty::Projection, projection_ty)
if D::normalization() == NormalizationStrategy::Lazy =>
{
return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid))); return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid)));
} }
@ -406,8 +408,8 @@ where
} }
}; };
let (a, b) = match (a.kind(), b.kind()) { let (a, b) = match (a.kind(), b.kind()) {
(&ty::Opaque(..), _) => (a, generalize(b, false)?), (&ty::Alias(ty::Opaque, ..), _) => (a, generalize(b, false)?),
(_, &ty::Opaque(..)) => (generalize(a, true)?, b), (_, &ty::Alias(ty::Opaque, ..)) => (generalize(a, true)?, b),
_ => unreachable!(), _ => unreachable!(),
}; };
let cause = ObligationCause::dummy_with_span(self.delegate.span()); let cause = ObligationCause::dummy_with_span(self.delegate.span());
@ -608,26 +610,30 @@ where
(&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)), (&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { (
infcx.super_combine_tys(self, a, b).or_else(|err| { &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: _ }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: _ }),
) if a_def_id == b_def_id => infcx.super_combine_tys(self, a, b).or_else(|err| {
self.tcx().sess.delay_span_bug( self.tcx().sess.delay_span_bug(
self.delegate.span(), self.delegate.span(),
"failure to relate an opaque to itself should result in an error later on", "failure to relate an opaque to itself should result in an error later on",
); );
if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) } if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) }
}) }),
} (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }), _)
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) if did.is_local() => { | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }))
if def_id.is_local() =>
{
self.relate_opaques(a, b) self.relate_opaques(a, b)
} }
(&ty::Projection(projection_ty), _) (&ty::Alias(ty::Projection, projection_ty), _)
if D::normalization() == NormalizationStrategy::Lazy => if D::normalization() == NormalizationStrategy::Lazy =>
{ {
Ok(self.relate_projection_ty(projection_ty, b)) Ok(self.relate_projection_ty(projection_ty, b))
} }
(_, &ty::Projection(projection_ty)) (_, &ty::Alias(ty::Projection, projection_ty))
if D::normalization() == NormalizationStrategy::Lazy => if D::normalization() == NormalizationStrategy::Lazy =>
{ {
Ok(self.relate_projection_ty(projection_ty, a)) Ok(self.relate_projection_ty(projection_ty, a))

View file

@ -66,7 +66,9 @@ impl<'tcx> InferCtxt<'tcx> {
lt_op: |lt| lt, lt_op: |lt| lt,
ct_op: |ct| ct, ct_op: |ct| ct,
ty_op: |ty| match *ty.kind() { ty_op: |ty| match *ty.kind() {
ty::Opaque(def_id, _substs) if replace_opaque_type(def_id) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ })
if replace_opaque_type(def_id) =>
{
let def_span = self.tcx.def_span(def_id); let def_span = self.tcx.def_span(def_id);
let span = if span.contains(def_span) { def_span } else { span }; let span = if span.contains(def_span) { def_span } else { span };
let code = traits::ObligationCauseCode::OpaqueReturnType(None); let code = traits::ObligationCauseCode::OpaqueReturnType(None);
@ -104,7 +106,7 @@ impl<'tcx> InferCtxt<'tcx> {
} }
let (a, b) = if a_is_expected { (a, b) } else { (b, a) }; let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() { let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
ty::Opaque(def_id, substs) if def_id.is_local() => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) if def_id.is_local() => {
let def_id = def_id.expect_local(); let def_id = def_id.expect_local();
let origin = match self.defining_use_anchor { let origin = match self.defining_use_anchor {
DefiningAnchor::Bind(_) => { DefiningAnchor::Bind(_) => {
@ -147,18 +149,21 @@ impl<'tcx> InferCtxt<'tcx> {
DefiningAnchor::Bubble => self.opaque_ty_origin_unchecked(def_id, cause.span), DefiningAnchor::Bubble => self.opaque_ty_origin_unchecked(def_id, cause.span),
DefiningAnchor::Error => return None, DefiningAnchor::Error => return None,
}; };
if let ty::Opaque(did2, _) = *b.kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: _ }) =
*b.kind()
{
// We could accept this, but there are various ways to handle this situation, and we don't // We could accept this, but there are various ways to handle this situation, and we don't
// want to make a decision on it right now. Likely this case is so super rare anyway, that // want to make a decision on it right now. Likely this case is so super rare anyway, that
// no one encounters it in practice. // no one encounters it in practice.
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`, // It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
// where it is of no concern, so we only check for TAITs. // where it is of no concern, so we only check for TAITs.
if let Some(OpaqueTyOrigin::TyAlias) = if let Some(OpaqueTyOrigin::TyAlias) = b_def_id
did2.as_local().and_then(|did2| self.opaque_type_origin(did2, cause.span)) .as_local()
.and_then(|b_def_id| self.opaque_type_origin(b_def_id, cause.span))
{ {
self.tcx.sess.emit_err(OpaqueHiddenTypeDiag { self.tcx.sess.emit_err(OpaqueHiddenTypeDiag {
span: cause.span, span: cause.span,
hidden_type: self.tcx.def_span(did2), hidden_type: self.tcx.def_span(b_def_id),
opaque_type: self.tcx.def_span(def_id), opaque_type: self.tcx.def_span(def_id),
}); });
} }
@ -475,7 +480,7 @@ where
substs.as_generator().resume_ty().visit_with(self); substs.as_generator().resume_ty().visit_with(self);
} }
ty::Opaque(def_id, ref substs) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, ref substs }) => {
// Skip lifetime paramters that are not captures. // Skip lifetime paramters that are not captures.
let variances = self.tcx.variances_of(*def_id); let variances = self.tcx.variances_of(*def_id);
@ -486,11 +491,11 @@ where
} }
} }
ty::Projection(proj) ty::Alias(ty::Projection, proj)
if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder => if self.tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder =>
{ {
// Skip lifetime paramters that are not captures. // Skip lifetime paramters that are not captures.
let variances = self.tcx.variances_of(proj.item_def_id); let variances = self.tcx.variances_of(proj.def_id);
for (v, s) in std::iter::zip(variances, proj.substs.iter()) { for (v, s) in std::iter::zip(variances, proj.substs.iter()) {
if *v != ty::Variance::Bivariant { if *v != ty::Variance::Bivariant {
@ -563,9 +568,9 @@ impl<'tcx> InferCtxt<'tcx> {
// We can't normalize associated types from `rustc_infer`, // We can't normalize associated types from `rustc_infer`,
// but we can eagerly register inference variables for them. // but we can eagerly register inference variables for them.
// FIXME(RPITIT): Don't replace RPITITs with inference vars. // FIXME(RPITIT): Don't replace RPITITs with inference vars.
ty::Projection(projection_ty) ty::Alias(ty::Projection, projection_ty)
if !projection_ty.has_escaping_bound_vars() if !projection_ty.has_escaping_bound_vars()
&& tcx.def_kind(projection_ty.item_def_id) && tcx.def_kind(projection_ty.def_id)
!= DefKind::ImplTraitPlaceholder => != DefKind::ImplTraitPlaceholder =>
{ {
self.infer_projection( self.infer_projection(
@ -578,14 +583,14 @@ impl<'tcx> InferCtxt<'tcx> {
} }
// Replace all other mentions of the same opaque type with the hidden type, // Replace all other mentions of the same opaque type with the hidden type,
// as the bounds must hold on the hidden type after all. // as the bounds must hold on the hidden type after all.
ty::Opaque(def_id2, substs2) ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2 })
if def_id.to_def_id() == def_id2 && substs == substs2 => if def_id.to_def_id() == def_id2 && substs == substs2 =>
{ {
hidden_ty hidden_ty
} }
// FIXME(RPITIT): This can go away when we move to associated types // FIXME(RPITIT): This can go away when we move to associated types
ty::Projection(proj) ty::Alias(ty::Projection, ty::AliasTy { def_id: def_id2, substs: substs2 })
if def_id.to_def_id() == proj.item_def_id && substs == proj.substs => if def_id.to_def_id() == def_id2 && substs == substs2 =>
{ {
hidden_ty hidden_ty
} }

View file

@ -23,7 +23,7 @@ pub enum Component<'tcx> {
// is not in a position to judge which is the best technique, so // is not in a position to judge which is the best technique, so
// we just product the projection as a component and leave it to // we just product the projection as a component and leave it to
// the consumer to decide (but see `EscapingProjection` below). // the consumer to decide (but see `EscapingProjection` below).
Projection(ty::ProjectionTy<'tcx>), Projection(ty::AliasTy<'tcx>),
// In the case where a projection has escaping regions -- meaning // In the case where a projection has escaping regions -- meaning
// regions bound within the type itself -- we always use // regions bound within the type itself -- we always use
@ -130,7 +130,7 @@ fn compute_components<'tcx>(
// outlives any other lifetime, which is unsound. // outlives any other lifetime, which is unsound.
// See https://github.com/rust-lang/rust/issues/84305 for // See https://github.com/rust-lang/rust/issues/84305 for
// more details. // more details.
ty::Opaque(def_id, substs) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
out.push(Component::Opaque(def_id, substs)); out.push(Component::Opaque(def_id, substs));
}, },
@ -142,7 +142,7 @@ fn compute_components<'tcx>(
// trait-ref. Therefore, if we see any higher-ranked regions, // trait-ref. Therefore, if we see any higher-ranked regions,
// we simply fallback to the most restrictive rule, which // we simply fallback to the most restrictive rule, which
// requires that `Pi: 'a` for all `i`. // requires that `Pi: 'a` for all `i`.
ty::Projection(ref data) => { ty::Alias(ty::Projection, ref data) => {
if !data.has_escaping_bound_vars() { if !data.has_escaping_bound_vars() {
// best case: no escaping regions, so push the // best case: no escaping regions, so push the
// projection and skip the subtree (thus generating no // projection and skip the subtree (thus generating no

View file

@ -338,7 +338,7 @@ where
substs, substs,
true, true,
|ty| match *ty.kind() { |ty| match *ty.kind() {
ty::Opaque(def_id, substs) => (def_id, substs), ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => (def_id, substs),
_ => bug!("expected only projection types from env, not {:?}", ty), _ => bug!("expected only projection types from env, not {:?}", ty),
}, },
); );
@ -349,17 +349,19 @@ where
&mut self, &mut self,
origin: infer::SubregionOrigin<'tcx>, origin: infer::SubregionOrigin<'tcx>,
region: ty::Region<'tcx>, region: ty::Region<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>, projection_ty: ty::AliasTy<'tcx>,
) { ) {
self.generic_must_outlive( self.generic_must_outlive(
origin, origin,
region, region,
GenericKind::Projection(projection_ty), GenericKind::Projection(projection_ty),
projection_ty.item_def_id, projection_ty.def_id,
projection_ty.substs, projection_ty.substs,
false, false,
|ty| match ty.kind() { |ty| match ty.kind() {
ty::Projection(projection_ty) => (projection_ty.item_def_id, projection_ty.substs), ty::Alias(ty::Projection, projection_ty) => {
(projection_ty.def_id, projection_ty.substs)
}
_ => bug!("expected only projection types from env, not {:?}", ty), _ => bug!("expected only projection types from env, not {:?}", ty),
}, },
); );

View file

@ -178,7 +178,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
), ),
Component::Projection(projection_ty) => self.projection_opaque_bounds( Component::Projection(projection_ty) => self.projection_opaque_bounds(
GenericKind::Projection(projection_ty), GenericKind::Projection(projection_ty),
projection_ty.item_def_id, projection_ty.def_id,
projection_ty.substs, projection_ty.substs,
visited, visited,
), ),

View file

@ -16,12 +16,12 @@ impl<'tcx> InferCtxt<'tcx> {
pub fn infer_projection( pub fn infer_projection(
&self, &self,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>, projection_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
recursion_depth: usize, recursion_depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>, obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let def_id = projection_ty.item_def_id; let def_id = projection_ty.def_id;
let ty_var = self.next_ty_var(TypeVariableOrigin { let ty_var = self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::NormalizeProjectionType, kind: TypeVariableOriginKind::NormalizeProjectionType,
span: self.tcx.def_span(def_id), span: self.tcx.def_span(def_id),

View file

@ -169,7 +169,7 @@ pub struct Verify<'tcx> {
#[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
pub enum GenericKind<'tcx> { pub enum GenericKind<'tcx> {
Param(ty::ParamTy), Param(ty::ParamTy),
Projection(ty::ProjectionTy<'tcx>), Projection(ty::AliasTy<'tcx>),
Opaque(DefId, SubstsRef<'tcx>), Opaque(DefId, SubstsRef<'tcx>),
} }
@ -773,7 +773,7 @@ impl<'tcx> GenericKind<'tcx> {
pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match *self { match *self {
GenericKind::Param(ref p) => p.to_ty(tcx), GenericKind::Param(ref p) => p.to_ty(tcx),
GenericKind::Projection(ref p) => tcx.mk_projection(p.item_def_id, p.substs), GenericKind::Projection(ref p) => tcx.mk_projection(p.def_id, p.substs),
GenericKind::Opaque(def_id, substs) => tcx.mk_opaque(def_id, substs), GenericKind::Opaque(def_id, substs) => tcx.mk_opaque(def_id, substs),
} }
} }

View file

@ -130,12 +130,16 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
Ok(self.tcx().ty_error_with_guaranteed(e)) Ok(self.tcx().ty_error_with_guaranteed(e))
} }
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { (
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: _ }),
&ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: _ }),
) if a_def_id == b_def_id => {
self.fields.infcx.super_combine_tys(self, a, b)?; self.fields.infcx.super_combine_tys(self, a, b)?;
Ok(a) Ok(a)
} }
(&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..)) (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }), _)
if self.fields.define_opaque_types && did.is_local() => | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }))
if self.fields.define_opaque_types && def_id.is_local() =>
{ {
self.fields.obligations.extend( self.fields.obligations.extend(
infcx infcx

View file

@ -77,11 +77,11 @@ pub struct ProjectionCacheStorage<'tcx> {
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct ProjectionCacheKey<'tcx> { pub struct ProjectionCacheKey<'tcx> {
ty: ty::ProjectionTy<'tcx>, ty: ty::AliasTy<'tcx>,
} }
impl<'tcx> ProjectionCacheKey<'tcx> { impl<'tcx> ProjectionCacheKey<'tcx> {
pub fn new(ty: ty::ProjectionTy<'tcx>) -> Self { pub fn new(ty: ty::AliasTy<'tcx>) -> Self {
Self { ty } Self { ty }
} }
} }

View file

@ -259,8 +259,7 @@ impl<'tcx> Elaborator<'tcx> {
Component::Projection(projection) => { Component::Projection(projection) => {
// We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`. // We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
// With this, we can deduce that `<Bar as Baz>::Assoc: 'a`. // With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
let ty = let ty = tcx.mk_projection(projection.def_id, projection.substs);
tcx.mk_projection(projection.item_def_id, projection.substs);
Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives( Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
ty::OutlivesPredicate(ty, r_min), ty::OutlivesPredicate(ty, r_min),
))) )))

View file

@ -3016,8 +3016,8 @@ impl ClashingExternDeclarations {
| (Closure(..), Closure(..)) | (Closure(..), Closure(..))
| (Generator(..), Generator(..)) | (Generator(..), Generator(..))
| (GeneratorWitness(..), GeneratorWitness(..)) | (GeneratorWitness(..), GeneratorWitness(..))
| (Projection(..), Projection(..)) | (Alias(ty::Projection, ..), Alias(ty::Projection, ..))
| (Opaque(..), Opaque(..)) => false, | (Alias(ty::Opaque, ..), Alias(ty::Opaque, ..)) => false,
// These definitely should have been caught above. // These definitely should have been caught above.
(Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(), (Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(),

View file

@ -82,7 +82,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
let Some(proj_term) = proj.term.ty() else { continue }; let Some(proj_term) = proj.term.ty() else { continue };
let proj_ty = let proj_ty =
cx.tcx.mk_projection(proj.projection_ty.item_def_id, proj.projection_ty.substs); cx.tcx.mk_projection(proj.projection_ty.def_id, proj.projection_ty.substs);
// For every instance of the projection type in the bounds, // For every instance of the projection type in the bounds,
// replace them with the term we're assigning to the associated // replace them with the term we're assigning to the associated
// type in our opaque type. // type in our opaque type.
@ -97,7 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// with `impl Send: OtherTrait`. // with `impl Send: OtherTrait`.
for (assoc_pred, assoc_pred_span) in cx for (assoc_pred, assoc_pred_span) in cx
.tcx .tcx
.bound_explicit_item_bounds(proj.projection_ty.item_def_id) .bound_explicit_item_bounds(proj.projection_ty.def_id)
.subst_iter_copied(cx.tcx, &proj.projection_ty.substs) .subst_iter_copied(cx.tcx, &proj.projection_ty.substs)
{ {
let assoc_pred = assoc_pred.fold_with(proj_replacer); let assoc_pred = assoc_pred.fold_with(proj_replacer);
@ -117,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
// then we can emit a suggestion to add the bound. // then we can emit a suggestion to add the bound.
let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) { let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
( (
ty::Opaque(def_id, _), ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }),
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)), ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)),
) => Some(AddBound { ) => Some(AddBound {
suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(), suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),

View file

@ -1139,18 +1139,20 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
// While opaque types are checked for earlier, if a projection in a struct field // While opaque types are checked for earlier, if a projection in a struct field
// normalizes to an opaque type, then it will reach this branch. // normalizes to an opaque type, then it will reach this branch.
ty::Opaque(..) => { ty::Alias(ty::Opaque, ..) => {
FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_opaque, help: None } FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_opaque, help: None }
} }
// `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe, // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
// so they are currently ignored for the purposes of this lint. // so they are currently ignored for the purposes of this lint.
ty::Param(..) | ty::Projection(..) if matches!(self.mode, CItemKind::Definition) => { ty::Param(..) | ty::Alias(ty::Projection, ..)
if matches!(self.mode, CItemKind::Definition) =>
{
FfiSafe FfiSafe
} }
ty::Param(..) ty::Param(..)
| ty::Projection(..) | ty::Alias(ty::Projection, ..)
| ty::Infer(..) | ty::Infer(..)
| ty::Bound(..) | ty::Bound(..)
| ty::Error(_) | ty::Error(_)
@ -1205,7 +1207,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
return ControlFlow::CONTINUE; return ControlFlow::CONTINUE;
} }
if let ty::Opaque(..) = ty.kind() { if let ty::Alias(ty::Opaque, ..) = ty.kind() {
ControlFlow::Break(ty) ControlFlow::Break(ty)
} else { } else {
ty.super_visit_with(self) ty.super_visit_with(self)

View file

@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind if let hir::ExprKind::Match(await_expr, _arms, hir::MatchSource::AwaitDesugar) = expr.kind
&& let ty = cx.typeck_results().expr_ty(&await_expr) && let ty = cx.typeck_results().expr_ty(&await_expr)
&& let ty::Opaque(future_def_id, _) = ty.kind() && let ty::Alias(ty::Opaque, ty::AliasTy { def_id: future_def_id, substs: _ }) = ty.kind()
&& cx.tcx.ty_is_opaque_future(ty) && cx.tcx.ty_is_opaque_future(ty)
// FIXME: This also includes non-async fns that return `impl Future`. // FIXME: This also includes non-async fns that return `impl Future`.
&& let async_fn_def_id = cx.tcx.parent(*future_def_id) && let async_fn_def_id = cx.tcx.parent(*future_def_id)
@ -251,7 +251,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
.map(|inner| MustUsePath::Boxed(Box::new(inner))) .map(|inner| MustUsePath::Boxed(Box::new(inner)))
} }
ty::Adt(def, _) => is_def_must_use(cx, def.did(), span), ty::Adt(def, _) => is_def_must_use(cx, def.did(), span),
ty::Opaque(def, _) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, substs: _ }) => {
elaborate_predicates_with_span( elaborate_predicates_with_span(
cx.tcx, cx.tcx,
cx.tcx.explicit_item_bounds(def).iter().cloned(), cx.tcx.explicit_item_bounds(def).iter().cloned(),

View file

@ -1111,8 +1111,8 @@ fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) ->
// associated types. // associated types.
tcx.fn_sig(trait_item_def_id).skip_binder().output().walk().any(|arg| { tcx.fn_sig(trait_item_def_id).skip_binder().output().walk().any(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack() if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(data) = ty.kind() && let ty::Alias(ty::Projection, data) = ty.kind()
&& tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder && tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder
{ {
true true
} else { } else {

View file

@ -250,7 +250,7 @@ pub enum ObligationCauseCode<'tcx> {
TupleElem, TupleElem,
/// This is the trait reference from the given projection. /// This is the trait reference from the given projection.
ProjectionWf(ty::ProjectionTy<'tcx>), ProjectionWf(ty::AliasTy<'tcx>),
/// Must satisfy all of the where-clause predicates of the /// Must satisfy all of the where-clause predicates of the
/// given item. /// given item.

View file

@ -76,8 +76,7 @@ pub mod type_op {
} }
} }
pub type CanonicalProjectionGoal<'tcx> = pub type CanonicalProjectionGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::AliasTy<'tcx>>>;
Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>;
pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>; pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>;
@ -218,6 +217,6 @@ pub struct NormalizationResult<'tcx> {
pub enum OutlivesBound<'tcx> { pub enum OutlivesBound<'tcx> {
RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>), RegionSubRegion(ty::Region<'tcx>, ty::Region<'tcx>),
RegionSubParam(ty::Region<'tcx>, ty::ParamTy), RegionSubParam(ty::Region<'tcx>, ty::ParamTy),
RegionSubProjection(ty::Region<'tcx>, ty::ProjectionTy<'tcx>), RegionSubProjection(ty::Region<'tcx>, ty::AliasTy<'tcx>),
RegionSubOpaque(ty::Region<'tcx>, DefId, SubstsRef<'tcx>), RegionSubOpaque(ty::Region<'tcx>, DefId, SubstsRef<'tcx>),
} }

View file

@ -18,12 +18,11 @@ use crate::thir::Thir;
use crate::traits; use crate::traits;
use crate::ty::query::{self, TyCtxtAt}; use crate::ty::query::{self, TyCtxtAt};
use crate::ty::{ use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, self, AdtDef, AdtDefData, AdtKind, AliasTy, Binder, BindingMode, BoundVar, CanonicalPolyFnSig,
ClosureSizeProfileData, Const, ConstS, DefIdTree, FloatTy, FloatVar, FloatVid, ClosureSizeProfileData, Const, ConstS, DefIdTree, FloatTy, FloatVar, FloatVid,
GenericParamDefKind, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, GenericParamDefKind, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy,
PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, ProjectionTy, Region, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions,
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, Visibility,
Visibility,
}; };
use crate::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef, UserSubsts}; use crate::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef, UserSubsts};
use rustc_ast as ast; use rustc_ast as ast;
@ -116,7 +115,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ListBinderExistentialPredicate = &'tcx List<PolyExistentialPredicate<'tcx>>; type ListBinderExistentialPredicate = &'tcx List<PolyExistentialPredicate<'tcx>>;
type BinderListTy = Binder<'tcx, &'tcx List<Ty<'tcx>>>; type BinderListTy = Binder<'tcx, &'tcx List<Ty<'tcx>>>;
type ListTy = &'tcx List<Ty<'tcx>>; type ListTy = &'tcx List<Ty<'tcx>>;
type ProjectionTy = ty::ProjectionTy<'tcx>; type AliasTy = ty::AliasTy<'tcx>;
type ParamTy = ParamTy; type ParamTy = ParamTy;
type BoundTy = ty::BoundTy; type BoundTy = ty::BoundTy;
type PlaceholderType = ty::PlaceholderType; type PlaceholderType = ty::PlaceholderType;
@ -2145,8 +2144,7 @@ impl<'tcx> TyCtxt<'tcx> {
Bound, Bound,
Param, Param,
Infer, Infer,
Projection, Alias,
Opaque,
Foreign Foreign
)?; )?;
@ -2323,7 +2321,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Given a `ty`, return whether it's an `impl Future<...>`. /// Given a `ty`, return whether it's an `impl Future<...>`.
pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool {
let ty::Opaque(def_id, _) = ty.kind() else { return false }; let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) = ty.kind() else { return false };
let future_trait = self.require_lang_item(LangItem::Future, None); let future_trait = self.require_lang_item(LangItem::Future, None);
self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| {
@ -2598,7 +2596,7 @@ impl<'tcx> TyCtxt<'tcx> {
substs.len(), substs.len(),
"wrong number of generic parameters for {item_def_id:?}: {substs:?}", "wrong number of generic parameters for {item_def_id:?}: {substs:?}",
); );
self.mk_ty(Projection(ProjectionTy { item_def_id, substs })) self.mk_ty(Alias(ty::Projection, AliasTy { def_id: item_def_id, substs }))
} }
#[inline] #[inline]
@ -2668,7 +2666,7 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline] #[inline]
pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> { pub fn mk_opaque(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
self.mk_ty(Opaque(def_id, substs)) self.mk_ty(Alias(ty::Opaque, ty::AliasTy { def_id, substs }))
} }
pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {

View file

@ -3,8 +3,8 @@
use std::ops::ControlFlow; use std::ops::ControlFlow;
use crate::ty::{ use crate::ty::{
visit::TypeVisitable, Const, ConstKind, DefIdTree, ExistentialPredicate, InferConst, InferTy, visit::TypeVisitable, AliasTy, Const, ConstKind, DefIdTree, ExistentialPredicate, InferConst,
PolyTraitPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, InferTy, Opaque, PolyTraitPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor,
}; };
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
@ -457,11 +457,11 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
return ControlFlow::Break(()); return ControlFlow::Break(());
} }
Opaque(did, _) => { Alias(Opaque, AliasTy { def_id, substs: _ }) => {
let parent = self.tcx.parent(*did); let parent = self.tcx.parent(*def_id);
if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent) if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
&& let Opaque(parent_did, _) = self.tcx.type_of(parent).kind() && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, substs: _ }) = self.tcx.type_of(parent).kind()
&& parent_did == did && parent_opaque_def_id == def_id
{ {
// Okay // Okay
} else { } else {

View file

@ -337,9 +337,9 @@ impl<'tcx> Ty<'tcx> {
ty::Infer(ty::FreshTy(_)) => "fresh type".into(), ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(), ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(), ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
ty::Projection(_) => "associated type".into(), ty::Alias(ty::Projection, _) => "associated type".into(),
ty::Param(p) => format!("type parameter `{}`", p).into(), ty::Param(p) => format!("type parameter `{}`", p).into(),
ty::Opaque(..) => "opaque type".into(), ty::Alias(ty::Opaque, ..) => "opaque type".into(),
ty::Error(_) => "type error".into(), ty::Error(_) => "type error".into(),
} }
} }
@ -375,9 +375,9 @@ impl<'tcx> Ty<'tcx> {
ty::Tuple(..) => "tuple".into(), ty::Tuple(..) => "tuple".into(),
ty::Placeholder(..) => "higher-ranked type".into(), ty::Placeholder(..) => "higher-ranked type".into(),
ty::Bound(..) => "bound type variable".into(), ty::Bound(..) => "bound type variable".into(),
ty::Projection(_) => "associated type".into(), ty::Alias(ty::Projection, _) => "associated type".into(),
ty::Param(_) => "type parameter".into(), ty::Param(_) => "type parameter".into(),
ty::Opaque(..) => "opaque type".into(), ty::Alias(ty::Opaque, ..) => "opaque type".into(),
} }
} }
} }
@ -400,7 +400,7 @@ impl<'tcx> TyCtxt<'tcx> {
diag.note("no two closures, even if identical, have the same type"); diag.note("no two closures, even if identical, have the same type");
diag.help("consider boxing your closure and/or using it as a trait object"); diag.help("consider boxing your closure and/or using it as a trait object");
} }
(ty::Opaque(..), ty::Opaque(..)) => { (ty::Alias(ty::Opaque, ..), ty::Alias(ty::Opaque, ..)) => {
// Issue #63167 // Issue #63167
diag.note("distinct uses of `impl Trait` result in different opaque types"); diag.note("distinct uses of `impl Trait` result in different opaque types");
} }
@ -439,11 +439,11 @@ impl<'tcx> TyCtxt<'tcx> {
#traits-as-parameters", #traits-as-parameters",
); );
} }
(ty::Projection(_), ty::Projection(_)) => { (ty::Alias(ty::Projection, _), ty::Alias(ty::Projection, _)) => {
diag.note("an associated type was expected, but a different one was found"); diag.note("an associated type was expected, but a different one was found");
} }
(ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p)) (ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p))
if self.def_kind(proj.item_def_id) != DefKind::ImplTraitPlaceholder => if self.def_kind(proj.def_id) != DefKind::ImplTraitPlaceholder =>
{ {
let generics = self.generics_of(body_owner_def_id); let generics = self.generics_of(body_owner_def_id);
let p_span = self.def_span(generics.type_param(p, self).def_id); let p_span = self.def_span(generics.type_param(p, self).def_id);
@ -466,7 +466,7 @@ impl<'tcx> TyCtxt<'tcx> {
let (trait_ref, assoc_substs) = proj.trait_ref_and_own_substs(self); let (trait_ref, assoc_substs) = proj.trait_ref_and_own_substs(self);
let path = let path =
self.def_path_str_with_substs(trait_ref.def_id, trait_ref.substs); self.def_path_str_with_substs(trait_ref.def_id, trait_ref.substs);
let item_name = self.item_name(proj.item_def_id); let item_name = self.item_name(proj.def_id);
let item_args = self.format_generic_args(assoc_substs); let item_args = self.format_generic_args(assoc_substs);
let path = if path.ends_with('>') { let path = if path.ends_with('>') {
@ -493,8 +493,8 @@ impl<'tcx> TyCtxt<'tcx> {
diag.note("you might be missing a type parameter or trait bound"); diag.note("you might be missing a type parameter or trait bound");
} }
} }
(ty::Param(p), ty::Dynamic(..) | ty::Opaque(..)) (ty::Param(p), ty::Dynamic(..) | ty::Alias(ty::Opaque, ..))
| (ty::Dynamic(..) | ty::Opaque(..), ty::Param(p)) => { | (ty::Dynamic(..) | ty::Alias(ty::Opaque, ..), ty::Param(p)) => {
let generics = self.generics_of(body_owner_def_id); let generics = self.generics_of(body_owner_def_id);
let p_span = self.def_span(generics.type_param(p, self).def_id); let p_span = self.def_span(generics.type_param(p, self).def_id);
if !sp.contains(p_span) { if !sp.contains(p_span) {
@ -553,7 +553,7 @@ impl<T> Trait<T> for X {
diag.span_label(p_span, "this type parameter"); diag.span_label(p_span, "this type parameter");
} }
} }
(ty::Projection(proj_ty), _) if self.def_kind(proj_ty.item_def_id) != DefKind::ImplTraitPlaceholder => { (ty::Alias(ty::Projection, proj_ty), _) if self.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => {
self.expected_projection( self.expected_projection(
diag, diag,
proj_ty, proj_ty,
@ -562,7 +562,7 @@ impl<T> Trait<T> for X {
cause.code(), cause.code(),
); );
} }
(_, ty::Projection(proj_ty)) if self.def_kind(proj_ty.item_def_id) != DefKind::ImplTraitPlaceholder => { (_, ty::Alias(ty::Projection, proj_ty)) if self.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => {
let msg = format!( let msg = format!(
"consider constraining the associated type `{}` to `{}`", "consider constraining the associated type `{}` to `{}`",
values.found, values.expected, values.found, values.expected,
@ -624,10 +624,10 @@ impl<T> Trait<T> for X {
diag: &mut Diagnostic, diag: &mut Diagnostic,
msg: &str, msg: &str,
body_owner_def_id: DefId, body_owner_def_id: DefId,
proj_ty: &ty::ProjectionTy<'tcx>, proj_ty: &ty::AliasTy<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> bool { ) -> bool {
let assoc = self.associated_item(proj_ty.item_def_id); let assoc = self.associated_item(proj_ty.def_id);
let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self); let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);
if let Some(item) = self.hir().get_if_local(body_owner_def_id) { if let Some(item) = self.hir().get_if_local(body_owner_def_id) {
if let Some(hir_generics) = item.generics() { if let Some(hir_generics) = item.generics() {
@ -680,7 +680,7 @@ impl<T> Trait<T> for X {
fn expected_projection( fn expected_projection(
self, self,
diag: &mut Diagnostic, diag: &mut Diagnostic,
proj_ty: &ty::ProjectionTy<'tcx>, proj_ty: &ty::AliasTy<'tcx>,
values: ExpectedFound<Ty<'tcx>>, values: ExpectedFound<Ty<'tcx>>,
body_owner_def_id: DefId, body_owner_def_id: DefId,
cause_code: &ObligationCauseCode<'_>, cause_code: &ObligationCauseCode<'_>,
@ -703,7 +703,7 @@ impl<T> Trait<T> for X {
); );
let impl_comparison = let impl_comparison =
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. }); matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
let assoc = self.associated_item(proj_ty.item_def_id); let assoc = self.associated_item(proj_ty.def_id);
if !callable_scope || impl_comparison { if !callable_scope || impl_comparison {
// We do not want to suggest calling functions when the reason of the // We do not want to suggest calling functions when the reason of the
// type error is a comparison of an `impl` with its `trait` or when the // type error is a comparison of an `impl` with its `trait` or when the
@ -716,7 +716,7 @@ impl<T> Trait<T> for X {
diag, diag,
assoc.container_id(self), assoc.container_id(self),
current_method_ident, current_method_ident,
proj_ty.item_def_id, proj_ty.def_id,
values.expected, values.expected,
); );
// Possibly suggest constraining the associated type to conform to the // Possibly suggest constraining the associated type to conform to the
@ -775,11 +775,12 @@ fn foo(&self) -> Self::T { String::new() }
self, self,
diag: &mut Diagnostic, diag: &mut Diagnostic,
msg: &str, msg: &str,
proj_ty: &ty::ProjectionTy<'tcx>, proj_ty: &ty::AliasTy<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> bool { ) -> bool {
let assoc = self.associated_item(proj_ty.item_def_id); let assoc = self.associated_item(proj_ty.def_id);
if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) = *proj_ty.self_ty().kind()
{
let opaque_local_def_id = def_id.as_local(); let opaque_local_def_id = def_id.as_local();
let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id { let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id {
match &self.hir().expect_item(opaque_local_def_id).kind { match &self.hir().expect_item(opaque_local_def_id).kind {
@ -828,7 +829,7 @@ fn foo(&self) -> Self::T { String::new() }
.filter_map(|(_, item)| { .filter_map(|(_, item)| {
let method = self.fn_sig(item.def_id); let method = self.fn_sig(item.def_id);
match *method.output().skip_binder().kind() { match *method.output().skip_binder().kind() {
ty::Projection(ty::ProjectionTy { item_def_id, .. }) ty::Alias(ty::Projection, ty::AliasTy { def_id: item_def_id, .. })
if item_def_id == proj_ty_item_def_id => if item_def_id == proj_ty_item_def_id =>
{ {
Some(( Some((

View file

@ -126,7 +126,7 @@ pub fn simplify_type<'tcx>(
TreatParams::AsPlaceholder => Some(PlaceholderSimplifiedType), TreatParams::AsPlaceholder => Some(PlaceholderSimplifiedType),
TreatParams::AsInfer => None, TreatParams::AsInfer => None,
}, },
ty::Opaque(..) | ty::Projection(_) => match treat_params { ty::Alias(..) => match treat_params {
// When treating `ty::Param` as a placeholder, projections also // When treating `ty::Param` as a placeholder, projections also
// don't unify with anything else as long as they are fully normalized. // don't unify with anything else as long as they are fully normalized.
// //
@ -225,7 +225,7 @@ impl DeepRejectCtxt {
match impl_ty.kind() { match impl_ty.kind() {
// Start by checking whether the type in the impl may unify with // Start by checking whether the type in the impl may unify with
// pretty much everything. Just return `true` in that case. // pretty much everything. Just return `true` in that case.
ty::Param(_) | ty::Projection(_) | ty::Error(_) | ty::Opaque(..) => return true, ty::Param(_) | ty::Error(_) | ty::Alias(..) => return true,
// These types only unify with inference variables or their own // These types only unify with inference variables or their own
// variant. // variant.
ty::Bool ty::Bool
@ -323,8 +323,6 @@ impl DeepRejectCtxt {
_ => false, _ => false,
}, },
ty::Opaque(..) => true,
// Impls cannot contain these types as these cannot be named directly. // Impls cannot contain these types as these cannot be named directly.
ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false, ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false,
@ -344,7 +342,7 @@ impl DeepRejectCtxt {
// projections can unify with other stuff. // projections can unify with other stuff.
// //
// Looking forward to lazy normalization this is the safer strategy anyways. // Looking forward to lazy normalization this is the safer strategy anyways.
ty::Projection(_) => true, ty::Alias(..) => true,
ty::Error(_) => true, ty::Error(_) => true,

View file

@ -155,12 +155,12 @@ impl FlagComputation {
self.add_substs(substs); self.add_substs(substs);
} }
&ty::Projection(data) => { &ty::Alias(ty::Projection, data) => {
self.add_flags(TypeFlags::HAS_TY_PROJECTION); self.add_flags(TypeFlags::HAS_TY_PROJECTION);
self.add_projection_ty(data); self.add_projection_ty(data);
} }
&ty::Opaque(_, substs) => { &ty::Alias(ty::Opaque, ty::AliasTy { def_id: _, substs }) => {
self.add_flags(TypeFlags::HAS_TY_OPAQUE); self.add_flags(TypeFlags::HAS_TY_OPAQUE);
self.add_substs(substs); self.add_substs(substs);
} }
@ -345,7 +345,7 @@ impl FlagComputation {
} }
} }
fn add_projection_ty(&mut self, projection_ty: ty::ProjectionTy<'_>) { fn add_projection_ty(&mut self, projection_ty: ty::AliasTy<'_>) {
self.add_substs(projection_ty.substs); self.add_substs(projection_ty.substs);
} }

View file

@ -112,7 +112,7 @@ impl<'tcx> Ty<'tcx> {
InhabitedPredicate::True InhabitedPredicate::True
} }
Never => InhabitedPredicate::False, Never => InhabitedPredicate::False,
Param(_) | Projection(_) => InhabitedPredicate::GenericType(self), Param(_) | Alias(ty::Projection, _) => InhabitedPredicate::GenericType(self),
Tuple(tys) if tys.is_empty() => InhabitedPredicate::True, Tuple(tys) if tys.is_empty() => InhabitedPredicate::True,
// use a query for more complex cases // use a query for more complex cases
Adt(..) | Array(..) | Tuple(_) => tcx.inhabited_predicate_type(self), Adt(..) | Array(..) | Tuple(_) => tcx.inhabited_predicate_type(self),

View file

@ -271,7 +271,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
let non_zero = !ty.is_unsafe_ptr(); let non_zero = !ty.is_unsafe_ptr();
let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
match tail.kind() { match tail.kind() {
ty::Param(_) | ty::Projection(_) => { ty::Param(_) | ty::Alias(ty::Projection, _) => {
debug_assert!(tail.has_non_region_param()); debug_assert!(tail.has_non_region_param());
Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) }) Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) })
} }
@ -349,7 +349,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
} }
} }
ty::Projection(_) | ty::Opaque(..) => { ty::Alias(..) => {
let normalized = tcx.normalize_erasing_regions(param_env, ty); let normalized = tcx.normalize_erasing_regions(param_env, ty);
if ty == normalized { if ty == normalized {
Err(err) Err(err)
@ -757,10 +757,9 @@ where
} }
} }
ty::Projection(_) ty::Alias(..)
| ty::Bound(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Opaque(..)
| ty::Param(_) | ty::Param(_)
| ty::Infer(_) | ty::Infer(_)
| ty::Error(_) => bug!("TyAndLayout::field: unexpected type `{}`", this.ty), | ty::Error(_) => bug!("TyAndLayout::field: unexpected type `{}`", this.ty),

View file

@ -64,6 +64,7 @@ use std::ops::ControlFlow;
use std::{fmt, str}; use std::{fmt, str};
pub use crate::ty::diagnostics::*; pub use crate::ty::diagnostics::*;
pub use rustc_type_ir::AliasKind::*;
pub use rustc_type_ir::DynKind::*; pub use rustc_type_ir::DynKind::*;
pub use rustc_type_ir::InferTy::*; pub use rustc_type_ir::InferTy::*;
pub use rustc_type_ir::RegionKind::*; pub use rustc_type_ir::RegionKind::*;
@ -93,14 +94,13 @@ pub use self::parameterized::ParameterizedOverTcx;
pub use self::rvalue_scopes::RvalueScopes; pub use self::rvalue_scopes::RvalueScopes;
pub use self::sty::BoundRegionKind::*; pub use self::sty::BoundRegionKind::*;
pub use self::sty::{ pub use self::sty::{
Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
BoundVariableKind, CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, BoundVariableKind, CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid,
EarlyBoundRegion, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, EarlyBoundRegion, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
FreeRegion, GenSig, GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts, FreeRegion, GenSig, GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts,
InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialPredicate, InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialPredicate,
PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef,
ProjectionTy, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, VarianceDiagInfo,
VarianceDiagInfo,
}; };
pub use self::trait_def::TraitDef; pub use self::trait_def::TraitDef;
@ -1010,7 +1010,7 @@ impl<'tcx> TermKind<'tcx> {
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ProjectionPredicate<'tcx> { pub struct ProjectionPredicate<'tcx> {
pub projection_ty: ProjectionTy<'tcx>, pub projection_ty: AliasTy<'tcx>,
pub term: Term<'tcx>, pub term: Term<'tcx>,
} }
@ -1046,7 +1046,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
/// associated type, which is in `tcx.associated_item(projection_def_id()).container`. /// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
pub fn projection_def_id(&self) -> DefId { pub fn projection_def_id(&self) -> DefId {
// Ok to skip binder since trait `DefId` does not care about regions. // Ok to skip binder since trait `DefId` does not care about regions.
self.skip_binder().projection_ty.item_def_id self.skip_binder().projection_ty.def_id
} }
} }

View file

@ -275,10 +275,9 @@ fn characteristic_def_id_of_type_cached<'a>(
| ty::Uint(_) | ty::Uint(_)
| ty::Str | ty::Str
| ty::FnPtr(_) | ty::FnPtr(_)
| ty::Projection(_) | ty::Alias(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Param(_) | ty::Param(_)
| ty::Opaque(..)
| ty::Infer(_) | ty::Infer(_)
| ty::Bound(..) | ty::Bound(..)
| ty::Error(_) | ty::Error(_)

View file

@ -718,17 +718,17 @@ pub trait PrettyPrinter<'tcx>:
ty::Foreign(def_id) => { ty::Foreign(def_id) => {
p!(print_def_path(def_id, &[])); p!(print_def_path(def_id, &[]));
} }
ty::Projection(ref data) => { ty::Alias(ty::Projection, ref data) => {
if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get())) if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get()))
&& self.tcx().def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder && self.tcx().def_kind(data.def_id) == DefKind::ImplTraitPlaceholder
{ {
return self.pretty_print_opaque_impl_type(data.item_def_id, data.substs); return self.pretty_print_opaque_impl_type(data.def_id, data.substs);
} else { } else {
p!(print(data)) p!(print(data))
} }
} }
ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
ty::Opaque(def_id, substs) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
// FIXME(eddyb) print this with `print_def_path`. // FIXME(eddyb) print this with `print_def_path`.
// We use verbose printing in 'NO_QUERIES' mode, to // We use verbose printing in 'NO_QUERIES' mode, to
// avoid needing to call `predicates_of`. This should // avoid needing to call `predicates_of`. This should
@ -743,7 +743,9 @@ pub trait PrettyPrinter<'tcx>:
let parent = self.tcx().parent(def_id); let parent = self.tcx().parent(def_id);
match self.tcx().def_kind(parent) { match self.tcx().def_kind(parent) {
DefKind::TyAlias | DefKind::AssocTy => { DefKind::TyAlias | DefKind::AssocTy => {
if let ty::Opaque(d, _) = *self.tcx().type_of(parent).kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, substs: _ }) =
*self.tcx().type_of(parent).kind()
{
if d == def_id { if d == def_id {
// If the type alias directly starts with the `impl` of the // If the type alias directly starts with the `impl` of the
// opaque type we're printing, then skip the `::{opaque#1}`. // opaque type we're printing, then skip the `::{opaque#1}`.
@ -1019,8 +1021,8 @@ pub trait PrettyPrinter<'tcx>:
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks, // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
// unless we can find out what generator return type it comes from. // unless we can find out what generator return type it comes from.
let term = if let Some(ty) = term.skip_binder().ty() let term = if let Some(ty) = term.skip_binder().ty()
&& let ty::Projection(proj) = ty.kind() && let ty::Alias(ty::Projection, proj) = ty.kind()
&& let Some(assoc) = tcx.opt_associated_item(proj.item_def_id) && let Some(assoc) = tcx.opt_associated_item(proj.def_id)
&& assoc.trait_container(tcx) == tcx.lang_items().gen_trait() && assoc.trait_container(tcx) == tcx.lang_items().gen_trait()
&& assoc.name == rustc_span::sym::Return && assoc.name == rustc_span::sym::Return
{ {
@ -2653,7 +2655,7 @@ define_print_and_forward_display! {
} }
ty::ExistentialProjection<'tcx> { ty::ExistentialProjection<'tcx> {
let name = cx.tcx().associated_item(self.item_def_id).name; let name = cx.tcx().associated_item(self.def_id).name;
p!(write("{} = ", name), print(self.term)) p!(write("{} = ", name), print(self.term))
} }
@ -2740,8 +2742,8 @@ define_print_and_forward_display! {
} }
} }
ty::ProjectionTy<'tcx> { ty::AliasTy<'tcx> {
p!(print_def_path(self.item_def_id, self.substs)); p!(print_def_path(self.def_id, self.substs));
} }
ty::ClosureKind { ty::ClosureKind {

View file

@ -270,21 +270,17 @@ impl<'tcx> Relate<'tcx> for abi::Abi {
} }
} }
impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> { impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
fn relate<R: TypeRelation<'tcx>>( fn relate<R: TypeRelation<'tcx>>(
relation: &mut R, relation: &mut R,
a: ty::ProjectionTy<'tcx>, a: ty::AliasTy<'tcx>,
b: ty::ProjectionTy<'tcx>, b: ty::AliasTy<'tcx>,
) -> RelateResult<'tcx, ty::ProjectionTy<'tcx>> { ) -> RelateResult<'tcx, ty::AliasTy<'tcx>> {
if a.item_def_id != b.item_def_id { if a.def_id != b.def_id {
Err(TypeError::ProjectionMismatched(expected_found( Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
relation,
a.item_def_id,
b.item_def_id,
)))
} else { } else {
let substs = relation.relate(a.substs, b.substs)?; let substs = relation.relate(a.substs, b.substs)?;
Ok(ty::ProjectionTy { item_def_id: a.item_def_id, substs: &substs }) Ok(ty::AliasTy { def_id: a.def_id, substs: &substs })
} }
} }
} }
@ -295,12 +291,8 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
a: ty::ExistentialProjection<'tcx>, a: ty::ExistentialProjection<'tcx>,
b: ty::ExistentialProjection<'tcx>, b: ty::ExistentialProjection<'tcx>,
) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> { ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
if a.item_def_id != b.item_def_id { if a.def_id != b.def_id {
Err(TypeError::ProjectionMismatched(expected_found( Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
relation,
a.item_def_id,
b.item_def_id,
)))
} else { } else {
let term = relation.relate_with_variance( let term = relation.relate_with_variance(
ty::Invariant, ty::Invariant,
@ -314,7 +306,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
a.substs, a.substs,
b.substs, b.substs,
)?; )?;
Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, term }) Ok(ty::ExistentialProjection { def_id: a.def_id, substs, term })
} }
} }
} }
@ -559,14 +551,15 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
} }
// these two are already handled downstream in case of lazy normalization // these two are already handled downstream in case of lazy normalization
(&ty::Projection(a_data), &ty::Projection(b_data)) => { (&ty::Alias(ty::Projection, a_data), &ty::Alias(ty::Projection, b_data)) => {
let projection_ty = relation.relate(a_data, b_data)?; let projection_ty = relation.relate(a_data, b_data)?;
Ok(tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs)) Ok(tcx.mk_projection(projection_ty.def_id, projection_ty.substs))
} }
(&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs)) (
if a_def_id == b_def_id => &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, substs: a_substs }),
{ &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, substs: b_substs }),
) if a_def_id == b_def_id => {
if relation.intercrate() { if relation.intercrate() {
// During coherence, opaque types should be treated as equal to each other, even if their generic params // During coherence, opaque types should be treated as equal to each other, even if their generic params
// differ, as they could resolve to the same hidden type, even for different generic params. // differ, as they could resolve to the same hidden type, even for different generic params.

View file

@ -651,8 +651,7 @@ impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
} }
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?), ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?), ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?), ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?),
ty::Bool ty::Bool
| ty::Char | ty::Char
@ -697,8 +696,7 @@ impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> {
ty::Generator(_did, ref substs, _) => substs.visit_with(visitor), ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
ty::GeneratorWitness(ref types) => types.visit_with(visitor), ty::GeneratorWitness(ref types) => types.visit_with(visitor),
ty::Closure(_did, ref substs) => substs.visit_with(visitor), ty::Closure(_did, ref substs) => substs.visit_with(visitor),
ty::Projection(ref data) => data.visit_with(visitor), ty::Alias(_, ref data) => data.visit_with(visitor),
ty::Opaque(_, ref substs) => substs.visit_with(visitor),
ty::Bool ty::Bool
| ty::Char | ty::Char

View file

@ -693,7 +693,7 @@ impl<'tcx> ExistentialPredicate<'tcx> {
match (*self, *other) { match (*self, *other) {
(Trait(_), Trait(_)) => Ordering::Equal, (Trait(_), Trait(_)) => Ordering::Equal,
(Projection(ref a), Projection(ref b)) => { (Projection(ref a), Projection(ref b)) => {
tcx.def_path_hash(a.item_def_id).cmp(&tcx.def_path_hash(b.item_def_id)) tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id))
} }
(AutoTrait(ref a), AutoTrait(ref b)) => { (AutoTrait(ref a), AutoTrait(ref b)) => {
tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b)) tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b))
@ -1139,28 +1139,41 @@ impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
} }
} }
/// Represents the projection of an associated type. In explicit UFCS /// Represents the projection of an associated type.
/// form this would be written `<T as Trait<..>>::N`. ///
/// For a projection, this would be `<Ty as Trait<...>>::N`.
///
/// For an opaque type, there is no explicit syntax.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ProjectionTy<'tcx> { pub struct AliasTy<'tcx> {
/// The parameters of the associated item. /// The parameters of the associated or opaque item.
///
/// For a projection, these are the substitutions for the trait and the
/// GAT substitutions, if there are any.
///
/// For RPIT the substitutions are for the generics of the function,
/// while for TAIT it is used for the generic parameters of the alias.
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
/// The `DefId` of the `TraitItem` for the associated type `N`. /// The `DefId` of the `TraitItem` for the associated type `N` if this is a projection,
/// or the `OpaqueType` item if this is an opaque.
/// ///
/// Note that this is not the `DefId` of the `TraitRef` containing this /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the
/// associated type, which is in `tcx.associated_item(item_def_id).container`, /// underlying type if the type is an opaque.
/// aka. `tcx.parent(item_def_id).unwrap()`. ///
pub item_def_id: DefId, /// Note that if this is an associated type, this is not the `DefId` of the
/// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`,
/// aka. `tcx.parent(def_id)`.
pub def_id: DefId,
} }
impl<'tcx> ProjectionTy<'tcx> { impl<'tcx> AliasTy<'tcx> {
pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
match tcx.def_kind(self.item_def_id) { match tcx.def_kind(self.def_id) {
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.item_def_id), DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
DefKind::ImplTraitPlaceholder => { DefKind::ImplTraitPlaceholder => {
tcx.parent(tcx.impl_trait_in_trait_parent(self.item_def_id)) tcx.parent(tcx.impl_trait_in_trait_parent(self.def_id))
} }
kind => bug!("unexpected DefKind in ProjectionTy: {kind:?}"), kind => bug!("unexpected DefKind in ProjectionTy: {kind:?}"),
} }
@ -1173,11 +1186,14 @@ impl<'tcx> ProjectionTy<'tcx> {
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
let def_id = tcx.parent(self.item_def_id); debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst));
assert_eq!(tcx.def_kind(def_id), DefKind::Trait); let trait_def_id = self.trait_def_id(tcx);
let trait_generics = tcx.generics_of(def_id); let trait_generics = tcx.generics_of(trait_def_id);
( (
ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, trait_generics) }, ty::TraitRef {
def_id: trait_def_id,
substs: self.substs.truncate_to(tcx, trait_generics),
},
&self.substs[trait_generics.count()..], &self.substs[trait_generics.count()..],
) )
} }
@ -1405,7 +1421,7 @@ impl From<BoundVar> for BoundTy {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct ExistentialProjection<'tcx> { pub struct ExistentialProjection<'tcx> {
pub item_def_id: DefId, pub def_id: DefId,
pub substs: SubstsRef<'tcx>, pub substs: SubstsRef<'tcx>,
pub term: Term<'tcx>, pub term: Term<'tcx>,
} }
@ -1418,7 +1434,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
/// then this function would return an `exists T. T: Iterator` existential trait /// then this function would return an `exists T. T: Iterator` existential trait
/// reference. /// reference.
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
let def_id = tcx.parent(self.item_def_id); let def_id = tcx.parent(self.def_id);
let subst_count = tcx.generics_of(def_id).count() - 1; let subst_count = tcx.generics_of(def_id).count() - 1;
let substs = tcx.intern_substs(&self.substs[..subst_count]); let substs = tcx.intern_substs(&self.substs[..subst_count]);
ty::ExistentialTraitRef { def_id, substs } ty::ExistentialTraitRef { def_id, substs }
@ -1433,8 +1449,8 @@ impl<'tcx> ExistentialProjection<'tcx> {
debug_assert!(!self_ty.has_escaping_bound_vars()); debug_assert!(!self_ty.has_escaping_bound_vars());
ty::ProjectionPredicate { ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy { projection_ty: ty::AliasTy {
item_def_id: self.item_def_id, def_id: self.def_id,
substs: tcx.mk_substs_trait(self_ty, self.substs), substs: tcx.mk_substs_trait(self_ty, self.substs),
}, },
term: self.term, term: self.term,
@ -1449,7 +1465,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
projection_predicate.projection_ty.substs.type_at(0); projection_predicate.projection_ty.substs.type_at(0);
Self { Self {
item_def_id: projection_predicate.projection_ty.item_def_id, def_id: projection_predicate.projection_ty.def_id,
substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]), substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
term: projection_predicate.term, term: projection_predicate.term,
} }
@ -1466,7 +1482,7 @@ impl<'tcx> PolyExistentialProjection<'tcx> {
} }
pub fn item_def_id(&self) -> DefId { pub fn item_def_id(&self) -> DefId {
self.skip_binder().item_def_id self.skip_binder().def_id
} }
} }
@ -1973,7 +1989,7 @@ impl<'tcx> Ty<'tcx> {
#[inline] #[inline]
pub fn is_impl_trait(self) -> bool { pub fn is_impl_trait(self) -> bool {
matches!(self.kind(), Opaque(..)) matches!(self.kind(), Alias(ty::Opaque, ..))
} }
#[inline] #[inline]
@ -2040,7 +2056,7 @@ impl<'tcx> Ty<'tcx> {
ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx), ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx),
ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx), ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
ty::Param(_) | ty::Projection(_) | ty::Opaque(..) | ty::Infer(ty::TyVar(_)) => { ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
let assoc_items = tcx.associated_item_def_ids( let assoc_items = tcx.associated_item_def_ids(
tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
); );
@ -2120,7 +2136,7 @@ impl<'tcx> Ty<'tcx> {
// type parameters only have unit metadata if they're sized, so return true // type parameters only have unit metadata if they're sized, so return true
// to make sure we double check this during confirmation // to make sure we double check this during confirmation
ty::Param(_) | ty::Projection(_) | ty::Opaque(..) => (tcx.types.unit, true), ty::Param(_) | ty::Alias(..) => (tcx.types.unit, true),
ty::Infer(ty::TyVar(_)) ty::Infer(ty::TyVar(_))
| ty::Bound(..) | ty::Bound(..)
@ -2196,7 +2212,7 @@ impl<'tcx> Ty<'tcx> {
ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(), ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),
ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => false, ty::Alias(..) | ty::Param(_) => false,
ty::Infer(ty::TyVar(_)) => false, ty::Infer(ty::TyVar(_)) => false,
@ -2252,9 +2268,12 @@ impl<'tcx> Ty<'tcx> {
ty::Generator(..) | ty::GeneratorWitness(..) => false, ty::Generator(..) | ty::GeneratorWitness(..) => false,
// Might be, but not "trivial" so just giving the safe answer. // Might be, but not "trivial" so just giving the safe answer.
ty::Adt(..) | ty::Closure(..) | ty::Opaque(..) => false, ty::Adt(..) | ty::Closure(..) => false,
ty::Projection(..) | ty::Param(..) | ty::Infer(..) | ty::Error(..) => false, // Needs normalization or revealing to determine, so no is the safe answer.
ty::Alias(..) => false,
ty::Param(..) | ty::Infer(..) | ty::Error(..) => false,
ty::Bound(..) | ty::Placeholder(..) => { ty::Bound(..) | ty::Placeholder(..) => {
bug!("`is_trivially_pure_clone_copy` applied to unexpected type: {:?}", self); bug!("`is_trivially_pure_clone_copy` applied to unexpected type: {:?}", self);

View file

@ -259,7 +259,7 @@ impl<'tcx> TyCtxt<'tcx> {
ty::Tuple(_) => break, ty::Tuple(_) => break,
ty::Projection(_) | ty::Opaque(..) => { ty::Alias(..) => {
let normalized = normalize(ty); let normalized = normalize(ty);
if ty == normalized { if ty == normalized {
return ty; return ty;
@ -332,8 +332,7 @@ impl<'tcx> TyCtxt<'tcx> {
break; break;
} }
} }
(ty::Projection(_) | ty::Opaque(..), _) (ty::Alias(..), _) | (_, ty::Alias(..)) => {
| (_, ty::Projection(_) | ty::Opaque(..)) => {
// If either side is a projection, attempt to // If either side is a projection, attempt to
// progress via normalization. (Should be safe to // progress via normalization. (Should be safe to
// apply to both sides as normalization is // apply to both sides as normalization is
@ -826,7 +825,7 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
} }
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Opaque(def_id, substs) = *t.kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) = *t.kind() {
self.expand_opaque_ty(def_id, substs).unwrap_or(t) self.expand_opaque_ty(def_id, substs).unwrap_or(t)
} else if t.has_opaque_types() { } else if t.has_opaque_types() {
t.super_fold_with(self) t.super_fold_with(self)
@ -938,10 +937,9 @@ impl<'tcx> Ty<'tcx> {
| ty::Generator(..) | ty::Generator(..)
| ty::GeneratorWitness(_) | ty::GeneratorWitness(_)
| ty::Infer(_) | ty::Infer(_)
| ty::Opaque(..) | ty::Alias(..)
| ty::Param(_) | ty::Param(_)
| ty::Placeholder(_) | ty::Placeholder(_) => false,
| ty::Projection(_) => false,
} }
} }
@ -978,10 +976,9 @@ impl<'tcx> Ty<'tcx> {
| ty::Generator(..) | ty::Generator(..)
| ty::GeneratorWitness(_) | ty::GeneratorWitness(_)
| ty::Infer(_) | ty::Infer(_)
| ty::Opaque(..) | ty::Alias(..)
| ty::Param(_) | ty::Param(_)
| ty::Placeholder(_) | ty::Placeholder(_) => false,
| ty::Projection(_) => false,
} }
} }
@ -1101,12 +1098,9 @@ impl<'tcx> Ty<'tcx> {
// //
// FIXME(ecstaticmorse): Maybe we should `bug` here? This should probably only be // FIXME(ecstaticmorse): Maybe we should `bug` here? This should probably only be
// called for known, fully-monomorphized types. // called for known, fully-monomorphized types.
ty::Projection(_) ty::Alias(..) | ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) => {
| ty::Opaque(..) false
| ty::Param(_) }
| ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(_) => false,
ty::Foreign(_) | ty::GeneratorWitness(..) | ty::Error(_) => false, ty::Foreign(_) | ty::GeneratorWitness(..) | ty::Error(_) => false,
} }
@ -1237,11 +1231,10 @@ pub fn needs_drop_components<'tcx>(
// These require checking for `Copy` bounds or `Adt` destructors. // These require checking for `Copy` bounds or `Adt` destructors.
ty::Adt(..) ty::Adt(..)
| ty::Projection(..) | ty::Alias(..)
| ty::Param(_) | ty::Param(_)
| ty::Bound(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Opaque(..)
| ty::Infer(_) | ty::Infer(_)
| ty::Closure(..) | ty::Closure(..)
| ty::Generator(..) => Ok(smallvec![ty]), | ty::Generator(..) => Ok(smallvec![ty]),
@ -1265,13 +1258,12 @@ pub fn is_trivially_const_drop<'tcx>(ty: Ty<'tcx>) -> bool {
| ty::Never | ty::Never
| ty::Foreign(_) => true, | ty::Foreign(_) => true,
ty::Opaque(..) ty::Alias(..)
| ty::Dynamic(..) | ty::Dynamic(..)
| ty::Error(_) | ty::Error(_)
| ty::Bound(..) | ty::Bound(..)
| ty::Param(_) | ty::Param(_)
| ty::Placeholder(_) | ty::Placeholder(_)
| ty::Projection(_)
| ty::Infer(_) => false, | ty::Infer(_) => false,
// Not trivial because they have components, and instead of looking inside, // Not trivial because they have components, and instead of looking inside,

View file

@ -654,7 +654,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
// ignore the inputs to a projection, as they may not appear // ignore the inputs to a projection, as they may not appear
// in the normalized form // in the normalized form
if self.just_constrained { if self.just_constrained {
if let ty::Projection(..) | ty::Opaque(..) = t.kind() { if let ty::Alias(..) = t.kind() {
return ControlFlow::CONTINUE; return ControlFlow::CONTINUE;
} }
} }

View file

@ -165,7 +165,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
stack.push(ty.into()); stack.push(ty.into());
stack.push(lt.into()); stack.push(lt.into());
} }
ty::Projection(data) => { ty::Alias(_, data) => {
stack.extend(data.substs.iter().rev()); stack.extend(data.substs.iter().rev());
} }
ty::Dynamic(obj, lt, _) => { ty::Dynamic(obj, lt, _) => {
@ -188,7 +188,6 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
})); }));
} }
ty::Adt(_, substs) ty::Adt(_, substs)
| ty::Opaque(_, substs)
| ty::Closure(_, substs) | ty::Closure(_, substs)
| ty::Generator(_, substs, _) | ty::Generator(_, substs, _)
| ty::FnDef(_, substs) => { | ty::FnDef(_, substs) => {

View file

@ -373,7 +373,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// the case of `!`, no return value is required, as the block will never return. // the case of `!`, no return value is required, as the block will never return.
// Opaque types of empty bodies also need this unit assignment, in order to infer that their // Opaque types of empty bodies also need this unit assignment, in order to infer that their
// type is actually unit. Otherwise there will be no defining use found in the MIR. // type is actually unit. Otherwise there will be no defining use found in the MIR.
if destination_ty.is_unit() || matches!(destination_ty.kind(), ty::Opaque(..)) { if destination_ty.is_unit()
|| matches!(destination_ty.kind(), ty::Alias(ty::Opaque, ..))
{
// We only want to assign an implicit `()` as the return value of the block if the // We only want to assign an implicit `()` as the return value of the block if the
// block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.) // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
this.cfg.push_assign_unit(block, source_info, destination, this.tcx); this.cfg.push_assign_unit(block, source_info, destination, this.tcx);

View file

@ -121,7 +121,7 @@ impl<'tcx> ConstToPat<'tcx> {
ty::Dynamic(..) => { ty::Dynamic(..) => {
"trait objects cannot be used in patterns".to_string() "trait objects cannot be used in patterns".to_string()
} }
ty::Opaque(..) => { ty::Alias(ty::Opaque, ..) => {
"opaque types cannot be used in patterns".to_string() "opaque types cannot be used in patterns".to_string()
} }
ty::Closure(..) => { ty::Closure(..) => {

View file

@ -845,7 +845,7 @@ fn is_useful<'p, 'tcx>(
// Opaque types can't get destructured/split, but the patterns can // Opaque types can't get destructured/split, but the patterns can
// actually hint at hidden types, so we use the patterns' types instead. // actually hint at hidden types, so we use the patterns' types instead.
if let ty::Opaque(..) = ty.kind() { if let ty::Alias(ty::Opaque, ..) = ty.kind() {
if let Some(row) = rows.first() { if let Some(row) = rows.first() {
ty = row.head().ty(); ty = row.head().ty();
} }

View file

@ -849,7 +849,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
}; };
let kind = match parent_ty.ty.kind() { let kind = match parent_ty.ty.kind() {
&ty::Opaque(def_id, substs) => { &ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind() self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind()
} }
kind => kind, kind => kind,

View file

@ -52,7 +52,11 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
fn maybe_zst(ty: Ty<'_>) -> bool { fn maybe_zst(ty: Ty<'_>) -> bool {
match ty.kind() { match ty.kind() {
// maybe ZST (could be more precise) // maybe ZST (could be more precise)
ty::Adt(..) | ty::Array(..) | ty::Closure(..) | ty::Tuple(..) | ty::Opaque(..) => true, ty::Adt(..)
| ty::Array(..)
| ty::Closure(..)
| ty::Tuple(..)
| ty::Alias(ty::Opaque, ..) => true,
// definitely ZST // definitely ZST
ty::FnDef(..) | ty::Never => true, ty::FnDef(..) | ty::Never => true,
// unreachable or can't be ZST // unreachable or can't be ZST

View file

@ -88,10 +88,7 @@ trait DefIdVisitor<'tcx> {
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> {
self.skeleton().visit_trait(trait_ref) self.skeleton().visit_trait(trait_ref)
} }
fn visit_projection_ty( fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<Self::BreakTy> {
&mut self,
projection: ty::ProjectionTy<'tcx>,
) -> ControlFlow<Self::BreakTy> {
self.skeleton().visit_projection_ty(projection) self.skeleton().visit_projection_ty(projection)
} }
fn visit_predicates( fn visit_predicates(
@ -118,18 +115,15 @@ where
if self.def_id_visitor.shallow() { ControlFlow::CONTINUE } else { substs.visit_with(self) } if self.def_id_visitor.shallow() { ControlFlow::CONTINUE } else { substs.visit_with(self) }
} }
fn visit_projection_ty( fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
&mut self,
projection: ty::ProjectionTy<'tcx>,
) -> ControlFlow<V::BreakTy> {
let tcx = self.def_id_visitor.tcx(); let tcx = self.def_id_visitor.tcx();
let (trait_ref, assoc_substs) = if tcx.def_kind(projection.item_def_id) let (trait_ref, assoc_substs) = if tcx.def_kind(projection.def_id)
!= DefKind::ImplTraitPlaceholder != DefKind::ImplTraitPlaceholder
{ {
projection.trait_ref_and_own_substs(tcx) projection.trait_ref_and_own_substs(tcx)
} else { } else {
// HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys // HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
let def_id = tcx.impl_trait_in_trait_parent(projection.item_def_id); let def_id = tcx.impl_trait_in_trait_parent(projection.def_id);
let trait_generics = tcx.generics_of(def_id); let trait_generics = tcx.generics_of(def_id);
( (
ty::TraitRef { def_id, substs: projection.substs.truncate_to(tcx, trait_generics) }, ty::TraitRef { def_id, substs: projection.substs.truncate_to(tcx, trait_generics) },
@ -214,7 +208,7 @@ where
} }
} }
} }
ty::Projection(proj) => { ty::Alias(ty::Projection, proj) => {
if self.def_id_visitor.skip_assoc_tys() { if self.def_id_visitor.skip_assoc_tys() {
// Visitors searching for minimal visibility/reachability want to // Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `<Type as Trait>::Alias` // conservatively approximate associated types like `<Type as Trait>::Alias`
@ -241,7 +235,7 @@ where
self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref)?; self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref)?;
} }
} }
ty::Opaque(def_id, ..) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) => {
// Skip repeated `Opaque`s to avoid infinite recursion. // Skip repeated `Opaque`s to avoid infinite recursion.
if self.visited_opaque_tys.insert(def_id) { if self.visited_opaque_tys.insert(def_id) {
// The intent is to treat `impl Trait1 + Trait2` identically to // The intent is to treat `impl Trait1 + Trait2` identically to

View file

@ -216,8 +216,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
match *ty.kind() { match *ty.kind() {
// Print all nominal types as paths (unlike `pretty_print_type`). // Print all nominal types as paths (unlike `pretty_print_type`).
ty::FnDef(def_id, substs) ty::FnDef(def_id, substs)
| ty::Opaque(def_id, substs) | ty::Alias(_, ty::AliasTy { def_id, substs })
| ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
| ty::Closure(def_id, substs) | ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
@ -287,11 +286,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> {
// Similar to `pretty_path_qualified`, but for the other // Similar to `pretty_path_qualified`, but for the other
// types that are printed as paths (see `print_type` above). // types that are printed as paths (see `print_type` above).
match self_ty.kind() { match self_ty.kind() {
ty::FnDef(..) ty::FnDef(..) | ty::Alias(..) | ty::Closure(..) | ty::Generator(..)
| ty::Opaque(..)
| ty::Projection(_)
| ty::Closure(..)
| ty::Generator(..)
if trait_ref.is_none() => if trait_ref.is_none() =>
{ {
self.print_type(self_ty) self.print_type(self_ty)

View file

@ -240,7 +240,7 @@ fn encode_predicate<'tcx>(
s.push_str(&encode_substs(tcx, trait_ref.substs, dict, options)); s.push_str(&encode_substs(tcx, trait_ref.substs, dict, options));
} }
ty::ExistentialPredicate::Projection(projection) => { ty::ExistentialPredicate::Projection(projection) => {
let name = encode_ty_name(tcx, projection.item_def_id); let name = encode_ty_name(tcx, projection.def_id);
let _ = write!(s, "u{}{}", name.len(), &name); let _ = write!(s, "u{}{}", name.len(), &name);
s.push_str(&encode_substs(tcx, projection.substs, dict, options)); s.push_str(&encode_substs(tcx, projection.substs, dict, options));
match projection.term.unpack() { match projection.term.unpack() {
@ -646,10 +646,9 @@ fn encode_ty<'tcx>(
| ty::Error(..) | ty::Error(..)
| ty::GeneratorWitness(..) | ty::GeneratorWitness(..)
| ty::Infer(..) | ty::Infer(..)
| ty::Opaque(..) | ty::Alias(..)
| ty::Param(..) | ty::Param(..)
| ty::Placeholder(..) | ty::Placeholder(..) => {
| ty::Projection(..) => {
bug!("encode_ty: unexpected `{:?}`", ty.kind()); bug!("encode_ty: unexpected `{:?}`", ty.kind());
} }
}; };
@ -799,10 +798,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
| ty::Error(..) | ty::Error(..)
| ty::GeneratorWitness(..) | ty::GeneratorWitness(..)
| ty::Infer(..) | ty::Infer(..)
| ty::Opaque(..) | ty::Alias(..)
| ty::Param(..) | ty::Param(..)
| ty::Placeholder(..) | ty::Placeholder(..) => {
| ty::Projection(..) => {
bug!("transform_ty: unexpected `{:?}`", ty.kind()); bug!("transform_ty: unexpected `{:?}`", ty.kind());
} }
} }

View file

@ -439,8 +439,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
// Mangle all nominal types as paths. // Mangle all nominal types as paths.
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs) ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
| ty::FnDef(def_id, substs) | ty::FnDef(def_id, substs)
| ty::Opaque(def_id, substs) | ty::Alias(_, ty::AliasTy { def_id, substs })
| ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
| ty::Closure(def_id, substs) | ty::Closure(def_id, substs)
| ty::Generator(def_id, substs, _) => { | ty::Generator(def_id, substs, _) => {
self = self.print_def_path(def_id, substs)?; self = self.print_def_path(def_id, substs)?;
@ -544,7 +543,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
cx = cx.print_def_path(trait_ref.def_id, trait_ref.substs)?; cx = cx.print_def_path(trait_ref.def_id, trait_ref.substs)?;
} }
ty::ExistentialPredicate::Projection(projection) => { ty::ExistentialPredicate::Projection(projection) => {
let name = cx.tcx.associated_item(projection.item_def_id).name; let name = cx.tcx.associated_item(projection.def_id).name;
cx.push("p"); cx.push("p");
cx.push_ident(name.as_str()); cx.push_ident(name.as_str());
cx = match projection.term.unpack() { cx = match projection.term.unpack() {

View file

@ -579,14 +579,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
pub fn is_of_param(&self, ty: Ty<'_>) -> bool { pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
match ty.kind() { match ty.kind() {
ty::Param(_) => true, 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, _ => false,
} }
} }
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool { fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
if let Some(ty) = p.term().skip_binder().ty() { 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 { } else {
false false
} }

View file

@ -659,7 +659,7 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
| ty::RawPtr(..) | ty::RawPtr(..)
| ty::Never | ty::Never
| ty::Tuple(..) | 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), ty::Param(..) => self.found_param_ty(ty),
@ -704,7 +704,7 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
); );
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
} }
ty::Opaque(..) => { ty::Alias(ty::Opaque, ..) => {
// This merits some explanation. // This merits some explanation.
// Normally, opaque types are not involved when performing // Normally, opaque types are not involved when performing
// coherence checking, since it is illegal to directly // 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( let normalized_ty = ocx.normalize(
&obligation.cause, &obligation.cause,
obligation.param_env, obligation.param_env,
self.tcx self.tcx.mk_projection(data.projection_ty.def_id, data.projection_ty.substs),
.mk_projection(data.projection_ty.item_def_id, data.projection_ty.substs),
); );
debug!(?obligation.cause, ?obligation.param_env); 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() { let secondary_span = match predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self
.tcx .tcx
.opt_associated_item(proj.projection_ty.item_def_id) .opt_associated_item(proj.projection_ty.def_id)
.and_then(|trait_assoc_item| { .and_then(|trait_assoc_item| {
self.tcx 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)) .map(|id| (trait_assoc_item, id))
}) })
.and_then(|(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 trait_def_id = pred.projection_ty.trait_def_id(self.tcx);
let self_ty = pred.projection_ty.self_ty(); 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!( Some(format!(
"expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it returns `{normalized_ty}`", "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) fn_kind = self_ty.prefix_string(self.tcx)
@ -1790,8 +1789,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::Closure(..) => Some(9), ty::Closure(..) => Some(9),
ty::Tuple(..) => Some(10), ty::Tuple(..) => Some(10),
ty::Param(..) => Some(11), ty::Param(..) => Some(11),
ty::Projection(..) => Some(12), ty::Alias(ty::Projection, ..) => Some(12),
ty::Opaque(..) => Some(13), ty::Alias(ty::Opaque, ..) => Some(13),
ty::Never => Some(14), ty::Never => Some(14),
ty::Adt(..) => Some(15), ty::Adt(..) => Some(15),
ty::Generator(..) => Some(16), ty::Generator(..) => Some(16),

View file

@ -371,7 +371,7 @@ fn suggest_restriction<'tcx>(
msg: &str, msg: &str,
err: &mut Diagnostic, err: &mut Diagnostic,
fn_sig: Option<&hir::FnSig<'_>>, fn_sig: Option<&hir::FnSig<'_>>,
projection: Option<&ty::ProjectionTy<'_>>, projection: Option<&ty::AliasTy<'_>>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
// When we are dealing with a trait, `super_traits` will be `Some`: // When we are dealing with a trait, `super_traits` will be `Some`:
// Given `trait T: A + B + C {}` // 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 self_ty = trait_pred.skip_binder().self_ty();
let (param_ty, projection) = match self_ty.kind() { let (param_ty, projection) = match self_ty.kind() {
ty::Param(_) => (true, None), ty::Param(_) => (true, None),
ty::Projection(projection) => (false, Some(projection)), ty::Alias(ty::Projection, projection) => (false, Some(projection)),
_ => (false, None), _ => (false, None),
}; };
@ -857,10 +857,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn_sig.inputs().map_bound(|inputs| &inputs[1..]), 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| { 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() 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] // args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind() && 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) => { ty::Dynamic(data, _, ty::Dyn) => {
data.iter().find_map(|pred| { data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder() 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 // for existential projection, substs are shifted over by 1
&& let ty::Tuple(args) = proj.substs.type_at(0).kind() && let ty::Tuple(args) = proj.substs.type_at(0).kind()
{ {
@ -894,7 +894,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::Param(_) => { ty::Param(_) => {
obligation.param_env.caller_bounds().iter().find_map(|pred| { obligation.param_env.caller_bounds().iter().find_map(|pred| {
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder() 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 && proj.projection_ty.self_ty() == found
// args tuple will always be substs[1] // args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind() && 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), Some(ident) => err.span_note(ident.span, &msg),
None => err.note(&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 // Avoid printing the future from `core::future::identity_future`, it's not helpful
if tcx.parent(*def_id) == identity_future { if tcx.parent(*def_id) == identity_future {
break 'print; break 'print;
@ -3218,7 +3218,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let ocx = ObligationCtxt::new_in_snapshot(self.infcx); let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
for diff in &type_diffs { for diff in &type_diffs {
let Sorts(expected_found) = diff else { continue; }; 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 = let origin =
TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
@ -3245,7 +3245,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// This corresponds to `<ExprTy as Iterator>::Item = _`. // This corresponds to `<ExprTy as Iterator>::Item = _`.
let trait_ref = ty::Binder::dummy(ty::PredicateKind::Clause( let trait_ref = ty::Binder::dummy(ty::PredicateKind::Clause(
ty::Clause::Projection(ty::ProjectionPredicate { 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(), term: ty_var.into(),
}), }),
)); ));
@ -3260,7 +3260,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if ocx.select_where_possible().is_empty() { if ocx.select_where_possible().is_empty() {
// `ty_var` now holds the type that `Item` is for `ExprTy`. // `ty_var` now holds the type that `Item` is for `ExprTy`.
let ty_var = self.resolve_vars_if_possible(ty_var); 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 { } else {
// `<ExprTy as Iterator>` didn't select, so likely we've // `<ExprTy as Iterator>` didn't select, so likely we've
// reached the end of the iterator chain, like the originating // 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()?; let pred = obligation.predicate.to_opt_poly_projection_pred()?;
Some(pred.map_bound(|p| { Some(pred.map_bound(|p| {
ty::ExistentialPredicate::Projection(ty::ExistentialProjection { 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, substs: p.projection_ty.substs,
term: p.term, term: p.term,
}) })
@ -794,13 +794,13 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
} }
ty::Projection(ref data) ty::Alias(ty::Projection, ref data)
if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder => if self.tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder =>
{ {
// We'll deny these later in their own pass // We'll deny these later in their own pass
ControlFlow::CONTINUE ControlFlow::CONTINUE
} }
ty::Projection(ref data) => { ty::Alias(ty::Projection, ref data) => {
// This is a projected type `<Foo as SomeTrait>::X`. // This is a projected type `<Foo as SomeTrait>::X`.
// Compute supertraits of current trait lazily. // 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? // FIXME(RPITIT): Perhaps we should use a visitor here?
ty.skip_binder().walk().find_map(|arg| { ty.skip_binder().walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack() 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.item_def_id) == DefKind::ImplTraitPlaceholder && 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 { } else {
None 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 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; 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 // This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with // severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark. // 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. // Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() { match self.param_env.reveal() {
Reveal::UserFacing => ty.super_fold_with(self), 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 // This branch is *mostly* just an optimization: when we don't
// have escaping bound vars, we don't need to replace them with // have escaping bound vars, we don't need to replace them with
// placeholders (see branch below). *Also*, we know that we can // 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() normalized_ty.ty().unwrap()
} }
ty::Projection(data) => { ty::Alias(ty::Projection, data) => {
// If there are escaping bound vars, we temporarily replace the // If there are escaping bound vars, we temporarily replace the
// bound vars with placeholders. Note though, that in the case // bound vars with placeholders. Note though, that in the case
// that we still can't project for whatever reason (e.g. self // 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>( pub fn normalize_projection_type<'a, 'b, 'tcx>(
selcx: &'a mut SelectionContext<'b, 'tcx>, selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>, projection_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
depth: usize, depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>, 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>( fn opt_normalize_projection_type<'a, 'b, 'tcx>(
selcx: &'a mut SelectionContext<'b, 'tcx>, selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>, projection_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
depth: usize, depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>, obligations: &mut Vec<PredicateObligation<'tcx>>,
@ -1177,7 +1179,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
fn normalize_to_error<'a, 'tcx>( fn normalize_to_error<'a, 'tcx>(
selcx: &mut SelectionContext<'a, 'tcx>, selcx: &mut SelectionContext<'a, 'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>, projection_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
depth: usize, depth: usize,
) -> NormalizedTy<'tcx> { ) -> NormalizedTy<'tcx> {
@ -1189,10 +1191,9 @@ fn normalize_to_error<'a, 'tcx>(
predicate: trait_ref.without_const().to_predicate(selcx.tcx()), predicate: trait_ref.without_const().to_predicate(selcx.tcx()),
}; };
let tcx = selcx.infcx.tcx; let tcx = selcx.infcx.tcx;
let def_id = projection_ty.item_def_id;
let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin { let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::NormalizeProjectionType, 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] } 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. // need to investigate whether or not this is fine.
selcx selcx
.tcx() .tcx()
.mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs) .mk_projection(obligation.predicate.def_id, obligation.predicate.substs)
.into(), .into(),
)), )),
// Error occurred while trying to processing impls. // 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>, candidate_set: &mut ProjectionCandidateSet<'tcx>,
) { ) {
let tcx = selcx.tcx(); let tcx = selcx.tcx();
if tcx.def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder { if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
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);
// If we are trying to project an RPITIT with trait's default `Self` parameter, // If we are trying to project an RPITIT with trait's default `Self` parameter,
// then we must be within a default trait body. // then we must be within a default trait body.
if obligation.predicate.self_ty() if obligation.predicate.self_ty()
== ty::InternalSubsts::identity_for_item(tcx, obligation.predicate.item_def_id) == ty::InternalSubsts::identity_for_item(tcx, obligation.predicate.def_id).type_at(0)
.type_at(0)
&& tcx.associated_item(trait_fn_def_id).defaultness(tcx).has_value() && tcx.associated_item(trait_fn_def_id).defaultness(tcx).has_value()
{ {
candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait( 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. // 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. // 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() { 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::Alias(_, ref data) => tcx.bound_item_bounds(data.def_id).subst(tcx, data.substs),
ty::Opaque(def_id, substs) => tcx.bound_item_bounds(def_id).subst(tcx, substs),
ty::Infer(ty::TyVar(_)) => { ty::Infer(ty::TyVar(_)) => {
// If the self-type is an inference variable, then it MAY wind up // If the self-type is an inference variable, then it MAY wind up
// being a projected type, so induce an ambiguity. // being a projected type, so induce an ambiguity.
@ -1430,7 +1429,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
}; };
let env_predicates = data let env_predicates = data
.projection_bounds() .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)); .map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx));
assemble_candidates_from_predicates( assemble_candidates_from_predicates(
@ -1462,7 +1461,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
predicate.kind().skip_binder() predicate.kind().skip_binder()
{ {
let data = bound_predicate.rebind(data); 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; continue;
} }
@ -1503,7 +1502,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
candidate_set: &mut ProjectionCandidateSet<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>,
) { ) {
// Can't assemble candidate from impl for RPITIT // 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; return;
} }
@ -1555,7 +1554,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// NOTE: This should be kept in sync with the similar code in // NOTE: This should be kept in sync with the similar code in
// `rustc_ty_utils::instance::resolve_associated_item()`. // `rustc_ty_utils::instance::resolve_associated_item()`.
let node_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 { .. }| ())?; .map_err(|ErrorGuaranteed { .. }| ())?;
if node_item.is_final() { if node_item.is_final() {
@ -1616,8 +1615,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// type parameters, opaques, and unnormalized projections have pointer // type parameters, opaques, and unnormalized projections have pointer
// metadata if they're known (e.g. by the param_env) to be sized // metadata if they're known (e.g. by the param_env) to be sized
ty::Param(_) ty::Param(_)
| ty::Projection(..) | ty::Alias(..)
| ty::Opaque(..)
| ty::Bound(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Infer(..) | ty::Infer(..)
@ -1671,7 +1669,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// type parameters, opaques, and unnormalized projections have pointer // type parameters, opaques, and unnormalized projections have pointer
// metadata if they're known (e.g. by the param_env) to be sized // 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( if selcx.infcx.predicate_must_hold_modulo_regions(
&obligation.with( &obligation.with(
selcx.tcx(), selcx.tcx(),
@ -1687,8 +1685,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized? // FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
ty::Param(_) ty::Param(_)
| ty::Projection(..) | ty::Alias(..)
| ty::Opaque(..)
| ty::Bound(..) | ty::Bound(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Infer(..) | ty::Infer(..)
@ -1788,7 +1785,7 @@ fn confirm_candidate<'cx, 'tcx>(
ProjectionCandidate::ImplTraitInTrait(ImplTraitInTraitCandidate::Trait) => Progress { ProjectionCandidate::ImplTraitInTrait(ImplTraitInTraitCandidate::Trait) => Progress {
term: selcx term: selcx
.tcx() .tcx()
.mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs) .mk_opaque(obligation.predicate.def_id, obligation.predicate.substs)
.into(), .into(),
obligations: vec![], obligations: vec![],
}, },
@ -1860,7 +1857,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
gen_sig, gen_sig,
) )
.map_bound(|(trait_ref, yield_ty, return_ty)| { .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 { let ty = if name == sym::Return {
return_ty return_ty
} else if name == sym::Yield { } else if name == sym::Yield {
@ -1870,9 +1867,9 @@ fn confirm_generator_candidate<'cx, 'tcx>(
}; };
ty::ProjectionPredicate { ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy { projection_ty: ty::AliasTy {
substs: trait_ref.substs, substs: trait_ref.substs,
item_def_id: obligation.predicate.item_def_id, def_id: obligation.predicate.def_id,
}, },
term: ty.into(), term: ty.into(),
} }
@ -1909,12 +1906,12 @@ fn confirm_future_candidate<'cx, 'tcx>(
gen_sig, gen_sig,
) )
.map_bound(|(trait_ref, return_ty)| { .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 { ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy { projection_ty: ty::AliasTy {
substs: trait_ref.substs, substs: trait_ref.substs,
item_def_id: obligation.predicate.item_def_id, def_id: obligation.predicate.def_id,
}, },
term: return_ty.into(), term: return_ty.into(),
} }
@ -1934,7 +1931,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
let self_ty = obligation.predicate.self_ty(); let self_ty = obligation.predicate.self_ty();
let substs = tcx.mk_substs([self_ty.into()].iter()); let substs = tcx.mk_substs([self_ty.into()].iter());
let lang_items = tcx.lang_items(); 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 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 (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); 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); bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
}; };
let predicate = let predicate = ty::ProjectionPredicate {
ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term }; projection_ty: ty::AliasTy { substs, def_id: item_def_id },
term,
};
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
.with_addl_obligations(obligations) .with_addl_obligations(obligations)
@ -2038,10 +2037,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
flag, flag,
) )
.map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate { .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy { projection_ty: ty::AliasTy { substs: trait_ref.substs, def_id: fn_once_output_def_id },
substs: trait_ref.substs,
item_def_id: fn_once_output_def_id,
},
term: ret_type.into(), term: ret_type.into(),
}); });
@ -2122,7 +2118,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
let tcx = selcx.tcx(); let tcx = selcx.tcx();
let ImplSourceUserDefinedData { impl_def_id, substs, mut nested } = impl_impl_source; 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 trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
let param_env = obligation.param_env; let param_env = obligation.param_env;
@ -2222,7 +2218,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
let tcx = selcx.tcx(); let tcx = selcx.tcx();
let mut obligations = data.nested; 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 { let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
return Progress { term: tcx.ty_error().into(), obligations }; 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 // Use the default `impl Trait` for the trait, e.g., for a default trait body
if leaf_def.item.container == ty::AssocItemContainer::TraitContainer { if leaf_def.item.container == ty::AssocItemContainer::TraitContainer {
return Progress { return Progress {
term: tcx term: tcx.mk_opaque(obligation.predicate.def_id, obligation.predicate.substs).into(),
.mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs)
.into(),
obligations, obligations,
}; };
} }
@ -2302,7 +2296,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
tcx.bound_trait_impl_trait_tys(impl_fn_def_id) tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
.map_bound(|tys| { .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), .subst(tcx, impl_fn_substs),
&mut obligations, &mut obligations,
@ -2320,7 +2314,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
) { ) {
let tcx = selcx.tcx(); let tcx = selcx.tcx();
let own = tcx let own = tcx
.predicates_of(obligation.predicate.item_def_id) .predicates_of(obligation.predicate.def_id)
.instantiate_own(tcx, obligation.predicate.substs); .instantiate_own(tcx, obligation.predicate.substs);
for (predicate, span) in std::iter::zip(own.predicates, own.spans) { for (predicate, span) in std::iter::zip(own.predicates, own.spans) {
let normalized = normalize_with_depth_to( let normalized = normalize_with_depth_to(
@ -2343,13 +2337,13 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
ObligationCause::new( ObligationCause::new(
obligation.cause.span, obligation.cause.span,
obligation.cause.body_id, obligation.cause.body_id,
super::ItemObligation(obligation.predicate.item_def_id), super::ItemObligation(obligation.predicate.def_id),
) )
} else { } else {
ObligationCause::new( ObligationCause::new(
obligation.cause.span, obligation.cause.span,
obligation.cause.body_id, obligation.cause.body_id,
super::BindingObligation(obligation.predicate.item_def_id, span), super::BindingObligation(obligation.predicate.def_id, span),
) )
}; };
nested.push(Obligation::with_depth( 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. // The following *might* require a destructor: needs deeper inspection.
ty::Dynamic(..) ty::Dynamic(..)
| ty::Projection(..) | ty::Alias(..)
| ty::Param(_) | ty::Param(_)
| ty::Opaque(..)
| ty::Placeholder(..) | ty::Placeholder(..)
| ty::Infer(_) | ty::Infer(_)
| ty::Bound(..) | 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 // This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with // severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark. // 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. // Only normalize `impl Trait` outside of type inference, usually in codegen.
match self.param_env.reveal() { match self.param_env.reveal() {
Reveal::UserFacing => ty.try_super_fold_with(self), 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, // 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). // 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` // See note in `rustc_trait_selection::traits::project`
let tcx = self.infcx.tcx; 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 // Before we go into the whole placeholder thing, just
// quickly check if the self-type is a projection at all. // quickly check if the self-type is a projection at all.
match obligation.predicate.skip_binder().trait_ref.self_ty().kind() { match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
ty::Projection(_) | ty::Opaque(..) => {} ty::Alias(..) => {}
ty::Infer(ty::TyVar(_)) => { ty::Infer(ty::TyVar(_)) => {
span_bug!( span_bug!(
obligation.cause.span, obligation.cause.span,
@ -394,7 +394,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// still be provided by a manual implementation for // still be provided by a manual implementation for
// this trait and type. // this trait and type.
} }
ty::Param(..) | ty::Projection(..) => { ty::Param(..) | ty::Alias(ty::Projection, ..) => {
// In these cases, we don't know what the actual // In these cases, we don't know what the actual
// type is. Therefore, we cannot break it down // type is. Therefore, we cannot break it down
// into its constituent types. So we don't // into its constituent types. So we don't
@ -536,10 +536,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let ty = traits::normalize_projection_type( let ty = traits::normalize_projection_type(
self, self,
param_env, param_env,
ty::ProjectionTy { ty::AliasTy { def_id: tcx.lang_items().deref_target()?, substs: trait_ref.substs },
item_def_id: tcx.lang_items().deref_target()?,
substs: trait_ref.substs,
},
cause.clone(), cause.clone(),
0, 0,
// We're *intentionally* throwing these away, // 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()); let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
match self_ty.skip_binder().kind() { match self_ty.skip_binder().kind() {
ty::Opaque(..) ty::Alias(..)
| ty::Dynamic(..) | ty::Dynamic(..)
| ty::Error(_) | ty::Error(_)
| ty::Bound(..) | ty::Bound(..)
| ty::Param(_) | ty::Param(_)
| ty::Placeholder(_) | ty::Placeholder(_) => {
| ty::Projection(_) => {
// We don't know if these are `~const Destruct`, at least // We don't know if these are `~const Destruct`, at least
// not structurally... so don't push a candidate. // not structurally... so don't push a candidate.
} }
@ -829,8 +825,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Generator(_, _, _) | ty::Generator(_, _, _)
| ty::GeneratorWitness(_) | ty::GeneratorWitness(_)
| ty::Never | ty::Never
| ty::Projection(_) | ty::Alias(..)
| ty::Opaque(_, _)
| ty::Param(_) | ty::Param(_)
| ty::Bound(_, _) | ty::Bound(_, _)
| ty::Error(_) | 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_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let (def_id, substs) = match *placeholder_self_ty.kind() { let (def_id, substs) = match *placeholder_self_ty.kind() {
ty::Projection(proj) => (proj.item_def_id, proj.substs), ty::Alias(_, ty::AliasTy { def_id, substs }) => (def_id, substs),
ty::Opaque(def_id, substs) => (def_id, substs),
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
}; };
@ -184,7 +183,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map_err(|_| Unimplemented) .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; let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates;
debug!(?predicates, "projection predicates"); debug!(?predicates, "projection predicates");
for predicate in 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 // If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable // with a fresh infer variable
ty::Projection(..) => { ty::Alias(ty::Projection, ..) => {
let predicate = normalize_with_depth_to( let predicate = normalize_with_depth_to(
self, self,
obligation.param_env, obligation.param_env,

View file

@ -1595,8 +1595,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() { let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
ty::Projection(ref data) => (data.item_def_id, data.substs), ty::Alias(_, ty::AliasTy { def_id, substs }) => (def_id, substs),
ty::Opaque(def_id, substs) => (def_id, substs),
_ => { _ => {
span_bug!( span_bug!(
obligation.cause.span, obligation.cause.span,
@ -1745,7 +1744,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}); });
if is_match { 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. // FIXME(generic-associated-types): Addresses aggressive inference in #92917.
// If this type is a GAT, and of the GAT substs resolve to something new, // 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. // 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::Infer(ty::TyVar(_)) => Ambiguous,
ty::Placeholder(..) 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. // Fallback to whatever user-defined impls exist in this case.
None None
} }
@ -2220,7 +2219,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Dynamic(..) | ty::Dynamic(..)
| ty::Param(..) | ty::Param(..)
| ty::Foreign(..) | ty::Foreign(..)
| ty::Projection(..) | ty::Alias(ty::Projection, ..)
| ty::Bound(..) | ty::Bound(..)
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { | ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("asked to assemble constituent types of unexpected type: {:?}", t); 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()) 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, // We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring // which enforces a DAG between the functions requiring
// the auto trait bounds in question. // the auto trait bounds in question.

View file

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

View file

@ -234,9 +234,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
// projection coming from another associated type. See // projection coming from another associated type. See
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and // `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
// `traits-assoc-type-in-supertrait-bad.rs`. // `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) = && 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 && let Some(impl_item_span) = items
.iter() .iter()
.find(|item| item.id.owner_id.to_def_id() == impl_item_id) .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 // 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`. // 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); 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) = && 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 && let Some(impl_item_span) = items
.iter() .iter()
.find(|item| item.id.owner_id.to_def_id() == impl_item_id) .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 /// Pushes the obligations required for `trait_ref::Item` to be WF
/// into `self.out`. /// 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 projection is well-formed if
// //
// (a) its predicates hold (*) // (a) its predicates hold (*)
@ -392,7 +392,7 @@ impl<'tcx> WfPredicates<'tcx> {
// `i32: Copy` // `i32: Copy`
// ] // ]
// Projection types do not require const predicates. // 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); self.out.extend(obligations);
let tcx = self.tcx(); let tcx = self.tcx();
@ -556,7 +556,7 @@ impl<'tcx> WfPredicates<'tcx> {
// Simple cases that are WF if their type args are WF. // 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. walker.skip_current_subtree(); // Subtree handled by compute_projection.
self.compute_projection(data); self.compute_projection(data);
} }
@ -648,12 +648,12 @@ impl<'tcx> WfPredicates<'tcx> {
// types appearing in the fn signature // 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 // All of the requirements on type parameters
// have already been checked for `impl Trait` in // have already been checked for `impl Trait` in
// return position. We do need to check type-alias-impl-trait though. // return position. We do need to check type-alias-impl-trait though.
if ty::is_impl_trait_defn(self.tcx, did).is_none() { if ty::is_impl_trait_defn(self.tcx, def_id).is_none() {
let obligations = self.nominal_obligations(did, substs); let obligations = self.nominal_obligations(def_id, substs);
self.out.extend(obligations); self.out.extend(obligations);
} }
} }

View file

@ -432,7 +432,10 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
(ast::Mutability::Not, chalk_ir::Mutability::Not) => true, (ast::Mutability::Not, chalk_ir::Mutability::Not) => true,
} }
} }
(&ty::Opaque(def_id, ..), OpaqueType(opaque_ty_id, ..)) => def_id == opaque_ty_id.0, (
&ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }),
OpaqueType(opaque_ty_id, ..),
) => def_id == opaque_ty_id.0,
(&ty::FnDef(def_id, ..), FnDef(fn_def_id, ..)) => def_id == fn_def_id.0, (&ty::FnDef(def_id, ..), FnDef(fn_def_id, ..)) => def_id == fn_def_id.0,
(&ty::Str, Str) => true, (&ty::Str, Str) => true,
(&ty::Never, Never) => true, (&ty::Never, Never) => true,
@ -786,7 +789,7 @@ impl<'tcx> ty::TypeFolder<'tcx> for ReplaceOpaqueTyFolder<'tcx> {
} }
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Opaque(def_id, substs) = *ty.kind() { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) = *ty.kind() {
if def_id == self.opaque_ty_id.0 && substs == self.identity_substs { if def_id == self.opaque_ty_id.0 && substs == self.identity_substs {
return self.tcx.mk_ty(ty::Bound( return self.tcx.mk_ty(ty::Bound(
self.binder_index, self.binder_index,

View file

@ -66,15 +66,6 @@ impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInte
} }
} }
impl<'tcx> LowerInto<'tcx, chalk_ir::AliasTy<RustInterner<'tcx>>> for ty::ProjectionTy<'tcx> {
fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::AliasTy<RustInterner<'tcx>> {
chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
associated_ty_id: chalk_ir::AssocTypeId(self.item_def_id),
substitution: self.substs.lower_into(interner),
})
}
}
impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>>> impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'tcx>>>>
for ChalkEnvironmentAndGoal<'tcx> for ChalkEnvironmentAndGoal<'tcx>
{ {
@ -255,7 +246,10 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq<RustInterner<'tcx>>>
// FIXME(associated_const_equality): teach chalk about terms for alias eq. // FIXME(associated_const_equality): teach chalk about terms for alias eq.
chalk_ir::AliasEq { chalk_ir::AliasEq {
ty: self.term.ty().unwrap().lower_into(interner), ty: self.term.ty().unwrap().lower_into(interner),
alias: self.projection_ty.lower_into(interner), alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.def_id),
substitution: self.projection_ty.substs.lower_into(interner),
}),
} }
} }
} }
@ -353,8 +347,13 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
ty::Tuple(types) => { ty::Tuple(types) => {
chalk_ir::TyKind::Tuple(types.len(), types.as_substs().lower_into(interner)) chalk_ir::TyKind::Tuple(types.len(), types.as_substs().lower_into(interner))
} }
ty::Projection(proj) => chalk_ir::TyKind::Alias(proj.lower_into(interner)), ty::Alias(ty::Projection, ty::AliasTy { def_id, substs }) => {
ty::Opaque(def_id, substs) => { chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
associated_ty_id: chalk_ir::AssocTypeId(def_id),
substitution: substs.lower_into(interner),
}))
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
opaque_ty_id: chalk_ir::OpaqueTyId(def_id), opaque_ty_id: chalk_ir::OpaqueTyId(def_id),
substitution: substs.lower_into(interner), substitution: substs.lower_into(interner),
@ -442,13 +441,14 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
mutbl.lower_into(interner), mutbl.lower_into(interner),
), ),
TyKind::Str => ty::Str, TyKind::Str => ty::Str,
TyKind::OpaqueType(opaque_ty, substitution) => { TyKind::OpaqueType(opaque_ty, substitution) => ty::Alias(
ty::Opaque(opaque_ty.0, substitution.lower_into(interner)) ty::Opaque,
} ty::AliasTy { def_id: opaque_ty.0, substs: substitution.lower_into(interner) },
TyKind::AssociatedType(assoc_ty, substitution) => ty::Projection(ty::ProjectionTy { ),
substs: substitution.lower_into(interner), TyKind::AssociatedType(assoc_ty, substitution) => ty::Alias(
item_def_id: assoc_ty.0, ty::Projection,
}), ty::AliasTy { substs: substitution.lower_into(interner), def_id: assoc_ty.0 },
),
TyKind::Foreign(def_id) => ty::Foreign(def_id.0), TyKind::Foreign(def_id) => ty::Foreign(def_id.0),
TyKind::Error => return interner.tcx.ty_error(), TyKind::Error => return interner.tcx.ty_error(),
TyKind::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder { TyKind::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder {
@ -456,13 +456,20 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> {
name: ty::BoundVar::from_usize(placeholder.idx), name: ty::BoundVar::from_usize(placeholder.idx),
}), }),
TyKind::Alias(alias_ty) => match alias_ty { TyKind::Alias(alias_ty) => match alias_ty {
chalk_ir::AliasTy::Projection(projection) => ty::Projection(ty::ProjectionTy { chalk_ir::AliasTy::Projection(projection) => ty::Alias(
item_def_id: projection.associated_ty_id.0, ty::Projection,
ty::AliasTy {
def_id: projection.associated_ty_id.0,
substs: projection.substitution.lower_into(interner), substs: projection.substitution.lower_into(interner),
}), },
chalk_ir::AliasTy::Opaque(opaque) => { ),
ty::Opaque(opaque.opaque_ty_id.0, opaque.substitution.lower_into(interner)) chalk_ir::AliasTy::Opaque(opaque) => ty::Alias(
} ty::Opaque,
ty::AliasTy {
def_id: opaque.opaque_ty_id.0,
substs: opaque.substitution.lower_into(interner),
},
),
}, },
TyKind::Function(_quantified_ty) => unimplemented!(), TyKind::Function(_quantified_ty) => unimplemented!(),
TyKind::BoundVar(_bound) => ty::Bound( TyKind::BoundVar(_bound) => ty::Bound(
@ -688,7 +695,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
binders.clone(), binders.clone(),
chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq {
alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
associated_ty_id: chalk_ir::AssocTypeId(predicate.item_def_id), associated_ty_id: chalk_ir::AssocTypeId(predicate.def_id),
substitution: interner substitution: interner
.tcx .tcx
.mk_substs_trait(self_ty, predicate.substs) .mk_substs_trait(self_ty, predicate.substs)
@ -844,7 +851,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>
let (trait_ref, own_substs) = self.projection_ty.trait_ref_and_own_substs(interner.tcx); let (trait_ref, own_substs) = self.projection_ty.trait_ref_and_own_substs(interner.tcx);
chalk_solve::rust_ir::AliasEqBound { chalk_solve::rust_ir::AliasEqBound {
trait_bound: trait_ref.lower_into(interner), trait_bound: trait_ref.lower_into(interner),
associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id), associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.def_id),
parameters: own_substs.iter().map(|arg| arg.lower_into(interner)).collect(), parameters: own_substs.iter().map(|arg| arg.lower_into(interner)).collect(),
value: self.term.ty().unwrap().lower_into(interner), value: self.term.ty().unwrap().lower_into(interner),
} }

View file

@ -112,7 +112,7 @@ fn dropck_outlives<'tcx>(
// A projection that we couldn't resolve - it // A projection that we couldn't resolve - it
// might have a destructor. // might have a destructor.
ty::Projection(..) | ty::Opaque(..) => { ty::Alias(..) => {
result.kinds.push(ty.into()); result.kinds.push(ty.into());
} }
@ -268,7 +268,7 @@ fn dtorck_constraint_for_ty<'tcx>(
} }
// Types that can't be resolved. Pass them forward. // Types that can't be resolved. Pass them forward.
ty::Projection(..) | ty::Opaque(..) | ty::Param(..) => { ty::Alias(..) | ty::Param(..) => {
constraints.dtorck_types.push(ty); constraints.dtorck_types.push(ty);
} }

Some files were not shown because too many files have changed in this diff Show more