Skip to content

Commit

Permalink
Auto merge of #104986 - compiler-errors:opaques, r=oli-obk
Browse files Browse the repository at this point in the history
Combine `ty::Projection` and `ty::Opaque` into `ty::Alias`

Implements rust-lang/types-team#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`
  • Loading branch information
bors committed Dec 14, 2022
2 parents 21ee03e + 99417d5 commit 918d0ac
Show file tree
Hide file tree
Showing 115 changed files with 632 additions and 674 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.map_bound(|p| p.predicates),
None,
),
ty::Opaque(did, substs) => {
find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*did), Some(*substs))
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*def_id), Some(*substs))
}
ty::Closure(_, substs) => match substs.as_closure().kind() {
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;

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)
};

Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ fn push_debuginfo_type_name<'tcx>(
let projection_bounds: SmallVec<[_; 4]> = trait_data
.projection_bounds()
.map(|bound| {
let ExistentialProjection { item_def_id, term, .. } =
let ExistentialProjection { def_id: item_def_id, term, .. } =
tcx.erase_late_bound_regions(bound);
// FIXME(associated_const_equality): allow for consts here
(item_def_id, term.ty().unwrap())
Expand Down Expand Up @@ -411,9 +411,8 @@ fn push_debuginfo_type_name<'tcx>(
ty::Error(_)
| ty::Infer(_)
| ty::Placeholder(..)
| ty::Projection(..)
| ty::Alias(..)
| ty::Bound(..)
| ty::Opaque(..)
| ty::GeneratorWitness(..) => {
bug!(
"debuginfo: Trying to create type name for \
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,11 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
| ty::Foreign(..)
| ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_))
| ty::Projection(..)
// FIXME(oli-obk): we could look behind opaque types
| ty::Alias(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(..)
// FIXME(oli-obk): we could look behind opaque types
| ty::Opaque(..)
| ty::Infer(_)
// FIXME(oli-obk): we can probably encode closures just like structs
| ty::Closure(..)
Expand Down Expand Up @@ -307,11 +306,10 @@ pub fn valtree_to_const_value<'tcx>(
| ty::Foreign(..)
| ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_))
| ty::Projection(..)
| ty::Alias(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Opaque(..)
| ty::Infer(_)
| ty::Closure(..)
| ty::Generator(..)
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,9 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
ty::Adt(ref adt, _) => {
ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx)
}
ty::Projection(_)
| ty::Opaque(_, _)
| ty::Param(_)
| ty::Placeholder(_)
| ty::Infer(_) => throw_inval!(TooGeneric),
ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
throw_inval!(TooGeneric)
}
ty::Bound(_, _) => bug!("bound ty during ctfe"),
ty::Bool
| ty::Char
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
| ty::Placeholder(..)
| ty::Bound(..)
| ty::Param(..)
| ty::Opaque(..)
| ty::Projection(..)
| ty::Alias(..)
| ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
};

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()
}
kind => kind,
Expand Down Expand Up @@ -652,7 +652,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
}
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(
location,
format!(
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_const_eval/src/util/type_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
// Types with identity (print the module path).
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
| ty::FnDef(def_id, substs)
| ty::Opaque(def_id, substs)
| ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
| ty::Alias(_, ty::AliasTy { def_id, substs })
| ty::Closure(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, &[]),
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,10 +1146,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

debug!(?substs_trait_ref_and_assoc_item);

ty::ProjectionTy {
item_def_id: assoc_item.def_id,
substs: substs_trait_ref_and_assoc_item,
}
ty::AliasTy { def_id: assoc_item.def_id, substs: substs_trait_ref_and_assoc_item }
});

if !speculative {
Expand Down Expand Up @@ -1195,7 +1192,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// the "projection predicate" for:
//
// `<T as Iterator>::Item = u32`
let assoc_item_def_id = projection_ty.skip_binder().item_def_id;
let assoc_item_def_id = projection_ty.skip_binder().def_id;
let def_kind = tcx.def_kind(assoc_item_def_id);
match (def_kind, term.unpack()) {
(hir::def::DefKind::AssocTy, ty::TermKind::Ty(_))
Expand Down Expand Up @@ -1244,7 +1241,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
//
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
// parameter to have a skipped binder.
let param_ty = tcx.mk_ty(ty::Projection(projection_ty.skip_binder()));
let param_ty = tcx.mk_ty(ty::Alias(ty::Projection, projection_ty.skip_binder()));
self.add_bounds(param_ty, ast_bounds.iter(), bounds, candidate.bound_vars());
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E
impl<'tcx> ty::visit::TypeVisitor<'tcx> for OpaqueTypeCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match *t.kind() {
ty::Opaque(def, _) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, substs: _ }) => {
self.0.push(def);
ControlFlow::CONTINUE
}
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_hir_analysis/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,10 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
}

fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Projection(proj) = ty.kind()
&& self.tcx().def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
if let ty::Alias(ty::Projection, proj) = ty.kind()
&& self.tcx().def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
{
if let Some((ty, _)) = self.types.get(&proj.item_def_id) {
if let Some((ty, _)) = self.types.get(&proj.def_id) {
return *ty;
}
//FIXME(RPITIT): Deny nested RPITIT in substs too
Expand All @@ -586,9 +586,9 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
span: self.span,
kind: TypeVariableOriginKind::MiscVariable,
});
self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
self.types.insert(proj.def_id, (infer_ty, proj.substs));
// Recurse into bounds
for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.item_def_id).subst_iter_copied(self.tcx(), proj.substs) {
for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.tcx(), proj.substs) {
let pred = pred.fold_with(self);
let pred = self.ocx.normalize(
&ObligationCause::misc(self.span, self.body_id),
Expand All @@ -601,7 +601,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
ObligationCause::new(
self.span,
self.body_id,
ObligationCauseCode::BindingObligation(proj.item_def_id, pred_span),
ObligationCauseCode::BindingObligation(proj.def_id, pred_span),
),
self.param_env,
pred,
Expand Down Expand Up @@ -1734,8 +1734,8 @@ pub fn check_type_bounds<'tcx>(
let normalize_param_env = {
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
match impl_ty_value.kind() {
ty::Projection(proj)
if proj.item_def_id == trait_ty.def_id && proj.substs == rebased_substs =>
ty::Alias(ty::Projection, proj)
if proj.def_id == trait_ty.def_id && proj.substs == rebased_substs =>
{
// Don't include this predicate if the projected type is
// exactly the same as the projection. This can occur in
Expand All @@ -1746,8 +1746,8 @@ pub fn check_type_bounds<'tcx>(
_ => predicates.push(
ty::Binder::bind_with_vars(
ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy {
item_def_id: trait_ty.def_id,
projection_ty: ty::AliasTy {
def_id: trait_ty.def_id,
substs: rebased_substs,
},
term: impl_ty_value.into(),
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,11 +352,7 @@ fn bounds_from_generic_predicates<'tcx>(
// insert the associated types where they correspond, but for now let's be "lazy" and
// propose this instead of the following valid resugaring:
// `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
where_clauses.push(format!(
"{} = {}",
tcx.def_path_str(p.projection_ty.item_def_id),
p.term,
));
where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.def_id), p.term));
}
let where_clauses = if where_clauses.is_empty() {
String::new()
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {

fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
ty::Projection(p) if p.item_def_id == self.gat => {
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
for (idx, subst) in p.substs.iter().enumerate() {
match subst.unpack() {
GenericArgKind::Lifetime(lt) if !lt.is_late_bound() => {
Expand Down Expand Up @@ -1592,12 +1592,12 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
{
for arg in fn_output.walk() {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
&& tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
&& let ty::Alias(ty::Projection, proj) = ty.kind()
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
&& tcx.impl_trait_in_trait_parent(proj.def_id) == fn_def_id.to_def_id()
{
let span = tcx.def_span(proj.item_def_id);
let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
let span = tcx.def_span(proj.def_id);
let bounds = wfcx.tcx().explicit_item_bounds(proj.def_id);
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs);
let normalized_bound = wfcx.normalize(span, None, bound);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ impl<'tcx> InherentCollect<'tcx> {
| ty::Tuple(..) => {
self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span)
}
ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
ty::Alias(..) | ty::Param(_) => {
let mut err = struct_span_err!(
self.tcx.sess,
ty.span,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1749,7 +1749,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
ty::Param(param_ty) => {
self.arg_is_constrained[param_ty.index as usize] = true;
}
ty::Projection(_) => return ControlFlow::Continue(()),
ty::Alias(ty::Projection, _) => return ControlFlow::Continue(()),
_ => (),
}
t.super_visit_with(self)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,9 @@ pub(super) fn explicit_predicates_of<'tcx>(
// identity substs of the trait.
// * It must be an associated type for this trait (*not* a
// supertrait).
if let ty::Projection(projection) = ty.kind() {
if let ty::Alias(ty::Projection, projection) = ty.kind() {
projection.substs == trait_identity_substs
&& tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id
&& tcx.associated_item(projection.def_id).container_id(tcx) == def_id
} else {
false
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
// Using the ItemCtxt convert the HIR for the unresolved assoc type into a
// ty which is a fully resolved projection.
// For the code example above, this would mean converting Self::Assoc<3>
// into a ty::Projection(<Self as Foo>::Assoc<3>)
// into a ty::Alias(ty::Projection, <Self as Foo>::Assoc<3>)
let item_hir_id = tcx
.hir()
.parent_iter(hir_id)
Expand All @@ -68,8 +68,8 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
// the def_id that this query was called with. We filter to only type and const args here
// as a precaution for if it's ever allowed to elide lifetimes in GAT's. It currently isn't
// but it can't hurt to be safe ^^
if let ty::Projection(projection) = ty.kind() {
let generics = tcx.generics_of(projection.item_def_id);
if let ty::Alias(ty::Projection, projection) = ty.kind() {
let generics = tcx.generics_of(projection.def_id);

let arg_index = segment
.args
Expand Down Expand Up @@ -666,7 +666,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T

let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let scope = tcx.hir().get_defining_scope(hir_id);
let mut locator = ConstraintLocator { def_id: def_id, tcx, found: None, typeck_types: vec![] };
let mut locator = ConstraintLocator { def_id, tcx, found: None, typeck_types: vec![] };

debug!(?scope);

Expand Down Expand Up @@ -803,7 +803,7 @@ fn find_opaque_ty_constraints_for_rpit(
if let Some(concrete) = concrete {
let scope = tcx.hir().local_def_id_to_hir_id(owner_def_id);
debug!(?scope);
let mut locator = ConstraintChecker { def_id: def_id, tcx, found: concrete };
let mut locator = ConstraintChecker { def_id, tcx, found: concrete };

match tcx.hir().get(scope) {
Node::Item(it) => intravisit::walk_item(&mut locator, it),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct ParameterCollector {
impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match *t.kind() {
ty::Projection(..) if !self.include_nonconstraining => {
ty::Alias(ty::Projection, ..) if !self.include_nonconstraining => {
// projections are not injective
return ControlFlow::CONTINUE;
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,13 @@ fn insert_required_predicates_to_be_wf<'tcx>(
}
}

ty::Projection(obj) => {
ty::Alias(ty::Projection, obj) => {
// This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
// explicit predicates as well.
debug!("Projection");
check_explicit_predicates(
tcx,
tcx.parent(obj.item_def_id),
tcx.parent(obj.def_id),
obj.substs,
required_predicates,
explicit_map,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/outlives/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
// ```
//
// Here we want to add an explicit `where <T as Iterator>::Item: 'a`.
let ty: Ty<'tcx> = tcx.mk_projection(proj_ty.item_def_id, proj_ty.substs);
let ty: Ty<'tcx> = tcx.mk_projection(proj_ty.def_id, proj_ty.substs);
required_predicates
.entry(ty::OutlivesPredicate(ty.into(), outlived_region))
.or_insert(span);
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_substs(current, def.did(), substs, variance);
}

ty::Projection(ref data) => {
ty::Alias(_, ref data) => {
self.add_constraints_from_invariant_substs(current, data.substs, variance);
}

ty::Opaque(_, substs) => {
self.add_constraints_from_invariant_substs(current, substs, variance);
}

ty::Dynamic(data, r, _) => {
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
let contra = self.contravariant(variance);
Expand Down
Loading

0 comments on commit 918d0ac

Please sign in to comment.