Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TyAlias into rustc_type_ir TyKind enum #97974

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a197c45
Add rustc_type_ir::TyKind::TyAlias variant
GuillaumeGomez Apr 20, 2022
61705b3
Add TyKind::TyAlias support in rustc_middle
GuillaumeGomez Apr 20, 2022
ed3f028
Add TyKind::TyAlias support in rustc_symbol_mangling
GuillaumeGomez Apr 20, 2022
2a25b28
Add TyKind::TyAlias support in rustc_infer
GuillaumeGomez Apr 25, 2022
71357dc
Add TyKind::TyAlias support in rustc_codegen_ssa
GuillaumeGomez Apr 25, 2022
02ee18f
Add TyKind::TyAlias support in rustc_trait_selection
GuillaumeGomez Apr 25, 2022
5cb94e7
Add TyKind::TyAlias support in rustc_ty_utils
GuillaumeGomez Apr 25, 2022
5ea1e63
Add TyKind::TyAlias support in rustc_traits
GuillaumeGomez Apr 25, 2022
87df978
Add TyKind::TyAlias support in rustc_lint
GuillaumeGomez Apr 25, 2022
db39bcd
Add traits::NonStructuralMatchTy::TyAlias support in rustc_mir_build
GuillaumeGomez Apr 25, 2022
5aa4e3c
Add TyKind::TyAlias support in rustc_mir_build
GuillaumeGomez Jun 12, 2022
b756929
Add TyKind::TyAlias support in rustc_const_eval
GuillaumeGomez Apr 25, 2022
8b20c6a
Add TyKind::TyAlias support in rustc_typeck
GuillaumeGomez Apr 25, 2022
2e215cd
Add TyKind::TyAlias support in rustc_privacy
GuillaumeGomez May 4, 2022
61b0cf7
Add TyKind::TyAlias support in librustdoc
GuillaumeGomez May 4, 2022
83ce044
Add HAS_TY_ALIAS into TypeFlags
GuillaumeGomez Jun 12, 2022
042c9ed
Replace `.type_of()` calls with `.bound_type_of()`
GuillaumeGomez Jun 12, 2022
4f632c3
Update failing mangling ui tests
GuillaumeGomez Jun 13, 2022
cc95610
Update ui-fulldeps test
GuillaumeGomez Jun 15, 2022
45f038f
crash if invalid type kind in const_to_valtree_inner
GuillaumeGomez Jun 20, 2022
94da537
Add missing mk_ty_alias call into astconv
GuillaumeGomez Jun 27, 2022
3381673
Add UI test for ty alias mangling
GuillaumeGomez Jun 27, 2022
29d628c
Fix compilation errors for TyAlias
GuillaumeGomez Jun 30, 2022
4815a60
Improve code
GuillaumeGomez Jul 7, 2022
dcca5d5
Update clippy to handle TyAlias
GuillaumeGomez Jul 11, 2022
7d76dc9
Improve TyCtxt::peel_off_ty_alias
GuillaumeGomez Jul 21, 2022
9e7f02b
Update some UI tests
GuillaumeGomez Jul 25, 2022
c383c9d
Fix missing type alias cycle detection
GuillaumeGomez Sep 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ fn push_debuginfo_type_name<'tcx>(
| ty::Projection(..)
| ty::Bound(..)
| ty::Opaque(..)
| ty::TyAlias(..)
| ty::GeneratorWitness(..) => {
bug!(
"debuginfo: Trying to create type name for \
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,21 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
ty::Never
| ty::Error(_)
| ty::Foreign(..)
| ty::Infer(ty::FreshIntTy(_))
| ty::Infer(ty::FreshFloatTy(_))
| ty::Projection(..)
| 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(..)
| ty::Generator(..)
| ty::GeneratorWitness(..) => Err(ValTreeCreationError::NonSupportedType),

ty::Infer(_)
| ty::TyAlias(..)
| ty::Projection(..)
| ty::Param(_)
| ty::Bound(..)
| ty::Placeholder(..) => {
bug!("{:?} should have errored and never gotten converted to valtree", ty.kind())
}
}
}

Expand Down Expand Up @@ -320,7 +322,8 @@ pub fn valtree_to_const_value<'tcx>(
| ty::RawPtr(_)
| ty::Str
| ty::Slice(_)
| ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
| ty::Dynamic(..)
| ty::TyAlias(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()),
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ use rustc_middle::mir::{
interpret::{ConstValue, GlobalId, InterpResult, PointerArithmetic, Scalar},
BinOp, NonDivergingIntrinsic,
};
use rustc_middle::ty;
use rustc_middle::ty::layout::LayoutOf as _;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::symbol::{sym, Symbol};
use rustc_target::abi::{Abi, Align, Primitive, Size};

Expand Down Expand Up @@ -102,6 +101,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
| ty::Never
| ty::Tuple(_)
| ty::Error(_) => ConstValue::from_machine_usize(0u64, &tcx),
ty::TyAlias(..) => bug!("unexpected TyAlias in eval_nullary_intrinsic"),
},
other => bug!("`{}` is not a zero arg intrinsic", other),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
| 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, &[]),
ty::TyAlias(def_id, substs) => {
let binder_ty = self.tcx.bound_type_of(def_id);
let ty = binder_ty.subst(self.tcx, substs);
self.print_type(ty)
}

ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
| ty::Param(..)
| ty::Opaque(..)
| ty::Projection(..)
| ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
| ty::GeneratorWitness(..)
| ty::TyAlias(..) => bug!("Encountered invalid type {:?}", ty),
}
}

Expand Down
13 changes: 8 additions & 5 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2391,12 +2391,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
self.normalize_ty(span, tcx.mk_opaque(did, substs))
}
Res::Def(DefKind::TyAlias, def_id) => {
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments.split_last().unwrap().1.iter(), |_| {});
let item_segment = path.segments.split_last().unwrap();
let substs = self.ast_path_substs_for_ty(span, def_id, item_segment.0);
self.normalize_ty(span, tcx.mk_ty_alias(def_id, substs))
}
Res::Def(
DefKind::Enum
| DefKind::TyAlias
| DefKind::Struct
| DefKind::Union
| DefKind::ForeignTy,
DefKind::Enum | DefKind::Struct | DefKind::Union | DefKind::ForeignTy,
did,
) => {
assert_eq!(opt_self_ty, None);
Expand Down
50 changes: 48 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{
self, AdtKind, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable,
TypeSuperVisitable, TypeVisitable, TypeVisitor,
self, AdtKind, DefIdTree, GenericParamDefKind, SubstsRef, ToPredicate, Ty, TyCtxt,
TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
};
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
use rustc_session::parse::feature_err;
Expand Down Expand Up @@ -239,6 +239,51 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
hir::ItemKind::TraitAlias(..) => {
check_trait(tcx, item);
}
hir::ItemKind::TyAlias { .. } => {
struct TyAliasPeeler<'t> {
tcx: TyCtxt<'t>,
visited: FxHashSet<(DefId, SubstsRef<'t>)>,
}

impl<'t> ty::TypeFolder<'t> for TyAliasPeeler<'t> {
fn tcx<'a>(&'a self) -> TyCtxt<'t> {
self.tcx
}

fn fold_ty(&mut self, t: Ty<'t>) -> Ty<'t> {
use crate::ty::fold::{TypeFoldable, TypeSuperFoldable};
use crate::ty::visit::TypeVisitable;

match *t.kind() {
ty::TyAlias(def_id, substs) => {
if !self.visited.insert((def_id, substs)) {
let def_span = self.tcx.def_span(def_id);
self.tcx
.sess
.struct_span_err(
def_span,
"cycle detected when expanding type alias",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep the name of the type alias being expanded in the main message.

)
.emit();
return t;
}
let binder_ty = self.tcx.bound_type_of(def_id);
let ty = binder_ty.subst(self.tcx, substs);
ty.fold_with(self)
}
_ if !t.has_ty_alias() => t,
_ => t.super_fold_with(self),
}
}
}

let ty = tcx.bound_type_of(item.def_id.to_def_id()).0;
if let ty::TyAlias(def_id, substs) = *ty.kind() {
let binder_ty = tcx.bound_type_of(def_id);
let ty = binder_ty.subst(tcx, substs);
ty.fold_with(&mut TyAliasPeeler { tcx, visited: FxHashSet::default() });
}
}
// `ForeignItem`s are handled separately.
hir::ItemKind::ForeignMod { .. } => {}
_ => {}
Expand Down Expand Up @@ -856,6 +901,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
// Const parameters are well formed if their type is structural match.
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id));
let ty = tcx.peel_off_ty_alias(ty);

if tcx.features().adt_const_params {
if let Some(non_structural_match_ty) =
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ impl<'tcx> InherentCollect<'tcx> {
};

let self_ty = self.tcx.type_of(item.def_id);
let self_ty = self.tcx.peel_off_ty_alias(self_ty);

match *self_ty.kind() {
ty::Adt(def, _) => {
self.check_def_id(item, self_ty, def.did());
Expand All @@ -197,6 +199,9 @@ impl<'tcx> InherentCollect<'tcx> {
ty::Dynamic(data, ..) if data.principal_def_id().is_some() => {
self.check_def_id(item, self_ty, data.principal_def_id().unwrap());
}
ty::TyAlias(..) => {
span_bug!(ty.span, "unexpected TyAlias in InherentCollect::check_item");
}
ty::Dynamic(..) => {
struct_span_err!(
self.tcx.sess,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ fn do_orphan_check_impl<'tcx>(
let sp = tcx.def_span(def_id);
let tr = impl_.of_trait.as_ref().unwrap();

let trait_ref = tcx.peel_off_ty_alias(trait_ref);

// Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples,
// and #84660 where it would otherwise allow unsoundness.
if trait_ref.has_opaque_types() {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_invariant_substs(current, substs, variance);
}

ty::TyAlias(def_id, substs) => {
let binder_ty = self.tcx().bound_type_of(def_id);
let ty = binder_ty.subst(self.tcx(), substs);
self.add_constraints_from_ty(current, ty, variance);
}

ty::Dynamic(data, r, _) => {
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
let contra = self.contravariant(variance);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We should really try to normalize here.
ty::Projection(ref pi) => Some(PointerKind::OfProjection(pi)),
ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)),
ty::TyAlias(..) => bug!("unexpected TyAlias in pointer_kind"),
ty::Param(ref p) => Some(PointerKind::OfParam(p)),
// Insufficient type information.
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
| ty::Projection(..)
| ty::Foreign(..)
| ty::Param(..)
| ty::Opaque(..) => {
| ty::Opaque(..)
| ty::TyAlias(..) => {
if t.flags().intersects(self.needs_canonical_flags) {
t.super_fold_with(self)
} else {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
| ty::Param(..)
| ty::Closure(..)
| ty::GeneratorWitness(..)
| ty::Opaque(..) => t.super_fold_with(self),
| ty::Opaque(..)
| ty::TyAlias(..) => t.super_fold_with(self),

ty::Placeholder(..) | ty::Bound(..) => bug!("unexpected type {:?}", t),
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<'tcx> InferCtxt<'tcx> {
span: Span,
param_env: ty::ParamEnv<'tcx>,
) -> InferOk<'tcx, T> {
if !value.has_opaque_types() {
if !value.has_opaque_types() && !value.has_ty_alias() {
return InferOk { value, obligations: vec![] };
}
let mut obligations = vec![];
Expand All @@ -61,7 +61,7 @@ impl<'tcx> InferCtxt<'tcx> {
.as_local()
.map_or(false, |def_id| self.opaque_type_origin(def_id, span).is_some())
};
let value = value.fold_with(&mut ty::fold::BottomUpFolder {
let value = self.tcx.peel_off_ty_alias(value).fold_with(&mut ty::fold::BottomUpFolder {
tcx: self.tcx,
lt_op: |lt| lt,
ct_op: |ct| ct,
Expand Down Expand Up @@ -548,6 +548,9 @@ impl<'tcx> InferCtxt<'tcx> {
let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());

for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) {
debug!(?predicate);
let predicate = tcx.peel_off_ty_alias(predicate);

let predicate = predicate.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| match *ty.kind() {
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_infer/src/infer/outlives/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ fn compute_components<'tcx>(
out.push(Component::UnresolvedInferenceVariable(infer_ty));
}

ty::TyAlias(def_id, substs) => {
let binder_ty = tcx.bound_type_of(def_id);
let ty = binder_ty.subst(tcx, substs);
compute_components(tcx, ty, out, visited);
}

// Most types do not introduce any region binders, nor
// involve any other subtle cases, and so the WF relation
// simply constraints any regions referenced directly by
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
use rustc_macros::LintDiagnostic;
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
use rustc_middle::ty::{
self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
};
use rustc_span::source_map;
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol, DUMMY_SP};
Expand Down Expand Up @@ -1134,6 +1136,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
FfiSafe
}

ty::TyAlias(def_id, substs) => {
let binder_ty = tcx.bound_type_of(def_id);
let ty = binder_ty.subst(tcx, substs);
let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
self.check_type_for_ffi(cache, ty)
}

ty::Foreign(..) => FfiSafe,

// While opaque types are checked for earlier, if a projection in a struct field
Expand Down
41 changes: 39 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1726,6 +1726,37 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
self.visibility(def_id).expect_local()
}

/// As long as the kind of `ty` is `TyAlias`, then it'll continue to peel it off and return
/// the type below it.
pub fn peel_off_ty_alias<T: ty::TypeFoldable<'tcx>>(self, ty: T) -> T {
struct TyAliasPeeler<'t> {
tcx: TyCtxt<'t>,
}
Comment on lines +1733 to +1735
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we detect the TyAlias Cycle error here? For example, add a visited: FxHashSet<(Defid, SubstsRef)> field to TyAliasPeeler.


impl<'t> ty::TypeFolder<'t> for TyAliasPeeler<'t> {
fn tcx<'a>(&'a self) -> TyCtxt<'t> {
self.tcx
}

fn fold_ty(&mut self, t: Ty<'t>) -> Ty<'t> {
use crate::ty::fold::{TypeFoldable, TypeSuperFoldable};
use crate::ty::visit::TypeVisitable;

match *t.kind() {
ty::TyAlias(def_id, substs) => {
let binder_ty = self.tcx.bound_type_of(def_id);
let ty = binder_ty.subst(self.tcx, substs);
ty.fold_with(self)
}
_ if !t.has_ty_alias() => t,
_ => t.super_fold_with(self),
}
}
}

ty.fold_with(&mut TyAliasPeeler { tcx: self })
}
}

/// A trait implemented for all `X<'a>` types that can be safely and
Expand Down Expand Up @@ -1996,7 +2027,7 @@ pub mod tls {
}

macro_rules! sty_debug_print {
($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
($fmt: expr, $ctxt: expr, $($variant: ident),* $(,)?) => {{
// Curious inner module to allow variant names to be used as
// variable names.
#[allow(non_snake_case)]
Expand Down Expand Up @@ -2095,7 +2126,8 @@ impl<'tcx> TyCtxt<'tcx> {
Infer,
Projection,
Opaque,
Foreign
Foreign,
TyAlias,
)?;

writeln!(fmt, "InternalSubsts interner: #{}", self.0.interners.substs.len())?;
Expand Down Expand Up @@ -2633,6 +2665,11 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(Opaque(def_id, substs))
}

#[inline]
pub fn mk_ty_alias(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
self.mk_ty(TyAlias(def_id, substs))
}

pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
self.mk_place_elem(place, PlaceElem::Field(f, ty))
}
Expand Down