1 //! This module contains `TyKind` and its major components. 2 3 #![allow(rustc::usage_of_ty_tykind)] 4 5 use crate::infer::canonical::Canonical; 6 use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; 7 use crate::ty::visit::ValidateBoundVars; 8 use crate::ty::InferTy::*; 9 use crate::ty::{ 10 self, AdtDef, Discr, Term, Ty, TyCtxt, TypeFlags, TypeSuperVisitable, TypeVisitable, 11 TypeVisitableExt, TypeVisitor, 12 }; 13 use crate::ty::{List, ParamEnv}; 14 use hir::def::DefKind; 15 use polonius_engine::Atom; 16 use rustc_data_structures::captures::Captures; 17 use rustc_data_structures::intern::Interned; 18 use rustc_error_messages::DiagnosticMessage; 19 use rustc_errors::{DiagnosticArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan}; 20 use rustc_hir as hir; 21 use rustc_hir::def_id::DefId; 22 use rustc_hir::LangItem; 23 use rustc_index::Idx; 24 use rustc_macros::HashStable; 25 use rustc_span::symbol::{kw, sym, Symbol}; 26 use rustc_span::{Span, DUMMY_SP}; 27 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; 28 use rustc_target::spec::abi::{self, Abi}; 29 use std::assert_matches::debug_assert_matches; 30 use std::borrow::Cow; 31 use std::cmp::Ordering; 32 use std::fmt; 33 use std::marker::PhantomData; 34 use std::ops::{ControlFlow, Deref, Range}; 35 use ty::util::IntTypeExt; 36 37 use rustc_type_ir::sty::TyKind::*; 38 use rustc_type_ir::TyKind as IrTyKind; 39 use rustc_type_ir::{CollectAndApply, ConstKind as IrConstKind}; 40 use rustc_type_ir::{DynKind, RegionKind as IrRegionKind}; 41 42 use super::GenericParamDefKind; 43 44 // Re-export the `TyKind` from `rustc_type_ir` here for convenience 45 #[rustc_diagnostic_item = "TyKind"] 46 pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>; 47 pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>; 48 pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>; 49 50 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 51 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] 52 pub struct TypeAndMut<'tcx> { 53 pub ty: Ty<'tcx>, 54 pub mutbl: hir::Mutability, 55 } 56 57 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] 58 #[derive(HashStable)] 59 /// A "free" region `fr` can be interpreted as "some region 60 /// at least as big as the scope `fr.scope`". 61 pub struct FreeRegion { 62 pub scope: DefId, 63 pub bound_region: BoundRegionKind, 64 } 65 66 #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] 67 #[derive(HashStable)] 68 pub enum BoundRegionKind { 69 /// An anonymous region parameter for a given fn (&T) 70 BrAnon(Option<Span>), 71 72 /// Named region parameters for functions (a in &'a T) 73 /// 74 /// The `DefId` is needed to distinguish free regions in 75 /// the event of shadowing. 76 BrNamed(DefId, Symbol), 77 78 /// Anonymous region for the implicit env pointer parameter 79 /// to a closure 80 BrEnv, 81 } 82 83 #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)] 84 #[derive(HashStable)] 85 pub struct BoundRegion { 86 pub var: BoundVar, 87 pub kind: BoundRegionKind, 88 } 89 90 impl BoundRegionKind { is_named(&self) -> bool91 pub fn is_named(&self) -> bool { 92 match *self { 93 BoundRegionKind::BrNamed(_, name) => { 94 name != kw::UnderscoreLifetime && name != kw::Empty 95 } 96 _ => false, 97 } 98 } 99 get_name(&self) -> Option<Symbol>100 pub fn get_name(&self) -> Option<Symbol> { 101 if self.is_named() { 102 match *self { 103 BoundRegionKind::BrNamed(_, name) => return Some(name), 104 _ => unreachable!(), 105 } 106 } 107 108 None 109 } 110 get_id(&self) -> Option<DefId>111 pub fn get_id(&self) -> Option<DefId> { 112 match *self { 113 BoundRegionKind::BrNamed(id, _) => return Some(id), 114 _ => None, 115 } 116 } 117 } 118 119 pub trait Article { article(&self) -> &'static str120 fn article(&self) -> &'static str; 121 } 122 123 impl<'tcx> Article for TyKind<'tcx> { 124 /// Get the article ("a" or "an") to use with this type. article(&self) -> &'static str125 fn article(&self) -> &'static str { 126 match self { 127 Int(_) | Float(_) | Array(_, _) => "an", 128 Adt(def, _) if def.is_enum() => "an", 129 // This should never happen, but ICEing and causing the user's code 130 // to not compile felt too harsh. 131 Error(_) => "a", 132 _ => "a", 133 } 134 } 135 } 136 137 /// A closure can be modeled as a struct that looks like: 138 /// ```ignore (illustrative) 139 /// struct Closure<'l0...'li, T0...Tj, CK, CS, U>(...U); 140 /// ``` 141 /// where: 142 /// 143 /// - 'l0...'li and T0...Tj are the generic parameters 144 /// in scope on the function that defined the closure, 145 /// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This 146 /// is rather hackily encoded via a scalar type. See 147 /// `Ty::to_opt_closure_kind` for details. 148 /// - CS represents the *closure signature*, representing as a `fn()` 149 /// type. For example, `fn(u32, u32) -> u32` would mean that the closure 150 /// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait 151 /// specified above. 152 /// - U is a type parameter representing the types of its upvars, tupled up 153 /// (borrowed, if appropriate; that is, if a U field represents a by-ref upvar, 154 /// and the up-var has the type `Foo`, then that field of U will be `&Foo`). 155 /// 156 /// So, for example, given this function: 157 /// ```ignore (illustrative) 158 /// fn foo<'a, T>(data: &'a mut T) { 159 /// do(|| data.count += 1) 160 /// } 161 /// ``` 162 /// the type of the closure would be something like: 163 /// ```ignore (illustrative) 164 /// struct Closure<'a, T, U>(...U); 165 /// ``` 166 /// Note that the type of the upvar is not specified in the struct. 167 /// You may wonder how the impl would then be able to use the upvar, 168 /// if it doesn't know it's type? The answer is that the impl is 169 /// (conceptually) not fully generic over Closure but rather tied to 170 /// instances with the expected upvar types: 171 /// ```ignore (illustrative) 172 /// impl<'b, 'a, T> FnMut() for Closure<'a, T, (&'b mut &'a mut T,)> { 173 /// ... 174 /// } 175 /// ``` 176 /// You can see that the *impl* fully specified the type of the upvar 177 /// and thus knows full well that `data` has type `&'b mut &'a mut T`. 178 /// (Here, I am assuming that `data` is mut-borrowed.) 179 /// 180 /// Now, the last question you may ask is: Why include the upvar types 181 /// in an extra type parameter? The reason for this design is that the 182 /// upvar types can reference lifetimes that are internal to the 183 /// creating function. In my example above, for example, the lifetime 184 /// `'b` represents the scope of the closure itself; this is some 185 /// subset of `foo`, probably just the scope of the call to the to 186 /// `do()`. If we just had the lifetime/type parameters from the 187 /// enclosing function, we couldn't name this lifetime `'b`. Note that 188 /// there can also be lifetimes in the types of the upvars themselves, 189 /// if one of them happens to be a reference to something that the 190 /// creating fn owns. 191 /// 192 /// OK, you say, so why not create a more minimal set of parameters 193 /// that just includes the extra lifetime parameters? The answer is 194 /// primarily that it would be hard --- we don't know at the time when 195 /// we create the closure type what the full types of the upvars are, 196 /// nor do we know which are borrowed and which are not. In this 197 /// design, we can just supply a fresh type parameter and figure that 198 /// out later. 199 /// 200 /// All right, you say, but why include the type parameters from the 201 /// original function then? The answer is that codegen may need them 202 /// when monomorphizing, and they may not appear in the upvars. A 203 /// closure could capture no variables but still make use of some 204 /// in-scope type parameter with a bound (e.g., if our example above 205 /// had an extra `U: Default`, and the closure called `U::default()`). 206 /// 207 /// There is another reason. This design (implicitly) prohibits 208 /// closures from capturing themselves (except via a trait 209 /// object). This simplifies closure inference considerably, since it 210 /// means that when we infer the kind of a closure or its upvars, we 211 /// don't have to handle cycles where the decisions we make for 212 /// closure C wind up influencing the decisions we ought to make for 213 /// closure C (which would then require fixed point iteration to 214 /// handle). Plus it fixes an ICE. :P 215 /// 216 /// ## Generators 217 /// 218 /// Generators are handled similarly in `GeneratorSubsts`. The set of 219 /// type parameters is similar, but `CK` and `CS` are replaced by the 220 /// following type parameters: 221 /// 222 /// * `GS`: The generator's "resume type", which is the type of the 223 /// argument passed to `resume`, and the type of `yield` expressions 224 /// inside the generator. 225 /// * `GY`: The "yield type", which is the type of values passed to 226 /// `yield` inside the generator. 227 /// * `GR`: The "return type", which is the type of value returned upon 228 /// completion of the generator. 229 /// * `GW`: The "generator witness". 230 #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)] 231 pub struct ClosureSubsts<'tcx> { 232 /// Lifetime and type parameters from the enclosing function, 233 /// concatenated with a tuple containing the types of the upvars. 234 /// 235 /// These are separated out because codegen wants to pass them around 236 /// when monomorphizing. 237 pub substs: SubstsRef<'tcx>, 238 } 239 240 /// Struct returned by `split()`. 241 pub struct ClosureSubstsParts<'tcx, T> { 242 pub parent_substs: &'tcx [GenericArg<'tcx>], 243 pub closure_kind_ty: T, 244 pub closure_sig_as_fn_ptr_ty: T, 245 pub tupled_upvars_ty: T, 246 } 247 248 impl<'tcx> ClosureSubsts<'tcx> { 249 /// Construct `ClosureSubsts` from `ClosureSubstsParts`, containing `Substs` 250 /// for the closure parent, alongside additional closure-specific components. new( tcx: TyCtxt<'tcx>, parts: ClosureSubstsParts<'tcx, Ty<'tcx>>, ) -> ClosureSubsts<'tcx>251 pub fn new( 252 tcx: TyCtxt<'tcx>, 253 parts: ClosureSubstsParts<'tcx, Ty<'tcx>>, 254 ) -> ClosureSubsts<'tcx> { 255 ClosureSubsts { 256 substs: tcx.mk_substs_from_iter( 257 parts.parent_substs.iter().copied().chain( 258 [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty] 259 .iter() 260 .map(|&ty| ty.into()), 261 ), 262 ), 263 } 264 } 265 266 /// Divides the closure substs into their respective components. 267 /// The ordering assumed here must match that used by `ClosureSubsts::new` above. split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>>268 fn split(self) -> ClosureSubstsParts<'tcx, GenericArg<'tcx>> { 269 match self.substs[..] { 270 [ 271 ref parent_substs @ .., 272 closure_kind_ty, 273 closure_sig_as_fn_ptr_ty, 274 tupled_upvars_ty, 275 ] => ClosureSubstsParts { 276 parent_substs, 277 closure_kind_ty, 278 closure_sig_as_fn_ptr_ty, 279 tupled_upvars_ty, 280 }, 281 _ => bug!("closure substs missing synthetics"), 282 } 283 } 284 285 /// Returns `true` only if enough of the synthetic types are known to 286 /// allow using all of the methods on `ClosureSubsts` without panicking. 287 /// 288 /// Used primarily by `ty::print::pretty` to be able to handle closure 289 /// types that haven't had their synthetic types substituted in. is_valid(self) -> bool290 pub fn is_valid(self) -> bool { 291 self.substs.len() >= 3 292 && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_)) 293 } 294 295 /// Returns the substitutions of the closure's parent. parent_substs(self) -> &'tcx [GenericArg<'tcx>]296 pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] { 297 self.split().parent_substs 298 } 299 300 /// Returns an iterator over the list of types of captured paths by the closure. 301 /// In case there was a type error in figuring out the types of the captured path, an 302 /// empty iterator is returned. 303 #[inline] upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx304 pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { 305 match self.tupled_upvars_ty().kind() { 306 TyKind::Error(_) => None, 307 TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), 308 TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), 309 ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), 310 } 311 .into_iter() 312 .flatten() 313 } 314 315 /// Returns the tuple type representing the upvars for this closure. 316 #[inline] tupled_upvars_ty(self) -> Ty<'tcx>317 pub fn tupled_upvars_ty(self) -> Ty<'tcx> { 318 self.split().tupled_upvars_ty.expect_ty() 319 } 320 321 /// Returns the closure kind for this closure; may return a type 322 /// variable during inference. To get the closure kind during 323 /// inference, use `infcx.closure_kind(substs)`. kind_ty(self) -> Ty<'tcx>324 pub fn kind_ty(self) -> Ty<'tcx> { 325 self.split().closure_kind_ty.expect_ty() 326 } 327 328 /// Returns the `fn` pointer type representing the closure signature for this 329 /// closure. 330 // FIXME(eddyb) this should be unnecessary, as the shallowly resolved 331 // type is known at the time of the creation of `ClosureSubsts`, 332 // see `rustc_hir_analysis::check::closure`. sig_as_fn_ptr_ty(self) -> Ty<'tcx>333 pub fn sig_as_fn_ptr_ty(self) -> Ty<'tcx> { 334 self.split().closure_sig_as_fn_ptr_ty.expect_ty() 335 } 336 337 /// Returns the closure kind for this closure; only usable outside 338 /// of an inference context, because in that context we know that 339 /// there are no type variables. 340 /// 341 /// If you have an inference context, use `infcx.closure_kind()`. kind(self) -> ty::ClosureKind342 pub fn kind(self) -> ty::ClosureKind { 343 self.kind_ty().to_opt_closure_kind().unwrap() 344 } 345 346 /// Extracts the signature from the closure. sig(self) -> ty::PolyFnSig<'tcx>347 pub fn sig(self) -> ty::PolyFnSig<'tcx> { 348 let ty = self.sig_as_fn_ptr_ty(); 349 match ty.kind() { 350 ty::FnPtr(sig) => *sig, 351 _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()), 352 } 353 } 354 print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx>355 pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> { 356 ty::print::PrintClosureAsImpl { closure: self } 357 } 358 } 359 360 /// Similar to `ClosureSubsts`; see the above documentation for more. 361 #[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)] 362 pub struct GeneratorSubsts<'tcx> { 363 pub substs: SubstsRef<'tcx>, 364 } 365 366 pub struct GeneratorSubstsParts<'tcx, T> { 367 pub parent_substs: &'tcx [GenericArg<'tcx>], 368 pub resume_ty: T, 369 pub yield_ty: T, 370 pub return_ty: T, 371 pub witness: T, 372 pub tupled_upvars_ty: T, 373 } 374 375 impl<'tcx> GeneratorSubsts<'tcx> { 376 /// Construct `GeneratorSubsts` from `GeneratorSubstsParts`, containing `Substs` 377 /// for the generator parent, alongside additional generator-specific components. new( tcx: TyCtxt<'tcx>, parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>, ) -> GeneratorSubsts<'tcx>378 pub fn new( 379 tcx: TyCtxt<'tcx>, 380 parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>, 381 ) -> GeneratorSubsts<'tcx> { 382 GeneratorSubsts { 383 substs: tcx.mk_substs_from_iter( 384 parts.parent_substs.iter().copied().chain( 385 [ 386 parts.resume_ty, 387 parts.yield_ty, 388 parts.return_ty, 389 parts.witness, 390 parts.tupled_upvars_ty, 391 ] 392 .iter() 393 .map(|&ty| ty.into()), 394 ), 395 ), 396 } 397 } 398 399 /// Divides the generator substs into their respective components. 400 /// The ordering assumed here must match that used by `GeneratorSubsts::new` above. split(self) -> GeneratorSubstsParts<'tcx, GenericArg<'tcx>>401 fn split(self) -> GeneratorSubstsParts<'tcx, GenericArg<'tcx>> { 402 match self.substs[..] { 403 [ref parent_substs @ .., resume_ty, yield_ty, return_ty, witness, tupled_upvars_ty] => { 404 GeneratorSubstsParts { 405 parent_substs, 406 resume_ty, 407 yield_ty, 408 return_ty, 409 witness, 410 tupled_upvars_ty, 411 } 412 } 413 _ => bug!("generator substs missing synthetics"), 414 } 415 } 416 417 /// Returns `true` only if enough of the synthetic types are known to 418 /// allow using all of the methods on `GeneratorSubsts` without panicking. 419 /// 420 /// Used primarily by `ty::print::pretty` to be able to handle generator 421 /// types that haven't had their synthetic types substituted in. is_valid(self) -> bool422 pub fn is_valid(self) -> bool { 423 self.substs.len() >= 5 424 && matches!(self.split().tupled_upvars_ty.expect_ty().kind(), Tuple(_)) 425 } 426 427 /// Returns the substitutions of the generator's parent. parent_substs(self) -> &'tcx [GenericArg<'tcx>]428 pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] { 429 self.split().parent_substs 430 } 431 432 /// This describes the types that can be contained in a generator. 433 /// It will be a type variable initially and unified in the last stages of typeck of a body. 434 /// It contains a tuple of all the types that could end up on a generator frame. 435 /// The state transformation MIR pass may only produce layouts which mention types 436 /// in this tuple. Upvars are not counted here. witness(self) -> Ty<'tcx>437 pub fn witness(self) -> Ty<'tcx> { 438 self.split().witness.expect_ty() 439 } 440 441 /// Returns an iterator over the list of types of captured paths by the generator. 442 /// In case there was a type error in figuring out the types of the captured path, an 443 /// empty iterator is returned. 444 #[inline] upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx445 pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { 446 match self.tupled_upvars_ty().kind() { 447 TyKind::Error(_) => None, 448 TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), 449 TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), 450 ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), 451 } 452 .into_iter() 453 .flatten() 454 } 455 456 /// Returns the tuple type representing the upvars for this generator. 457 #[inline] tupled_upvars_ty(self) -> Ty<'tcx>458 pub fn tupled_upvars_ty(self) -> Ty<'tcx> { 459 self.split().tupled_upvars_ty.expect_ty() 460 } 461 462 /// Returns the type representing the resume type of the generator. resume_ty(self) -> Ty<'tcx>463 pub fn resume_ty(self) -> Ty<'tcx> { 464 self.split().resume_ty.expect_ty() 465 } 466 467 /// Returns the type representing the yield type of the generator. yield_ty(self) -> Ty<'tcx>468 pub fn yield_ty(self) -> Ty<'tcx> { 469 self.split().yield_ty.expect_ty() 470 } 471 472 /// Returns the type representing the return type of the generator. return_ty(self) -> Ty<'tcx>473 pub fn return_ty(self) -> Ty<'tcx> { 474 self.split().return_ty.expect_ty() 475 } 476 477 /// Returns the "generator signature", which consists of its yield 478 /// and return types. 479 /// 480 /// N.B., some bits of the code prefers to see this wrapped in a 481 /// binder, but it never contains bound regions. Probably this 482 /// function should be removed. poly_sig(self) -> PolyGenSig<'tcx>483 pub fn poly_sig(self) -> PolyGenSig<'tcx> { 484 ty::Binder::dummy(self.sig()) 485 } 486 487 /// Returns the "generator signature", which consists of its resume, yield 488 /// and return types. sig(self) -> GenSig<'tcx>489 pub fn sig(self) -> GenSig<'tcx> { 490 ty::GenSig { 491 resume_ty: self.resume_ty(), 492 yield_ty: self.yield_ty(), 493 return_ty: self.return_ty(), 494 } 495 } 496 } 497 498 impl<'tcx> GeneratorSubsts<'tcx> { 499 /// Generator has not been resumed yet. 500 pub const UNRESUMED: usize = 0; 501 /// Generator has returned or is completed. 502 pub const RETURNED: usize = 1; 503 /// Generator has been poisoned. 504 pub const POISONED: usize = 2; 505 506 const UNRESUMED_NAME: &'static str = "Unresumed"; 507 const RETURNED_NAME: &'static str = "Returned"; 508 const POISONED_NAME: &'static str = "Panicked"; 509 510 /// The valid variant indices of this generator. 511 #[inline] variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx>512 pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> { 513 // FIXME requires optimized MIR 514 FIRST_VARIANT..tcx.generator_layout(def_id).unwrap().variant_fields.next_index() 515 } 516 517 /// The discriminant for the given variant. Panics if the `variant_index` is 518 /// out of range. 519 #[inline] discriminant_for_variant( &self, def_id: DefId, tcx: TyCtxt<'tcx>, variant_index: VariantIdx, ) -> Discr<'tcx>520 pub fn discriminant_for_variant( 521 &self, 522 def_id: DefId, 523 tcx: TyCtxt<'tcx>, 524 variant_index: VariantIdx, 525 ) -> Discr<'tcx> { 526 // Generators don't support explicit discriminant values, so they are 527 // the same as the variant index. 528 assert!(self.variant_range(def_id, tcx).contains(&variant_index)); 529 Discr { val: variant_index.as_usize() as u128, ty: self.discr_ty(tcx) } 530 } 531 532 /// The set of all discriminants for the generator, enumerated with their 533 /// variant indices. 534 #[inline] discriminants( self, def_id: DefId, tcx: TyCtxt<'tcx>, ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx>535 pub fn discriminants( 536 self, 537 def_id: DefId, 538 tcx: TyCtxt<'tcx>, 539 ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> { 540 self.variant_range(def_id, tcx).map(move |index| { 541 (index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) }) 542 }) 543 } 544 545 /// Calls `f` with a reference to the name of the enumerator for the given 546 /// variant `v`. variant_name(v: VariantIdx) -> Cow<'static, str>547 pub fn variant_name(v: VariantIdx) -> Cow<'static, str> { 548 match v.as_usize() { 549 Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME), 550 Self::RETURNED => Cow::from(Self::RETURNED_NAME), 551 Self::POISONED => Cow::from(Self::POISONED_NAME), 552 _ => Cow::from(format!("Suspend{}", v.as_usize() - 3)), 553 } 554 } 555 556 /// The type of the state discriminant used in the generator type. 557 #[inline] discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>558 pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 559 tcx.types.u32 560 } 561 562 /// This returns the types of the MIR locals which had to be stored across suspension points. 563 /// It is calculated in rustc_mir_transform::generator::StateTransform. 564 /// All the types here must be in the tuple in GeneratorInterior. 565 /// 566 /// The locals are grouped by their variant number. Note that some locals may 567 /// be repeated in multiple variants. 568 #[inline] state_tys( self, def_id: DefId, tcx: TyCtxt<'tcx>, ) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>> + Captures<'tcx>>569 pub fn state_tys( 570 self, 571 def_id: DefId, 572 tcx: TyCtxt<'tcx>, 573 ) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>> + Captures<'tcx>> { 574 let layout = tcx.generator_layout(def_id).unwrap(); 575 layout.variant_fields.iter().map(move |variant| { 576 variant.iter().map(move |field| { 577 ty::EarlyBinder::bind(layout.field_tys[*field].ty).subst(tcx, self.substs) 578 }) 579 }) 580 } 581 582 /// This is the types of the fields of a generator which are not stored in a 583 /// variant. 584 #[inline] prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>>585 pub fn prefix_tys(self) -> impl Iterator<Item = Ty<'tcx>> { 586 self.upvar_tys() 587 } 588 } 589 590 #[derive(Debug, Copy, Clone, HashStable)] 591 pub enum UpvarSubsts<'tcx> { 592 Closure(SubstsRef<'tcx>), 593 Generator(SubstsRef<'tcx>), 594 } 595 596 impl<'tcx> UpvarSubsts<'tcx> { 597 /// Returns an iterator over the list of types of captured paths by the closure/generator. 598 /// In case there was a type error in figuring out the types of the captured path, an 599 /// empty iterator is returned. 600 #[inline] upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx601 pub fn upvar_tys(self) -> impl Iterator<Item = Ty<'tcx>> + 'tcx { 602 let tupled_tys = match self { 603 UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(), 604 UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(), 605 }; 606 607 match tupled_tys.kind() { 608 TyKind::Error(_) => None, 609 TyKind::Tuple(..) => Some(self.tupled_upvars_ty().tuple_fields()), 610 TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"), 611 ty => bug!("Unexpected representation of upvar types tuple {:?}", ty), 612 } 613 .into_iter() 614 .flatten() 615 } 616 617 #[inline] tupled_upvars_ty(self) -> Ty<'tcx>618 pub fn tupled_upvars_ty(self) -> Ty<'tcx> { 619 match self { 620 UpvarSubsts::Closure(substs) => substs.as_closure().tupled_upvars_ty(), 621 UpvarSubsts::Generator(substs) => substs.as_generator().tupled_upvars_ty(), 622 } 623 } 624 } 625 626 /// An inline const is modeled like 627 /// ```ignore (illustrative) 628 /// const InlineConst<'l0...'li, T0...Tj, R>: R; 629 /// ``` 630 /// where: 631 /// 632 /// - 'l0...'li and T0...Tj are the generic parameters 633 /// inherited from the item that defined the inline const, 634 /// - R represents the type of the constant. 635 /// 636 /// When the inline const is instantiated, `R` is substituted as the actual inferred 637 /// type of the constant. The reason that `R` is represented as an extra type parameter 638 /// is the same reason that [`ClosureSubsts`] have `CS` and `U` as type parameters: 639 /// inline const can reference lifetimes that are internal to the creating function. 640 #[derive(Copy, Clone, Debug)] 641 pub struct InlineConstSubsts<'tcx> { 642 /// Generic parameters from the enclosing item, 643 /// concatenated with the inferred type of the constant. 644 pub substs: SubstsRef<'tcx>, 645 } 646 647 /// Struct returned by `split()`. 648 pub struct InlineConstSubstsParts<'tcx, T> { 649 pub parent_substs: &'tcx [GenericArg<'tcx>], 650 pub ty: T, 651 } 652 653 impl<'tcx> InlineConstSubsts<'tcx> { 654 /// Construct `InlineConstSubsts` from `InlineConstSubstsParts`. new( tcx: TyCtxt<'tcx>, parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>, ) -> InlineConstSubsts<'tcx>655 pub fn new( 656 tcx: TyCtxt<'tcx>, 657 parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>, 658 ) -> InlineConstSubsts<'tcx> { 659 InlineConstSubsts { 660 substs: tcx.mk_substs_from_iter( 661 parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())), 662 ), 663 } 664 } 665 666 /// Divides the inline const substs into their respective components. 667 /// The ordering assumed here must match that used by `InlineConstSubsts::new` above. split(self) -> InlineConstSubstsParts<'tcx, GenericArg<'tcx>>668 fn split(self) -> InlineConstSubstsParts<'tcx, GenericArg<'tcx>> { 669 match self.substs[..] { 670 [ref parent_substs @ .., ty] => InlineConstSubstsParts { parent_substs, ty }, 671 _ => bug!("inline const substs missing synthetics"), 672 } 673 } 674 675 /// Returns the substitutions of the inline const's parent. parent_substs(self) -> &'tcx [GenericArg<'tcx>]676 pub fn parent_substs(self) -> &'tcx [GenericArg<'tcx>] { 677 self.split().parent_substs 678 } 679 680 /// Returns the type of this inline const. ty(self) -> Ty<'tcx>681 pub fn ty(self) -> Ty<'tcx> { 682 self.split().ty.expect_ty() 683 } 684 } 685 686 #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, TyEncodable, TyDecodable)] 687 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] 688 pub enum ExistentialPredicate<'tcx> { 689 /// E.g., `Iterator`. 690 Trait(ExistentialTraitRef<'tcx>), 691 /// E.g., `Iterator::Item = T`. 692 Projection(ExistentialProjection<'tcx>), 693 /// E.g., `Send`. 694 AutoTrait(DefId), 695 } 696 697 impl<'tcx> ExistentialPredicate<'tcx> { 698 /// Compares via an ordering that will not change if modules are reordered or other changes are 699 /// made to the tree. In particular, this ordering is preserved across incremental compilations. stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering700 pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { 701 use self::ExistentialPredicate::*; 702 match (*self, *other) { 703 (Trait(_), Trait(_)) => Ordering::Equal, 704 (Projection(ref a), Projection(ref b)) => { 705 tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id)) 706 } 707 (AutoTrait(ref a), AutoTrait(ref b)) => { 708 tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b)) 709 } 710 (Trait(_), _) => Ordering::Less, 711 (Projection(_), Trait(_)) => Ordering::Greater, 712 (Projection(_), _) => Ordering::Less, 713 (AutoTrait(_), _) => Ordering::Greater, 714 } 715 } 716 } 717 718 pub type PolyExistentialPredicate<'tcx> = Binder<'tcx, ExistentialPredicate<'tcx>>; 719 720 impl<'tcx> PolyExistentialPredicate<'tcx> { 721 /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`), 722 /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` 723 /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example). with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx>724 pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx> { 725 use crate::ty::ToPredicate; 726 match self.skip_binder() { 727 ExistentialPredicate::Trait(tr) => { 728 self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx) 729 } 730 ExistentialPredicate::Projection(p) => { 731 self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) 732 } 733 ExistentialPredicate::AutoTrait(did) => { 734 let generics = tcx.generics_of(did); 735 let trait_ref = if generics.params.len() == 1 { 736 ty::TraitRef::new(tcx, did, [self_ty]) 737 } else { 738 // If this is an ill-formed auto trait, then synthesize 739 // new error substs for the missing generics. 740 let err_substs = 741 ty::InternalSubsts::extend_with_error(tcx, did, &[self_ty.into()]); 742 ty::TraitRef::new(tcx, did, err_substs) 743 }; 744 self.rebind(trait_ref).without_const().to_predicate(tcx) 745 } 746 } 747 } 748 } 749 750 impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> { 751 /// Returns the "principal `DefId`" of this set of existential predicates. 752 /// 753 /// A Rust trait object type consists (in addition to a lifetime bound) 754 /// of a set of trait bounds, which are separated into any number 755 /// of auto-trait bounds, and at most one non-auto-trait bound. The 756 /// non-auto-trait bound is called the "principal" of the trait 757 /// object. 758 /// 759 /// Only the principal can have methods or type parameters (because 760 /// auto traits can have neither of them). This is important, because 761 /// it means the auto traits can be treated as an unordered set (methods 762 /// would force an order for the vtable, while relating traits with 763 /// type parameters without knowing the order to relate them in is 764 /// a rather non-trivial task). 765 /// 766 /// For example, in the trait object `dyn fmt::Debug + Sync`, the 767 /// principal bound is `Some(fmt::Debug)`, while the auto-trait bounds 768 /// are the set `{Sync}`. 769 /// 770 /// It is also possible to have a "trivial" trait object that 771 /// consists only of auto traits, with no principal - for example, 772 /// `dyn Send + Sync`. In that case, the set of auto-trait bounds 773 /// is `{Send, Sync}`, while there is no principal. These trait objects 774 /// have a "trivial" vtable consisting of just the size, alignment, 775 /// and destructor. principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>>776 pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> { 777 self[0] 778 .map_bound(|this| match this { 779 ExistentialPredicate::Trait(tr) => Some(tr), 780 _ => None, 781 }) 782 .transpose() 783 } 784 principal_def_id(&self) -> Option<DefId>785 pub fn principal_def_id(&self) -> Option<DefId> { 786 self.principal().map(|trait_ref| trait_ref.skip_binder().def_id) 787 } 788 789 #[inline] projection_bounds<'a>( &'a self, ) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> + 'a790 pub fn projection_bounds<'a>( 791 &'a self, 792 ) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> + 'a { 793 self.iter().filter_map(|predicate| { 794 predicate 795 .map_bound(|pred| match pred { 796 ExistentialPredicate::Projection(projection) => Some(projection), 797 _ => None, 798 }) 799 .transpose() 800 }) 801 } 802 803 #[inline] auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + Captures<'tcx> + 'a804 pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + Captures<'tcx> + 'a { 805 self.iter().filter_map(|predicate| match predicate.skip_binder() { 806 ExistentialPredicate::AutoTrait(did) => Some(did), 807 _ => None, 808 }) 809 } 810 } 811 812 /// A complete reference to a trait. These take numerous guises in syntax, 813 /// but perhaps the most recognizable form is in a where-clause: 814 /// ```ignore (illustrative) 815 /// T: Foo<U> 816 /// ``` 817 /// This would be represented by a trait-reference where the `DefId` is the 818 /// `DefId` for the trait `Foo` and the substs define `T` as parameter 0, 819 /// and `U` as parameter 1. 820 /// 821 /// Trait references also appear in object types like `Foo<U>`, but in 822 /// that case the `Self` parameter is absent from the substitutions. 823 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 824 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] 825 pub struct TraitRef<'tcx> { 826 pub def_id: DefId, 827 pub substs: SubstsRef<'tcx>, 828 /// This field exists to prevent the creation of `TraitRef` without 829 /// calling [`TraitRef::new`]. 830 pub(super) _use_trait_ref_new_instead: (), 831 } 832 833 impl<'tcx> TraitRef<'tcx> { new( tcx: TyCtxt<'tcx>, trait_def_id: DefId, substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> Self834 pub fn new( 835 tcx: TyCtxt<'tcx>, 836 trait_def_id: DefId, 837 substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, 838 ) -> Self { 839 let substs = tcx.check_and_mk_substs(trait_def_id, substs); 840 Self { def_id: trait_def_id, substs, _use_trait_ref_new_instead: () } 841 } 842 from_lang_item( tcx: TyCtxt<'tcx>, trait_lang_item: LangItem, span: Span, substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, ) -> Self843 pub fn from_lang_item( 844 tcx: TyCtxt<'tcx>, 845 trait_lang_item: LangItem, 846 span: Span, 847 substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, 848 ) -> Self { 849 let trait_def_id = tcx.require_lang_item(trait_lang_item, Some(span)); 850 Self::new(tcx, trait_def_id, substs) 851 } 852 from_method( tcx: TyCtxt<'tcx>, trait_id: DefId, substs: SubstsRef<'tcx>, ) -> ty::TraitRef<'tcx>853 pub fn from_method( 854 tcx: TyCtxt<'tcx>, 855 trait_id: DefId, 856 substs: SubstsRef<'tcx>, 857 ) -> ty::TraitRef<'tcx> { 858 let defs = tcx.generics_of(trait_id); 859 ty::TraitRef::new(tcx, trait_id, tcx.mk_substs(&substs[..defs.params.len()])) 860 } 861 862 /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` 863 /// are the parameters defined on trait. identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx>864 pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> { 865 ty::TraitRef::new(tcx, def_id, InternalSubsts::identity_for_item(tcx, def_id)) 866 } 867 with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self868 pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { 869 ty::TraitRef::new( 870 tcx, 871 self.def_id, 872 [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)), 873 ) 874 } 875 876 /// Converts this trait ref to a trait predicate with a given `constness` and a positive polarity. 877 #[inline] with_constness(self, constness: ty::BoundConstness) -> ty::TraitPredicate<'tcx>878 pub fn with_constness(self, constness: ty::BoundConstness) -> ty::TraitPredicate<'tcx> { 879 ty::TraitPredicate { trait_ref: self, constness, polarity: ty::ImplPolarity::Positive } 880 } 881 882 /// Converts this trait ref to a trait predicate without `const` and a positive polarity. 883 #[inline] without_const(self) -> ty::TraitPredicate<'tcx>884 pub fn without_const(self) -> ty::TraitPredicate<'tcx> { 885 self.with_constness(ty::BoundConstness::NotConst) 886 } 887 888 #[inline] self_ty(&self) -> Ty<'tcx>889 pub fn self_ty(&self) -> Ty<'tcx> { 890 self.substs.type_at(0) 891 } 892 } 893 894 pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>; 895 896 impl<'tcx> PolyTraitRef<'tcx> { self_ty(&self) -> Binder<'tcx, Ty<'tcx>>897 pub fn self_ty(&self) -> Binder<'tcx, Ty<'tcx>> { 898 self.map_bound_ref(|tr| tr.self_ty()) 899 } 900 def_id(&self) -> DefId901 pub fn def_id(&self) -> DefId { 902 self.skip_binder().def_id 903 } 904 } 905 906 impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> { into_diagnostic_arg(self) -> DiagnosticArgValue<'static>907 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { 908 self.to_string().into_diagnostic_arg() 909 } 910 } 911 912 /// An existential reference to a trait, where `Self` is erased. 913 /// For example, the trait object `Trait<'a, 'b, X, Y>` is: 914 /// ```ignore (illustrative) 915 /// exists T. T: Trait<'a, 'b, X, Y> 916 /// ``` 917 /// The substitutions don't include the erased `Self`, only trait 918 /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). 919 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 920 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] 921 pub struct ExistentialTraitRef<'tcx> { 922 pub def_id: DefId, 923 pub substs: SubstsRef<'tcx>, 924 } 925 926 impl<'tcx> ExistentialTraitRef<'tcx> { erase_self_ty( tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, ) -> ty::ExistentialTraitRef<'tcx>927 pub fn erase_self_ty( 928 tcx: TyCtxt<'tcx>, 929 trait_ref: ty::TraitRef<'tcx>, 930 ) -> ty::ExistentialTraitRef<'tcx> { 931 // Assert there is a Self. 932 trait_ref.substs.type_at(0); 933 934 ty::ExistentialTraitRef { 935 def_id: trait_ref.def_id, 936 substs: tcx.mk_substs(&trait_ref.substs[1..]), 937 } 938 } 939 940 /// Object types don't have a self type specified. Therefore, when 941 /// we convert the principal trait-ref into a normal trait-ref, 942 /// you must give *some* self type. A common choice is `mk_err()` 943 /// or some placeholder type. with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx>944 pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> { 945 // otherwise the escaping vars would be captured by the binder 946 // debug_assert!(!self_ty.has_escaping_bound_vars()); 947 948 ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter())) 949 } 950 } 951 952 impl<'tcx> IntoDiagnosticArg for ExistentialTraitRef<'tcx> { into_diagnostic_arg(self) -> DiagnosticArgValue<'static>953 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { 954 self.to_string().into_diagnostic_arg() 955 } 956 } 957 958 pub type PolyExistentialTraitRef<'tcx> = Binder<'tcx, ExistentialTraitRef<'tcx>>; 959 960 impl<'tcx> PolyExistentialTraitRef<'tcx> { def_id(&self) -> DefId961 pub fn def_id(&self) -> DefId { 962 self.skip_binder().def_id 963 } 964 965 /// Object types don't have a self type specified. Therefore, when 966 /// we convert the principal trait-ref into a normal trait-ref, 967 /// you must give *some* self type. A common choice is `mk_err()` 968 /// or some placeholder type. with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx>969 pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> { 970 self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty)) 971 } 972 } 973 974 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 975 #[derive(HashStable)] 976 pub enum BoundVariableKind { 977 Ty(BoundTyKind), 978 Region(BoundRegionKind), 979 Const, 980 } 981 982 impl BoundVariableKind { expect_region(self) -> BoundRegionKind983 pub fn expect_region(self) -> BoundRegionKind { 984 match self { 985 BoundVariableKind::Region(lt) => lt, 986 _ => bug!("expected a region, but found another kind"), 987 } 988 } 989 expect_ty(self) -> BoundTyKind990 pub fn expect_ty(self) -> BoundTyKind { 991 match self { 992 BoundVariableKind::Ty(ty) => ty, 993 _ => bug!("expected a type, but found another kind"), 994 } 995 } 996 expect_const(self)997 pub fn expect_const(self) { 998 match self { 999 BoundVariableKind::Const => (), 1000 _ => bug!("expected a const, but found another kind"), 1001 } 1002 } 1003 } 1004 1005 /// Binder is a binder for higher-ranked lifetimes or types. It is part of the 1006 /// compiler's representation for things like `for<'a> Fn(&'a isize)` 1007 /// (which would be represented by the type `PolyTraitRef == 1008 /// Binder<'tcx, TraitRef>`). Note that when we instantiate, 1009 /// erase, or otherwise "discharge" these bound vars, we change the 1010 /// type from `Binder<'tcx, T>` to just `T` (see 1011 /// e.g., `liberate_late_bound_regions`). 1012 /// 1013 /// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro. 1014 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] 1015 #[derive(HashStable, Lift)] 1016 pub struct Binder<'tcx, T> { 1017 value: T, 1018 bound_vars: &'tcx List<BoundVariableKind>, 1019 } 1020 1021 impl<'tcx, T> Binder<'tcx, T> 1022 where 1023 T: TypeVisitable<TyCtxt<'tcx>>, 1024 { 1025 /// Wraps `value` in a binder, asserting that `value` does not 1026 /// contain any bound vars that would be bound by the 1027 /// binder. This is commonly used to 'inject' a value T into a 1028 /// different binding level. 1029 #[track_caller] dummy(value: T) -> Binder<'tcx, T>1030 pub fn dummy(value: T) -> Binder<'tcx, T> { 1031 assert!( 1032 !value.has_escaping_bound_vars(), 1033 "`{value:?}` has escaping bound vars, so it cannot be wrapped in a dummy binder." 1034 ); 1035 Binder { value, bound_vars: ty::List::empty() } 1036 } 1037 bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T>1038 pub fn bind_with_vars(value: T, bound_vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> { 1039 if cfg!(debug_assertions) { 1040 let mut validator = ValidateBoundVars::new(bound_vars); 1041 value.visit_with(&mut validator); 1042 } 1043 Binder { value, bound_vars } 1044 } 1045 } 1046 1047 impl<'tcx, T> Binder<'tcx, T> { 1048 /// Skips the binder and returns the "bound" value. This is a 1049 /// risky thing to do because it's easy to get confused about 1050 /// De Bruijn indices and the like. It is usually better to 1051 /// discharge the binder using `no_bound_vars` or 1052 /// `replace_late_bound_regions` or something like 1053 /// that. `skip_binder` is only valid when you are either 1054 /// extracting data that has nothing to do with bound vars, you 1055 /// are doing some sort of test that does not involve bound 1056 /// regions, or you are being very careful about your depth 1057 /// accounting. 1058 /// 1059 /// Some examples where `skip_binder` is reasonable: 1060 /// 1061 /// - extracting the `DefId` from a PolyTraitRef; 1062 /// - comparing the self type of a PolyTraitRef to see if it is equal to 1063 /// a type parameter `X`, since the type `X` does not reference any regions skip_binder(self) -> T1064 pub fn skip_binder(self) -> T { 1065 self.value 1066 } 1067 bound_vars(&self) -> &'tcx List<BoundVariableKind>1068 pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> { 1069 self.bound_vars 1070 } 1071 as_ref(&self) -> Binder<'tcx, &T>1072 pub fn as_ref(&self) -> Binder<'tcx, &T> { 1073 Binder { value: &self.value, bound_vars: self.bound_vars } 1074 } 1075 as_deref(&self) -> Binder<'tcx, &T::Target> where T: Deref,1076 pub fn as_deref(&self) -> Binder<'tcx, &T::Target> 1077 where 1078 T: Deref, 1079 { 1080 Binder { value: &self.value, bound_vars: self.bound_vars } 1081 } 1082 map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U> where F: FnOnce(&T) -> U,1083 pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U> 1084 where 1085 F: FnOnce(&T) -> U, 1086 { 1087 let value = f(&self.value); 1088 Binder { value, bound_vars: self.bound_vars } 1089 } 1090 map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U> where F: FnOnce(&T) -> U,1091 pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U> 1092 where 1093 F: FnOnce(&T) -> U, 1094 { 1095 self.as_ref().map_bound(f) 1096 } 1097 map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx, U> where F: FnOnce(T) -> U,1098 pub fn map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx, U> 1099 where 1100 F: FnOnce(T) -> U, 1101 { 1102 let Binder { value, bound_vars } = self; 1103 let value = f(value); 1104 if cfg!(debug_assertions) { 1105 let mut validator = ValidateBoundVars::new(bound_vars); 1106 value.visit_with(&mut validator); 1107 } 1108 Binder { value, bound_vars } 1109 } 1110 try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>( self, f: F, ) -> Result<Binder<'tcx, U>, E> where F: FnOnce(T) -> Result<U, E>,1111 pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>( 1112 self, 1113 f: F, 1114 ) -> Result<Binder<'tcx, U>, E> 1115 where 1116 F: FnOnce(T) -> Result<U, E>, 1117 { 1118 let Binder { value, bound_vars } = self; 1119 let value = f(value)?; 1120 if cfg!(debug_assertions) { 1121 let mut validator = ValidateBoundVars::new(bound_vars); 1122 value.visit_with(&mut validator); 1123 } 1124 Ok(Binder { value, bound_vars }) 1125 } 1126 1127 /// Wraps a `value` in a binder, using the same bound variables as the 1128 /// current `Binder`. This should not be used if the new value *changes* 1129 /// the bound variables. Note: the (old or new) value itself does not 1130 /// necessarily need to *name* all the bound variables. 1131 /// 1132 /// This currently doesn't do anything different than `bind`, because we 1133 /// don't actually track bound vars. However, semantically, it is different 1134 /// because bound vars aren't allowed to change here, whereas they are 1135 /// in `bind`. This may be (debug) asserted in the future. rebind<U>(&self, value: U) -> Binder<'tcx, U> where U: TypeVisitable<TyCtxt<'tcx>>,1136 pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U> 1137 where 1138 U: TypeVisitable<TyCtxt<'tcx>>, 1139 { 1140 Binder::bind_with_vars(value, self.bound_vars) 1141 } 1142 1143 /// Unwraps and returns the value within, but only if it contains 1144 /// no bound vars at all. (In other words, if this binder -- 1145 /// and indeed any enclosing binder -- doesn't bind anything at 1146 /// all.) Otherwise, returns `None`. 1147 /// 1148 /// (One could imagine having a method that just unwraps a single 1149 /// binder, but permits late-bound vars bound by enclosing 1150 /// binders, but that would require adjusting the debruijn 1151 /// indices, and given the shallow binding structure we often use, 1152 /// would not be that useful.) no_bound_vars(self) -> Option<T> where T: TypeVisitable<TyCtxt<'tcx>>,1153 pub fn no_bound_vars(self) -> Option<T> 1154 where 1155 T: TypeVisitable<TyCtxt<'tcx>>, 1156 { 1157 if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) } 1158 } 1159 1160 /// Splits the contents into two things that share the same binder 1161 /// level as the original, returning two distinct binders. 1162 /// 1163 /// `f` should consider bound regions at depth 1 to be free, and 1164 /// anything it produces with bound regions at depth 1 will be 1165 /// bound in the resulting return values. split<U, V, F>(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>) where F: FnOnce(T) -> (U, V),1166 pub fn split<U, V, F>(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>) 1167 where 1168 F: FnOnce(T) -> (U, V), 1169 { 1170 let Binder { value, bound_vars } = self; 1171 let (u, v) = f(value); 1172 (Binder { value: u, bound_vars }, Binder { value: v, bound_vars }) 1173 } 1174 } 1175 1176 impl<'tcx, T> Binder<'tcx, Option<T>> { transpose(self) -> Option<Binder<'tcx, T>>1177 pub fn transpose(self) -> Option<Binder<'tcx, T>> { 1178 let Binder { value, bound_vars } = self; 1179 value.map(|value| Binder { value, bound_vars }) 1180 } 1181 } 1182 1183 impl<'tcx, T: IntoIterator> Binder<'tcx, T> { iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>>1184 pub fn iter(self) -> impl Iterator<Item = ty::Binder<'tcx, T::Item>> { 1185 let Binder { value, bound_vars } = self; 1186 value.into_iter().map(|value| Binder { value, bound_vars }) 1187 } 1188 } 1189 1190 impl<'tcx, T> IntoDiagnosticArg for Binder<'tcx, T> 1191 where 1192 T: IntoDiagnosticArg, 1193 { into_diagnostic_arg(self) -> DiagnosticArgValue<'static>1194 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { 1195 self.value.into_diagnostic_arg() 1196 } 1197 } 1198 1199 /// Represents the projection of an associated type. 1200 /// 1201 /// * For a projection, this would be `<Ty as Trait<...>>::N<...>`. 1202 /// * For an inherent projection, this would be `Ty::N<...>`. 1203 /// * For an opaque type, there is no explicit syntax. 1204 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 1205 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] 1206 pub struct AliasTy<'tcx> { 1207 /// The parameters of the associated or opaque item. 1208 /// 1209 /// For a projection, these are the substitutions for the trait and the 1210 /// GAT substitutions, if there are any. 1211 /// 1212 /// For an inherent projection, they consist of the self type and the GAT substitutions, 1213 /// if there are any. 1214 /// 1215 /// For RPIT the substitutions are for the generics of the function, 1216 /// while for TAIT it is used for the generic parameters of the alias. 1217 pub substs: SubstsRef<'tcx>, 1218 1219 /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether 1220 /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if 1221 /// this is an opaque. 1222 /// 1223 /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the 1224 /// underlying type if the type is an opaque. 1225 /// 1226 /// Note that if this is an associated type, this is not the `DefId` of the 1227 /// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`, 1228 /// aka. `tcx.parent(def_id)`. 1229 pub def_id: DefId, 1230 1231 /// This field exists to prevent the creation of `AliasTy` without using 1232 /// [TyCtxt::mk_alias_ty]. 1233 pub(super) _use_mk_alias_ty_instead: (), 1234 } 1235 1236 impl<'tcx> AliasTy<'tcx> { kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind1237 pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind { 1238 match tcx.def_kind(self.def_id) { 1239 DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent, 1240 DefKind::AssocTy | DefKind::ImplTraitPlaceholder => ty::Projection, 1241 DefKind::OpaqueTy => ty::Opaque, 1242 DefKind::TyAlias => ty::Weak, 1243 kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), 1244 } 1245 } 1246 to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>1247 pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 1248 Ty::new_alias(tcx, self.kind(tcx), self) 1249 } 1250 } 1251 1252 /// The following methods work only with associated type projections. 1253 impl<'tcx> AliasTy<'tcx> { self_ty(self) -> Ty<'tcx>1254 pub fn self_ty(self) -> Ty<'tcx> { 1255 self.substs.type_at(0) 1256 } 1257 with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self1258 pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { 1259 tcx.mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter().skip(1))) 1260 } 1261 } 1262 1263 /// The following methods work only with trait associated type projections. 1264 impl<'tcx> AliasTy<'tcx> { trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId1265 pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { 1266 match tcx.def_kind(self.def_id) { 1267 DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), 1268 DefKind::ImplTraitPlaceholder => { 1269 tcx.parent(tcx.impl_trait_in_trait_parent_fn(self.def_id)) 1270 } 1271 kind => bug!("expected a projection AliasTy; found {kind:?}"), 1272 } 1273 } 1274 1275 /// Extracts the underlying trait reference and own substs from this projection. 1276 /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`, 1277 /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own substs trait_ref_and_own_substs( self, tcx: TyCtxt<'tcx>, ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>])1278 pub fn trait_ref_and_own_substs( 1279 self, 1280 tcx: TyCtxt<'tcx>, 1281 ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { 1282 debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst)); 1283 let trait_def_id = self.trait_def_id(tcx); 1284 let trait_generics = tcx.generics_of(trait_def_id); 1285 ( 1286 ty::TraitRef::new(tcx, trait_def_id, self.substs.truncate_to(tcx, trait_generics)), 1287 &self.substs[trait_generics.count()..], 1288 ) 1289 } 1290 1291 /// Extracts the underlying trait reference from this projection. 1292 /// For example, if this is a projection of `<T as Iterator>::Item`, 1293 /// then this function would return a `T: Iterator` trait reference. 1294 /// 1295 /// WARNING: This will drop the substs for generic associated types 1296 /// consider calling [Self::trait_ref_and_own_substs] to get those 1297 /// as well. trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx>1298 pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { 1299 let def_id = self.trait_def_id(tcx); 1300 ty::TraitRef::new(tcx, def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id))) 1301 } 1302 } 1303 1304 /// The following methods work only with inherent associated type projections. 1305 impl<'tcx> AliasTy<'tcx> { 1306 /// Transform the substitutions to have the given `impl` substs as the base and the GAT substs on top of that. 1307 /// 1308 /// Does the following transformation: 1309 /// 1310 /// ```text 1311 /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m] 1312 /// 1313 /// I_i impl subst 1314 /// P_j GAT subst 1315 /// ``` rebase_substs_onto_impl( self, impl_substs: ty::SubstsRef<'tcx>, tcx: TyCtxt<'tcx>, ) -> ty::SubstsRef<'tcx>1316 pub fn rebase_substs_onto_impl( 1317 self, 1318 impl_substs: ty::SubstsRef<'tcx>, 1319 tcx: TyCtxt<'tcx>, 1320 ) -> ty::SubstsRef<'tcx> { 1321 debug_assert_eq!(self.kind(tcx), ty::Inherent); 1322 1323 tcx.mk_substs_from_iter(impl_substs.into_iter().chain(self.substs.into_iter().skip(1))) 1324 } 1325 } 1326 1327 #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)] 1328 pub struct GenSig<'tcx> { 1329 pub resume_ty: Ty<'tcx>, 1330 pub yield_ty: Ty<'tcx>, 1331 pub return_ty: Ty<'tcx>, 1332 } 1333 1334 pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>; 1335 1336 /// Signature of a function type, which we have arbitrarily 1337 /// decided to use to refer to the input/output types. 1338 /// 1339 /// - `inputs`: is the list of arguments and their modes. 1340 /// - `output`: is the return type. 1341 /// - `c_variadic`: indicates whether this is a C-variadic function. 1342 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 1343 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] 1344 pub struct FnSig<'tcx> { 1345 pub inputs_and_output: &'tcx List<Ty<'tcx>>, 1346 pub c_variadic: bool, 1347 pub unsafety: hir::Unsafety, 1348 pub abi: abi::Abi, 1349 } 1350 1351 impl<'tcx> FnSig<'tcx> { inputs(&self) -> &'tcx [Ty<'tcx>]1352 pub fn inputs(&self) -> &'tcx [Ty<'tcx>] { 1353 &self.inputs_and_output[..self.inputs_and_output.len() - 1] 1354 } 1355 output(&self) -> Ty<'tcx>1356 pub fn output(&self) -> Ty<'tcx> { 1357 self.inputs_and_output[self.inputs_and_output.len() - 1] 1358 } 1359 1360 // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible 1361 // method. fake() -> FnSig<'tcx>1362 fn fake() -> FnSig<'tcx> { 1363 FnSig { 1364 inputs_and_output: List::empty(), 1365 c_variadic: false, 1366 unsafety: hir::Unsafety::Normal, 1367 abi: abi::Abi::Rust, 1368 } 1369 } 1370 } 1371 1372 impl<'tcx> IntoDiagnosticArg for FnSig<'tcx> { into_diagnostic_arg(self) -> DiagnosticArgValue<'static>1373 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { 1374 self.to_string().into_diagnostic_arg() 1375 } 1376 } 1377 1378 pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; 1379 1380 impl<'tcx> PolyFnSig<'tcx> { 1381 #[inline] inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]>1382 pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { 1383 self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs()) 1384 } 1385 #[inline] input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>>1386 pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { 1387 self.map_bound_ref(|fn_sig| fn_sig.inputs()[index]) 1388 } inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>1389 pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> { 1390 self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output) 1391 } 1392 #[inline] output(&self) -> ty::Binder<'tcx, Ty<'tcx>>1393 pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> { 1394 self.map_bound_ref(|fn_sig| fn_sig.output()) 1395 } c_variadic(&self) -> bool1396 pub fn c_variadic(&self) -> bool { 1397 self.skip_binder().c_variadic 1398 } unsafety(&self) -> hir::Unsafety1399 pub fn unsafety(&self) -> hir::Unsafety { 1400 self.skip_binder().unsafety 1401 } abi(&self) -> abi::Abi1402 pub fn abi(&self) -> abi::Abi { 1403 self.skip_binder().abi 1404 } 1405 is_fn_trait_compatible(&self) -> bool1406 pub fn is_fn_trait_compatible(&self) -> bool { 1407 matches!( 1408 self.skip_binder(), 1409 ty::FnSig { 1410 unsafety: rustc_hir::Unsafety::Normal, 1411 abi: Abi::Rust, 1412 c_variadic: false, 1413 .. 1414 } 1415 ) 1416 } 1417 } 1418 1419 pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>; 1420 1421 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 1422 #[derive(HashStable)] 1423 pub struct ParamTy { 1424 pub index: u32, 1425 pub name: Symbol, 1426 } 1427 1428 impl<'tcx> ParamTy { new(index: u32, name: Symbol) -> ParamTy1429 pub fn new(index: u32, name: Symbol) -> ParamTy { 1430 ParamTy { index, name } 1431 } 1432 for_def(def: &ty::GenericParamDef) -> ParamTy1433 pub fn for_def(def: &ty::GenericParamDef) -> ParamTy { 1434 ParamTy::new(def.index, def.name) 1435 } 1436 1437 #[inline] to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>1438 pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 1439 Ty::new_param(tcx, self.index, self.name) 1440 } 1441 span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span1442 pub fn span_from_generics(&self, tcx: TyCtxt<'tcx>, item_with_generics: DefId) -> Span { 1443 let generics = tcx.generics_of(item_with_generics); 1444 let type_param = generics.type_param(self, tcx); 1445 tcx.def_span(type_param.def_id) 1446 } 1447 } 1448 1449 #[derive(Copy, Clone, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] 1450 #[derive(HashStable)] 1451 pub struct ParamConst { 1452 pub index: u32, 1453 pub name: Symbol, 1454 } 1455 1456 impl ParamConst { new(index: u32, name: Symbol) -> ParamConst1457 pub fn new(index: u32, name: Symbol) -> ParamConst { 1458 ParamConst { index, name } 1459 } 1460 for_def(def: &ty::GenericParamDef) -> ParamConst1461 pub fn for_def(def: &ty::GenericParamDef) -> ParamConst { 1462 ParamConst::new(def.index, def.name) 1463 } 1464 } 1465 1466 /// Use this rather than `RegionKind`, whenever possible. 1467 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)] 1468 #[rustc_pass_by_value] 1469 pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>); 1470 1471 impl<'tcx> Region<'tcx> { 1472 #[inline] new_early_bound( tcx: TyCtxt<'tcx>, early_bound_region: ty::EarlyBoundRegion, ) -> Region<'tcx>1473 pub fn new_early_bound( 1474 tcx: TyCtxt<'tcx>, 1475 early_bound_region: ty::EarlyBoundRegion, 1476 ) -> Region<'tcx> { 1477 tcx.intern_region(ty::ReEarlyBound(early_bound_region)) 1478 } 1479 1480 #[inline] new_late_bound( tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, bound_region: ty::BoundRegion, ) -> Region<'tcx>1481 pub fn new_late_bound( 1482 tcx: TyCtxt<'tcx>, 1483 debruijn: ty::DebruijnIndex, 1484 bound_region: ty::BoundRegion, 1485 ) -> Region<'tcx> { 1486 // Use a pre-interned one when possible. 1487 if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region 1488 && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize()) 1489 && let Some(re) = inner.get(var.as_usize()).copied() 1490 { 1491 re 1492 } else { 1493 tcx.intern_region(ty::ReLateBound(debruijn, bound_region)) 1494 } 1495 } 1496 1497 #[inline] new_free( tcx: TyCtxt<'tcx>, scope: DefId, bound_region: ty::BoundRegionKind, ) -> Region<'tcx>1498 pub fn new_free( 1499 tcx: TyCtxt<'tcx>, 1500 scope: DefId, 1501 bound_region: ty::BoundRegionKind, 1502 ) -> Region<'tcx> { 1503 tcx.intern_region(ty::ReFree(ty::FreeRegion { scope, bound_region })) 1504 } 1505 1506 #[inline] new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx>1507 pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> { 1508 // Use a pre-interned one when possible. 1509 tcx.lifetimes 1510 .re_vars 1511 .get(v.as_usize()) 1512 .copied() 1513 .unwrap_or_else(|| tcx.intern_region(ty::ReVar(v))) 1514 } 1515 1516 #[inline] new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Region<'tcx>1517 pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Region<'tcx> { 1518 tcx.intern_region(ty::RePlaceholder(placeholder)) 1519 } 1520 1521 /// Constructs a `RegionKind::ReError` region. 1522 #[track_caller] new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Region<'tcx>1523 pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Region<'tcx> { 1524 tcx.intern_region(ty::ReError(reported)) 1525 } 1526 1527 /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` to ensure it 1528 /// gets used. 1529 #[track_caller] new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx>1530 pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> { 1531 Region::new_error_with_message( 1532 tcx, 1533 DUMMY_SP, 1534 "RegionKind::ReError constructed but no error reported", 1535 ) 1536 } 1537 1538 /// Constructs a `RegionKind::ReError` region and registers a `delay_span_bug` with the given 1539 /// `msg` to ensure it gets used. 1540 #[track_caller] new_error_with_message<S: Into<MultiSpan>>( tcx: TyCtxt<'tcx>, span: S, msg: &'static str, ) -> Region<'tcx>1541 pub fn new_error_with_message<S: Into<MultiSpan>>( 1542 tcx: TyCtxt<'tcx>, 1543 span: S, 1544 msg: &'static str, 1545 ) -> Region<'tcx> { 1546 let reported = tcx.sess.delay_span_bug(span, msg); 1547 Region::new_error(tcx, reported) 1548 } 1549 1550 /// Avoid this in favour of more specific `new_*` methods, where possible, 1551 /// to avoid the cost of the `match`. new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx>1552 pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> { 1553 match kind { 1554 ty::ReEarlyBound(region) => Region::new_early_bound(tcx, region), 1555 ty::ReLateBound(debruijn, region) => Region::new_late_bound(tcx, debruijn, region), 1556 ty::ReFree(ty::FreeRegion { scope, bound_region }) => { 1557 Region::new_free(tcx, scope, bound_region) 1558 } 1559 ty::ReStatic => tcx.lifetimes.re_static, 1560 ty::ReVar(vid) => Region::new_var(tcx, vid), 1561 ty::RePlaceholder(region) => Region::new_placeholder(tcx, region), 1562 ty::ReErased => tcx.lifetimes.re_erased, 1563 ty::ReError(reported) => Region::new_error(tcx, reported), 1564 } 1565 } 1566 } 1567 1568 impl<'tcx> Deref for Region<'tcx> { 1569 type Target = RegionKind<'tcx>; 1570 1571 #[inline] deref(&self) -> &RegionKind<'tcx>1572 fn deref(&self) -> &RegionKind<'tcx> { 1573 &self.0.0 1574 } 1575 } 1576 1577 impl<'tcx> fmt::Debug for Region<'tcx> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1578 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1579 write!(f, "{:?}", self.kind()) 1580 } 1581 } 1582 1583 #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] 1584 #[derive(HashStable)] 1585 pub struct EarlyBoundRegion { 1586 pub def_id: DefId, 1587 pub index: u32, 1588 pub name: Symbol, 1589 } 1590 1591 impl fmt::Debug for EarlyBoundRegion { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1592 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1593 write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name) 1594 } 1595 } 1596 1597 /// A **`const`** **v**ariable **ID**. 1598 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 1599 #[derive(HashStable, TyEncodable, TyDecodable)] 1600 pub struct ConstVid<'tcx> { 1601 pub index: u32, 1602 pub phantom: PhantomData<&'tcx ()>, 1603 } 1604 1605 rustc_index::newtype_index! { 1606 /// A **region** (lifetime) **v**ariable **ID**. 1607 #[derive(HashStable)] 1608 #[debug_format = "'?{}"] 1609 pub struct RegionVid {} 1610 } 1611 1612 impl Atom for RegionVid { index(self) -> usize1613 fn index(self) -> usize { 1614 Idx::index(self) 1615 } 1616 } 1617 1618 rustc_index::newtype_index! { 1619 #[derive(HashStable)] 1620 #[debug_format = "{}"] 1621 pub struct BoundVar {} 1622 } 1623 1624 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] 1625 #[derive(HashStable)] 1626 pub struct BoundTy { 1627 pub var: BoundVar, 1628 pub kind: BoundTyKind, 1629 } 1630 1631 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 1632 #[derive(HashStable)] 1633 pub enum BoundTyKind { 1634 Anon, 1635 Param(DefId, Symbol), 1636 } 1637 1638 impl From<BoundVar> for BoundTy { from(var: BoundVar) -> Self1639 fn from(var: BoundVar) -> Self { 1640 BoundTy { var, kind: BoundTyKind::Anon } 1641 } 1642 } 1643 1644 /// A `ProjectionPredicate` for an `ExistentialTraitRef`. 1645 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] 1646 #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] 1647 pub struct ExistentialProjection<'tcx> { 1648 pub def_id: DefId, 1649 pub substs: SubstsRef<'tcx>, 1650 pub term: Term<'tcx>, 1651 } 1652 1653 pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>; 1654 1655 impl<'tcx> ExistentialProjection<'tcx> { 1656 /// Extracts the underlying existential trait reference from this projection. 1657 /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`, 1658 /// then this function would return an `exists T. T: Iterator` existential trait 1659 /// reference. trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx>1660 pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { 1661 let def_id = tcx.parent(self.def_id); 1662 let subst_count = tcx.generics_of(def_id).count() - 1; 1663 let substs = tcx.mk_substs(&self.substs[..subst_count]); 1664 ty::ExistentialTraitRef { def_id, substs } 1665 } 1666 with_self_ty( &self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>, ) -> ty::ProjectionPredicate<'tcx>1667 pub fn with_self_ty( 1668 &self, 1669 tcx: TyCtxt<'tcx>, 1670 self_ty: Ty<'tcx>, 1671 ) -> ty::ProjectionPredicate<'tcx> { 1672 // otherwise the escaping regions would be captured by the binders 1673 debug_assert!(!self_ty.has_escaping_bound_vars()); 1674 1675 ty::ProjectionPredicate { 1676 projection_ty: tcx 1677 .mk_alias_ty(self.def_id, [self_ty.into()].into_iter().chain(self.substs)), 1678 term: self.term, 1679 } 1680 } 1681 erase_self_ty( tcx: TyCtxt<'tcx>, projection_predicate: ty::ProjectionPredicate<'tcx>, ) -> Self1682 pub fn erase_self_ty( 1683 tcx: TyCtxt<'tcx>, 1684 projection_predicate: ty::ProjectionPredicate<'tcx>, 1685 ) -> Self { 1686 // Assert there is a Self. 1687 projection_predicate.projection_ty.substs.type_at(0); 1688 1689 Self { 1690 def_id: projection_predicate.projection_ty.def_id, 1691 substs: tcx.mk_substs(&projection_predicate.projection_ty.substs[1..]), 1692 term: projection_predicate.term, 1693 } 1694 } 1695 } 1696 1697 impl<'tcx> PolyExistentialProjection<'tcx> { with_self_ty( &self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>, ) -> ty::PolyProjectionPredicate<'tcx>1698 pub fn with_self_ty( 1699 &self, 1700 tcx: TyCtxt<'tcx>, 1701 self_ty: Ty<'tcx>, 1702 ) -> ty::PolyProjectionPredicate<'tcx> { 1703 self.map_bound(|p| p.with_self_ty(tcx, self_ty)) 1704 } 1705 item_def_id(&self) -> DefId1706 pub fn item_def_id(&self) -> DefId { 1707 self.skip_binder().def_id 1708 } 1709 } 1710 1711 /// Region utilities 1712 impl<'tcx> Region<'tcx> { kind(self) -> RegionKind<'tcx>1713 pub fn kind(self) -> RegionKind<'tcx> { 1714 *self.0.0 1715 } 1716 get_name(self) -> Option<Symbol>1717 pub fn get_name(self) -> Option<Symbol> { 1718 if self.has_name() { 1719 match *self { 1720 ty::ReEarlyBound(ebr) => Some(ebr.name), 1721 ty::ReLateBound(_, br) => br.kind.get_name(), 1722 ty::ReFree(fr) => fr.bound_region.get_name(), 1723 ty::ReStatic => Some(kw::StaticLifetime), 1724 ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(), 1725 _ => None, 1726 } 1727 } else { 1728 None 1729 } 1730 } 1731 get_name_or_anon(self) -> Symbol1732 pub fn get_name_or_anon(self) -> Symbol { 1733 match self.get_name() { 1734 Some(name) => name, 1735 None => sym::anon, 1736 } 1737 } 1738 1739 /// Is this region named by the user? has_name(self) -> bool1740 pub fn has_name(self) -> bool { 1741 match *self { 1742 ty::ReEarlyBound(ebr) => ebr.has_name(), 1743 ty::ReLateBound(_, br) => br.kind.is_named(), 1744 ty::ReFree(fr) => fr.bound_region.is_named(), 1745 ty::ReStatic => true, 1746 ty::ReVar(..) => false, 1747 ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(), 1748 ty::ReErased => false, 1749 ty::ReError(_) => false, 1750 } 1751 } 1752 1753 #[inline] is_error(self) -> bool1754 pub fn is_error(self) -> bool { 1755 matches!(*self, ty::ReError(_)) 1756 } 1757 1758 #[inline] is_static(self) -> bool1759 pub fn is_static(self) -> bool { 1760 matches!(*self, ty::ReStatic) 1761 } 1762 1763 #[inline] is_erased(self) -> bool1764 pub fn is_erased(self) -> bool { 1765 matches!(*self, ty::ReErased) 1766 } 1767 1768 #[inline] is_late_bound(self) -> bool1769 pub fn is_late_bound(self) -> bool { 1770 matches!(*self, ty::ReLateBound(..)) 1771 } 1772 1773 #[inline] is_placeholder(self) -> bool1774 pub fn is_placeholder(self) -> bool { 1775 matches!(*self, ty::RePlaceholder(..)) 1776 } 1777 1778 #[inline] bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool1779 pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { 1780 match *self { 1781 ty::ReLateBound(debruijn, _) => debruijn >= index, 1782 _ => false, 1783 } 1784 } 1785 type_flags(self) -> TypeFlags1786 pub fn type_flags(self) -> TypeFlags { 1787 let mut flags = TypeFlags::empty(); 1788 1789 match *self { 1790 ty::ReVar(..) => { 1791 flags = flags | TypeFlags::HAS_FREE_REGIONS; 1792 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; 1793 flags = flags | TypeFlags::HAS_RE_INFER; 1794 } 1795 ty::RePlaceholder(..) => { 1796 flags = flags | TypeFlags::HAS_FREE_REGIONS; 1797 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; 1798 flags = flags | TypeFlags::HAS_RE_PLACEHOLDER; 1799 } 1800 ty::ReEarlyBound(..) => { 1801 flags = flags | TypeFlags::HAS_FREE_REGIONS; 1802 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; 1803 flags = flags | TypeFlags::HAS_RE_PARAM; 1804 } 1805 ty::ReFree { .. } => { 1806 flags = flags | TypeFlags::HAS_FREE_REGIONS; 1807 flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; 1808 } 1809 ty::ReStatic => { 1810 flags = flags | TypeFlags::HAS_FREE_REGIONS; 1811 } 1812 ty::ReLateBound(..) => { 1813 flags = flags | TypeFlags::HAS_RE_LATE_BOUND; 1814 } 1815 ty::ReErased => { 1816 flags = flags | TypeFlags::HAS_RE_ERASED; 1817 } 1818 ty::ReError(_) => { 1819 flags = flags | TypeFlags::HAS_FREE_REGIONS; 1820 } 1821 } 1822 1823 debug!("type_flags({:?}) = {:?}", self, flags); 1824 1825 flags 1826 } 1827 1828 /// Given an early-bound or free region, returns the `DefId` where it was bound. 1829 /// For example, consider the regions in this snippet of code: 1830 /// 1831 /// ```ignore (illustrative) 1832 /// impl<'a> Foo { 1833 /// // ^^ -- early bound, declared on an impl 1834 /// 1835 /// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c 1836 /// // ^^ ^^ ^ anonymous, late-bound 1837 /// // | early-bound, appears in where-clauses 1838 /// // late-bound, appears only in fn args 1839 /// {..} 1840 /// } 1841 /// ``` 1842 /// 1843 /// Here, `free_region_binding_scope('a)` would return the `DefId` 1844 /// of the impl, and for all the other highlighted regions, it 1845 /// would return the `DefId` of the function. In other cases (not shown), this 1846 /// function might return the `DefId` of a closure. free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId1847 pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId { 1848 match *self { 1849 ty::ReEarlyBound(br) => tcx.parent(br.def_id), 1850 ty::ReFree(fr) => fr.scope, 1851 _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), 1852 } 1853 } 1854 1855 /// True for free regions other than `'static`. is_free(self) -> bool1856 pub fn is_free(self) -> bool { 1857 matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_)) 1858 } 1859 1860 /// True if `self` is a free region or static. is_free_or_static(self) -> bool1861 pub fn is_free_or_static(self) -> bool { 1862 match *self { 1863 ty::ReStatic => true, 1864 _ => self.is_free(), 1865 } 1866 } 1867 is_var(self) -> bool1868 pub fn is_var(self) -> bool { 1869 matches!(self.kind(), ty::ReVar(_)) 1870 } 1871 as_var(self) -> RegionVid1872 pub fn as_var(self) -> RegionVid { 1873 match self.kind() { 1874 ty::ReVar(vid) => vid, 1875 _ => bug!("expected region {:?} to be of kind ReVar", self), 1876 } 1877 } 1878 } 1879 1880 /// Constructors for `Ty` 1881 impl<'tcx> Ty<'tcx> { 1882 // Avoid this in favour of more specific `new_*` methods, where possible. 1883 #[allow(rustc::usage_of_ty_tykind)] 1884 #[inline] new(tcx: TyCtxt<'tcx>, st: TyKind<'tcx>) -> Ty<'tcx>1885 pub fn new(tcx: TyCtxt<'tcx>, st: TyKind<'tcx>) -> Ty<'tcx> { 1886 tcx.mk_ty_from_kind(st) 1887 } 1888 1889 #[inline] new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferTy) -> Ty<'tcx>1890 pub fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferTy) -> Ty<'tcx> { 1891 Ty::new(tcx, TyKind::Infer(infer)) 1892 } 1893 1894 #[inline] new_var(tcx: TyCtxt<'tcx>, v: ty::TyVid) -> Ty<'tcx>1895 pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::TyVid) -> Ty<'tcx> { 1896 // Use a pre-interned one when possible. 1897 tcx.types 1898 .ty_vars 1899 .get(v.as_usize()) 1900 .copied() 1901 .unwrap_or_else(|| Ty::new(tcx, Infer(TyVar(v)))) 1902 } 1903 1904 #[inline] new_int_var(tcx: TyCtxt<'tcx>, v: ty::IntVid) -> Ty<'tcx>1905 pub fn new_int_var(tcx: TyCtxt<'tcx>, v: ty::IntVid) -> Ty<'tcx> { 1906 Ty::new_infer(tcx, IntVar(v)) 1907 } 1908 1909 #[inline] new_float_var(tcx: TyCtxt<'tcx>, v: ty::FloatVid) -> Ty<'tcx>1910 pub fn new_float_var(tcx: TyCtxt<'tcx>, v: ty::FloatVid) -> Ty<'tcx> { 1911 Ty::new_infer(tcx, FloatVar(v)) 1912 } 1913 1914 #[inline] new_fresh(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx>1915 pub fn new_fresh(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> { 1916 // Use a pre-interned one when possible. 1917 tcx.types 1918 .fresh_tys 1919 .get(n as usize) 1920 .copied() 1921 .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshTy(n))) 1922 } 1923 1924 #[inline] new_fresh_int(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx>1925 pub fn new_fresh_int(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> { 1926 // Use a pre-interned one when possible. 1927 tcx.types 1928 .fresh_int_tys 1929 .get(n as usize) 1930 .copied() 1931 .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshIntTy(n))) 1932 } 1933 1934 #[inline] new_fresh_float(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx>1935 pub fn new_fresh_float(tcx: TyCtxt<'tcx>, n: u32) -> Ty<'tcx> { 1936 // Use a pre-interned one when possible. 1937 tcx.types 1938 .fresh_float_tys 1939 .get(n as usize) 1940 .copied() 1941 .unwrap_or_else(|| Ty::new_infer(tcx, ty::FreshFloatTy(n))) 1942 } 1943 1944 #[inline] new_param(tcx: TyCtxt<'tcx>, index: u32, name: Symbol) -> Ty<'tcx>1945 pub fn new_param(tcx: TyCtxt<'tcx>, index: u32, name: Symbol) -> Ty<'tcx> { 1946 tcx.mk_ty_from_kind(Param(ParamTy { index, name })) 1947 } 1948 1949 #[inline] new_bound( tcx: TyCtxt<'tcx>, index: ty::DebruijnIndex, bound_ty: ty::BoundTy, ) -> Ty<'tcx>1950 pub fn new_bound( 1951 tcx: TyCtxt<'tcx>, 1952 index: ty::DebruijnIndex, 1953 bound_ty: ty::BoundTy, 1954 ) -> Ty<'tcx> { 1955 Ty::new(tcx, Bound(index, bound_ty)) 1956 } 1957 1958 #[inline] new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Ty<'tcx>1959 pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Ty<'tcx> { 1960 Ty::new(tcx, Placeholder(placeholder)) 1961 } 1962 1963 #[inline] new_alias( tcx: TyCtxt<'tcx>, kind: ty::AliasKind, alias_ty: ty::AliasTy<'tcx>, ) -> Ty<'tcx>1964 pub fn new_alias( 1965 tcx: TyCtxt<'tcx>, 1966 kind: ty::AliasKind, 1967 alias_ty: ty::AliasTy<'tcx>, 1968 ) -> Ty<'tcx> { 1969 debug_assert_matches!( 1970 (kind, tcx.def_kind(alias_ty.def_id)), 1971 (ty::Opaque, DefKind::OpaqueTy) 1972 | (ty::Projection | ty::Inherent, DefKind::AssocTy) 1973 | (ty::Opaque | ty::Projection, DefKind::ImplTraitPlaceholder) 1974 | (ty::Weak, DefKind::TyAlias) 1975 ); 1976 Ty::new(tcx, Alias(kind, alias_ty)) 1977 } 1978 1979 #[inline] new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx>1980 pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> { 1981 Ty::new_alias(tcx, ty::Opaque, tcx.mk_alias_ty(def_id, substs)) 1982 } 1983 1984 /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Ty<'tcx>1985 pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Ty<'tcx> { 1986 Ty::new(tcx, Error(reported)) 1987 } 1988 1989 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. 1990 #[track_caller] new_misc_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx>1991 pub fn new_misc_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 1992 Ty::new_error_with_message(tcx, DUMMY_SP, "TyKind::Error constructed but no error reported") 1993 } 1994 1995 /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` with the given `msg` to 1996 /// ensure it gets used. 1997 #[track_caller] new_error_with_message<S: Into<MultiSpan>>( tcx: TyCtxt<'tcx>, span: S, msg: impl Into<DiagnosticMessage>, ) -> Ty<'tcx>1998 pub fn new_error_with_message<S: Into<MultiSpan>>( 1999 tcx: TyCtxt<'tcx>, 2000 span: S, 2001 msg: impl Into<DiagnosticMessage>, 2002 ) -> Ty<'tcx> { 2003 let reported = tcx.sess.delay_span_bug(span, msg); 2004 Ty::new(tcx, Error(reported)) 2005 } 2006 2007 #[inline] new_int(tcx: TyCtxt<'tcx>, i: ty::IntTy) -> Ty<'tcx>2008 pub fn new_int(tcx: TyCtxt<'tcx>, i: ty::IntTy) -> Ty<'tcx> { 2009 use ty::IntTy::*; 2010 match i { 2011 Isize => tcx.types.isize, 2012 I8 => tcx.types.i8, 2013 I16 => tcx.types.i16, 2014 I32 => tcx.types.i32, 2015 I64 => tcx.types.i64, 2016 I128 => tcx.types.i128, 2017 } 2018 } 2019 2020 #[inline] new_uint(tcx: TyCtxt<'tcx>, ui: ty::UintTy) -> Ty<'tcx>2021 pub fn new_uint(tcx: TyCtxt<'tcx>, ui: ty::UintTy) -> Ty<'tcx> { 2022 use ty::UintTy::*; 2023 match ui { 2024 Usize => tcx.types.usize, 2025 U8 => tcx.types.u8, 2026 U16 => tcx.types.u16, 2027 U32 => tcx.types.u32, 2028 U64 => tcx.types.u64, 2029 U128 => tcx.types.u128, 2030 } 2031 } 2032 2033 #[inline] new_float(tcx: TyCtxt<'tcx>, f: ty::FloatTy) -> Ty<'tcx>2034 pub fn new_float(tcx: TyCtxt<'tcx>, f: ty::FloatTy) -> Ty<'tcx> { 2035 use ty::FloatTy::*; 2036 match f { 2037 F32 => tcx.types.f32, 2038 F64 => tcx.types.f64, 2039 } 2040 } 2041 2042 #[inline] new_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx>2043 pub fn new_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { 2044 Ty::new(tcx, Ref(r, tm.ty, tm.mutbl)) 2045 } 2046 2047 #[inline] new_mut_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx>2048 pub fn new_mut_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 2049 Ty::new_ref(tcx, r, TypeAndMut { ty, mutbl: hir::Mutability::Mut }) 2050 } 2051 2052 #[inline] new_imm_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx>2053 pub fn new_imm_ref(tcx: TyCtxt<'tcx>, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 2054 Ty::new_ref(tcx, r, TypeAndMut { ty, mutbl: hir::Mutability::Not }) 2055 } 2056 2057 #[inline] new_ptr(tcx: TyCtxt<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx>2058 pub fn new_ptr(tcx: TyCtxt<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { 2059 Ty::new(tcx, RawPtr(tm)) 2060 } 2061 2062 #[inline] new_mut_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx>2063 pub fn new_mut_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 2064 Ty::new_ptr(tcx, TypeAndMut { ty, mutbl: hir::Mutability::Mut }) 2065 } 2066 2067 #[inline] new_imm_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx>2068 pub fn new_imm_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 2069 Ty::new_ptr(tcx, TypeAndMut { ty, mutbl: hir::Mutability::Not }) 2070 } 2071 2072 #[inline] new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx>2073 pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> { 2074 Ty::new(tcx, Adt(def, substs)) 2075 } 2076 2077 #[inline] new_foreign(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx>2078 pub fn new_foreign(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> { 2079 Ty::new(tcx, Foreign(def_id)) 2080 } 2081 2082 #[inline] new_array(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, n: u64) -> Ty<'tcx>2083 pub fn new_array(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { 2084 Ty::new(tcx, Array(ty, ty::Const::from_target_usize(tcx, n))) 2085 } 2086 2087 #[inline] new_array_with_const_len( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, ct: ty::Const<'tcx>, ) -> Ty<'tcx>2088 pub fn new_array_with_const_len( 2089 tcx: TyCtxt<'tcx>, 2090 ty: Ty<'tcx>, 2091 ct: ty::Const<'tcx>, 2092 ) -> Ty<'tcx> { 2093 Ty::new(tcx, Array(ty, ct)) 2094 } 2095 2096 #[inline] new_slice(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx>2097 pub fn new_slice(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 2098 Ty::new(tcx, Slice(ty)) 2099 } 2100 2101 #[inline] new_tup(tcx: TyCtxt<'tcx>, ts: &[Ty<'tcx>]) -> Ty<'tcx>2102 pub fn new_tup(tcx: TyCtxt<'tcx>, ts: &[Ty<'tcx>]) -> Ty<'tcx> { 2103 if ts.is_empty() { tcx.types.unit } else { Ty::new(tcx, Tuple(tcx.mk_type_list(&ts))) } 2104 } 2105 new_tup_from_iter<I, T>(tcx: TyCtxt<'tcx>, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<Ty<'tcx>, Ty<'tcx>>,2106 pub fn new_tup_from_iter<I, T>(tcx: TyCtxt<'tcx>, iter: I) -> T::Output 2107 where 2108 I: Iterator<Item = T>, 2109 T: CollectAndApply<Ty<'tcx>, Ty<'tcx>>, 2110 { 2111 T::collect_and_apply(iter, |ts| Ty::new_tup(tcx, ts)) 2112 } 2113 2114 #[inline] new_fn_def( tcx: TyCtxt<'tcx>, def_id: DefId, substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> Ty<'tcx>2115 pub fn new_fn_def( 2116 tcx: TyCtxt<'tcx>, 2117 def_id: DefId, 2118 substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, 2119 ) -> Ty<'tcx> { 2120 let substs = tcx.check_and_mk_substs(def_id, substs); 2121 Ty::new(tcx, FnDef(def_id, substs)) 2122 } 2123 2124 #[inline] new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx>2125 pub fn new_fn_ptr(tcx: TyCtxt<'tcx>, fty: PolyFnSig<'tcx>) -> Ty<'tcx> { 2126 Ty::new(tcx, FnPtr(fty)) 2127 } 2128 2129 #[inline] new_dynamic( tcx: TyCtxt<'tcx>, obj: &'tcx List<PolyExistentialPredicate<'tcx>>, reg: ty::Region<'tcx>, repr: DynKind, ) -> Ty<'tcx>2130 pub fn new_dynamic( 2131 tcx: TyCtxt<'tcx>, 2132 obj: &'tcx List<PolyExistentialPredicate<'tcx>>, 2133 reg: ty::Region<'tcx>, 2134 repr: DynKind, 2135 ) -> Ty<'tcx> { 2136 Ty::new(tcx, Dynamic(obj, reg, repr)) 2137 } 2138 2139 #[inline] new_projection( tcx: TyCtxt<'tcx>, item_def_id: DefId, substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> Ty<'tcx>2140 pub fn new_projection( 2141 tcx: TyCtxt<'tcx>, 2142 item_def_id: DefId, 2143 substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, 2144 ) -> Ty<'tcx> { 2145 Ty::new_alias(tcx, ty::Projection, tcx.mk_alias_ty(item_def_id, substs)) 2146 } 2147 2148 #[inline] new_closure( tcx: TyCtxt<'tcx>, def_id: DefId, closure_substs: SubstsRef<'tcx>, ) -> Ty<'tcx>2149 pub fn new_closure( 2150 tcx: TyCtxt<'tcx>, 2151 def_id: DefId, 2152 closure_substs: SubstsRef<'tcx>, 2153 ) -> Ty<'tcx> { 2154 debug_assert_eq!( 2155 closure_substs.len(), 2156 tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3, 2157 "closure constructed with incorrect substitutions" 2158 ); 2159 Ty::new(tcx, Closure(def_id, closure_substs)) 2160 } 2161 2162 #[inline] new_generator( tcx: TyCtxt<'tcx>, def_id: DefId, generator_substs: SubstsRef<'tcx>, movability: hir::Movability, ) -> Ty<'tcx>2163 pub fn new_generator( 2164 tcx: TyCtxt<'tcx>, 2165 def_id: DefId, 2166 generator_substs: SubstsRef<'tcx>, 2167 movability: hir::Movability, 2168 ) -> Ty<'tcx> { 2169 debug_assert_eq!( 2170 generator_substs.len(), 2171 tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 5, 2172 "generator constructed with incorrect number of substitutions" 2173 ); 2174 Ty::new(tcx, Generator(def_id, generator_substs, movability)) 2175 } 2176 2177 #[inline] new_generator_witness( tcx: TyCtxt<'tcx>, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>, ) -> Ty<'tcx>2178 pub fn new_generator_witness( 2179 tcx: TyCtxt<'tcx>, 2180 types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>, 2181 ) -> Ty<'tcx> { 2182 Ty::new(tcx, GeneratorWitness(types)) 2183 } 2184 2185 #[inline] new_generator_witness_mir( tcx: TyCtxt<'tcx>, id: DefId, substs: SubstsRef<'tcx>, ) -> Ty<'tcx>2186 pub fn new_generator_witness_mir( 2187 tcx: TyCtxt<'tcx>, 2188 id: DefId, 2189 substs: SubstsRef<'tcx>, 2190 ) -> Ty<'tcx> { 2191 Ty::new(tcx, GeneratorWitnessMIR(id, substs)) 2192 } 2193 2194 // misc 2195 2196 #[inline] new_unit(tcx: TyCtxt<'tcx>) -> Ty<'tcx>2197 pub fn new_unit(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 2198 tcx.types.unit 2199 } 2200 2201 #[inline] new_static_str(tcx: TyCtxt<'tcx>) -> Ty<'tcx>2202 pub fn new_static_str(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 2203 Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_) 2204 } 2205 2206 #[inline] new_diverging_default(tcx: TyCtxt<'tcx>) -> Ty<'tcx>2207 pub fn new_diverging_default(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 2208 if tcx.features().never_type_fallback { tcx.types.never } else { tcx.types.unit } 2209 } 2210 2211 // lang and diagnostic tys 2212 new_generic_adt(tcx: TyCtxt<'tcx>, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx>2213 fn new_generic_adt(tcx: TyCtxt<'tcx>, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> { 2214 let adt_def = tcx.adt_def(wrapper_def_id); 2215 let substs = 2216 InternalSubsts::for_item(tcx, wrapper_def_id, |param, substs| match param.kind { 2217 GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(), 2218 GenericParamDefKind::Type { has_default, .. } => { 2219 if param.index == 0 { 2220 ty_param.into() 2221 } else { 2222 assert!(has_default); 2223 tcx.type_of(param.def_id).subst(tcx, substs).into() 2224 } 2225 } 2226 }); 2227 Ty::new(tcx, Adt(adt_def, substs)) 2228 } 2229 2230 #[inline] new_lang_item(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>>2231 pub fn new_lang_item(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, item: LangItem) -> Option<Ty<'tcx>> { 2232 let def_id = tcx.lang_items().get(item)?; 2233 Some(Ty::new_generic_adt(tcx, def_id, ty)) 2234 } 2235 2236 #[inline] new_diagnostic_item(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>>2237 pub fn new_diagnostic_item(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> { 2238 let def_id = tcx.get_diagnostic_item(name)?; 2239 Some(Ty::new_generic_adt(tcx, def_id, ty)) 2240 } 2241 2242 #[inline] new_box(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx>2243 pub fn new_box(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 2244 let def_id = tcx.require_lang_item(LangItem::OwnedBox, None); 2245 Ty::new_generic_adt(tcx, def_id, ty) 2246 } 2247 2248 #[inline] new_maybe_uninit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx>2249 pub fn new_maybe_uninit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { 2250 let def_id = tcx.require_lang_item(LangItem::MaybeUninit, None); 2251 Ty::new_generic_adt(tcx, def_id, ty) 2252 } 2253 2254 /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes. new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx>2255 pub fn new_task_context(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 2256 let context_did = tcx.require_lang_item(LangItem::Context, None); 2257 let context_adt_ref = tcx.adt_def(context_did); 2258 let context_substs = tcx.mk_substs(&[tcx.lifetimes.re_erased.into()]); 2259 let context_ty = Ty::new_adt(tcx, context_adt_ref, context_substs); 2260 Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, context_ty) 2261 } 2262 } 2263 2264 /// Type utilities 2265 impl<'tcx> Ty<'tcx> { 2266 #[inline(always)] kind(self) -> &'tcx TyKind<'tcx>2267 pub fn kind(self) -> &'tcx TyKind<'tcx> { 2268 &self.0.0 2269 } 2270 2271 #[inline(always)] flags(self) -> TypeFlags2272 pub fn flags(self) -> TypeFlags { 2273 self.0.0.flags 2274 } 2275 2276 #[inline] is_unit(self) -> bool2277 pub fn is_unit(self) -> bool { 2278 match self.kind() { 2279 Tuple(ref tys) => tys.is_empty(), 2280 _ => false, 2281 } 2282 } 2283 2284 #[inline] is_never(self) -> bool2285 pub fn is_never(self) -> bool { 2286 matches!(self.kind(), Never) 2287 } 2288 2289 #[inline] is_primitive(self) -> bool2290 pub fn is_primitive(self) -> bool { 2291 self.kind().is_primitive() 2292 } 2293 2294 #[inline] is_adt(self) -> bool2295 pub fn is_adt(self) -> bool { 2296 matches!(self.kind(), Adt(..)) 2297 } 2298 2299 #[inline] is_ref(self) -> bool2300 pub fn is_ref(self) -> bool { 2301 matches!(self.kind(), Ref(..)) 2302 } 2303 2304 #[inline] is_ty_var(self) -> bool2305 pub fn is_ty_var(self) -> bool { 2306 matches!(self.kind(), Infer(TyVar(_))) 2307 } 2308 2309 #[inline] ty_vid(self) -> Option<ty::TyVid>2310 pub fn ty_vid(self) -> Option<ty::TyVid> { 2311 match self.kind() { 2312 &Infer(TyVar(vid)) => Some(vid), 2313 _ => None, 2314 } 2315 } 2316 2317 #[inline] is_ty_or_numeric_infer(self) -> bool2318 pub fn is_ty_or_numeric_infer(self) -> bool { 2319 matches!(self.kind(), Infer(_)) 2320 } 2321 2322 #[inline] is_phantom_data(self) -> bool2323 pub fn is_phantom_data(self) -> bool { 2324 if let Adt(def, _) = self.kind() { def.is_phantom_data() } else { false } 2325 } 2326 2327 #[inline] is_bool(self) -> bool2328 pub fn is_bool(self) -> bool { 2329 *self.kind() == Bool 2330 } 2331 2332 /// Returns `true` if this type is a `str`. 2333 #[inline] is_str(self) -> bool2334 pub fn is_str(self) -> bool { 2335 *self.kind() == Str 2336 } 2337 2338 #[inline] is_param(self, index: u32) -> bool2339 pub fn is_param(self, index: u32) -> bool { 2340 match self.kind() { 2341 ty::Param(ref data) => data.index == index, 2342 _ => false, 2343 } 2344 } 2345 2346 #[inline] is_slice(self) -> bool2347 pub fn is_slice(self) -> bool { 2348 matches!(self.kind(), Slice(_)) 2349 } 2350 2351 #[inline] is_array_slice(self) -> bool2352 pub fn is_array_slice(self) -> bool { 2353 match self.kind() { 2354 Slice(_) => true, 2355 RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => matches!(ty.kind(), Slice(_)), 2356 _ => false, 2357 } 2358 } 2359 2360 #[inline] is_array(self) -> bool2361 pub fn is_array(self) -> bool { 2362 matches!(self.kind(), Array(..)) 2363 } 2364 2365 #[inline] is_simd(self) -> bool2366 pub fn is_simd(self) -> bool { 2367 match self.kind() { 2368 Adt(def, _) => def.repr().simd(), 2369 _ => false, 2370 } 2371 } 2372 sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>2373 pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 2374 match self.kind() { 2375 Array(ty, _) | Slice(ty) => *ty, 2376 Str => tcx.types.u8, 2377 _ => bug!("`sequence_element_type` called on non-sequence value: {}", self), 2378 } 2379 } 2380 simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>)2381 pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) { 2382 match self.kind() { 2383 Adt(def, substs) => { 2384 assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type"); 2385 let variant = def.non_enum_variant(); 2386 let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, substs); 2387 2388 match f0_ty.kind() { 2389 // If the first field is an array, we assume it is the only field and its 2390 // elements are the SIMD components. 2391 Array(f0_elem_ty, f0_len) => { 2392 // FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112 2393 // The way we evaluate the `N` in `[T; N]` here only works since we use 2394 // `simd_size_and_type` post-monomorphization. It will probably start to ICE 2395 // if we use it in generic code. See the `simd-array-trait` ui test. 2396 (f0_len.eval_target_usize(tcx, ParamEnv::empty()), *f0_elem_ty) 2397 } 2398 // Otherwise, the fields of this Adt are the SIMD components (and we assume they 2399 // all have the same type). 2400 _ => (variant.fields.len() as u64, f0_ty), 2401 } 2402 } 2403 _ => bug!("`simd_size_and_type` called on invalid type"), 2404 } 2405 } 2406 2407 #[inline] is_mutable_ptr(self) -> bool2408 pub fn is_mutable_ptr(self) -> bool { 2409 matches!( 2410 self.kind(), 2411 RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. }) 2412 | Ref(_, _, hir::Mutability::Mut) 2413 ) 2414 } 2415 2416 /// Get the mutability of the reference or `None` when not a reference 2417 #[inline] ref_mutability(self) -> Option<hir::Mutability>2418 pub fn ref_mutability(self) -> Option<hir::Mutability> { 2419 match self.kind() { 2420 Ref(_, _, mutability) => Some(*mutability), 2421 _ => None, 2422 } 2423 } 2424 2425 #[inline] is_unsafe_ptr(self) -> bool2426 pub fn is_unsafe_ptr(self) -> bool { 2427 matches!(self.kind(), RawPtr(_)) 2428 } 2429 2430 /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer). 2431 #[inline] is_any_ptr(self) -> bool2432 pub fn is_any_ptr(self) -> bool { 2433 self.is_ref() || self.is_unsafe_ptr() || self.is_fn_ptr() 2434 } 2435 2436 #[inline] is_box(self) -> bool2437 pub fn is_box(self) -> bool { 2438 match self.kind() { 2439 Adt(def, _) => def.is_box(), 2440 _ => false, 2441 } 2442 } 2443 2444 /// Panics if called on any type other than `Box<T>`. boxed_ty(self) -> Ty<'tcx>2445 pub fn boxed_ty(self) -> Ty<'tcx> { 2446 match self.kind() { 2447 Adt(def, substs) if def.is_box() => substs.type_at(0), 2448 _ => bug!("`boxed_ty` is called on non-box type {:?}", self), 2449 } 2450 } 2451 2452 /// A scalar type is one that denotes an atomic datum, with no sub-components. 2453 /// (A RawPtr is scalar because it represents a non-managed pointer, so its 2454 /// contents are abstract to rustc.) 2455 #[inline] is_scalar(self) -> bool2456 pub fn is_scalar(self) -> bool { 2457 matches!( 2458 self.kind(), 2459 Bool | Char 2460 | Int(_) 2461 | Float(_) 2462 | Uint(_) 2463 | FnDef(..) 2464 | FnPtr(_) 2465 | RawPtr(_) 2466 | Infer(IntVar(_) | FloatVar(_)) 2467 ) 2468 } 2469 2470 /// Returns `true` if this type is a floating point type. 2471 #[inline] is_floating_point(self) -> bool2472 pub fn is_floating_point(self) -> bool { 2473 matches!(self.kind(), Float(_) | Infer(FloatVar(_))) 2474 } 2475 2476 #[inline] is_trait(self) -> bool2477 pub fn is_trait(self) -> bool { 2478 matches!(self.kind(), Dynamic(_, _, ty::Dyn)) 2479 } 2480 2481 #[inline] is_dyn_star(self) -> bool2482 pub fn is_dyn_star(self) -> bool { 2483 matches!(self.kind(), Dynamic(_, _, ty::DynStar)) 2484 } 2485 2486 #[inline] is_enum(self) -> bool2487 pub fn is_enum(self) -> bool { 2488 matches!(self.kind(), Adt(adt_def, _) if adt_def.is_enum()) 2489 } 2490 2491 #[inline] is_union(self) -> bool2492 pub fn is_union(self) -> bool { 2493 matches!(self.kind(), Adt(adt_def, _) if adt_def.is_union()) 2494 } 2495 2496 #[inline] is_closure(self) -> bool2497 pub fn is_closure(self) -> bool { 2498 matches!(self.kind(), Closure(..)) 2499 } 2500 2501 #[inline] is_generator(self) -> bool2502 pub fn is_generator(self) -> bool { 2503 matches!(self.kind(), Generator(..)) 2504 } 2505 2506 #[inline] is_integral(self) -> bool2507 pub fn is_integral(self) -> bool { 2508 matches!(self.kind(), Infer(IntVar(_)) | Int(_) | Uint(_)) 2509 } 2510 2511 #[inline] is_fresh_ty(self) -> bool2512 pub fn is_fresh_ty(self) -> bool { 2513 matches!(self.kind(), Infer(FreshTy(_))) 2514 } 2515 2516 #[inline] is_fresh(self) -> bool2517 pub fn is_fresh(self) -> bool { 2518 matches!(self.kind(), Infer(FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_))) 2519 } 2520 2521 #[inline] is_char(self) -> bool2522 pub fn is_char(self) -> bool { 2523 matches!(self.kind(), Char) 2524 } 2525 2526 #[inline] is_numeric(self) -> bool2527 pub fn is_numeric(self) -> bool { 2528 self.is_integral() || self.is_floating_point() 2529 } 2530 2531 #[inline] is_signed(self) -> bool2532 pub fn is_signed(self) -> bool { 2533 matches!(self.kind(), Int(_)) 2534 } 2535 2536 #[inline] is_ptr_sized_integral(self) -> bool2537 pub fn is_ptr_sized_integral(self) -> bool { 2538 matches!(self.kind(), Int(ty::IntTy::Isize) | Uint(ty::UintTy::Usize)) 2539 } 2540 2541 #[inline] has_concrete_skeleton(self) -> bool2542 pub fn has_concrete_skeleton(self) -> bool { 2543 !matches!(self.kind(), Param(_) | Infer(_) | Error(_)) 2544 } 2545 2546 /// Checks whether a type recursively contains another type 2547 /// 2548 /// Example: `Option<()>` contains `()` contains(self, other: Ty<'tcx>) -> bool2549 pub fn contains(self, other: Ty<'tcx>) -> bool { 2550 struct ContainsTyVisitor<'tcx>(Ty<'tcx>); 2551 2552 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor<'tcx> { 2553 type BreakTy = (); 2554 2555 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { 2556 if self.0 == t { ControlFlow::Break(()) } else { t.super_visit_with(self) } 2557 } 2558 } 2559 2560 let cf = self.visit_with(&mut ContainsTyVisitor(other)); 2561 cf.is_break() 2562 } 2563 2564 /// Checks whether a type recursively contains any closure 2565 /// 2566 /// Example: `Option<[closure@file.rs:4:20]>` returns true contains_closure(self) -> bool2567 pub fn contains_closure(self) -> bool { 2568 struct ContainsClosureVisitor; 2569 2570 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsClosureVisitor { 2571 type BreakTy = (); 2572 2573 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { 2574 if let ty::Closure(_, _) = t.kind() { 2575 ControlFlow::Break(()) 2576 } else { 2577 t.super_visit_with(self) 2578 } 2579 } 2580 } 2581 2582 let cf = self.visit_with(&mut ContainsClosureVisitor); 2583 cf.is_break() 2584 } 2585 2586 /// Returns the type and mutability of `*ty`. 2587 /// 2588 /// The parameter `explicit` indicates if this is an *explicit* dereference. 2589 /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly. builtin_deref(self, explicit: bool) -> Option<TypeAndMut<'tcx>>2590 pub fn builtin_deref(self, explicit: bool) -> Option<TypeAndMut<'tcx>> { 2591 match self.kind() { 2592 Adt(def, _) if def.is_box() => { 2593 Some(TypeAndMut { ty: self.boxed_ty(), mutbl: hir::Mutability::Not }) 2594 } 2595 Ref(_, ty, mutbl) => Some(TypeAndMut { ty: *ty, mutbl: *mutbl }), 2596 RawPtr(mt) if explicit => Some(*mt), 2597 _ => None, 2598 } 2599 } 2600 2601 /// Returns the type of `ty[i]`. builtin_index(self) -> Option<Ty<'tcx>>2602 pub fn builtin_index(self) -> Option<Ty<'tcx>> { 2603 match self.kind() { 2604 Array(ty, _) | Slice(ty) => Some(*ty), 2605 _ => None, 2606 } 2607 } 2608 fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx>2609 pub fn fn_sig(self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> { 2610 match self.kind() { 2611 FnDef(def_id, substs) => tcx.fn_sig(*def_id).subst(tcx, substs), 2612 FnPtr(f) => *f, 2613 Error(_) => { 2614 // ignore errors (#54954) 2615 ty::Binder::dummy(FnSig::fake()) 2616 } 2617 Closure(..) => bug!( 2618 "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`", 2619 ), 2620 _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self), 2621 } 2622 } 2623 2624 #[inline] is_fn(self) -> bool2625 pub fn is_fn(self) -> bool { 2626 matches!(self.kind(), FnDef(..) | FnPtr(_)) 2627 } 2628 2629 #[inline] is_fn_ptr(self) -> bool2630 pub fn is_fn_ptr(self) -> bool { 2631 matches!(self.kind(), FnPtr(_)) 2632 } 2633 2634 #[inline] is_impl_trait(self) -> bool2635 pub fn is_impl_trait(self) -> bool { 2636 matches!(self.kind(), Alias(ty::Opaque, ..)) 2637 } 2638 2639 #[inline] ty_adt_def(self) -> Option<AdtDef<'tcx>>2640 pub fn ty_adt_def(self) -> Option<AdtDef<'tcx>> { 2641 match self.kind() { 2642 Adt(adt, _) => Some(*adt), 2643 _ => None, 2644 } 2645 } 2646 2647 /// Iterates over tuple fields. 2648 /// Panics when called on anything but a tuple. 2649 #[inline] tuple_fields(self) -> &'tcx List<Ty<'tcx>>2650 pub fn tuple_fields(self) -> &'tcx List<Ty<'tcx>> { 2651 match self.kind() { 2652 Tuple(substs) => substs, 2653 _ => bug!("tuple_fields called on non-tuple"), 2654 } 2655 } 2656 2657 /// If the type contains variants, returns the valid range of variant indices. 2658 // 2659 // FIXME: This requires the optimized MIR in the case of generators. 2660 #[inline] variant_range(self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>>2661 pub fn variant_range(self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> { 2662 match self.kind() { 2663 TyKind::Adt(adt, _) => Some(adt.variant_range()), 2664 TyKind::Generator(def_id, substs, _) => { 2665 Some(substs.as_generator().variant_range(*def_id, tcx)) 2666 } 2667 _ => None, 2668 } 2669 } 2670 2671 /// If the type contains variants, returns the variant for `variant_index`. 2672 /// Panics if `variant_index` is out of range. 2673 // 2674 // FIXME: This requires the optimized MIR in the case of generators. 2675 #[inline] discriminant_for_variant( self, tcx: TyCtxt<'tcx>, variant_index: VariantIdx, ) -> Option<Discr<'tcx>>2676 pub fn discriminant_for_variant( 2677 self, 2678 tcx: TyCtxt<'tcx>, 2679 variant_index: VariantIdx, 2680 ) -> Option<Discr<'tcx>> { 2681 match self.kind() { 2682 TyKind::Adt(adt, _) if adt.variants().is_empty() => { 2683 // This can actually happen during CTFE, see 2684 // https://github.com/rust-lang/rust/issues/89765. 2685 None 2686 } 2687 TyKind::Adt(adt, _) if adt.is_enum() => { 2688 Some(adt.discriminant_for_variant(tcx, variant_index)) 2689 } 2690 TyKind::Generator(def_id, substs, _) => { 2691 Some(substs.as_generator().discriminant_for_variant(*def_id, tcx, variant_index)) 2692 } 2693 _ => None, 2694 } 2695 } 2696 2697 /// Returns the type of the discriminant of this type. discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>2698 pub fn discriminant_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { 2699 match self.kind() { 2700 ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx), 2701 ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx), 2702 2703 ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => { 2704 let assoc_items = tcx.associated_item_def_ids( 2705 tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), 2706 ); 2707 Ty::new_projection(tcx, assoc_items[0], tcx.mk_substs(&[self.into()])) 2708 } 2709 2710 ty::Bool 2711 | ty::Char 2712 | ty::Int(_) 2713 | ty::Uint(_) 2714 | ty::Float(_) 2715 | ty::Adt(..) 2716 | ty::Foreign(_) 2717 | ty::Str 2718 | ty::Array(..) 2719 | ty::Slice(_) 2720 | ty::RawPtr(_) 2721 | ty::Ref(..) 2722 | ty::FnDef(..) 2723 | ty::FnPtr(..) 2724 | ty::Dynamic(..) 2725 | ty::Closure(..) 2726 | ty::GeneratorWitness(..) 2727 | ty::GeneratorWitnessMIR(..) 2728 | ty::Never 2729 | ty::Tuple(_) 2730 | ty::Error(_) 2731 | ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8, 2732 2733 ty::Bound(..) 2734 | ty::Placeholder(_) 2735 | ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { 2736 bug!("`discriminant_ty` applied to unexpected type: {:?}", self) 2737 } 2738 } 2739 } 2740 2741 /// Returns the type of metadata for (potentially fat) pointers to this type, 2742 /// and a boolean signifying if this is conditional on this type being `Sized`. ptr_metadata_ty( self, tcx: TyCtxt<'tcx>, normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, ) -> (Ty<'tcx>, bool)2743 pub fn ptr_metadata_ty( 2744 self, 2745 tcx: TyCtxt<'tcx>, 2746 normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, 2747 ) -> (Ty<'tcx>, bool) { 2748 let tail = tcx.struct_tail_with_normalize(self, normalize, || {}); 2749 match tail.kind() { 2750 // Sized types 2751 ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) 2752 | ty::Uint(_) 2753 | ty::Int(_) 2754 | ty::Bool 2755 | ty::Float(_) 2756 | ty::FnDef(..) 2757 | ty::FnPtr(_) 2758 | ty::RawPtr(..) 2759 | ty::Char 2760 | ty::Ref(..) 2761 | ty::Generator(..) 2762 | ty::GeneratorWitness(..) 2763 | ty::GeneratorWitnessMIR(..) 2764 | ty::Array(..) 2765 | ty::Closure(..) 2766 | ty::Never 2767 | ty::Error(_) 2768 // Extern types have metadata = (). 2769 | ty::Foreign(..) 2770 // If returned by `struct_tail_without_normalization` this is a unit struct 2771 // without any fields, or not a struct, and therefore is Sized. 2772 | ty::Adt(..) 2773 // If returned by `struct_tail_without_normalization` this is the empty tuple, 2774 // a.k.a. unit type, which is Sized 2775 | ty::Tuple(..) => (tcx.types.unit, false), 2776 2777 ty::Str | ty::Slice(_) => (tcx.types.usize, false), 2778 ty::Dynamic(..) => { 2779 let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); 2780 (tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) 2781 }, 2782 2783 // type parameters only have unit metadata if they're sized, so return true 2784 // to make sure we double check this during confirmation 2785 ty::Param(_) | ty::Alias(..) => (tcx.types.unit, true), 2786 2787 ty::Infer(ty::TyVar(_)) 2788 | ty::Bound(..) 2789 | ty::Placeholder(..) 2790 | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { 2791 bug!("`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})", self, tail) 2792 } 2793 } 2794 } 2795 2796 /// When we create a closure, we record its kind (i.e., what trait 2797 /// it implements) into its `ClosureSubsts` using a type 2798 /// parameter. This is kind of a phantom type, except that the 2799 /// most convenient thing for us to are the integral types. This 2800 /// function converts such a special type into the closure 2801 /// kind. To go the other way, use `closure_kind.to_ty(tcx)`. 2802 /// 2803 /// Note that during type checking, we use an inference variable 2804 /// to represent the closure kind, because it has not yet been 2805 /// inferred. Once upvar inference (in `rustc_hir_analysis/src/check/upvar.rs`) 2806 /// is complete, that type variable will be unified. to_opt_closure_kind(self) -> Option<ty::ClosureKind>2807 pub fn to_opt_closure_kind(self) -> Option<ty::ClosureKind> { 2808 match self.kind() { 2809 Int(int_ty) => match int_ty { 2810 ty::IntTy::I8 => Some(ty::ClosureKind::Fn), 2811 ty::IntTy::I16 => Some(ty::ClosureKind::FnMut), 2812 ty::IntTy::I32 => Some(ty::ClosureKind::FnOnce), 2813 _ => bug!("cannot convert type `{:?}` to a closure kind", self), 2814 }, 2815 2816 // "Bound" types appear in canonical queries when the 2817 // closure type is not yet known 2818 Bound(..) | Infer(_) => None, 2819 2820 Error(_) => Some(ty::ClosureKind::Fn), 2821 2822 _ => bug!("cannot convert type `{:?}` to a closure kind", self), 2823 } 2824 } 2825 2826 /// Fast path helper for testing if a type is `Sized`. 2827 /// 2828 /// Returning true means the type is known to be sized. Returning 2829 /// `false` means nothing -- could be sized, might not be. 2830 /// 2831 /// Note that we could never rely on the fact that a type such as `[_]` is 2832 /// trivially `!Sized` because we could be in a type environment with a 2833 /// bound such as `[_]: Copy`. A function with such a bound obviously never 2834 /// can be called, but that doesn't mean it shouldn't typecheck. This is why 2835 /// this method doesn't return `Option<bool>`. is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool2836 pub fn is_trivially_sized(self, tcx: TyCtxt<'tcx>) -> bool { 2837 match self.kind() { 2838 ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) 2839 | ty::Uint(_) 2840 | ty::Int(_) 2841 | ty::Bool 2842 | ty::Float(_) 2843 | ty::FnDef(..) 2844 | ty::FnPtr(_) 2845 | ty::RawPtr(..) 2846 | ty::Char 2847 | ty::Ref(..) 2848 | ty::Generator(..) 2849 | ty::GeneratorWitness(..) 2850 | ty::GeneratorWitnessMIR(..) 2851 | ty::Array(..) 2852 | ty::Closure(..) 2853 | ty::Never 2854 | ty::Error(_) => true, 2855 2856 ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false, 2857 2858 ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)), 2859 2860 ty::Adt(def, _substs) => def.sized_constraint(tcx).skip_binder().is_empty(), 2861 2862 ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) => false, 2863 2864 ty::Infer(ty::TyVar(_)) => false, 2865 2866 ty::Bound(..) | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { 2867 bug!("`is_trivially_sized` applied to unexpected type: {:?}", self) 2868 } 2869 } 2870 } 2871 2872 /// Fast path helper for primitives which are always `Copy` and which 2873 /// have a side-effect-free `Clone` impl. 2874 /// 2875 /// Returning true means the type is known to be pure and `Copy+Clone`. 2876 /// Returning `false` means nothing -- could be `Copy`, might not be. 2877 /// 2878 /// This is mostly useful for optimizations, as there are the types 2879 /// on which we can replace cloning with dereferencing. is_trivially_pure_clone_copy(self) -> bool2880 pub fn is_trivially_pure_clone_copy(self) -> bool { 2881 match self.kind() { 2882 ty::Bool | ty::Char | ty::Never => true, 2883 2884 // These aren't even `Clone` 2885 ty::Str | ty::Slice(..) | ty::Foreign(..) | ty::Dynamic(..) => false, 2886 2887 ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_)) 2888 | ty::Int(..) 2889 | ty::Uint(..) 2890 | ty::Float(..) => true, 2891 2892 // The voldemort ZSTs are fine. 2893 ty::FnDef(..) => true, 2894 2895 ty::Array(element_ty, _len) => element_ty.is_trivially_pure_clone_copy(), 2896 2897 // A 100-tuple isn't "trivial", so doing this only for reasonable sizes. 2898 ty::Tuple(field_tys) => { 2899 field_tys.len() <= 3 && field_tys.iter().all(Self::is_trivially_pure_clone_copy) 2900 } 2901 2902 // Sometimes traits aren't implemented for every ABI or arity, 2903 // because we can't be generic over everything yet. 2904 ty::FnPtr(..) => false, 2905 2906 // Definitely absolutely not copy. 2907 ty::Ref(_, _, hir::Mutability::Mut) => false, 2908 2909 // Thin pointers & thin shared references are pure-clone-copy, but for 2910 // anything with custom metadata it might be more complicated. 2911 ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false, 2912 2913 ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => false, 2914 2915 // Might be, but not "trivial" so just giving the safe answer. 2916 ty::Adt(..) | ty::Closure(..) => false, 2917 2918 // Needs normalization or revealing to determine, so no is the safe answer. 2919 ty::Alias(..) => false, 2920 2921 ty::Param(..) | ty::Infer(..) | ty::Error(..) => false, 2922 2923 ty::Bound(..) | ty::Placeholder(..) => { 2924 bug!("`is_trivially_pure_clone_copy` applied to unexpected type: {:?}", self); 2925 } 2926 } 2927 } 2928 2929 /// If `self` is a primitive, return its [`Symbol`]. primitive_symbol(self) -> Option<Symbol>2930 pub fn primitive_symbol(self) -> Option<Symbol> { 2931 match self.kind() { 2932 ty::Bool => Some(sym::bool), 2933 ty::Char => Some(sym::char), 2934 ty::Float(f) => match f { 2935 ty::FloatTy::F32 => Some(sym::f32), 2936 ty::FloatTy::F64 => Some(sym::f64), 2937 }, 2938 ty::Int(f) => match f { 2939 ty::IntTy::Isize => Some(sym::isize), 2940 ty::IntTy::I8 => Some(sym::i8), 2941 ty::IntTy::I16 => Some(sym::i16), 2942 ty::IntTy::I32 => Some(sym::i32), 2943 ty::IntTy::I64 => Some(sym::i64), 2944 ty::IntTy::I128 => Some(sym::i128), 2945 }, 2946 ty::Uint(f) => match f { 2947 ty::UintTy::Usize => Some(sym::usize), 2948 ty::UintTy::U8 => Some(sym::u8), 2949 ty::UintTy::U16 => Some(sym::u16), 2950 ty::UintTy::U32 => Some(sym::u32), 2951 ty::UintTy::U64 => Some(sym::u64), 2952 ty::UintTy::U128 => Some(sym::u128), 2953 }, 2954 _ => None, 2955 } 2956 } 2957 is_c_void(self, tcx: TyCtxt<'_>) -> bool2958 pub fn is_c_void(self, tcx: TyCtxt<'_>) -> bool { 2959 match self.kind() { 2960 ty::Adt(adt, _) => tcx.lang_items().get(LangItem::CVoid) == Some(adt.did()), 2961 _ => false, 2962 } 2963 } 2964 } 2965 2966 /// Extra information about why we ended up with a particular variance. 2967 /// This is only used to add more information to error messages, and 2968 /// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo` 2969 /// may lead to confusing notes in error messages, it will never cause 2970 /// a miscompilation or unsoundness. 2971 /// 2972 /// When in doubt, use `VarianceDiagInfo::default()` 2973 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] 2974 pub enum VarianceDiagInfo<'tcx> { 2975 /// No additional information - this is the default. 2976 /// We will not add any additional information to error messages. 2977 #[default] 2978 None, 2979 /// We switched our variance because a generic argument occurs inside 2980 /// the invariant generic argument of another type. 2981 Invariant { 2982 /// The generic type containing the generic parameter 2983 /// that changes the variance (e.g. `*mut T`, `MyStruct<T>`) 2984 ty: Ty<'tcx>, 2985 /// The index of the generic parameter being used 2986 /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`) 2987 param_index: u32, 2988 }, 2989 } 2990 2991 impl<'tcx> VarianceDiagInfo<'tcx> { 2992 /// Mirrors `Variance::xform` - used to 'combine' the existing 2993 /// and new `VarianceDiagInfo`s when our variance changes. xform(self, other: VarianceDiagInfo<'tcx>) -> VarianceDiagInfo<'tcx>2994 pub fn xform(self, other: VarianceDiagInfo<'tcx>) -> VarianceDiagInfo<'tcx> { 2995 // For now, just use the first `VarianceDiagInfo::Invariant` that we see 2996 match self { 2997 VarianceDiagInfo::None => other, 2998 VarianceDiagInfo::Invariant { .. } => self, 2999 } 3000 } 3001 } 3002 3003 // Some types are used a lot. Make sure they don't unintentionally get bigger. 3004 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] 3005 mod size_asserts { 3006 use super::*; 3007 use rustc_data_structures::static_assert_size; 3008 // tidy-alphabetical-start 3009 static_assert_size!(RegionKind<'_>, 28); 3010 static_assert_size!(TyKind<'_>, 32); 3011 // tidy-alphabetical-end 3012 } 3013