]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/sty.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / sty.rs
CommitLineData
0731742a 1//! This module contains `TyKind` and its major components.
e9174d1e 2
e1599b0c 3#![allow(rustc::usage_of_ty_tykind)]
416331ca 4
9fa01778 5use crate::infer::canonical::Canonical;
2b03887a 6use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
064997fb 7use crate::ty::visit::ValidateBoundVars;
923072b8 8use crate::ty::InferTy::*;
5099ac24 9use crate::ty::{
353b0b11
FG
10 self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable,
11 TypeVisitableExt, TypeVisitor,
5099ac24 12};
923072b8 13use crate::ty::{List, ParamEnv};
f2b60f7d 14use hir::def::DefKind;
60c5eb7d 15use polonius_engine::Atom;
dfeec247 16use rustc_data_structures::captures::Captures;
5099ac24 17use rustc_data_structures::intern::Interned;
353b0b11 18use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
dfeec247 19use rustc_hir as hir;
3dfed10e 20use rustc_hir::def_id::DefId;
487cf647 21use rustc_hir::LangItem;
60c5eb7d
XL
22use rustc_index::vec::Idx;
23use rustc_macros::HashStable;
2b03887a 24use rustc_span::symbol::{kw, sym, Symbol};
487cf647 25use rustc_span::Span;
353b0b11
FG
26use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
27use rustc_target::spec::abi::{self, Abi};
48663c56 28use std::borrow::Cow;
476ff2be 29use std::cmp::Ordering;
5099ac24 30use std::fmt;
532ac7d7 31use std::marker::PhantomData;
5099ac24 32use std::ops::{ControlFlow, Deref, Range};
f9f354fc 33use ty::util::IntTypeExt;
e9174d1e 34
923072b8
FG
35use rustc_type_ir::sty::TyKind::*;
36use rustc_type_ir::RegionKind as IrRegionKind;
37use rustc_type_ir::TyKind as IrTyKind;
38
39// Re-export the `TyKind` from `rustc_type_ir` here for convenience
40#[rustc_diagnostic_item = "TyKind"]
41pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
42pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
43
3dfed10e 44#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
064997fb 45#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
e9174d1e
SL
46pub struct TypeAndMut<'tcx> {
47 pub ty: Ty<'tcx>,
48 pub mutbl: hir::Mutability,
49}
50
3dfed10e 51#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
ba9703b0 52#[derive(HashStable)]
e9174d1e
SL
53/// A "free" region `fr` can be interpreted as "some region
54/// at least as big as the scope `fr.scope`".
55pub struct FreeRegion {
7cac9316 56 pub scope: DefId,
fc512014 57 pub bound_region: BoundRegionKind,
e9174d1e
SL
58}
59
3dfed10e 60#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
ba9703b0 61#[derive(HashStable)]
fc512014 62pub enum BoundRegionKind {
e9174d1e 63 /// An anonymous region parameter for a given fn (&T)
353b0b11 64 BrAnon(Option<Span>),
e9174d1e
SL
65
66 /// Named region parameters for functions (a in &'a T)
67 ///
9fa01778 68 /// The `DefId` is needed to distinguish free regions in
e9174d1e 69 /// the event of shadowing.
e74abb32 70 BrNamed(DefId, Symbol),
e9174d1e 71
7cac9316
XL
72 /// Anonymous region for the implicit env pointer parameter
73 /// to a closure
cc61c64b 74 BrEnv,
e9174d1e
SL
75}
76
fc512014
XL
77#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
78#[derive(HashStable)]
79pub struct BoundRegion {
cdc7bbd5 80 pub var: BoundVar,
fc512014
XL
81 pub kind: BoundRegionKind,
82}
a1dfa0c6 83
fc512014
XL
84impl BoundRegionKind {
85 pub fn is_named(&self) -> bool {
86 match *self {
487cf647
FG
87 BoundRegionKind::BrNamed(_, name) => {
88 name != kw::UnderscoreLifetime && name != kw::Empty
89 }
fc512014
XL
90 _ => false,
91 }
92 }
2b03887a
FG
93
94 pub fn get_name(&self) -> Option<Symbol> {
95 if self.is_named() {
96 match *self {
97 BoundRegionKind::BrNamed(_, name) => return Some(name),
98 _ => unreachable!(),
99 }
100 }
101
102 None
103 }
9c376795
FG
104
105 pub fn get_id(&self) -> Option<DefId> {
106 match *self {
107 BoundRegionKind::BrNamed(id, _) => return Some(id),
108 _ => None,
109 }
110 }
fc512014
XL
111}
112
923072b8
FG
113pub trait Article {
114 fn article(&self) -> &'static str;
e9174d1e
SL
115}
116
923072b8 117impl<'tcx> Article for TyKind<'tcx> {
29967ef6 118 /// Get the article ("a" or "an") to use with this type.
923072b8 119 fn article(&self) -> &'static str {
29967ef6
XL
120 match self {
121 Int(_) | Float(_) | Array(_, _) => "an",
122 Adt(def, _) if def.is_enum() => "an",
123 // This should never happen, but ICEing and causing the user's code
124 // to not compile felt too harsh.
125 Error(_) => "a",
126 _ => "a",
127 }
128 }
3dfed10e 129}
f035d41b 130
e9174d1e 131/// A closure can be modeled as a struct that looks like:
04454e1e
FG
132/// ```ignore (illustrative)
133/// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U);
134/// ```
ff7c6d11
XL
135/// where:
136///
ba9703b0 137/// - 'l0...'li and T0...Tj are the generic parameters
ff7c6d11
XL
138/// in scope on the function that defined the closure,
139/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
140/// is rather hackily encoded via a scalar type. See
5099ac24 141/// `Ty::to_opt_closure_kind` for details.
ff7c6d11
XL
142/// - CS represents the *closure signature*, representing as a `fn()`
143/// type. For example, `fn(u32, u32) -> u32` would mean that the closure
144/// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
145/// specified above.
ba9703b0 146/// - U is a type parameter representing the types of its upvars, tupled up
94222f64 147/// (borrowed, if appropriate; that is, if a U field represents a by-ref upvar,
ba9703b0 148/// and the up-var has the type `Foo`, then that field of U will be `&Foo`).
e9174d1e
SL
149///
150/// So, for example, given this function:
04454e1e
FG
151/// ```ignore (illustrative)
152/// fn foo<'a, T>(data: &'a mut T) {
153/// do(|| data.count += 1)
154/// }
155/// ```
e9174d1e 156/// the type of the closure would be something like:
04454e1e
FG
157/// ```ignore (illustrative)
158/// struct Closure<'a, T, U>(...U);
159/// ```
e9174d1e
SL
160/// Note that the type of the upvar is not specified in the struct.
161/// You may wonder how the impl would then be able to use the upvar,
162/// if it doesn't know it's type? The answer is that the impl is
163/// (conceptually) not fully generic over Closure but rather tied to
164/// instances with the expected upvar types:
04454e1e
FG
165/// ```ignore (illustrative)
166/// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> {
167/// ...
168/// }
169/// ```
e9174d1e
SL
170/// You can see that the *impl* fully specified the type of the upvar
171/// and thus knows full well that `data` has type `&'b mut &'a mut T`.
172/// (Here, I am assuming that `data` is mut-borrowed.)
173///
174/// Now, the last question you may ask is: Why include the upvar types
ba9703b0 175/// in an extra type parameter? The reason for this design is that the
e9174d1e
SL
176/// upvar types can reference lifetimes that are internal to the
177/// creating function. In my example above, for example, the lifetime
ea8adc8c
XL
178/// `'b` represents the scope of the closure itself; this is some
179/// subset of `foo`, probably just the scope of the call to the to
e9174d1e
SL
180/// `do()`. If we just had the lifetime/type parameters from the
181/// enclosing function, we couldn't name this lifetime `'b`. Note that
182/// there can also be lifetimes in the types of the upvars themselves,
183/// if one of them happens to be a reference to something that the
184/// creating fn owns.
185///
186/// OK, you say, so why not create a more minimal set of parameters
187/// that just includes the extra lifetime parameters? The answer is
188/// primarily that it would be hard --- we don't know at the time when
189/// we create the closure type what the full types of the upvars are,
190/// nor do we know which are borrowed and which are not. In this
191/// design, we can just supply a fresh type parameter and figure that
192/// out later.
193///
194/// All right, you say, but why include the type parameters from the
94b46f34 195/// original function then? The answer is that codegen may need them
9fa01778 196/// when monomorphizing, and they may not appear in the upvars. A
e9174d1e
SL
197/// closure could capture no variables but still make use of some
198/// in-scope type parameter with a bound (e.g., if our example above
199/// had an extra `U: Default`, and the closure called `U::default()`).
200///
201/// There is another reason. This design (implicitly) prohibits
202/// closures from capturing themselves (except via a trait
203/// object). This simplifies closure inference considerably, since it
204/// means that when we infer the kind of a closure or its upvars, we
205/// don't have to handle cycles where the decisions we make for
206/// closure C wind up influencing the decisions we ought to make for
207/// closure C (which would then require fixed point iteration to
208/// handle). Plus it fixes an ICE. :P
ff7c6d11
XL
209///
210/// ## Generators
211///
9c376795 212/// Generators are handled similarly in `GeneratorSubsts`. The set of
74b04a01
XL
213/// type parameters is similar, but `CK` and `CS` are replaced by the
214/// following type parameters:
215///
216/// * `GS`: The generator's "resume type", which is the type of the
217/// argument passed to `resume`, and the type of `yield` expressions
218/// inside the generator.
219/// * `GY`: The "yield type", which is the type of values passed to
220/// `yield` inside the generator.
221/// * `GR`: The "return type", which is the type of value returned upon
222/// completion of the generator.
223/// * `GW`: The "generator witness".
9c376795 224#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
e9174d1e 225pub struct ClosureSubsts<'tcx> {
476ff2be 226 /// Lifetime and type parameters from the enclosing function,
ba9703b0 227 /// concatenated with a tuple containing the types of the upvars.
476ff2be 228 ///
94b46f34 229 /// These are separated out because codegen wants to pass them around
e9174d1e 230 /// when monomorphizing.
532ac7d7 231 pub substs: SubstsRef<'tcx>,
476ff2be 232}
e9174d1e 233
3dfed10e
XL
234/// Struct returned by `split()`.
235pub struct ClosureSubstsParts<'tcx, T> {
236 pub parent_substs: &'tcx [GenericArg<'tcx>],
237 pub closure_kind_ty: T,
238 pub closure_sig_as_fn_ptr_ty: T,
239 pub tupled_upvars_ty: T,
ff7c6d11
XL
240}
241
242impl<'tcx> ClosureSubsts<'tcx> {
3dfed10e
XL
243 /// Construct `ClosureSubsts` from `ClosureSubstsParts`, containing `Substs`
244 /// for the closure parent, alongside additional closure-specific components.
245 pub fn new(
246 tcx: TyCtxt<'tcx>,
247 parts: ClosureSubstsParts<'tcx, Ty<'tcx>>,
248 ) -> ClosureSubsts<'tcx> {
249 ClosureSubsts {
9ffffee4 250 substs: tcx.mk_substs_from_iter(
3dfed10e
XL
251 parts.parent_substs.iter().copied().chain(
252 [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty]
253 .iter()
254 .map(|&ty| ty.into()),
255 ),
256 ),
257 }
258 }
259
260 /// Divides the closure substs into their respective components.
261 /// The ordering assumed here must match that used by `ClosureSubsts::new` above.
262 fn split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>> {
ba9703b0 263 match self.substs[..] {
a2a8927a
XL
264 [
265 ref parent_substs @ ..,
266 closure_kind_ty,
267 closure_sig_as_fn_ptr_ty,
268 tupled_upvars_ty,
269 ] => ClosureSubstsParts {
270 parent_substs,
271 closure_kind_ty,
272 closure_sig_as_fn_ptr_ty,
273 tupled_upvars_ty,
274 },
ba9703b0 275 _ => bug!("closure substs missing synthetics"),
ff7c6d11
XL
276 }
277 }
278
ba9703b0
XL
279 /// Returns `true` only if enough of the synthetic types are known to
280 /// allow using all of the methods on `ClosureSubsts` without panicking.
281 ///
282 /// Used primarily by `ty::print::pretty` to be able to handle closure
283 /// types that haven't had their synthetic types substituted in.
284 pub fn is_valid(self) -> bool {
1b1a35ee
XL
285 self.substs.len() >= 3
286 && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
ba9703b0
XL
287 }
288
3dfed10e
XL
289 /// Returns the substitutions of the closure's parent.
290 pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
291 self.split().parent_substs
292 }
293
29967ef6
XL
294 /// Returns an iterator over the list of types of captured paths by the closure.
295 /// In case there was a type error in figuring out the types of the captured path, an
296 /// empty iterator is returned.
476ff2be 297 #[inline]
ba9703b0 298 pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
29967ef6
XL
299 match self.tupled_upvars_ty().kind() {
300 TyKind::Error(_) => None,
301 TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
302 TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
303 ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
304 }
305 .into_iter()
306 .flatten()
3dfed10e
XL
307 }
308
309 /// Returns the tuple type representing the upvars for this closure.
310 #[inline]
311 pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
312 self.split().tupled_upvars_ty.expect_ty()
ff7c6d11
XL
313 }
314
315 /// Returns the closure kind for this closure; may return a type
316 /// variable during inference. To get the closure kind during
ba9703b0
XL
317 /// inference, use `infcx.closure_kind(substs)`.
318 pub fn kind_ty(self) -> Ty<'tcx> {
319 self.split().closure_kind_ty.expect_ty()
ff7c6d11
XL
320 }
321
ba9703b0
XL
322 /// Returns the `fn` pointer type representing the closure signature for this
323 /// closure.
324 // FIXME(eddyb) this should be unnecessary, as the shallowly resolved
325 // type is known at the time of the creation of `ClosureSubsts`,
2b03887a 326 // see `rustc_hir_analysis::check::closure`.
ba9703b0
XL
327 pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> {
328 self.split().closure_sig_as_fn_ptr_ty.expect_ty()
ff7c6d11
XL
329 }
330
ff7c6d11
XL
331 /// Returns the closure kind for this closure; only usable outside
332 /// of an inference context, because in that context we know that
333 /// there are no type variables.
334 ///
335 /// If you have an inference context, use `infcx.closure_kind()`.
ba9703b0
XL
336 pub fn kind(self) -> ty::ClosureKind {
337 self.kind_ty().to_opt_closure_kind().unwrap()
ff7c6d11
XL
338 }
339
ba9703b0
XL
340 /// Extracts the signature from the closure.
341 pub fn sig(self) -> ty::PolyFnSig<'tcx> {
342 let ty = self.sig_as_fn_ptr_ty();
1b1a35ee
XL
343 match ty.kind() {
344 ty::FnPtr(sig) => *sig,
345 _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()),
ff7c6d11 346 }
476ff2be 347 }
f2b60f7d
FG
348
349 pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> {
350 ty::print::PrintClosureAsImpl { closure: self }
351 }
a7813a04 352}
9cc50fc6 353
48663c56 354/// Similar to `ClosureSubsts`; see the above documentation for more.
9c376795 355#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
94b46f34 356pub struct GeneratorSubsts<'tcx> {
532ac7d7 357 pub substs: SubstsRef<'tcx>,
94b46f34
XL
358}
359
3dfed10e
XL
360pub struct GeneratorSubstsParts<'tcx, T> {
361 pub parent_substs: &'tcx [GenericArg<'tcx>],
362 pub resume_ty: T,
363 pub yield_ty: T,
364 pub return_ty: T,
365 pub witness: T,
366 pub tupled_upvars_ty: T,
94b46f34
XL
367}
368
369impl<'tcx> GeneratorSubsts<'tcx> {
3dfed10e
XL
370 /// Construct `GeneratorSubsts` from `GeneratorSubstsParts`, containing `Substs`
371 /// for the generator parent, alongside additional generator-specific components.
372 pub fn new(
373 tcx: TyCtxt<'tcx>,
374 parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>,
375 ) -> GeneratorSubsts<'tcx> {
376 GeneratorSubsts {
9ffffee4 377 substs: tcx.mk_substs_from_iter(
3dfed10e
XL
378 parts.parent_substs.iter().copied().chain(
379 [
380 parts.resume_ty,
381 parts.yield_ty,
382 parts.return_ty,
383 parts.witness,
384 parts.tupled_upvars_ty,
385 ]
386 .iter()
387 .map(|&ty| ty.into()),
388 ),
389 ),
390 }
391 }
392
393 /// Divides the generator substs into their respective components.
394 /// The ordering assumed here must match that used by `GeneratorSubsts::new` above.
395 fn split(self) -> GeneratorSubstsParts<'tcx, GenericArg<'tcx>> {
ba9703b0 396 match self.substs[..] {
3dfed10e
XL
397 [ref parent_substs @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => {
398 GeneratorSubstsParts {
399 parent_substs,
400 resume_ty,
401 yield_ty,
402 return_ty,
403 witness,
404 tupled_upvars_ty,
405 }
ba9703b0
XL
406 }
407 _ => bug!("generator substs missing synthetics"),
94b46f34
XL
408 }
409 }
410
ba9703b0
XL
411 /// Returns `true` only if enough of the synthetic types are known to
412 /// allow using all of the methods on `GeneratorSubsts` without panicking.
413 ///
414 /// Used primarily by `ty::print::pretty` to be able to handle generator
415 /// types that haven't had their synthetic types substituted in.
416 pub fn is_valid(self) -> bool {
1b1a35ee
XL
417 self.substs.len() >= 5
418 && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_))
ba9703b0
XL
419 }
420
3dfed10e
XL
421 /// Returns the substitutions of the generator's parent.
422 pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
423 self.split().parent_substs
424 }
425
94b46f34
XL
426 /// This describes the types that can be contained in a generator.
427 /// It will be a type variable initially and unified in the last stages of typeck of a body.
428 /// It contains a tuple of all the types that could end up on a generator frame.
429 /// The state transformation MIR pass may only produce layouts which mention types
430 /// in this tuple. Upvars are not counted here.
ba9703b0
XL
431 pub fn witness(self) -> Ty<'tcx> {
432 self.split().witness.expect_ty()
94b46f34
XL
433 }
434
29967ef6
XL
435 /// Returns an iterator over the list of types of captured paths by the generator.
436 /// In case there was a type error in figuring out the types of the captured path, an
437 /// empty iterator is returned.
94b46f34 438 #[inline]
ba9703b0 439 pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
29967ef6
XL
440 match self.tupled_upvars_ty().kind() {
441 TyKind::Error(_) => None,
442 TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
443 TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
444 ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
445 }
446 .into_iter()
447 .flatten()
3dfed10e
XL
448 }
449
450 /// Returns the tuple type representing the upvars for this generator.
451 #[inline]
452 pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
453 self.split().tupled_upvars_ty.expect_ty()
94b46f34
XL
454 }
455
74b04a01 456 /// Returns the type representing the resume type of the generator.
ba9703b0
XL
457 pub fn resume_ty(self) -> Ty<'tcx> {
458 self.split().resume_ty.expect_ty()
74b04a01
XL
459 }
460
94b46f34 461 /// Returns the type representing the yield type of the generator.
ba9703b0
XL
462 pub fn yield_ty(self) -> Ty<'tcx> {
463 self.split().yield_ty.expect_ty()
94b46f34
XL
464 }
465
466 /// Returns the type representing the return type of the generator.
ba9703b0
XL
467 pub fn return_ty(self) -> Ty<'tcx> {
468 self.split().return_ty.expect_ty()
94b46f34
XL
469 }
470
9fa01778 471 /// Returns the "generator signature", which consists of its yield
94b46f34
XL
472 /// and return types.
473 ///
9fa01778 474 /// N.B., some bits of the code prefers to see this wrapped in a
94b46f34
XL
475 /// binder, but it never contains bound regions. Probably this
476 /// function should be removed.
ba9703b0
XL
477 pub fn poly_sig(self) -> PolyGenSig<'tcx> {
478 ty::Binder::dummy(self.sig())
94b46f34
XL
479 }
480
74b04a01 481 /// Returns the "generator signature", which consists of its resume, yield
94b46f34 482 /// and return types.
ba9703b0 483 pub fn sig(self) -> GenSig<'tcx> {
74b04a01 484 ty::GenSig {
ba9703b0
XL
485 resume_ty: self.resume_ty(),
486 yield_ty: self.yield_ty(),
487 return_ty: self.return_ty(),
74b04a01 488 }
94b46f34
XL
489 }
490}
491
dc9dc135 492impl<'tcx> GeneratorSubsts<'tcx> {
60c5eb7d 493 /// Generator has not been resumed yet.
48663c56 494 pub const UNRESUMED: usize = 0;
60c5eb7d 495 /// Generator has returned or is completed.
48663c56 496 pub const RETURNED: usize = 1;
60c5eb7d 497 /// Generator has been poisoned.
48663c56
XL
498 pub const POISONED: usize = 2;
499
500 const UNRESUMED_NAME: &'static str = "Unresumed";
501 const RETURNED_NAME: &'static str = "Returned";
502 const POISONED_NAME: &'static str = "Panicked";
503
60c5eb7d 504 /// The valid variant indices of this generator.
48663c56 505 #[inline]
dc9dc135 506 pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
48663c56 507 // FIXME requires optimized MIR
353b0b11 508 FIRST_VARIANT..tcx.generator_layout(def_id).unwrap().variant_fields.next_index()
48663c56
XL
509 }
510
60c5eb7d 511 /// The discriminant for the given variant. Panics if the `variant_index` is
48663c56
XL
512 /// out of range.
513 #[inline]
514 pub fn discriminant_for_variant(
dc9dc135
XL
515 &self,
516 def_id: DefId,
517 tcx: TyCtxt<'tcx>,
518 variant_index: VariantIdx,
48663c56
XL
519 ) -> Discr<'tcx> {
520 // Generators don't support explicit discriminant values, so they are
521 // the same as the variant index.
522 assert!(self.variant_range(def_id, tcx).contains(&variant_index));
523 Discr { val: variant_index.as_usize() as u128, ty: self.discr_ty(tcx) }
524 }
525
60c5eb7d 526 /// The set of all discriminants for the generator, enumerated with their
48663c56
XL
527 /// variant indices.
528 #[inline]
529 pub fn discriminants(
e74abb32 530 self,
dc9dc135
XL
531 def_id: DefId,
532 tcx: TyCtxt<'tcx>,
533 ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
48663c56
XL
534 self.variant_range(def_id, tcx).map(move |index| {
535 (index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) })
536 })
537 }
538
539 /// Calls `f` with a reference to the name of the enumerator for the given
540 /// variant `v`.
f035d41b 541 pub fn variant_name(v: VariantIdx) -> Cow<'static, str> {
48663c56
XL
542 match v.as_usize() {
543 Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),
544 Self::RETURNED => Cow::from(Self::RETURNED_NAME),
545 Self::POISONED => Cow::from(Self::POISONED_NAME),
dfeec247 546 _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)),
48663c56
XL
547 }
548 }
549
550 /// The type of the state discriminant used in the generator type.
551 #[inline]
dc9dc135 552 pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
48663c56
XL
553 tcx.types.u32
554 }
555
ea8adc8c 556 /// This returns the types of the MIR locals which had to be stored across suspension points.
5e7ed085 557 /// It is calculated in rustc_mir_transform::generator::StateTransform.
ea8adc8c 558 /// All the types here must be in the tuple in GeneratorInterior.
48663c56
XL
559 ///
560 /// The locals are grouped by their variant number. Note that some locals may
561 /// be repeated in multiple variants.
562 #[inline]
dc9dc135
XL
563 pub fn state_tys(
564 self,
565 def_id: DefId,
566 tcx: TyCtxt<'tcx>,
9ffffee4 567 ) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
5869c6ff 568 let layout = tcx.generator_layout(def_id).unwrap();
48663c56 569 layout.variant_fields.iter().map(move |variant| {
9ffffee4
FG
570 variant.iter().map(move |field| {
571 ty::EarlyBinder(layout.field_tys[*field].ty).subst(tcx, self.substs)
572 })
48663c56 573 })
2c00a5a8
XL
574 }
575
48663c56
XL
576 /// This is the types of the fields of a generator which are not stored in a
577 /// variant.
578 #[inline]
ba9703b0
XL
579 pub fn prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>> {
580 self.upvar_tys()
ea8adc8c
XL
581 }
582}
583
17df50a5 584#[derive(Debug, Copy, Clone, HashStable)]
94b46f34 585pub enum UpvarSubsts<'tcx> {
e74abb32
XL
586 Closure(SubstsRef<'tcx>),
587 Generator(SubstsRef<'tcx>),
94b46f34
XL
588}
589
590impl<'tcx> UpvarSubsts<'tcx> {
29967ef6
XL
591 /// Returns an iterator over the list of types of captured paths by the closure/generator.
592 /// In case there was a type error in figuring out the types of the captured path, an
593 /// empty iterator is returned.
94b46f34 594 #[inline]
ba9703b0 595 pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
29967ef6
XL
596 let tupled_tys = match self {
597 UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
598 UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
94b46f34 599 };
29967ef6
XL
600
601 match tupled_tys.kind() {
602 TyKind::Error(_) => None,
603 TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()),
604 TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
605 ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
606 }
607 .into_iter()
608 .flatten()
609 }
610
611 #[inline]
612 pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
613 match self {
614 UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(),
615 UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(),
616 }
94b46f34 617 }
ea8adc8c
XL
618}
619
3c0e092e 620/// An inline const is modeled like
04454e1e
FG
621/// ```ignore (illustrative)
622/// const InlineConst<'l0...'li, T0...Tj, R>: R;
623/// ```
3c0e092e
XL
624/// where:
625///
626/// - 'l0...'li and T0...Tj are the generic parameters
627/// inherited from the item that defined the inline const,
628/// - R represents the type of the constant.
629///
630/// When the inline const is instantiated, `R` is substituted as the actual inferred
631/// type of the constant. The reason that `R` is represented as an extra type parameter
632/// is the same reason that [`ClosureSubsts`] have `CS` and `U` as type parameters:
633/// inline const can reference lifetimes that are internal to the creating function.
064997fb 634#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
3c0e092e
XL
635pub struct InlineConstSubsts<'tcx> {
636 /// Generic parameters from the enclosing item,
637 /// concatenated with the inferred type of the constant.
638 pub substs: SubstsRef<'tcx>,
639}
640
641/// Struct returned by `split()`.
642pub struct InlineConstSubstsParts<'tcx, T> {
643 pub parent_substs: &'tcx [GenericArg<'tcx>],
644 pub ty: T,
645}
646
647impl<'tcx> InlineConstSubsts<'tcx> {
648 /// Construct `InlineConstSubsts` from `InlineConstSubstsParts`.
649 pub fn new(
650 tcx: TyCtxt<'tcx>,
651 parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>,
652 ) -> InlineConstSubsts<'tcx> {
653 InlineConstSubsts {
9ffffee4 654 substs: tcx.mk_substs_from_iter(
3c0e092e
XL
655 parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())),
656 ),
657 }
658 }
659
660 /// Divides the inline const substs into their respective components.
661 /// The ordering assumed here must match that used by `InlineConstSubsts::new` above.
662 fn split(self) -> InlineConstSubstsParts<'tcx, GenericArg<'tcx>> {
663 match self.substs[..] {
664 [ref parent_substs @ .., ty] => InlineConstSubstsParts { parent_substs, ty },
665 _ => bug!("inline const substs missing synthetics"),
666 }
667 }
668
669 /// Returns the substitutions of the inline const's parent.
670 pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] {
671 self.split().parent_substs
672 }
673
674 /// Returns the type of this inline const.
675 pub fn ty(self) -> Ty<'tcx> {
676 self.split().ty.expect_ty()
677 }
678}
679
3dfed10e 680#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)]
f2b60f7d 681#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
476ff2be 682pub enum ExistentialPredicate<'tcx> {
9fa01778 683 /// E.g., `Iterator`.
476ff2be 684 Trait(ExistentialTraitRef<'tcx>),
9fa01778 685 /// E.g., `Iterator::Item = T`.
476ff2be 686 Projection(ExistentialProjection<'tcx>),
9fa01778 687 /// E.g., `Send`.
476ff2be
SL
688 AutoTrait(DefId),
689}
690
dc9dc135 691impl<'tcx> ExistentialPredicate<'tcx> {
94b46f34
XL
692 /// Compares via an ordering that will not change if modules are reordered or other changes are
693 /// made to the tree. In particular, this ordering is preserved across incremental compilations.
dc9dc135 694 pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
476ff2be
SL
695 use self::ExistentialPredicate::*;
696 match (*self, *other) {
697 (Trait(_), Trait(_)) => Ordering::Equal,
dfeec247 698 (Projection(ref a), Projection(ref b)) => {
9c376795 699 tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id))
dfeec247
XL
700 }
701 (AutoTrait(ref a), AutoTrait(ref b)) => {
a2a8927a 702 tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b))
dfeec247 703 }
476ff2be
SL
704 (Trait(_), _) => Ordering::Less,
705 (Projection(_), Trait(_)) => Ordering::Greater,
706 (Projection(_), _) => Ordering::Less,
707 (AutoTrait(_), _) => Ordering::Greater,
708 }
709 }
476ff2be
SL
710}
711
487cf647
FG
712pub type PolyExistentialPredicate<'tcx> = Binder<'tcx, ExistentialPredicate<'tcx>>;
713
714impl<'tcx> PolyExistentialPredicate<'tcx> {
f2b60f7d
FG
715 /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
716 /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
717 /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
dc9dc135 718 pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
9fa01778 719 use crate::ty::ToPredicate;
f035d41b 720 match self.skip_binder() {
dfeec247 721 ExistentialPredicate::Trait(tr) => {
29967ef6 722 self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
dfeec247
XL
723 }
724 ExistentialPredicate::Projection(p) => {
29967ef6 725 self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
dfeec247 726 }
476ff2be 727 ExistentialPredicate::AutoTrait(did) => {
487cf647
FG
728 let generics = tcx.generics_of(did);
729 let trait_ref = if generics.params.len() == 1 {
730 tcx.mk_trait_ref(did, [self_ty])
731 } else {
732 // If this is an ill-formed auto trait, then synthesize
733 // new error substs for the missing generics.
734 let err_substs =
735 ty::InternalSubsts::extend_with_error(tcx, did, &[self_ty.into()]);
736 tcx.mk_trait_ref(did, err_substs)
737 };
738 self.rebind(trait_ref).without_const().to_predicate(tcx)
476ff2be
SL
739 }
740 }
741 }
742}
743
487cf647 744impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> {
e1599b0c 745 /// Returns the "principal `DefId`" of this set of existential predicates.
0731742a
XL
746 ///
747 /// A Rust trait object type consists (in addition to a lifetime bound)
748 /// of a set of trait bounds, which are separated into any number
416331ca 749 /// of auto-trait bounds, and at most one non-auto-trait bound. The
0731742a
XL
750 /// non-auto-trait bound is called the "principal" of the trait
751 /// object.
752 ///
753 /// Only the principal can have methods or type parameters (because
754 /// auto traits can have neither of them). This is important, because
755 /// it means the auto traits can be treated as an unordered set (methods
756 /// would force an order for the vtable, while relating traits with
757 /// type parameters without knowing the order to relate them in is
758 /// a rather non-trivial task).
759 ///
760 /// For example, in the trait object `dyn fmt::Debug + Sync`, the
761 /// principal bound is `Some(fmt::Debug)`, while the auto-trait bounds
762 /// are the set `{Sync}`.
763 ///
764 /// It is also possible to have a "trivial" trait object that
765 /// consists only of auto traits, with no principal - for example,
766 /// `dyn Send + Sync`. In that case, the set of auto-trait bounds
767 /// is `{Send, Sync}`, while there is no principal. These trait objects
768 /// have a "trivial" vtable consisting of just the size, alignment,
769 /// and destructor.
cdc7bbd5 770 pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
fc512014
XL
771 self[0]
772 .map_bound(|this| match this {
773 ExistentialPredicate::Trait(tr) => Some(tr),
774 _ => None,
775 })
776 .transpose()
476ff2be
SL
777 }
778
0731742a 779 pub fn principal_def_id(&self) -> Option<DefId> {
fc512014 780 self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
0731742a
XL
781 }
782
476ff2be 783 #[inline]
dfeec247
XL
784 pub fn projection_bounds<'a>(
785 &'a self,
cdc7bbd5 786 ) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> + 'a {
fc512014
XL
787 self.iter().filter_map(|predicate| {
788 predicate
789 .map_bound(|pred| match pred {
790 ExistentialPredicate::Projection(projection) => Some(projection),
791 _ => None,
792 })
793 .transpose()
476ff2be
SL
794 })
795 }
796
797 #[inline]
923072b8 798 pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + Captures<'tcx> + 'a {
fc512014 799 self.iter().filter_map(|predicate| match predicate.skip_binder() {
dfeec247
XL
800 ExistentialPredicate::AutoTrait(did) => Some(did),
801 _ => None,
476ff2be
SL
802 })
803 }
804}
805
e9174d1e 806/// A complete reference to a trait. These take numerous guises in syntax,
9fa01778 807/// but perhaps the most recognizable form is in a where-clause:
04454e1e
FG
808/// ```ignore (illustrative)
809/// T: Foo<U>
810/// ```
9fa01778
XL
811/// This would be represented by a trait-reference where the `DefId` is the
812/// `DefId` for the trait `Foo` and the substs define `T` as parameter 0,
9e0c209e 813/// and `U` as parameter 1.
e9174d1e
SL
814///
815/// Trait references also appear in object types like `Foo<U>`, but in
816/// that case the `Self` parameter is absent from the substitutions.
3c0e092e 817#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
f2b60f7d 818#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
e9174d1e
SL
819pub struct TraitRef<'tcx> {
820 pub def_id: DefId,
532ac7d7 821 pub substs: SubstsRef<'tcx>,
9c376795
FG
822 /// This field exists to prevent the creation of `TraitRef` without
823 /// calling [TyCtxt::mk_trait_ref].
824 pub(super) _use_mk_trait_ref_instead: (),
e9174d1e
SL
825}
826
8bb4bdeb 827impl<'tcx> TraitRef<'tcx> {
9c376795 828 pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
487cf647
FG
829 tcx.mk_trait_ref(
830 self.def_id,
831 [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)),
832 )
833 }
834
a1dfa0c6 835 /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
8faf50e0 836 /// are the parameters defined on trait.
c295e0f8 837 pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
9c376795 838 ty::Binder::dummy(tcx.mk_trait_ref(def_id, InternalSubsts::identity_for_item(tcx, def_id)))
8faf50e0
XL
839 }
840
a1dfa0c6 841 #[inline]
8bb4bdeb
XL
842 pub fn self_ty(&self) -> Ty<'tcx> {
843 self.substs.type_at(0)
844 }
845
dc9dc135
XL
846 pub fn from_method(
847 tcx: TyCtxt<'tcx>,
848 trait_id: DefId,
849 substs: SubstsRef<'tcx>,
850 ) -> ty::TraitRef<'tcx> {
94b46f34 851 let defs = tcx.generics_of(trait_id);
9ffffee4 852 tcx.mk_trait_ref(trait_id, tcx.mk_substs(&substs[..defs.params.len()]))
94b46f34 853 }
8bb4bdeb
XL
854}
855
cdc7bbd5 856pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>;
e9174d1e
SL
857
858impl<'tcx> PolyTraitRef<'tcx> {
cdc7bbd5 859 pub fn self_ty(&self) -> Binder<'tcx, Ty<'tcx>> {
f035d41b 860 self.map_bound_ref(|tr| tr.self_ty())
e9174d1e
SL
861 }
862
863 pub fn def_id(&self) -> DefId {
83c7162d 864 self.skip_binder().def_id
e9174d1e 865 }
e9174d1e
SL
866}
867
353b0b11
FG
868impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> {
869 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
f2b60f7d
FG
870 self.to_string().into_diagnostic_arg()
871 }
872}
873
9e0c209e
SL
874/// An existential reference to a trait, where `Self` is erased.
875/// For example, the trait object `Trait<'a, 'b, X, Y>` is:
04454e1e
FG
876/// ```ignore (illustrative)
877/// exists T. T: Trait<'a, 'b, X, Y>
878/// ```
9e0c209e
SL
879/// The substitutions don't include the erased `Self`, only trait
880/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
3dfed10e 881#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
f2b60f7d 882#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
9e0c209e
SL
883pub struct ExistentialTraitRef<'tcx> {
884 pub def_id: DefId,
532ac7d7 885 pub substs: SubstsRef<'tcx>,
9e0c209e
SL
886}
887
dc9dc135 888impl<'tcx> ExistentialTraitRef<'tcx> {
dc9dc135
XL
889 pub fn erase_self_ty(
890 tcx: TyCtxt<'tcx>,
891 trait_ref: ty::TraitRef<'tcx>,
892 ) -> ty::ExistentialTraitRef<'tcx> {
94b46f34
XL
893 // Assert there is a Self.
894 trait_ref.substs.type_at(0);
895
896 ty::ExistentialTraitRef {
897 def_id: trait_ref.def_id,
9ffffee4 898 substs: tcx.mk_substs(&trait_ref.substs[1..]),
94b46f34
XL
899 }
900 }
901
9fa01778 902 /// Object types don't have a self type specified. Therefore, when
476ff2be 903 /// we convert the principal trait-ref into a normal trait-ref,
9fa01778 904 /// you must give *some* self type. A common choice is `mk_err()`
0bf4aa26 905 /// or some placeholder type.
dc9dc135 906 pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> {
a1dfa0c6
XL
907 // otherwise the escaping vars would be captured by the binder
908 // debug_assert!(!self_ty.has_escaping_bound_vars());
476ff2be 909
487cf647 910 tcx.mk_trait_ref(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter()))
476ff2be 911 }
9e0c209e
SL
912}
913
353b0b11
FG
914impl<'tcx> IntoDiagnosticArg for ExistentialTraitRef<'tcx> {
915 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
916 self.to_string().into_diagnostic_arg()
917 }
918}
919
cdc7bbd5 920pub type PolyExistentialTraitRef<'tcx> = Binder<'tcx, ExistentialTraitRef<'tcx>>;
9e0c209e
SL
921
922impl<'tcx> PolyExistentialTraitRef<'tcx> {
923 pub fn def_id(&self) -> DefId {
83c7162d 924 self.skip_binder().def_id
9e0c209e 925 }
94b46f34 926
9fa01778 927 /// Object types don't have a self type specified. Therefore, when
94b46f34 928 /// we convert the principal trait-ref into a normal trait-ref,
9fa01778 929 /// you must give *some* self type. A common choice is `mk_err()`
0bf4aa26 930 /// or some placeholder type.
dc9dc135 931 pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> {
94b46f34
XL
932 self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
933 }
9e0c209e
SL
934}
935
cdc7bbd5
XL
936#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
937#[derive(HashStable)]
938pub enum BoundVariableKind {
939 Ty(BoundTyKind),
940 Region(BoundRegionKind),
941 Const,
942}
943
064997fb
FG
944impl BoundVariableKind {
945 pub fn expect_region(self) -> BoundRegionKind {
946 match self {
947 BoundVariableKind::Region(lt) => lt,
948 _ => bug!("expected a region, but found another kind"),
949 }
950 }
951
952 pub fn expect_ty(self) -> BoundTyKind {
953 match self {
954 BoundVariableKind::Ty(ty) => ty,
955 _ => bug!("expected a type, but found another kind"),
956 }
957 }
958
959 pub fn expect_const(self) {
960 match self {
961 BoundVariableKind::Const => (),
962 _ => bug!("expected a const, but found another kind"),
963 }
964 }
965}
966
a1dfa0c6 967/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
e9174d1e
SL
968/// compiler's representation for things like `for<'a> Fn(&'a isize)`
969/// (which would be represented by the type `PolyTraitRef ==
cdc7bbd5 970/// Binder<'tcx, TraitRef>`). Note that when we instantiate,
a1dfa0c6 971/// erase, or otherwise "discharge" these bound vars, we change the
cdc7bbd5 972/// type from `Binder<'tcx, T>` to just `T` (see
0731742a 973/// e.g., `liberate_late_bound_regions`).
5869c6ff
XL
974///
975/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
976#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
f2b60f7d 977#[derive(HashStable, Lift)]
cdc7bbd5 978pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
e9174d1e 979
cdc7bbd5
XL
980impl<'tcx, T> Binder<'tcx, T>
981where
9ffffee4 982 T: TypeVisitable<TyCtxt<'tcx>>,
cdc7bbd5 983{
ff7c6d11 984 /// Wraps `value` in a binder, asserting that `value` does not
a1dfa0c6 985 /// contain any bound vars that would be bound by the
ff7c6d11
XL
986 /// binder. This is commonly used to 'inject' a value T into a
987 /// different binding level.
9c376795 988 #[track_caller]
cdc7bbd5 989 pub fn dummy(value: T) -> Binder<'tcx, T> {
9c376795
FG
990 assert!(
991 !value.has_escaping_bound_vars(),
992 "`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder."
993 );
cdc7bbd5 994 Binder(value, ty::List::empty())
ff7c6d11
XL
995 }
996
cdc7bbd5
XL
997 pub fn bind_with_vars(value: T, vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
998 if cfg!(debug_assertions) {
999 let mut validator = ValidateBoundVars::new(vars);
1000 value.visit_with(&mut validator);
3dfed10e 1001 }
cdc7bbd5 1002 Binder(value, vars)
3dfed10e 1003 }
cdc7bbd5 1004}
3dfed10e 1005
cdc7bbd5 1006impl<'tcx, T> Binder<'tcx, T> {
e9174d1e
SL
1007 /// Skips the binder and returns the "bound" value. This is a
1008 /// risky thing to do because it's easy to get confused about
9fa01778 1009 /// De Bruijn indices and the like. It is usually better to
a1dfa0c6 1010 /// discharge the binder using `no_bound_vars` or
e9174d1e
SL
1011 /// `replace_late_bound_regions` or something like
1012 /// that. `skip_binder` is only valid when you are either
a1dfa0c6 1013 /// extracting data that has nothing to do with bound vars, you
e9174d1e
SL
1014 /// are doing some sort of test that does not involve bound
1015 /// regions, or you are being very careful about your depth
1016 /// accounting.
1017 ///
1018 /// Some examples where `skip_binder` is reasonable:
ff7c6d11 1019 ///
9fa01778 1020 /// - extracting the `DefId` from a PolyTraitRef;
e9174d1e 1021 /// - comparing the self type of a PolyTraitRef to see if it is equal to
a1dfa0c6 1022 /// a type parameter `X`, since the type `X` does not reference any regions
f035d41b
XL
1023 pub fn skip_binder(self) -> T {
1024 self.0
e9174d1e
SL
1025 }
1026
cdc7bbd5
XL
1027 pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> {
1028 self.1
e9174d1e
SL
1029 }
1030
cdc7bbd5
XL
1031 pub fn as_ref(&self) -> Binder<'tcx, &T> {
1032 Binder(&self.0, self.1)
1033 }
1034
923072b8
FG
1035 pub fn as_deref(&self) -> Binder<'tcx, &T::Target>
1036 where
1037 T: Deref,
1038 {
1039 Binder(&self.0, self.1)
1040 }
1041
cdc7bbd5
XL
1042 pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
1043 where
1044 F: FnOnce(&T) -> U,
1045 {
1046 let value = f(&self.0);
1047 Binder(value, self.1)
1048 }
1049
9ffffee4 1050 pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
dfeec247
XL
1051 where
1052 F: FnOnce(&T) -> U,
e9174d1e
SL
1053 {
1054 self.as_ref().map_bound(f)
1055 }
1056
9ffffee4 1057 pub fn map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx, U>
dfeec247
XL
1058 where
1059 F: FnOnce(T) -> U,
e9174d1e 1060 {
cdc7bbd5
XL
1061 let value = f(self.0);
1062 if cfg!(debug_assertions) {
1063 let mut validator = ValidateBoundVars::new(self.1);
1064 value.visit_with(&mut validator);
1065 }
1066 Binder(value, self.1)
e9174d1e 1067 }
ff7c6d11 1068
9ffffee4
FG
1069 pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>(
1070 self,
1071 f: F,
1072 ) -> Result<Binder<'tcx, U>, E>
a2a8927a
XL
1073 where
1074 F: FnOnce(T) -> Result<U, E>,
1075 {
1076 let value = f(self.0)?;
1077 if cfg!(debug_assertions) {
1078 let mut validator = ValidateBoundVars::new(self.1);
1079 value.visit_with(&mut validator);
1080 }
1081 Ok(Binder(value, self.1))
1082 }
1083
29967ef6
XL
1084 /// Wraps a `value` in a binder, using the same bound variables as the
1085 /// current `Binder`. This should not be used if the new value *changes*
1086 /// the bound variables. Note: the (old or new) value itself does not
1087 /// necessarily need to *name* all the bound variables.
1088 ///
1089 /// This currently doesn't do anything different than `bind`, because we
1090 /// don't actually track bound vars. However, semantically, it is different
1091 /// because bound vars aren't allowed to change here, whereas they are
1092 /// in `bind`. This may be (debug) asserted in the future.
cdc7bbd5
XL
1093 pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U>
1094 where
9ffffee4 1095 U: TypeVisitable<TyCtxt<'tcx>>,
cdc7bbd5
XL
1096 {
1097 if cfg!(debug_assertions) {
1098 let mut validator = ValidateBoundVars::new(self.bound_vars());
1099 value.visit_with(&mut validator);
1100 }
1101 Binder(value, self.1)
29967ef6
XL
1102 }
1103
ff7c6d11 1104 /// Unwraps and returns the value within, but only if it contains
a1dfa0c6 1105 /// no bound vars at all. (In other words, if this binder --
ff7c6d11
XL
1106 /// and indeed any enclosing binder -- doesn't bind anything at
1107 /// all.) Otherwise, returns `None`.
1108 ///
1109 /// (One could imagine having a method that just unwraps a single
a1dfa0c6 1110 /// binder, but permits late-bound vars bound by enclosing
ff7c6d11
XL
1111 /// binders, but that would require adjusting the debruijn
1112 /// indices, and given the shallow binding structure we often use,
1113 /// would not be that useful.)
cdc7bbd5 1114 pub fn no_bound_vars(self) -> Option<T>
dfeec247 1115 where
9ffffee4 1116 T: TypeVisitable<TyCtxt<'tcx>>,
ff7c6d11 1117 {
f035d41b 1118 if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
ff7c6d11
XL
1119 }
1120
9fa01778 1121 /// Splits the contents into two things that share the same binder
ff7c6d11
XL
1122 /// level as the original, returning two distinct binders.
1123 ///
1124 /// `f` should consider bound regions at depth 1 to be free, and
1125 /// anything it produces with bound regions at depth 1 will be
1126 /// bound in the resulting return values.
cdc7bbd5 1127 pub fn split<U, V, F>(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>)
dfeec247
XL
1128 where
1129 F: FnOnce(T) -> (U, V),
ff7c6d11
XL
1130 {
1131 let (u, v) = f(self.0);
cdc7bbd5 1132 (Binder(u, self.1), Binder(v, self.1))
ff7c6d11 1133 }
e9174d1e
SL
1134}
1135
cdc7bbd5
XL
1136impl<'tcx, T> Binder<'tcx, Option<T>> {
1137 pub fn transpose(self) -> Option<Binder<'tcx, T>> {
1138 let bound_vars = self.1;
1139 self.0.map(|v| Binder(v, bound_vars))
3dfed10e
XL
1140 }
1141}
1142
9c376795
FG
1143impl<'tcx, T: IntoIterator> Binder<'tcx, T> {
1144 pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> {
1145 let bound_vars = self.1;
1146 self.0.into_iter().map(|v| Binder(v, bound_vars))
1147 }
1148}
1149
353b0b11
FG
1150impl<'tcx, T> IntoDiagnosticArg for Binder<'tcx, T>
1151where
1152 T: IntoDiagnosticArg,
1153{
1154 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
1155 self.0.into_diagnostic_arg()
9c376795
FG
1156 }
1157}
1158
1159/// Represents the projection of an associated type.
1160///
1161/// For a projection, this would be `<Ty as Trait<...>>::N`.
1162///
1163/// For an opaque type, there is no explicit syntax.
1164#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
f2b60f7d 1165#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
9c376795
FG
1166pub struct AliasTy<'tcx> {
1167 /// The parameters of the associated or opaque item.
1168 ///
1169 /// For a projection, these are the substitutions for the trait and the
1170 /// GAT substitutions, if there are any.
1171 ///
1172 /// For RPIT the substitutions are for the generics of the function,
1173 /// while for TAIT it is used for the generic parameters of the alias.
532ac7d7 1174 pub substs: SubstsRef<'tcx>,
e9174d1e 1175
9c376795
FG
1176 /// The `DefId` of the `TraitItem` for the associated type `N` if this is a projection,
1177 /// or the `OpaqueType` item if this is an opaque.
7cac9316 1178 ///
9c376795
FG
1179 /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the
1180 /// underlying type if the type is an opaque.
1181 ///
1182 /// Note that if this is an associated type, this is not the `DefId` of the
1183 /// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`,
1184 /// aka. `tcx.parent(def_id)`.
1185 pub def_id: DefId,
1186
1187 /// This field exists to prevent the creation of `AliasTy` without using
1188 /// [TyCtxt::mk_alias_ty].
1189 pub(super) _use_mk_alias_ty_instead: (),
e9174d1e 1190}
7cac9316 1191
9c376795
FG
1192impl<'tcx> AliasTy<'tcx> {
1193 pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind {
1194 match tcx.def_kind(self.def_id) {
1195 DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection,
1196 DefKind::OpaqueTy => ty::Opaque,
1197 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
1198 }
1199 }
1200
1201 pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
9ffffee4 1202 tcx.mk_alias(self.kind(tcx), self)
9c376795
FG
1203 }
1204}
1205
1206/// The following methods work only with associated type projections.
1207impl<'tcx> AliasTy<'tcx> {
1208 pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
1209 match tcx.def_kind(self.def_id) {
1210 DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
2b03887a 1211 DefKind::ImplTraitPlaceholder => {
353b0b11 1212 tcx.parent(tcx.impl_trait_in_trait_parent_fn(self.def_id))
2b03887a 1213 }
9c376795 1214 kind => bug!("expected a projection AliasTy; found {kind:?}"),
2b03887a 1215 }
6a06907d 1216 }
7cac9316 1217
6a06907d
XL
1218 /// Extracts the underlying trait reference and own substs from this projection.
1219 /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
1220 /// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs
1221 pub fn trait_ref_and_own_substs(
9c376795 1222 self,
6a06907d
XL
1223 tcx: TyCtxt<'tcx>,
1224 ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
9c376795
FG
1225 debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst));
1226 let trait_def_id = self.trait_def_id(tcx);
1227 let trait_generics = tcx.generics_of(trait_def_id);
6a06907d 1228 (
9c376795 1229 tcx.mk_trait_ref(trait_def_id, self.substs.truncate_to(tcx, trait_generics)),
6a06907d
XL
1230 &self.substs[trait_generics.count()..],
1231 )
7cac9316
XL
1232 }
1233
041b39d2
XL
1234 /// Extracts the underlying trait reference from this projection.
1235 /// For example, if this is a projection of `<T as Iterator>::Item`,
1236 /// then this function would return a `T: Iterator` trait reference.
6a06907d
XL
1237 ///
1238 /// WARNING: This will drop the substs for generic associated types
1239 /// consider calling [Self::trait_ref_and_own_substs] to get those
1240 /// as well.
9c376795 1241 pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
6a06907d 1242 let def_id = self.trait_def_id(tcx);
9c376795 1243 tcx.mk_trait_ref(def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id)))
041b39d2
XL
1244 }
1245
9c376795 1246 pub fn self_ty(self) -> Ty<'tcx> {
041b39d2 1247 self.substs.type_at(0)
7cac9316 1248 }
9c376795
FG
1249
1250 pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
1251 tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)))
1252 }
7cac9316
XL
1253}
1254
f2b60f7d 1255#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
ea8adc8c 1256pub struct GenSig<'tcx> {
74b04a01 1257 pub resume_ty: Ty<'tcx>,
ea8adc8c
XL
1258 pub yield_ty: Ty<'tcx>,
1259 pub return_ty: Ty<'tcx>,
1260}
1261
cdc7bbd5 1262pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>;
7cac9316 1263
e1599b0c 1264/// Signature of a function type, which we have arbitrarily
e9174d1e
SL
1265/// decided to use to refer to the input/output types.
1266///
532ac7d7
XL
1267/// - `inputs`: is the list of arguments and their modes.
1268/// - `output`: is the return type.
1269/// - `c_variadic`: indicates whether this is a C-variadic function.
3dfed10e 1270#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
f2b60f7d 1271#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
e9174d1e 1272pub struct FnSig<'tcx> {
b7449926 1273 pub inputs_and_output: &'tcx List<Ty<'tcx>>,
532ac7d7 1274 pub c_variadic: bool,
8bb4bdeb
XL
1275 pub unsafety: hir::Unsafety,
1276 pub abi: abi::Abi,
e9174d1e
SL
1277}
1278
476ff2be 1279impl<'tcx> FnSig<'tcx> {
8bb4bdeb 1280 pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
476ff2be
SL
1281 &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1282 }
1283
1284 pub fn output(&self) -> Ty<'tcx> {
1285 self.inputs_and_output[self.inputs_and_output.len() - 1]
1286 }
48663c56 1287
e1599b0c
XL
1288 // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
1289 // method.
48663c56
XL
1290 fn fake() -> FnSig<'tcx> {
1291 FnSig {
1292 inputs_and_output: List::empty(),
1293 c_variadic: false,
1294 unsafety: hir::Unsafety::Normal,
1295 abi: abi::Abi::Rust,
1296 }
1297 }
476ff2be
SL
1298}
1299
353b0b11
FG
1300impl<'tcx> IntoDiagnosticArg for FnSig<'tcx> {
1301 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
1302 self.to_string().into_diagnostic_arg()
1303 }
1304}
1305
cdc7bbd5 1306pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>;
e9174d1e
SL
1307
1308impl<'tcx> PolyFnSig<'tcx> {
a1dfa0c6 1309 #[inline]
cdc7bbd5
XL
1310 pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> {
1311 self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs())
e9174d1e 1312 }
a1dfa0c6 1313 #[inline]
cdc7bbd5 1314 pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> {
476ff2be 1315 self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
e9174d1e 1316 }
cdc7bbd5 1317 pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> {
ff7c6d11
XL
1318 self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
1319 }
a1dfa0c6 1320 #[inline]
cdc7bbd5 1321 pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
0bf4aa26 1322 self.map_bound_ref(|fn_sig| fn_sig.output())
e9174d1e 1323 }
532ac7d7
XL
1324 pub fn c_variadic(&self) -> bool {
1325 self.skip_binder().c_variadic
e9174d1e 1326 }
8bb4bdeb
XL
1327 pub fn unsafety(&self) -> hir::Unsafety {
1328 self.skip_binder().unsafety
1329 }
1330 pub fn abi(&self) -> abi::Abi {
1331 self.skip_binder().abi
1332 }
353b0b11
FG
1333
1334 pub fn is_fn_trait_compatible(&self) -> bool {
1335 matches!(
1336 self.skip_binder(),
1337 ty::FnSig {
1338 unsafety: rustc_hir::Unsafety::Normal,
1339 abi: Abi::Rust,
1340 c_variadic: false,
1341 ..
1342 }
1343 )
1344 }
e9174d1e
SL
1345}
1346
cdc7bbd5 1347pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>;
0bf4aa26 1348
3dfed10e 1349#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
ba9703b0 1350#[derive(HashStable)]
e9174d1e 1351pub struct ParamTy {
48663c56 1352 pub index: u32,
e74abb32 1353 pub name: Symbol,
e9174d1e
SL
1354}
1355
dc9dc135 1356impl<'tcx> ParamTy {
e74abb32 1357 pub fn new(index: u32, name: Symbol) -> ParamTy {
74b04a01 1358 ParamTy { index, name }
e9174d1e
SL
1359 }
1360
94b46f34 1361 pub fn for_def(def: &ty::GenericParamDef) -> ParamTy {
9e0c209e 1362 ParamTy::new(def.index, def.name)
e9174d1e
SL
1363 }
1364
6a06907d 1365 #[inline]
dc9dc135 1366 pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
48663c56 1367 tcx.mk_ty_param(self.index, self.name)
e9174d1e 1368 }
487cf647
FG
1369
1370 pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span {
1371 let generics = tcx.generics_of(item_with_generics);
1372 let type_param = generics.type_param(self, tcx);
1373 tcx.def_span(type_param.def_id)
1374 }
e9174d1e
SL
1375}
1376
3dfed10e 1377#[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)]
ba9703b0 1378#[derive(HashStable)]
532ac7d7
XL
1379pub struct ParamConst {
1380 pub index: u32,
e74abb32 1381 pub name: Symbol,
532ac7d7
XL
1382}
1383
cdc7bbd5 1384impl ParamConst {
e74abb32 1385 pub fn new(index: u32, name: Symbol) -> ParamConst {
532ac7d7
XL
1386 ParamConst { index, name }
1387 }
1388
1389 pub fn for_def(def: &ty::GenericParamDef) -> ParamConst {
1390 ParamConst::new(def.index, def.name)
1391 }
532ac7d7
XL
1392}
1393
923072b8 1394/// Use this rather than `RegionKind`, whenever possible.
5099ac24 1395#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
5e7ed085 1396#[rustc_pass_by_value]
923072b8 1397pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
5099ac24
FG
1398
1399impl<'tcx> Deref for Region<'tcx> {
923072b8 1400 type Target = RegionKind<'tcx>;
5099ac24 1401
064997fb 1402 #[inline]
923072b8 1403 fn deref(&self) -> &RegionKind<'tcx> {
5099ac24
FG
1404 &self.0.0
1405 }
1406}
1407
1408impl<'tcx> fmt::Debug for Region<'tcx> {
1409 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1410 write!(f, "{:?}", self.kind())
1411 }
1412}
7cac9316 1413
923072b8 1414#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
064997fb 1415#[derive(HashStable)]
e9174d1e 1416pub struct EarlyBoundRegion {
7cac9316 1417 pub def_id: DefId,
e9174d1e 1418 pub index: u32,
e74abb32 1419 pub name: Symbol,
e9174d1e
SL
1420}
1421
923072b8
FG
1422impl fmt::Debug for EarlyBoundRegion {
1423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1424 write!(f, "{}, {}", self.index, self.name)
1425 }
1426}
1427
5869c6ff 1428/// A **`const`** **v**ariable **ID**.
064997fb
FG
1429#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1430#[derive(HashStable, TyEncodable, TyDecodable)]
532ac7d7
XL
1431pub struct ConstVid<'tcx> {
1432 pub index: u32,
1433 pub phantom: PhantomData<&'tcx ()>,
1434}
1435
e74abb32 1436rustc_index::newtype_index! {
5869c6ff 1437 /// A **region** (lifetime) **v**ariable **ID**.
064997fb 1438 #[derive(HashStable)]
9c376795
FG
1439 #[debug_format = "'_#{}r"]
1440 pub struct RegionVid {}
b7449926 1441}
abe05a73 1442
94b46f34
XL
1443impl Atom for RegionVid {
1444 fn index(self) -> usize {
1445 Idx::index(self)
1446 }
1447}
1448
e74abb32 1449rustc_index::newtype_index! {
064997fb 1450 #[derive(HashStable)]
9c376795 1451 pub struct BoundVar {}
0bf4aa26
XL
1452}
1453
3dfed10e 1454#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
ba9703b0 1455#[derive(HashStable)]
0bf4aa26 1456pub struct BoundTy {
a1dfa0c6
XL
1457 pub var: BoundVar,
1458 pub kind: BoundTyKind,
1459}
1460
3dfed10e 1461#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
ba9703b0 1462#[derive(HashStable)]
a1dfa0c6 1463pub enum BoundTyKind {
353b0b11 1464 Anon,
9ffffee4
FG
1465 Param(DefId, Symbol),
1466}
1467
a1dfa0c6
XL
1468impl From<BoundVar> for BoundTy {
1469 fn from(var: BoundVar) -> Self {
353b0b11 1470 BoundTy { var, kind: BoundTyKind::Anon }
a1dfa0c6
XL
1471 }
1472}
0bf4aa26 1473
9e0c209e 1474/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
3dfed10e 1475#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
f2b60f7d 1476#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
9e0c209e 1477pub struct ExistentialProjection<'tcx> {
9c376795 1478 pub def_id: DefId,
532ac7d7 1479 pub substs: SubstsRef<'tcx>,
5099ac24 1480 pub term: Term<'tcx>,
e9174d1e
SL
1481}
1482
cdc7bbd5 1483pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>;
9e0c209e 1484
dc9dc135 1485impl<'tcx> ExistentialProjection<'tcx> {
041b39d2
XL
1486 /// Extracts the underlying existential trait reference from this projection.
1487 /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
94222f64 1488 /// then this function would return an `exists T. T: Iterator` existential trait
041b39d2 1489 /// reference.
6a06907d 1490 pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
9c376795 1491 let def_id = tcx.parent(self.def_id);
6a06907d 1492 let subst_count = tcx.generics_of(def_id).count() - 1;
9ffffee4 1493 let substs = tcx.mk_substs(&self.substs[..subst_count]);
6a06907d 1494 ty::ExistentialTraitRef { def_id, substs }
9e0c209e
SL
1495 }
1496
dc9dc135
XL
1497 pub fn with_self_ty(
1498 &self,
1499 tcx: TyCtxt<'tcx>,
1500 self_ty: Ty<'tcx>,
1501 ) -> ty::ProjectionPredicate<'tcx> {
9e0c209e 1502 // otherwise the escaping regions would be captured by the binders
a1dfa0c6 1503 debug_assert!(!self_ty.has_escaping_bound_vars());
9e0c209e 1504
476ff2be 1505 ty::ProjectionPredicate {
9c376795
FG
1506 projection_ty: tcx
1507 .mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs)),
5099ac24 1508 term: self.term,
476ff2be 1509 }
e9174d1e 1510 }
6a06907d
XL
1511
1512 pub fn erase_self_ty(
1513 tcx: TyCtxt<'tcx>,
1514 projection_predicate: ty::ProjectionPredicate<'tcx>,
1515 ) -> Self {
1516 // Assert there is a Self.
1517 projection_predicate.projection_ty.substs.type_at(0);
1518
1519 Self {
9c376795 1520 def_id: projection_predicate.projection_ty.def_id,
9ffffee4 1521 substs: tcx.mk_substs(&projection_predicate.projection_ty.substs[1..]),
5099ac24 1522 term: projection_predicate.term,
6a06907d
XL
1523 }
1524 }
e9174d1e
SL
1525}
1526
dc9dc135
XL
1527impl<'tcx> PolyExistentialProjection<'tcx> {
1528 pub fn with_self_ty(
1529 &self,
1530 tcx: TyCtxt<'tcx>,
1531 self_ty: Ty<'tcx>,
1532 ) -> ty::PolyProjectionPredicate<'tcx> {
476ff2be 1533 self.map_bound(|p| p.with_self_ty(tcx, self_ty))
e9174d1e 1534 }
83c7162d
XL
1535
1536 pub fn item_def_id(&self) -> DefId {
9c376795 1537 self.skip_binder().def_id
83c7162d 1538 }
e9174d1e
SL
1539}
1540
7cac9316 1541/// Region utilities
5099ac24 1542impl<'tcx> Region<'tcx> {
923072b8 1543 pub fn kind(self) -> RegionKind<'tcx> {
5099ac24
FG
1544 *self.0.0
1545 }
1546
2b03887a
FG
1547 pub fn get_name(self) -> Option<Symbol> {
1548 if self.has_name() {
353b0b11 1549 match *self {
2b03887a
FG
1550 ty::ReEarlyBound(ebr) => Some(ebr.name),
1551 ty::ReLateBound(_, br) => br.kind.get_name(),
1552 ty::ReFree(fr) => fr.bound_region.get_name(),
1553 ty::ReStatic => Some(kw::StaticLifetime),
353b0b11 1554 ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
2b03887a 1555 _ => None,
353b0b11
FG
1556 }
1557 } else {
1558 None
2b03887a 1559 }
353b0b11 1560 }
2b03887a 1561
353b0b11
FG
1562 pub fn get_name_or_anon(self) -> Symbol {
1563 match self.get_name() {
1564 Some(name) => name,
1565 None => sym::anon,
1566 }
2b03887a
FG
1567 }
1568
0bf4aa26 1569 /// Is this region named by the user?
5099ac24 1570 pub fn has_name(self) -> bool {
0bf4aa26 1571 match *self {
5099ac24
FG
1572 ty::ReEarlyBound(ebr) => ebr.has_name(),
1573 ty::ReLateBound(_, br) => br.kind.is_named(),
1574 ty::ReFree(fr) => fr.bound_region.is_named(),
1575 ty::ReStatic => true,
1576 ty::ReVar(..) => false,
353b0b11 1577 ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
5099ac24 1578 ty::ReErased => false,
9ffffee4 1579 ty::ReError(_) => false,
0bf4aa26
XL
1580 }
1581 }
1582
9ffffee4
FG
1583 #[inline]
1584 pub fn is_error(self) -> bool {
1585 matches!(*self, ty::ReError(_))
1586 }
1587
6a06907d 1588 #[inline]
5099ac24
FG
1589 pub fn is_static(self) -> bool {
1590 matches!(*self, ty::ReStatic)
1591 }
1592
1593 #[inline]
1594 pub fn is_erased(self) -> bool {
1595 matches!(*self, ty::ReErased)
1596 }
1597
1598 #[inline]
1599 pub fn is_late_bound(self) -> bool {
fc512014 1600 matches!(*self, ty::ReLateBound(..))
e9174d1e
SL
1601 }
1602
6a06907d 1603 #[inline]
5099ac24 1604 pub fn is_placeholder(self) -> bool {
fc512014 1605 matches!(*self, ty::RePlaceholder(..))
0731742a
XL
1606 }
1607
5099ac24
FG
1608 #[inline]
1609 pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
e9174d1e 1610 match *self {
94b46f34 1611 ty::ReLateBound(debruijn, _) => debruijn >= index,
e9174d1e
SL
1612 _ => false,
1613 }
1614 }
1615
5099ac24 1616 pub fn type_flags(self) -> TypeFlags {
c30ab7b3
SL
1617 let mut flags = TypeFlags::empty();
1618
1619 match *self {
1620 ty::ReVar(..) => {
5099ac24
FG
1621 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1622 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
c30ab7b3 1623 flags = flags | TypeFlags::HAS_RE_INFER;
c30ab7b3 1624 }
0bf4aa26 1625 ty::RePlaceholder(..) => {
5099ac24
FG
1626 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1627 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
a1dfa0c6 1628 flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
c30ab7b3 1629 }
ff7c6d11 1630 ty::ReEarlyBound(..) => {
5099ac24
FG
1631 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1632 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
1633 flags = flags | TypeFlags::HAS_RE_PARAM;
ff7c6d11 1634 }
f9f354fc 1635 ty::ReFree { .. } => {
5099ac24
FG
1636 flags = flags | TypeFlags::HAS_FREE_REGIONS;
1637 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
74b04a01 1638 }
f2b60f7d 1639 ty::ReStatic => {
5099ac24 1640 flags = flags | TypeFlags::HAS_FREE_REGIONS;
ff7c6d11 1641 }
74b04a01
XL
1642 ty::ReLateBound(..) => {
1643 flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
1644 }
1645 ty::ReErased => {
1646 flags = flags | TypeFlags::HAS_RE_ERASED;
1647 }
9ffffee4 1648 ty::ReError(_) => {}
c30ab7b3
SL
1649 }
1650
1651 debug!("type_flags({:?}) = {:?}", self, flags);
1652
1653 flags
1654 }
abe05a73 1655
9fa01778 1656 /// Given an early-bound or free region, returns the `DefId` where it was bound.
abe05a73
XL
1657 /// For example, consider the regions in this snippet of code:
1658 ///
04454e1e 1659 /// ```ignore (illustrative)
abe05a73 1660 /// impl<'a> Foo {
04454e1e 1661 /// // ^^ -- early bound, declared on an impl
abe05a73
XL
1662 ///
1663 /// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
04454e1e
FG
1664 /// // ^^ ^^ ^ anonymous, late-bound
1665 /// // | early-bound, appears in where-clauses
1666 /// // late-bound, appears only in fn args
abe05a73
XL
1667 /// {..}
1668 /// }
1669 /// ```
1670 ///
9fa01778 1671 /// Here, `free_region_binding_scope('a)` would return the `DefId`
abe05a73 1672 /// of the impl, and for all the other highlighted regions, it
9fa01778
XL
1673 /// would return the `DefId` of the function. In other cases (not shown), this
1674 /// function might return the `DefId` of a closure.
5099ac24
FG
1675 pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
1676 match *self {
04454e1e 1677 ty::ReEarlyBound(br) => tcx.parent(br.def_id),
abe05a73
XL
1678 ty::ReFree(fr) => fr.scope,
1679 _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
1680 }
1681 }
064997fb
FG
1682
1683 /// True for free regions other than `'static`.
1684 pub fn is_free(self) -> bool {
1685 matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_))
1686 }
1687
1688 /// True if `self` is a free region or static.
1689 pub fn is_free_or_static(self) -> bool {
1690 match *self {
1691 ty::ReStatic => true,
1692 _ => self.is_free(),
1693 }
1694 }
f2b60f7d
FG
1695
1696 pub fn is_var(self) -> bool {
1697 matches!(self.kind(), ty::ReVar(_))
1698 }
9ffffee4 1699
353b0b11 1700 pub fn as_var(self) -> RegionVid {
9ffffee4 1701 match self.kind() {
353b0b11
FG
1702 ty::ReVar(vid) => vid,
1703 _ => bug!("expected region {:?} to be of kind ReVar", self),
9ffffee4
FG
1704 }
1705 }
e9174d1e
SL
1706}
1707
7cac9316 1708/// Type utilities
5099ac24 1709impl<'tcx> Ty<'tcx> {
1b1a35ee 1710 #[inline(always)]
5099ac24 1711 pub fn kind(self) -> &'tcx TyKind<'tcx> {
487cf647 1712 &self.0.0
1b1a35ee
XL
1713 }
1714
1715 #[inline(always)]
5099ac24
FG
1716 pub fn flags(self) -> TypeFlags {
1717 self.0.0.flags
1b1a35ee
XL
1718 }
1719
dc9dc135 1720 #[inline]
5099ac24 1721 pub fn is_unit(self) -> bool {
1b1a35ee 1722 match self.kind() {
b7449926 1723 Tuple(ref tys) => tys.is_empty(),
cc61c64b 1724 _ => false,
e9174d1e
SL
1725 }
1726 }
1727
dc9dc135 1728 #[inline]
5099ac24 1729 pub fn is_never(self) -> bool {
29967ef6 1730 matches!(self.kind(), Never)
5bcae85e
SL
1731 }
1732
dc9dc135 1733 #[inline]
5099ac24 1734 pub fn is_primitive(self) -> bool {
1b1a35ee
XL
1735 self.kind().is_primitive()
1736 }
1737
1738 #[inline]
5099ac24 1739 pub fn is_adt(self) -> bool {
29967ef6 1740 matches!(self.kind(), Adt(..))
1b1a35ee
XL
1741 }
1742
1743 #[inline]
5099ac24 1744 pub fn is_ref(self) -> bool {
29967ef6 1745 matches!(self.kind(), Ref(..))
8bb4bdeb
XL
1746 }
1747
a1dfa0c6 1748 #[inline]
5099ac24 1749 pub fn is_ty_var(self) -> bool {
29967ef6 1750 matches!(self.kind(), Infer(TyVar(_)))
9cc50fc6
SL
1751 }
1752
c295e0f8 1753 #[inline]
5099ac24 1754 pub fn ty_vid(self) -> Option<ty::TyVid> {
c295e0f8
XL
1755 match self.kind() {
1756 &Infer(TyVar(vid)) => Some(vid),
1757 _ => None,
1758 }
1759 }
1760
dc9dc135 1761 #[inline]
9c376795 1762 pub fn is_ty_or_numeric_infer(self) -> bool {
29967ef6 1763 matches!(self.kind(), Infer(_))
e9174d1e
SL
1764 }
1765
dc9dc135 1766 #[inline]
5099ac24 1767 pub fn is_phantom_data(self) -> bool {
1b1a35ee 1768 if let Adt(def, _) = self.kind() { def.is_phantom_data() } else { false }
b039eaaf
SL
1769 }
1770
dc9dc135 1771 #[inline]
5099ac24 1772 pub fn is_bool(self) -> bool {
1b1a35ee 1773 *self.kind() == Bool
dfeec247 1774 }
e74abb32
XL
1775
1776 /// Returns `true` if this type is a `str`.
1777 #[inline]
5099ac24 1778 pub fn is_str(self) -> bool {
1b1a35ee 1779 *self.kind() == Str
dfeec247 1780 }
e9174d1e 1781
dc9dc135 1782 #[inline]
5099ac24 1783 pub fn is_param(self, index: u32) -> bool {
1b1a35ee 1784 match self.kind() {
48663c56 1785 ty::Param(ref data) => data.index == index,
e9174d1e
SL
1786 _ => false,
1787 }
1788 }
1789
dc9dc135 1790 #[inline]
5099ac24 1791 pub fn is_slice(self) -> bool {
5e7ed085
FG
1792 matches!(self.kind(), Slice(_))
1793 }
1794
1795 #[inline]
1796 pub fn is_array_slice(self) -> bool {
1b1a35ee 1797 match self.kind() {
5e7ed085
FG
1798 Slice(_) => true,
1799 RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => matches!(ty.kind(), Slice(_)),
dfeec247 1800 _ => false,
e9174d1e
SL
1801 }
1802 }
1803
1b1a35ee 1804 #[inline]
5099ac24 1805 pub fn is_array(self) -> bool {
29967ef6 1806 matches!(self.kind(), Array(..))
1b1a35ee
XL
1807 }
1808
e9174d1e 1809 #[inline]
5099ac24 1810 pub fn is_simd(self) -> bool {
1b1a35ee 1811 match self.kind() {
5e7ed085 1812 Adt(def, _) => def.repr().simd(),
cc61c64b 1813 _ => false,
e9174d1e
SL
1814 }
1815 }
1816
5099ac24 1817 pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
1b1a35ee 1818 match self.kind() {
5099ac24
FG
1819 Array(ty, _) | Slice(ty) => *ty,
1820 Str => tcx.types.u8,
60c5eb7d 1821 _ => bug!("`sequence_element_type` called on non-sequence value: {}", self),
e9174d1e
SL
1822 }
1823 }
1824
5099ac24 1825 pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
1b1a35ee 1826 match self.kind() {
60c5eb7d 1827 Adt(def, substs) => {
5e7ed085 1828 assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
60c5eb7d 1829 let variant = def.non_enum_variant();
353b0b11 1830 let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, substs);
fc512014
XL
1831
1832 match f0_ty.kind() {
3c0e092e
XL
1833 // If the first field is an array, we assume it is the only field and its
1834 // elements are the SIMD components.
fc512014
XL
1835 Array(f0_elem_ty, f0_len) => {
1836 // FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112
1837 // The way we evaluate the `N` in `[T; N]` here only works since we use
1838 // `simd_size_and_type` post-monomorphization. It will probably start to ICE
1839 // if we use it in generic code. See the `simd-array-trait` ui test.
353b0b11 1840 (f0_len.eval_target_usize(tcx, ParamEnv::empty()), *f0_elem_ty)
fc512014 1841 }
3c0e092e
XL
1842 // Otherwise, the fields of this Adt are the SIMD components (and we assume they
1843 // all have the same type).
fc512014
XL
1844 _ => (variant.fields.len() as u64, f0_ty),
1845 }
60c5eb7d
XL
1846 }
1847 _ => bug!("`simd_size_and_type` called on invalid type"),
e9174d1e
SL
1848 }
1849 }
1850
dc9dc135 1851 #[inline]
5099ac24 1852 pub fn is_mutable_ptr(self) -> bool {
29967ef6
XL
1853 matches!(
1854 self.kind(),
dfeec247 1855 RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. })
29967ef6
XL
1856 | Ref(_, _, hir::Mutability::Mut)
1857 )
32a655c1
SL
1858 }
1859
6a06907d
XL
1860 /// Get the mutability of the reference or `None` when not a reference
1861 #[inline]
5099ac24 1862 pub fn ref_mutability(self) -> Option<hir::Mutability> {
6a06907d
XL
1863 match self.kind() {
1864 Ref(_, _, mutability) => Some(*mutability),
1865 _ => None,
1866 }
1867 }
1868
dc9dc135 1869 #[inline]
5099ac24 1870 pub fn is_unsafe_ptr(self) -> bool {
29967ef6 1871 matches!(self.kind(), RawPtr(_))
e9174d1e
SL
1872 }
1873
416331ca
XL
1874 /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
1875 #[inline]
5099ac24 1876 pub fn is_any_ptr(self) -> bool {
353b0b11 1877 self.is_ref() || self.is_unsafe_ptr() || self.is_fn_ptr()
416331ca
XL
1878 }
1879
dc9dc135 1880 #[inline]
5099ac24 1881 pub fn is_box(self) -> bool {
1b1a35ee 1882 match self.kind() {
b7449926 1883 Adt(def, _) => def.is_box(),
32a655c1
SL
1884 _ => false,
1885 }
1886 }
1887
60c5eb7d 1888 /// Panics if called on any type other than `Box<T>`.
5099ac24 1889 pub fn boxed_ty(self) -> Ty<'tcx> {
1b1a35ee 1890 match self.kind() {
b7449926 1891 Adt(def, substs) if def.is_box() => substs.type_at(0),
32a655c1 1892 _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
e9174d1e
SL
1893 }
1894 }
1895
7cac9316 1896 /// A scalar type is one that denotes an atomic datum, with no sub-components.
b7449926 1897 /// (A RawPtr is scalar because it represents a non-managed pointer, so its
7cac9316 1898 /// contents are abstract to rustc.)
dc9dc135 1899 #[inline]
5099ac24 1900 pub fn is_scalar(self) -> bool {
29967ef6
XL
1901 matches!(
1902 self.kind(),
5869c6ff
XL
1903 Bool | Char
1904 | Int(_)
1905 | Float(_)
1906 | Uint(_)
1907 | FnDef(..)
1908 | FnPtr(_)
1909 | RawPtr(_)
1910 | Infer(IntVar(_) | FloatVar(_))
29967ef6 1911 )
e9174d1e
SL
1912 }
1913
9fa01778 1914 /// Returns `true` if this type is a floating point type.
dc9dc135 1915 #[inline]
5099ac24 1916 pub fn is_floating_point(self) -> bool {
29967ef6 1917 matches!(self.kind(), Float(_) | Infer(FloatVar(_)))
e9174d1e
SL
1918 }
1919
dc9dc135 1920 #[inline]
5099ac24 1921 pub fn is_trait(self) -> bool {
f2b60f7d
FG
1922 matches!(self.kind(), Dynamic(_, _, ty::Dyn))
1923 }
1924
1925 #[inline]
1926 pub fn is_dyn_star(self) -> bool {
1927 matches!(self.kind(), Dynamic(_, _, ty::DynStar))
e9174d1e
SL
1928 }
1929
dc9dc135 1930 #[inline]
5099ac24 1931 pub fn is_enum(self) -> bool {
17df50a5
XL
1932 matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum())
1933 }
1934
1935 #[inline]
5099ac24 1936 pub fn is_union(self) -> bool {
17df50a5 1937 matches!(self.kind(), Adt(adt_def, _) if adt_def.is_union())
ff7c6d11
XL
1938 }
1939
dc9dc135 1940 #[inline]
5099ac24 1941 pub fn is_closure(self) -> bool {
29967ef6 1942 matches!(self.kind(), Closure(..))
7cac9316
XL
1943 }
1944
dc9dc135 1945 #[inline]
5099ac24 1946 pub fn is_generator(self) -> bool {
29967ef6 1947 matches!(self.kind(), Generator(..))
ff7c6d11
XL
1948 }
1949
a1dfa0c6 1950 #[inline]
5099ac24 1951 pub fn is_integral(self) -> bool {
29967ef6 1952 matches!(self.kind(), Infer(IntVar(_)) | Int(_) | Uint(_))
e9174d1e
SL
1953 }
1954
dc9dc135 1955 #[inline]
5099ac24 1956 pub fn is_fresh_ty(self) -> bool {
29967ef6 1957 matches!(self.kind(), Infer(FreshTy(_)))
ff7c6d11
XL
1958 }
1959
dc9dc135 1960 #[inline]
5099ac24 1961 pub fn is_fresh(self) -> bool {
29967ef6 1962 matches!(self.kind(), Infer(FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_)))
e9174d1e
SL
1963 }
1964
dc9dc135 1965 #[inline]
5099ac24 1966 pub fn is_char(self) -> bool {
29967ef6 1967 matches!(self.kind(), Char)
e9174d1e
SL
1968 }
1969
a1dfa0c6 1970 #[inline]
5099ac24 1971 pub fn is_numeric(self) -> bool {
dc9dc135 1972 self.is_integral() || self.is_floating_point()
e9174d1e
SL
1973 }
1974
dc9dc135 1975 #[inline]
5099ac24 1976 pub fn is_signed(self) -> bool {
29967ef6 1977 matches!(self.kind(), Int(_))
e9174d1e
SL
1978 }
1979
dc9dc135 1980 #[inline]
5099ac24 1981 pub fn is_ptr_sized_integral(self) -> bool {
5869c6ff 1982 matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize))
0731742a
XL
1983 }
1984
dc9dc135 1985 #[inline]
5099ac24 1986 pub fn has_concrete_skeleton(self) -> bool {
29967ef6 1987 !matches!(self.kind(), Param(_) | Infer(_) | Error(_))
54a0048b
SL
1988 }
1989
5099ac24
FG
1990 /// Checks whether a type recursively contains another type
1991 ///
1992 /// Example: `Option<()>` contains `()`
1993 pub fn contains(self, other: Ty<'tcx>) -> bool {
1994 struct ContainsTyVisitor<'tcx>(Ty<'tcx>);
1995
9ffffee4 1996 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor<'tcx> {
5099ac24
FG
1997 type BreakTy = ();
1998
1999 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
9c376795 2000 if self.0 == t { ControlFlow::Break(()) } else { t.super_visit_with(self) }
5099ac24
FG
2001 }
2002 }
2003
2004 let cf = self.visit_with(&mut ContainsTyVisitor(other));
2005 cf.is_break()
2006 }
2007
9ffffee4
FG
2008 /// Checks whether a type recursively contains any closure
2009 ///
2010 /// Example: `Option<[closure@file.rs:4:20]>` returns true
2011 pub fn contains_closure(self) -> bool {
2012 struct ContainsClosureVisitor;
2013
2014 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsClosureVisitor {
2015 type BreakTy = ();
2016
2017 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
2018 if let ty::Closure(_, _) = t.kind() {
2019 ControlFlow::Break(())
2020 } else {
2021 t.super_visit_with(self)
2022 }
2023 }
2024 }
2025
2026 let cf = self.visit_with(&mut ContainsClosureVisitor);
2027 cf.is_break()
2028 }
2029
0731742a 2030 /// Returns the type and mutability of `*ty`.
7cac9316
XL
2031 ///
2032 /// The parameter `explicit` indicates if this is an *explicit* dereference.
0731742a 2033 /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
5099ac24 2034 pub fn builtin_deref(self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
1b1a35ee 2035 match self.kind() {
b7449926 2036 Adt(def, _) if def.is_box() => {
dfeec247
XL
2037 Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not })
2038 }
5099ac24 2039 Ref(_, ty, mutbl) => Some(TypeAndMut { ty: *ty, mutbl: *mutbl }),
1b1a35ee 2040 RawPtr(mt) if explicit => Some(*mt),
cc61c64b 2041 _ => None,
e9174d1e
SL
2042 }
2043 }
2044
83c7162d 2045 /// Returns the type of `ty[i]`.
5099ac24 2046 pub fn builtin_index(self) -> Option<Ty<'tcx>> {
1b1a35ee 2047 match self.kind() {
5099ac24 2048 Array(ty, _) | Slice(ty) => Some(*ty),
cc61c64b 2049 _ => None,
e9174d1e
SL
2050 }
2051 }
2052
5099ac24 2053 pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
1b1a35ee 2054 match self.kind() {
9ffffee4 2055 FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs),
1b1a35ee 2056 FnPtr(f) => *f,
f035d41b 2057 Error(_) => {
dfeec247 2058 // ignore errors (#54954)
48663c56
XL
2059 ty::Binder::dummy(FnSig::fake())
2060 }
ba9703b0
XL
2061 Closure(..) => bug!(
2062 "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
2063 ),
dfeec247 2064 _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
e9174d1e
SL
2065 }
2066 }
2067
dc9dc135 2068 #[inline]
5099ac24 2069 pub fn is_fn(self) -> bool {
29967ef6 2070 matches!(self.kind(), FnDef(..) | FnPtr(_))
e9174d1e
SL
2071 }
2072
dc9dc135 2073 #[inline]
5099ac24 2074 pub fn is_fn_ptr(self) -> bool {
29967ef6 2075 matches!(self.kind(), FnPtr(_))
dc9dc135
XL
2076 }
2077
2078 #[inline]
5099ac24 2079 pub fn is_impl_trait(self) -> bool {
9c376795 2080 matches!(self.kind(), Alias(ty::Opaque, ..))
e9174d1e
SL
2081 }
2082
a1dfa0c6 2083 #[inline]
5e7ed085 2084 pub fn ty_adt_def(self) -> Option<AdtDef<'tcx>> {
1b1a35ee 2085 match self.kind() {
5e7ed085 2086 Adt(adt, _) => Some(*adt),
cc61c64b 2087 _ => None,
e9174d1e
SL
2088 }
2089 }
2090
416331ca
XL
2091 /// Iterates over tuple fields.
2092 /// Panics when called on anything but a tuple.
5e7ed085
FG
2093 #[inline]
2094 pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> {
fc512014 2095 match self.kind() {
5e7ed085 2096 Tuple(substs) => substs,
fc512014
XL
2097 _ => bug!("tuple_fields called on non-tuple"),
2098 }
2099 }
2100
48663c56 2101 /// If the type contains variants, returns the valid range of variant indices.
60c5eb7d
XL
2102 //
2103 // FIXME: This requires the optimized MIR in the case of generators.
48663c56 2104 #[inline]
5099ac24 2105 pub fn variant_range(self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
1b1a35ee 2106 match self.kind() {
48663c56 2107 TyKind::Adt(adt, _) => Some(adt.variant_range()),
dfeec247 2108 TyKind::Generator(def_id, substs, _) => {
1b1a35ee 2109 Some(substs.as_generator().variant_range(*def_id, tcx))
dfeec247 2110 }
48663c56
XL
2111 _ => None,
2112 }
2113 }
2114
2115 /// If the type contains variants, returns the variant for `variant_index`.
2116 /// Panics if `variant_index` is out of range.
60c5eb7d
XL
2117 //
2118 // FIXME: This requires the optimized MIR in the case of generators.
48663c56
XL
2119 #[inline]
2120 pub fn discriminant_for_variant(
5099ac24 2121 self,
dc9dc135
XL
2122 tcx: TyCtxt<'tcx>,
2123 variant_index: VariantIdx,
48663c56 2124 ) -> Option<Discr<'tcx>> {
1b1a35ee 2125 match self.kind() {
5e7ed085 2126 TyKind::Adt(adt, _) if adt.variants().is_empty() => {
3c0e092e
XL
2127 // This can actually happen during CTFE, see
2128 // https://github.com/rust-lang/rust/issues/89765.
2129 None
f035d41b 2130 }
f9f354fc
XL
2131 TyKind::Adt(adt, _) if adt.is_enum() => {
2132 Some(adt.discriminant_for_variant(tcx, variant_index))
2133 }
dfeec247 2134 TyKind::Generator(def_id, substs, _) => {
1b1a35ee 2135 Some(substs.as_generator().discriminant_for_variant(*def_id, tcx, variant_index))
dfeec247 2136 }
48663c56
XL
2137 _ => None,
2138 }
2139 }
2140
f9f354fc 2141 /// Returns the type of the discriminant of this type.
5099ac24 2142 pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
1b1a35ee 2143 match self.kind() {
5e7ed085 2144 ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx),
f9f354fc 2145 ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
fc512014 2146
9c376795 2147 ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
3c0e092e
XL
2148 let assoc_items = tcx.associated_item_def_ids(
2149 tcx.require_lang_item(hir::LangItem::DiscriminantKind, None),
2150 );
9ffffee4 2151 tcx.mk_projection(assoc_items[0], tcx.mk_substs(&[self.into()]))
fc512014
XL
2152 }
2153
2154 ty::Bool
2155 | ty::Char
2156 | ty::Int(_)
2157 | ty::Uint(_)
2158 | ty::Float(_)
2159 | ty::Adt(..)
2160 | ty::Foreign(_)
2161 | ty::Str
2162 | ty::Array(..)
2163 | ty::Slice(_)
2164 | ty::RawPtr(_)
2165 | ty::Ref(..)
2166 | ty::FnDef(..)
2167 | ty::FnPtr(..)
2168 | ty::Dynamic(..)
2169 | ty::Closure(..)
2170 | ty::GeneratorWitness(..)
9ffffee4 2171 | ty::GeneratorWitnessMIR(..)
fc512014
XL
2172 | ty::Never
2173 | ty::Tuple(_)
2174 | ty::Error(_)
2175 | ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8,
2176
2177 ty::Bound(..)
2178 | ty::Placeholder(_)
2179 | ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
2180 bug!("`discriminant_ty` applied to unexpected type: {:?}", self)
f9f354fc
XL
2181 }
2182 }
2183 }
2184
5e7ed085
FG
2185 /// Returns the type of metadata for (potentially fat) pointers to this type,
2186 /// and a boolean signifying if this is conditional on this type being `Sized`.
5099ac24
FG
2187 pub fn ptr_metadata_ty(
2188 self,
2189 tcx: TyCtxt<'tcx>,
2190 normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
5e7ed085 2191 ) -> (Ty<'tcx>, bool) {
04454e1e 2192 let tail = tcx.struct_tail_with_normalize(self, normalize, || {});
6a06907d
XL
2193 match tail.kind() {
2194 // Sized types
2195 ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
2196 | ty::Uint(_)
2197 | ty::Int(_)
2198 | ty::Bool
2199 | ty::Float(_)
2200 | ty::FnDef(..)
2201 | ty::FnPtr(_)
2202 | ty::RawPtr(..)
2203 | ty::Char
2204 | ty::Ref(..)
2205 | ty::Generator(..)
2206 | ty::GeneratorWitness(..)
9ffffee4 2207 | ty::GeneratorWitnessMIR(..)
6a06907d
XL
2208 | ty::Array(..)
2209 | ty::Closure(..)
2210 | ty::Never
2211 | ty::Error(_)
5e7ed085 2212 // Extern types have metadata = ().
6a06907d
XL
2213 | ty::Foreign(..)
2214 // If returned by `struct_tail_without_normalization` this is a unit struct
2215 // without any fields, or not a struct, and therefore is Sized.
2216 | ty::Adt(..)
2217 // If returned by `struct_tail_without_normalization` this is the empty tuple,
2218 // a.k.a. unit type, which is Sized
5e7ed085 2219 | ty::Tuple(..) => (tcx.types.unit, false),
6a06907d 2220
5e7ed085 2221 ty::Str | ty::Slice(_) => (tcx.types.usize, false),
6a06907d 2222 ty::Dynamic(..) => {
487cf647 2223 let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
9ffffee4 2224 (tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]), false)
6a06907d
XL
2225 },
2226
5e7ed085
FG
2227 // type parameters only have unit metadata if they're sized, so return true
2228 // to make sure we double check this during confirmation
9c376795 2229 ty::Param(_) | ty::Alias(..) => (tcx.types.unit, true),
5e7ed085
FG
2230
2231 ty::Infer(ty::TyVar(_))
6a06907d
XL
2232 | ty::Bound(..)
2233 | ty::Placeholder(..)
2234 | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
5e7ed085 2235 bug!("`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})", self, tail)
6a06907d
XL
2236 }
2237 }
2238 }
2239
ff7c6d11
XL
2240 /// When we create a closure, we record its kind (i.e., what trait
2241 /// it implements) into its `ClosureSubsts` using a type
2242 /// parameter. This is kind of a phantom type, except that the
2243 /// most convenient thing for us to are the integral types. This
2244 /// function converts such a special type into the closure
487cf647 2245 /// kind. To go the other way, use `closure_kind.to_ty(tcx)`.
ff7c6d11
XL
2246 ///
2247 /// Note that during type checking, we use an inference variable
2248 /// to represent the closure kind, because it has not yet been
2b03887a 2249 /// inferred. Once upvar inference (in `rustc_hir_analysis/src/check/upvar.rs`)
ff7c6d11 2250 /// is complete, that type variable will be unified.
5099ac24 2251 pub fn to_opt_closure_kind(self) -> Option<ty::ClosureKind> {
1b1a35ee 2252 match self.kind() {
b7449926 2253 Int(int_ty) => match int_ty {
5869c6ff
XL
2254 ty::IntTy::I8 => Some(ty::ClosureKind::Fn),
2255 ty::IntTy::I16 => Some(ty::ClosureKind::FnMut),
2256 ty::IntTy::I32 => Some(ty::ClosureKind::FnOnce),
ff7c6d11
XL
2257 _ => bug!("cannot convert type `{:?}` to a closure kind", self),
2258 },
2259
e74abb32
XL
2260 // "Bound" types appear in canonical queries when the
2261 // closure type is not yet known
2262 Bound(..) | Infer(_) => None,
ff7c6d11 2263
f035d41b 2264 Error(_) => Some(ty::ClosureKind::Fn),
ff7c6d11
XL
2265
2266 _ => bug!("cannot convert type `{:?}` to a closure kind", self),
2267 }
2268 }
b7449926
XL
2269
2270 /// Fast path helper for testing if a type is `Sized`.
2271 ///
2272 /// Returning true means the type is known to be sized. Returning
2273 /// `false` means nothing -- could be sized, might not be.
1b1a35ee
XL
2274 ///
2275 /// Note that we could never rely on the fact that a type such as `[_]` is
2276 /// trivially `!Sized` because we could be in a type environment with a
2277 /// bound such as `[_]: Copy`. A function with such a bound obviously never
2278 /// can be called, but that doesn't mean it shouldn't typecheck. This is why
2279 /// this method doesn't return `Option<bool>`.
5099ac24 2280 pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool {
1b1a35ee 2281 match self.kind() {
ba9703b0 2282 ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
dfeec247
XL
2283 | ty::Uint(_)
2284 | ty::Int(_)
2285 | ty::Bool
2286 | ty::Float(_)
2287 | ty::FnDef(..)
2288 | ty::FnPtr(_)
2289 | ty::RawPtr(..)
2290 | ty::Char
2291 | ty::Ref(..)
2292 | ty::Generator(..)
2293 | ty::GeneratorWitness(..)
9ffffee4 2294 | ty::GeneratorWitnessMIR(..)
dfeec247
XL
2295 | ty::Array(..)
2296 | ty::Closure(..)
2297 | ty::Never
f035d41b 2298 | ty::Error(_) => true,
dfeec247
XL
2299
2300 ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false,
2301
5e7ed085 2302 ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)),
dfeec247 2303
064997fb 2304 ty::Adt(def, _substs) => def.sized_constraint(tcx).0.is_empty(),
b7449926 2305
9c376795 2306 ty::Alias(..) | ty::Param(_) => false,
b7449926
XL
2307
2308 ty::Infer(ty::TyVar(_)) => false,
2309
dfeec247
XL
2310 ty::Bound(..)
2311 | ty::Placeholder(..)
ba9703b0 2312 | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
dfeec247
XL
2313 bug!("`is_trivially_sized` applied to unexpected type: {:?}", self)
2314 }
b7449926
XL
2315 }
2316 }
5e7ed085
FG
2317
2318 /// Fast path helper for primitives which are always `Copy` and which
2319 /// have a side-effect-free `Clone` impl.
2320 ///
2321 /// Returning true means the type is known to be pure and `Copy+Clone`.
2322 /// Returning `false` means nothing -- could be `Copy`, might not be.
2323 ///
2324 /// This is mostly useful for optimizations, as there are the types
2325 /// on which we can replace cloning with dereferencing.
2326 pub fn is_trivially_pure_clone_copy(self) -> bool {
2327 match self.kind() {
2328 ty::Bool | ty::Char | ty::Never => true,
2329
2330 // These aren't even `Clone`
2331 ty::Str | ty::Slice(..) | ty::Foreign(..) | ty::Dynamic(..) => false,
2332
2b03887a
FG
2333 ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_))
2334 | ty::Int(..)
2335 | ty::Uint(..)
2336 | ty::Float(..) => true,
5e7ed085
FG
2337
2338 // The voldemort ZSTs are fine.
2339 ty::FnDef(..) => true,
2340
2341 ty::Array(element_ty, _len) => element_ty.is_trivially_pure_clone_copy(),
2342
2343 // A 100-tuple isn't "trivial", so doing this only for reasonable sizes.
2344 ty::Tuple(field_tys) => {
2345 field_tys.len() <= 3 && field_tys.iter().all(Self::is_trivially_pure_clone_copy)
2346 }
2347
2348 // Sometimes traits aren't implemented for every ABI or arity,
2349 // because we can't be generic over everything yet.
2350 ty::FnPtr(..) => false,
2351
2352 // Definitely absolutely not copy.
2353 ty::Ref(_, _, hir::Mutability::Mut) => false,
2354
2355 // Thin pointers & thin shared references are pure-clone-copy, but for
2356 // anything with custom metadata it might be more complicated.
2357 ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false,
2358
9ffffee4 2359 ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => false,
5e7ed085
FG
2360
2361 // Might be, but not "trivial" so just giving the safe answer.
9c376795
FG
2362 ty::Adt(..) | ty::Closure(..) => false,
2363
2364 // Needs normalization or revealing to determine, so no is the safe answer.
2365 ty::Alias(..) => false,
5e7ed085 2366
9c376795 2367 ty::Param(..) | ty::Infer(..) | ty::Error(..) => false,
5e7ed085
FG
2368
2369 ty::Bound(..) | ty::Placeholder(..) => {
2370 bug!("`is_trivially_pure_clone_copy` applied to unexpected type: {:?}", self);
2371 }
2372 }
2373 }
2b03887a 2374
487cf647 2375 /// If `self` is a primitive, return its [`Symbol`].
2b03887a
FG
2376 pub fn primitive_symbol(self) -> Option<Symbol> {
2377 match self.kind() {
2378 ty::Bool => Some(sym::bool),
2379 ty::Char => Some(sym::char),
2380 ty::Float(f) => match f {
2381 ty::FloatTy::F32 => Some(sym::f32),
2382 ty::FloatTy::F64 => Some(sym::f64),
2383 },
2384 ty::Int(f) => match f {
2385 ty::IntTy::Isize => Some(sym::isize),
2386 ty::IntTy::I8 => Some(sym::i8),
2387 ty::IntTy::I16 => Some(sym::i16),
2388 ty::IntTy::I32 => Some(sym::i32),
2389 ty::IntTy::I64 => Some(sym::i64),
2390 ty::IntTy::I128 => Some(sym::i128),
2391 },
2392 ty::Uint(f) => match f {
2393 ty::UintTy::Usize => Some(sym::usize),
2394 ty::UintTy::U8 => Some(sym::u8),
2395 ty::UintTy::U16 => Some(sym::u16),
2396 ty::UintTy::U32 => Some(sym::u32),
2397 ty::UintTy::U64 => Some(sym::u64),
2398 ty::UintTy::U128 => Some(sym::u128),
2399 },
2400 _ => None,
2401 }
2402 }
e9174d1e 2403}
17df50a5
XL
2404
2405/// Extra information about why we ended up with a particular variance.
2406/// This is only used to add more information to error messages, and
2407/// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo`
2408/// may lead to confusing notes in error messages, it will never cause
2409/// a miscompilation or unsoundness.
2410///
2411/// When in doubt, use `VarianceDiagInfo::default()`
3c0e092e 2412#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
17df50a5
XL
2413pub enum VarianceDiagInfo<'tcx> {
2414 /// No additional information - this is the default.
2415 /// We will not add any additional information to error messages.
3c0e092e 2416 #[default]
17df50a5 2417 None,
a2a8927a
XL
2418 /// We switched our variance because a generic argument occurs inside
2419 /// the invariant generic argument of another type.
2420 Invariant {
2421 /// The generic type containing the generic parameter
2422 /// that changes the variance (e.g. `*mut T`, `MyStruct<T>`)
17df50a5 2423 ty: Ty<'tcx>,
a2a8927a
XL
2424 /// The index of the generic parameter being used
2425 /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`)
2426 param_index: u32,
17df50a5
XL
2427 },
2428}
2429
17df50a5
XL
2430impl<'tcx> VarianceDiagInfo<'tcx> {
2431 /// Mirrors `Variance::xform` - used to 'combine' the existing
2432 /// and new `VarianceDiagInfo`s when our variance changes.
2433 pub fn xform(self, other: VarianceDiagInfo<'tcx>) -> VarianceDiagInfo<'tcx> {
a2a8927a 2434 // For now, just use the first `VarianceDiagInfo::Invariant` that we see
17df50a5
XL
2435 match self {
2436 VarianceDiagInfo::None => other,
a2a8927a 2437 VarianceDiagInfo::Invariant { .. } => self,
17df50a5
XL
2438 }
2439 }
2440}
353b0b11
FG
2441
2442// Some types are used a lot. Make sure they don't unintentionally get bigger.
2443#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
2444mod size_asserts {
2445 use super::*;
2446 use rustc_data_structures::static_assert_size;
2447 // tidy-alphabetical-start
2448 static_assert_size!(RegionKind<'_>, 28);
2449 static_assert_size!(TyKind<'_>, 32);
2450 // tidy-alphabetical-end
2451}