@@ -63,10 +63,10 @@ Here is a summary:
63
63
HIR is built, some basic type inference and type checking is done. During the type inference, we
64
64
figure out what the ` ty::Ty ` of everything is and we also check if the type of something is
65
65
ambiguous. The ` ty::Ty ` then, is used for type checking while making sure everything has the
66
- expected type. The [ ` astconv ` module] [ astconv ] , is where the code responsible for converting a
66
+ expected type. The [ ` astconv ` module] [ astconv ] is where the code responsible for converting a
67
67
` rustc_hir::Ty ` into a ` ty::Ty ` is located. This occurs during the type-checking phase,
68
68
but also in other parts of the compiler that want to ask questions like "what argument types does
69
- this function expect"?.
69
+ this function expect?"
70
70
71
71
[ astconv ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/astconv/index.html
72
72
@@ -79,13 +79,13 @@ They are syntactically two strings: `"u32"` at line N column 20 and `"u32"` at l
79
79
don’t know that they are the same yet. So, in the HIR we treat them as if they are different. Later,
80
80
we determine that they semantically are the same type and that’s the ` ty::Ty ` we use.
81
81
82
- Consider another example: ` fn foo<T>(x: T) -> u32 ` and suppose that someone invokes ` foo::<u32>(0) ` .
82
+ Consider another example: ` fn foo<T>(x: T) -> u32 ` . Suppose that someone invokes ` foo::<u32>(0) ` .
83
83
This means that ` T ` and ` u32 ` (in this invocation) actually turns out to be the same type, so we
84
84
would eventually end up with the same ` ty::Ty ` in the end, but we have distinct ` rustc_hir::Ty ` .
85
85
(This is a bit over-simplified, though, since during type checking, we would check the function
86
86
generically and would still have a ` T ` distinct from ` u32 ` . Later, when doing code generation,
87
87
we would always be handling "monomorphized" (fully substituted) versions of each function,
88
- and hence we would know what ` T ` represents (and specifically that it is ` u32 ` ).
88
+ and hence we would know what ` T ` represents (and specifically that it is ` u32 ` ).)
89
89
90
90
Here is one more example:
91
91
@@ -107,13 +107,15 @@ or `fn(i32) -> i32` (with type aliases fully expanded).
107
107
108
108
## ` ty::Ty ` implementation
109
109
110
- [ ` rustc::ty::Ty ` ] [ ty_ty ] is actually a type alias to [ ` &TyS ` ] [ tys ] (more about that later). ` TyS `
111
- (Type Structure) is where the main functionality is located. You can ignore ` TyS ` struct in general;
112
- you will basically never access it explicitly. We always pass it by reference using the ` Ty ` alias.
110
+ [ ` rustc::ty::Ty ` ] [ ty_ty ] is actually a type alias to [ ` &TyS ` ] [ tys ] .
111
+ This type, which is short for "Type Structure", is where the main functionality is located.
112
+ You can ignore ` TyS ` struct in general; you will basically never access it explicitly.
113
+ We always pass it by reference using the ` Ty ` alias.
113
114
The only exception is to define inherent methods on types. In particular, ` TyS ` has a [ ` kind ` ] [ kind ]
114
115
field of type [ ` TyKind ` ] [ tykind ] , which represents the key type information. ` TyKind ` is a big enum
115
- which represents different kinds of types (e.g. primitives, references, abstract data types,
116
- generics, lifetimes, etc). ` TyS ` also has 2 more fields, ` flags ` and ` outer_exclusive_binder ` . They
116
+ with variants to represent many different Rust types
117
+ (e.g. primitives, references, abstract data types, generics, lifetimes, etc).
118
+ ` TyS ` also has 2 more fields, ` flags ` and ` outer_exclusive_binder ` . They
117
119
are convenient hacks for efficiency and summarize information about the type that we may want to
118
120
know, but they don’t come into the picture as much here. Finally, ` ty::TyS ` s
119
121
are [ interned] ( ./memory.md ) , so that the ` ty::Ty ` can be a thin pointer-like
@@ -137,14 +139,15 @@ These methods all return a `Ty<'tcx>` – note that the lifetime you get back is
137
139
arena that this ` tcx ` has access to. Types are always canonicalized and interned (so we never
138
140
allocate exactly the same type twice).
139
141
140
- > NB. Because types are interned, it is possible to compare them for equality efficiently using ` == `
142
+ > N.B.
143
+ > Because types are interned, it is possible to compare them for equality efficiently using ` == `
141
144
> – however, this is almost never what you want to do unless you happen to be hashing and looking
142
145
> for duplicates. This is because often in Rust there are multiple ways to represent the same type,
143
146
> particularly once inference is involved. If you are going to be testing for type equality, you
144
147
> probably need to start looking into the inference code to do it right.
145
148
146
- You can also find various common types in the ` tcx ` itself by accessing ` tcx.types.bool ` ,
147
- ` tcx.types.char ` , etc (see [ ` CommonTypes ` ] for more).
149
+ You can also find various common types in the ` tcx ` itself by accessing its fields:
150
+ ` tcx.types.bool ` , ` tcx.types. char` , etc. (See [ ` CommonTypes ` ] for more.)
148
151
149
152
[ `CommonTypes` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.CommonTypes.html
150
153
@@ -172,35 +175,27 @@ types in the compiler.
172
175
There are a lot of related types, and we’ll cover them in time (e.g regions/lifetimes,
173
176
“substitutions”, etc).
174
177
175
- There are a bunch of variants on the ` TyKind ` enum, which you can see by looking at the rustdocs.
176
- Here is a sampling:
177
-
178
- [ ** Algebraic Data Types (ADTs)** ] [ kindadt ] An [ * algebraic Data Type* ] [ wikiadt ] is a ` struct ` ,
179
- ` enum ` or ` union ` . Under the hood, ` struct ` , ` enum ` and ` union ` are actually implemented
180
- the same way: they are all [ ` ty::TyKind::Adt ` ] [ kindadt ] . It’s basically a user defined type.
181
- We will talk more about these later.
182
-
183
- [ ** Foreign** ] [ kindforeign ] Corresponds to ` extern type T ` .
184
-
185
- [ ** Str** ] [ kindstr ] Is the type str. When the user writes ` &str ` , ` Str ` is the how we represent the
186
- ` str ` part of that type.
187
-
188
- [ ** Slice** ] [ kindslice ] Corresponds to ` [T] ` .
189
-
190
- [ ** Array** ] [ kindarray ] Corresponds to ` [T; n] ` .
191
-
192
- [ ** RawPtr** ] [ kindrawptr ] Corresponds to ` *mut T ` or ` *const T `
193
-
194
- [ ** Ref** ] [ kindref ] ` Ref ` stands for safe references, ` &'a mut T ` or ` &'a T ` . ` Ref ` has some
195
- associated parts, like ` Ty<'tcx> ` which is the type that the reference references, ` Region<'tcx> ` is
196
- the lifetime or region of the reference and ` Mutability ` if the reference is mutable or not.
197
-
198
- [ ** Param** ] [ kindparam ] Represents a type parameter (e.g. the ` T ` in ` Vec<T> ` ).
199
-
200
- [ ** Error** ] [ kinderr ] Represents a type error somewhere so that we can print better diagnostics. We
201
- will discuss this more later.
202
-
203
- [ ** And Many More** ...] [ kindvars ]
178
+ There are many variants on the ` TyKind ` enum, which you can see by looking at its
179
+ [ documentation] [ tykind ] . Here is a sampling:
180
+
181
+ - [ ** Algebraic Data Types (ADTs)** ] [ kindadt ] An [ * algebraic data type* ] [ wikiadt ] is a ` struct ` ,
182
+ ` enum ` or ` union ` . Under the hood, ` struct ` , ` enum ` and ` union ` are actually implemented
183
+ the same way: they are all [ ` ty::TyKind::Adt ` ] [ kindadt ] . It’s basically a user defined type.
184
+ We will talk more about these later.
185
+ - [ ** Foreign** ] [ kindforeign ] Corresponds to ` extern type T ` .
186
+ - [ ** Str** ] [ kindstr ] Is the type str. When the user writes ` &str ` , ` Str ` is the how we represent the
187
+ ` str ` part of that type.
188
+ - [ ** Slice** ] [ kindslice ] Corresponds to ` [T] ` .
189
+ - [ ** Array** ] [ kindarray ] Corresponds to ` [T; n] ` .
190
+ - [ ** RawPtr** ] [ kindrawptr ] Corresponds to ` *mut T ` or ` *const T ` .
191
+ - [ ** Ref** ] [ kindref ] ` Ref ` stands for safe references, ` &'a mut T ` or ` &'a T ` . ` Ref ` has some
192
+ associated parts, like ` Ty<'tcx> ` which is the type that the reference references.
193
+ ` Region<'tcx> ` is the lifetime or region of the reference and ` Mutability ` if the reference
194
+ is mutable or not.
195
+ - [ ** Param** ] [ kindparam ] Represents a type parameter (e.g. the ` T ` in ` Vec<T> ` ).
196
+ - [ ** Error** ] [ kinderr ] Represents a type error somewhere so that we can print better diagnostics. We
197
+ will discuss this more later.
198
+ - [ ** And many more** ...] [ kindvars ]
204
199
205
200
[ wikiadt ] : https://en.wikipedia.org/wiki/Algebraic_data_type
206
201
[ kindadt ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Adt
@@ -249,8 +244,8 @@ There are two parts:
249
244
250
245
- The [ ` AdtDef ` ] [ adtdef ] references the struct/enum/union but without the values for its type
251
246
parameters. In our example, this is the ` MyStruct ` part * without* the argument ` u32 ` .
252
- - Note that in the HIR, structs, enums and unions are represented differently, but in ` ty::Ty ` ,
253
- they are all represented using ` TyKind::Adt ` .
247
+ ( Note that in the HIR, structs, enums and unions are represented differently, but in ` ty::Ty ` ,
248
+ they are all represented using ` TyKind::Adt ` .)
254
249
- The [ ` SubstsRef ` ] [ substsref ] is an interned list of values that are to be substituted for the
255
250
generic parameters. In our example of ` MyStruct<u32> ` , we would end up with a list like ` [u32] ` .
256
251
We’ll dig more into generics and substitutions in a little bit.
@@ -268,8 +263,8 @@ is only referenced).
268
263
269
264
` AdtDef ` is more or less a wrapper around ` DefId ` with lots of useful helper methods. There is
270
265
essentially a one-to-one relationship between ` AdtDef ` and ` DefId ` . You can get the ` AdtDef ` for a
271
- ` DefId ` with the [ ` tcx.adt_def(def_id) ` query] [ adtdefq ] . The ` AdtDef ` s are all interned ( as you can
272
- see ` 'tcx ` lifetime on it) .
266
+ ` DefId ` with the [ ` tcx.adt_def(def_id) ` query] [ adtdefq ] . ` AdtDef ` s are all interned, as shown
267
+ by the ` 'tcx ` lifetime.
273
268
274
269
[ adtdefq ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.adt_def
275
270
0 commit comments