Skip to content

Commit a197c45

Browse files
Add rustc_type_ir::TyKind::TyAlias variant
1 parent 607878d commit a197c45

File tree

2 files changed

+207
-15
lines changed

2 files changed

+207
-15
lines changed

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 177 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,22 +98,184 @@ impl BoundRegionKind {
9898
}
9999
}
100100

101-
pub trait Article {
102-
fn article(&self) -> &'static str;
103-
}
101+
/// Defines the kinds of types used by the type system.
102+
///
103+
/// Types written by the user start out as [hir::TyKind](rustc_hir::TyKind) and get
104+
/// converted to this representation using `AstConv::ast_ty_to_ty`.
105+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable, Debug)]
106+
#[derive(HashStable)]
107+
#[rustc_diagnostic_item = "TyKind"]
108+
pub enum TyKind<'tcx> {
109+
/// The primitive boolean type. Written as `bool`.
110+
Bool,
104111

105-
impl<'tcx> Article for TyKind<'tcx> {
106-
/// Get the article ("a" or "an") to use with this type.
107-
fn article(&self) -> &'static str {
108-
match self {
109-
Int(_) | Float(_) | Array(_, _) => "an",
110-
Adt(def, _) if def.is_enum() => "an",
111-
// This should never happen, but ICEing and causing the user's code
112-
// to not compile felt too harsh.
113-
Error(_) => "a",
114-
_ => "a",
115-
}
116-
}
112+
/// The primitive character type; holds a Unicode scalar value
113+
/// (a non-surrogate code point). Written as `char`.
114+
Char,
115+
116+
/// A primitive signed integer type. For example, `i32`.
117+
Int(ty::IntTy),
118+
119+
/// A primitive unsigned integer type. For example, `u32`.
120+
Uint(ty::UintTy),
121+
122+
/// A primitive floating-point type. For example, `f64`.
123+
Float(ty::FloatTy),
124+
125+
/// Algebraic data types (ADT). For example: structures, enumerations and unions.
126+
///
127+
/// For example, the type `List<i32>` would be represented using the `AdtDef`
128+
/// for `struct List<T>` and the substs `[i32]`.
129+
///
130+
/// Note that generic parameters in fields only get lazily substituted
131+
/// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, substs))`.
132+
Adt(AdtDef<'tcx>, SubstsRef<'tcx>),
133+
134+
/// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
135+
Foreign(DefId),
136+
137+
/// The pointee of a string slice. Written as `str`.
138+
Str,
139+
140+
/// An array with the given length. Written as `[T; N]`.
141+
Array(Ty<'tcx>, ty::Const<'tcx>),
142+
143+
/// The pointee of an array slice. Written as `[T]`.
144+
Slice(Ty<'tcx>),
145+
146+
/// A raw pointer. Written as `*mut T` or `*const T`
147+
RawPtr(TypeAndMut<'tcx>),
148+
149+
/// A reference; a pointer with an associated lifetime. Written as
150+
/// `&'a mut T` or `&'a T`.
151+
Ref(Region<'tcx>, Ty<'tcx>, hir::Mutability),
152+
153+
/// The anonymous type of a function declaration/definition. Each
154+
/// function has a unique type.
155+
///
156+
/// For the function `fn foo() -> i32 { 3 }` this type would be
157+
/// shown to the user as `fn() -> i32 {foo}`.
158+
///
159+
/// For example the type of `bar` here:
160+
/// ```rust
161+
/// fn foo() -> i32 { 1 }
162+
/// let bar = foo; // bar: fn() -> i32 {foo}
163+
/// ```
164+
FnDef(DefId, SubstsRef<'tcx>),
165+
166+
/// A type alias (`type Alias = i8;`) containing the `DefId` of the aliased type and its
167+
/// generics.
168+
TyAlias(DefId, SubstsRef<'tcx>),
169+
170+
/// A pointer to a function. Written as `fn() -> i32`.
171+
///
172+
/// Note that both functions and closures start out as either
173+
/// [FnDef] or [Closure] which can be then be coerced to this variant.
174+
///
175+
/// For example the type of `bar` here:
176+
///
177+
/// ```rust
178+
/// fn foo() -> i32 { 1 }
179+
/// let bar: fn() -> i32 = foo;
180+
/// ```
181+
FnPtr(PolyFnSig<'tcx>),
182+
183+
/// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
184+
Dynamic(&'tcx List<Binder<'tcx, ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
185+
186+
/// The anonymous type of a closure. Used to represent the type of `|a| a`.
187+
///
188+
/// Closure substs contain both the - potentially substituted - generic parameters
189+
/// of its parent and some synthetic parameters. See the documentation for
190+
/// [ClosureSubsts] for more details.
191+
Closure(DefId, SubstsRef<'tcx>),
192+
193+
/// The anonymous type of a generator. Used to represent the type of
194+
/// `|a| yield a`.
195+
///
196+
/// For more info about generator substs, visit the documentation for
197+
/// [GeneratorSubsts].
198+
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
199+
200+
/// A type representing the types stored inside a generator.
201+
/// This should only appear as part of the [GeneratorSubsts].
202+
///
203+
/// Note that the captured variables for generators are stored separately
204+
/// using a tuple in the same way as for closures.
205+
///
206+
/// Unlike upvars, the witness can reference lifetimes from
207+
/// inside of the generator itself. To deal with them in
208+
/// the type of the generator, we convert them to higher ranked
209+
/// lifetimes bound by the witness itself.
210+
///
211+
/// Looking at the following example, the witness for this generator
212+
/// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
213+
///
214+
/// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
215+
/// #![feature(generators)]
216+
/// |a| {
217+
/// let x = &vec![3];
218+
/// yield a;
219+
/// yield x[0];
220+
/// }
221+
/// # ;
222+
/// ```
223+
GeneratorWitness(Binder<'tcx, &'tcx List<Ty<'tcx>>>),
224+
225+
/// The never type `!`.
226+
Never,
227+
228+
/// A tuple type. For example, `(i32, bool)`.
229+
Tuple(&'tcx List<Ty<'tcx>>),
230+
231+
/// The projection of an associated type. For example,
232+
/// `<T as Trait<..>>::N`.
233+
Projection(ProjectionTy<'tcx>),
234+
235+
/// Opaque (`impl Trait`) type found in a return type.
236+
///
237+
/// The `DefId` comes either from
238+
/// * the `impl Trait` ast::Ty node,
239+
/// * or the `type Foo = impl Trait` declaration
240+
///
241+
/// For RPIT the substitutions are for the generics of the function,
242+
/// while for TAIT it is used for the generic parameters of the alias.
243+
///
244+
/// During codegen, `tcx.type_of(def_id)` can be used to get the underlying type.
245+
Opaque(DefId, SubstsRef<'tcx>),
246+
247+
/// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
248+
Param(ParamTy),
249+
250+
/// Bound type variable, used to represent the `'a` in `for<'a> fn(&'a ())`.
251+
///
252+
/// For canonical queries, we replace inference variables with bound variables,
253+
/// so e.g. when checking whether `&'_ (): Trait<_>` holds, we canonicalize that to
254+
/// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables
255+
/// back to inference variables in a new inference context when inside of the query.
256+
///
257+
/// See the `rustc-dev-guide` for more details about
258+
/// [higher-ranked trait bounds][1] and [canonical queries][2].
259+
///
260+
/// [1]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
261+
/// [2]: https://rustc-dev-guide.rust-lang.org/traits/canonical-queries.html
262+
Bound(ty::DebruijnIndex, BoundTy),
263+
264+
/// A placeholder type, used during higher ranked subtyping to instantiate
265+
/// bound variables.
266+
Placeholder(ty::PlaceholderType),
267+
268+
/// A type variable used during type checking.
269+
///
270+
/// Similar to placeholders, inference variables also live in a universe to
271+
/// correctly deal with higher ranked types. Though unlike placeholders,
272+
/// that universe is stored in the `InferCtxt` instead of directly
273+
/// inside of the type.
274+
Infer(InferTy),
275+
276+
/// A placeholder for a type which could not be computed; this is
277+
/// propagated to avoid useless error messages.
278+
Error(DelaySpanBugEmitted),
117279
}
118280

119281
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.

compiler/rustc_type_ir/src/sty.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ pub enum TyKind<I: Interner> {
109109
/// ```
110110
FnDef(I::DefId, I::SubstsRef),
111111

112+
/// A type alias (`type Alias = i8;`) containing the `DefId` of the aliased type and its
113+
/// generics.
114+
TyAlias(I::DefId, I::SubstsRef),
115+
112116
/// A pointer to a function. Written as `fn() -> i32`.
113117
///
114118
/// Note that both functions and closures start out as either
@@ -259,6 +263,7 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
259263
Placeholder(_) => 24,
260264
Infer(_) => 25,
261265
Error(_) => 26,
266+
TyAlias(_, _) => 27,
262267
}
263268
}
264269

@@ -293,6 +298,7 @@ impl<I: Interner> Clone for TyKind<I> {
293298
Placeholder(p) => Placeholder(p.clone()),
294299
Infer(t) => Infer(t.clone()),
295300
Error(e) => Error(e.clone()),
301+
TyAlias(t, s) => TyAlias(t.clone(), s.clone()),
296302
}
297303
}
298304
}
@@ -351,6 +357,9 @@ impl<I: Interner> PartialEq for TyKind<I> {
351357
(&Placeholder(ref __self_0), &Placeholder(ref __arg_1_0)) => __self_0 == __arg_1_0,
352358
(&Infer(ref __self_0), &Infer(ref __arg_1_0)) => __self_0 == __arg_1_0,
353359
(&Error(ref __self_0), &Error(ref __arg_1_0)) => __self_0 == __arg_1_0,
360+
(&TyAlias(ref __self_0, ref __self_1), &TyAlias(ref __arg_1_0, ref __arg_1_1)) => {
361+
__self_0 == __arg_1_0 && __self_1 == __arg_1_1
362+
}
354363
_ => true,
355364
}
356365
} else {
@@ -464,6 +473,12 @@ impl<I: Interner> Ord for TyKind<I> {
464473
}
465474
(&Infer(ref __self_0), &Infer(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
466475
(&Error(ref __self_0), &Error(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
476+
(&TyAlias(ref __self_0, ref __self_1), &TyAlias(ref __arg_1_0, ref __arg_1_1)) => {
477+
match Ord::cmp(__self_0, __arg_1_0) {
478+
Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
479+
cmp => cmp,
480+
}
481+
}
467482
_ => Ordering::Equal,
468483
}
469484
} else {
@@ -580,6 +595,11 @@ impl<I: Interner> hash::Hash for TyKind<I> {
580595
hash::Hash::hash(&tykind_discriminant(self), state);
581596
hash::Hash::hash(__self_0, state)
582597
}
598+
(&TyAlias(ref __self_0, ref __self_1),) => {
599+
hash::Hash::hash(&tykind_discriminant(self), state);
600+
hash::Hash::hash(__self_0, state);
601+
hash::Hash::hash(__self_1, state)
602+
}
583603
_ => hash::Hash::hash(&tykind_discriminant(self), state),
584604
}
585605
}
@@ -619,6 +639,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
619639
Placeholder(f0) => Formatter::debug_tuple_field1_finish(f, "Placeholder", f0),
620640
Infer(f0) => Formatter::debug_tuple_field1_finish(f, "Infer", f0),
621641
TyKind::Error(f0) => Formatter::debug_tuple_field1_finish(f, "Error", f0),
642+
TyAlias(f0, f1) => Formatter::debug_tuple_field2_finish(f, "TyAlias", f0, f1),
622643
}
623644
}
624645
}
@@ -721,6 +742,10 @@ where
721742
def_id.encode(e);
722743
substs.encode(e);
723744
}),
745+
TyAlias(def_id, substs) => e.emit_enum_variant(disc, |e| {
746+
def_id.encode(e);
747+
substs.encode(e);
748+
}),
724749
Param(p) => e.emit_enum_variant(disc, |e| {
725750
p.encode(e);
726751
}),
@@ -796,6 +821,7 @@ where
796821
24 => Placeholder(Decodable::decode(d)),
797822
25 => Infer(Decodable::decode(d)),
798823
26 => Error(Decodable::decode(d)),
824+
27 => TyAlias(Decodable::decode(d), Decodable::decode(d)),
799825
_ => panic!(
800826
"{}",
801827
format!(
@@ -924,6 +950,10 @@ where
924950
Error(d) => {
925951
d.hash_stable(__hcx, __hasher);
926952
}
953+
TyAlias(def_id, substs) => {
954+
def_id.hash_stable(__hcx, __hasher);
955+
substs.hash_stable(__hcx, __hasher);
956+
}
927957
}
928958
}
929959
}

0 commit comments

Comments
 (0)