]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/ty/mod.rs
New upstream version 1.58.1+dfsg1
[rustc.git] / compiler / rustc_middle / src / ty / mod.rs
CommitLineData
fc512014
XL
1//! Defines how the compiler represents types internally.
2//!
3//! Two important entities in this module are:
4//!
5//! - [`rustc_middle::ty::Ty`], used to represent the semantics of a type.
6//! - [`rustc_middle::ty::TyCtxt`], the central data structure in the compiler.
7//!
8//! For more information, see ["The `ty` module: representing types"] in the ructc-dev-guide.
9//!
10//! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html
11
3dfed10e 12pub use self::fold::{TypeFoldable, TypeFolder, TypeVisitor};
dc9dc135 13pub use self::AssocItemContainer::*;
e9174d1e 14pub use self::BorrowKind::*;
e9174d1e 15pub use self::IntVarValue::*;
dfeec247 16pub use self::Variance::*;
6a06907d
XL
17pub use adt::*;
18pub use assoc::*;
6a06907d 19pub use generics::*;
136023e0 20pub use vtable::*;
dfeec247 21
dfeec247 22use crate::hir::exports::ExportMap;
6a06907d 23use crate::mir::{Body, GeneratorLayout};
9fa01778
XL
24use crate::traits::{self, Reveal};
25use crate::ty;
f035d41b 26use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
6a06907d 27use crate::ty::util::Discr;
3dfed10e 28use rustc_ast as ast;
74b04a01 29use rustc_attr as attr;
6a06907d 30use rustc_data_structures::fx::{FxHashMap, FxHashSet};
dfeec247 31use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3dfed10e 32use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
dfeec247 33use rustc_hir as hir;
6a06907d 34use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
17df50a5 35use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_INDEX};
94222f64 36use rustc_hir::Node;
dfeec247 37use rustc_macros::HashStable;
c295e0f8
XL
38use rustc_query_system::ich::StableHashingContext;
39use rustc_session::cstore::CrateStoreDyn;
6a06907d 40use rustc_span::symbol::{kw, Ident, Symbol};
c295e0f8 41use rustc_span::{sym, Span};
6a06907d 42use rustc_target::abi::Align;
74b04a01 43
f9f354fc 44use std::cmp::Ordering;
94222f64 45use std::collections::BTreeMap;
e9174d1e 46use std::hash::{Hash, Hasher};
6a06907d
XL
47use std::ops::ControlFlow;
48use std::{fmt, ptr, str};
54a0048b 49
60c5eb7d 50pub use crate::ty::diagnostics::*;
5869c6ff
XL
51pub use rustc_type_ir::InferTy::*;
52pub use rustc_type_ir::*;
e9174d1e 53
3b2f2976
XL
54pub use self::binding::BindingMode;
55pub use self::binding::BindingMode::*;
94222f64
XL
56pub use self::closure::{
57 is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
58 CapturedPlace, ClosureKind, MinCaptureInformationMap, MinCaptureList,
59 RootVariableMinCaptureList, UpvarBorrow, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap,
60 UpvarPath, CAPTURE_STRUCT_LOCAL,
61};
cdc7bbd5 62pub use self::consts::{Const, ConstInt, ConstKind, InferConst, ScalarInt, Unevaluated, ValTree};
0731742a 63pub use self::context::{
6a06907d
XL
64 tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
65 CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt,
136023e0 66 Lift, OnDiskCache, TyCtxt, TypeckResults, UserType, UserTypeAnnotationIndex,
0731742a 67};
cc61c64b 68pub use self::instance::{Instance, InstanceDef};
f9f354fc 69pub use self::list::List;
6a06907d
XL
70pub use self::sty::BoundRegionKind::*;
71pub use self::sty::RegionKind::*;
72pub use self::sty::TyKind::*;
73pub use self::sty::{
cdc7bbd5
XL
74 Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind,
75 CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion,
76 ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig,
3c0e092e
XL
77 GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts, InlineConstSubstsParts, ParamConst,
78 ParamTy, PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig,
79 PolyTraitRef, ProjectionTy, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut,
80 UpvarSubsts, VarianceDiagInfo, VarianceDiagMutKind,
6a06907d 81};
7cac9316 82pub use self::trait_def::TraitDef;
9cc50fc6 83
3dfed10e 84pub mod _match;
e9174d1e 85pub mod adjustment;
3b2f2976 86pub mod binding;
e9174d1e 87pub mod cast;
abe05a73 88pub mod codec;
dfeec247 89pub mod error;
e9174d1e 90pub mod fast_reject;
48663c56 91pub mod flags;
e9174d1e 92pub mod fold;
32a655c1 93pub mod inhabitedness;
54a0048b 94pub mod layout;
dfeec247 95pub mod normalize_erasing_regions;
532ac7d7 96pub mod print;
94b46f34 97pub mod query;
e9174d1e 98pub mod relate;
54a0048b 99pub mod subst;
9cc50fc6 100pub mod trait_def;
e9174d1e 101pub mod util;
136023e0 102pub mod vtable;
dfeec247 103pub mod walk;
e9174d1e 104
6a06907d
XL
105mod adt;
106mod assoc;
107mod closure;
f035d41b 108mod consts;
e9174d1e 109mod context;
dfeec247 110mod diagnostics;
6a06907d
XL
111mod erase_regions;
112mod generics;
c295e0f8 113mod impls_ty;
cc61c64b 114mod instance;
f9f354fc 115mod list;
e9174d1e
SL
116mod structural_impls;
117mod sty;
118
e9174d1e
SL
119// Data types
120
136023e0 121#[derive(Debug)]
e74abb32 122pub struct ResolverOutputs {
ba9703b0 123 pub definitions: rustc_hir::definitions::Definitions,
e74abb32 124 pub cstore: Box<CrateStoreDyn>,
29967ef6 125 pub visibilities: FxHashMap<LocalDefId, Visibility>,
f9f354fc 126 pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
f9f354fc
XL
127 pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
128 pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
c295e0f8 129 pub export_map: ExportMap,
f9f354fc 130 pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
0bf4aa26
XL
131 /// Extern prelude entries. The value is `true` if the entry was introduced
132 /// via `extern crate` item and not `--extern` option or compiler built-in.
f9f354fc 133 pub extern_prelude: FxHashMap<Symbol, bool>,
cdc7bbd5 134 pub main_def: Option<MainDefinition>,
94222f64
XL
135 pub trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
136 /// A list of proc macro LocalDefIds, written out in the order in which
137 /// they are declared in the static array generated by proc_macro_harness.
138 pub proc_macros: Vec<LocalDefId>,
c295e0f8
XL
139 /// Mapping from ident span to path span for paths that don't exist as written, but that
140 /// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
141 pub confused_type_with_std_module: FxHashMap<Span, Span>,
cdc7bbd5
XL
142}
143
136023e0 144#[derive(Clone, Copy, Debug)]
cdc7bbd5
XL
145pub struct MainDefinition {
146 pub res: Res<ast::NodeId>,
147 pub is_import: bool,
148 pub span: Span,
149}
150
151impl MainDefinition {
152 pub fn opt_fn_def_id(self) -> Option<DefId> {
153 if let Res::Def(DefKind::Fn, def_id) = self.res { Some(def_id) } else { None }
154 }
e9174d1e
SL
155}
156
54a0048b
SL
157/// The "header" of an impl is everything outside the body: a Self type, a trait
158/// ref (in the case of a trait impl), and a set of predicates (from the
9fa01778 159/// bounds / where-clauses).
60c5eb7d 160#[derive(Clone, Debug, TypeFoldable)]
54a0048b
SL
161pub struct ImplHeader<'tcx> {
162 pub impl_def_id: DefId,
163 pub self_ty: Ty<'tcx>,
164 pub trait_ref: Option<TraitRef<'tcx>>,
165 pub predicates: Vec<Predicate<'tcx>>,
166}
167
3c0e092e
XL
168#[derive(
169 Copy,
170 Clone,
171 PartialEq,
172 Eq,
173 Hash,
174 TyEncodable,
175 TyDecodable,
176 HashStable,
177 Debug,
178 TypeFoldable
179)]
e74abb32
XL
180pub enum ImplPolarity {
181 /// `impl Trait for Type`
182 Positive,
183 /// `impl !Trait for Type`
184 Negative,
185 /// `#[rustc_reservation_impl] impl Trait for Type`
186 ///
187 /// This is a "stability hack", not a real Rust feature.
188 /// See #64631 for details.
189 Reservation,
190}
191
3c0e092e
XL
192impl ImplPolarity {
193 /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`.
194 pub fn flip(&self) -> Option<ImplPolarity> {
195 match self {
196 ImplPolarity::Positive => Some(ImplPolarity::Negative),
197 ImplPolarity::Negative => Some(ImplPolarity::Positive),
198 ImplPolarity::Reservation => None,
199 }
200 }
201}
202
203impl fmt::Display for ImplPolarity {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 match self {
206 Self::Positive => f.write_str("positive"),
207 Self::Negative => f.write_str("negative"),
208 Self::Reservation => f.write_str("reservation"),
209 }
210 }
211}
212
3dfed10e 213#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
54a0048b
SL
214pub enum Visibility {
215 /// Visible everywhere (including in other crates).
216 Public,
217 /// Visible only in the given crate-local module.
32a655c1 218 Restricted(DefId),
54a0048b 219 /// Not visible anywhere in the local crate. This is the visibility of private external items.
32a655c1 220 Invisible,
54a0048b
SL
221}
222
94222f64
XL
223#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
224pub enum BoundConstness {
225 /// `T: Trait`
226 NotConst,
227 /// `T: ~const Trait`
228 ///
229 /// Requires resolving to const only when we are in a const context.
230 ConstIfConst,
231}
232
233impl fmt::Display for BoundConstness {
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 match self {
236 Self::NotConst => f.write_str("normal"),
237 Self::ConstIfConst => f.write_str("`~const`"),
238 }
239 }
240}
241
136023e0
XL
242#[derive(
243 Clone,
244 Debug,
245 PartialEq,
246 Eq,
247 Copy,
248 Hash,
249 TyEncodable,
250 TyDecodable,
251 HashStable,
252 TypeFoldable
253)]
254pub struct ClosureSizeProfileData<'tcx> {
255 /// Tuple containing the types of closure captures before the feature `capture_disjoint_fields`
256 pub before_feature_tys: Ty<'tcx>,
257 /// Tuple containing the types of closure captures after the feature `capture_disjoint_fields`
258 pub after_feature_tys: Ty<'tcx>,
259}
260
32a655c1
SL
261pub trait DefIdTree: Copy {
262 fn parent(self, id: DefId) -> Option<DefId>;
a7813a04 263
32a655c1
SL
264 fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool {
265 if descendant.krate != ancestor.krate {
266 return false;
267 }
268
269 while descendant != ancestor {
270 match self.parent(descendant) {
271 Some(parent) => descendant = parent,
272 None => return false,
a7813a04 273 }
a7813a04
XL
274 }
275 true
276 }
277}
278
dc9dc135 279impl<'tcx> DefIdTree for TyCtxt<'tcx> {
32a655c1 280 fn parent(self, id: DefId) -> Option<DefId> {
74b04a01 281 self.def_key(id).parent.map(|index| DefId { index, ..id })
32a655c1
SL
282 }
283}
284
54a0048b 285impl Visibility {
dfeec247 286 pub fn from_hir(visibility: &hir::Visibility<'_>, id: hir::HirId, tcx: TyCtxt<'_>) -> Self {
8faf50e0
XL
287 match visibility.node {
288 hir::VisibilityKind::Public => Visibility::Public,
289 hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
48663c56 290 hir::VisibilityKind::Restricted { ref path, .. } => match path.res {
a7813a04
XL
291 // If there is no resolution, `resolve` will have already reported an error, so
292 // assume that the visibility is public to avoid reporting more privacy errors.
48663c56 293 Res::Err => Visibility::Public,
32a655c1 294 def => Visibility::Restricted(def.def_id()),
a7813a04 295 },
ba9703b0
XL
296 hir::VisibilityKind::Inherited => {
297 Visibility::Restricted(tcx.parent_module(id).to_def_id())
298 }
54a0048b
SL
299 }
300 }
301
a1dfa0c6 302 /// Returns `true` if an item with this visibility is accessible from the given block.
32a655c1 303 pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
54a0048b
SL
304 let restriction = match self {
305 // Public items are visible everywhere.
306 Visibility::Public => return true,
307 // Private items from other crates are visible nowhere.
32a655c1 308 Visibility::Invisible => return false,
54a0048b 309 // Restricted items are visible in an arbitrary local module.
32a655c1 310 Visibility::Restricted(other) if other.krate != module.krate => return false,
54a0048b
SL
311 Visibility::Restricted(module) => module,
312 };
313
32a655c1 314 tree.is_descendant_of(module, restriction)
54a0048b
SL
315 }
316
a1dfa0c6 317 /// Returns `true` if this visibility is at least as accessible as the given visibility
32a655c1 318 pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
54a0048b
SL
319 let vis_restriction = match vis {
320 Visibility::Public => return self == Visibility::Public,
32a655c1 321 Visibility::Invisible => return true,
54a0048b
SL
322 Visibility::Restricted(module) => module,
323 };
324
a7813a04 325 self.is_accessible_from(vis_restriction, tree)
54a0048b 326 }
ff7c6d11 327
a1dfa0c6 328 // Returns `true` if this item is visible anywhere in the local crate.
ff7c6d11
XL
329 pub fn is_visible_locally(self) -> bool {
330 match self {
331 Visibility::Public => true,
332 Visibility::Restricted(def_id) => def_id.is_local(),
333 Visibility::Invisible => false,
334 }
335 }
3c0e092e
XL
336
337 pub fn is_public(self) -> bool {
338 matches!(self, Visibility::Public)
339 }
54a0048b
SL
340}
341
7cac9316
XL
342/// The crate variances map is computed during typeck and contains the
343/// variance of every item in the local crate. You should not use it
344/// directly, because to do so will make your pass dependent on the
345/// HIR of every item in the local crate. Instead, use
346/// `tcx.variances_of()` to get the variance for a *particular*
347/// item.
5869c6ff 348#[derive(HashStable, Debug)]
48663c56 349pub struct CrateVariancesMap<'tcx> {
7cac9316 350 /// For each item with generics, maps to a vector of the variance
9fa01778 351 /// of its generics. If an item has no generics, it will have no
7cac9316 352 /// entry.
48663c56 353 pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>,
7cac9316
XL
354}
355
e9174d1e
SL
356// Contains information needed to resolve types and (in the future) look up
357// the types of AST nodes.
358#[derive(Copy, Clone, PartialEq, Eq, Hash)]
359pub struct CReaderCacheKey {
17df50a5 360 pub cnum: Option<CrateNum>,
e9174d1e 361 pub pos: usize,
e9174d1e
SL
362}
363
e1599b0c 364#[allow(rustc::usage_of_ty_tykind)]
e9174d1e 365pub struct TyS<'tcx> {
1b1a35ee
XL
366 /// This field shouldn't be used directly and may be removed in the future.
367 /// Use `TyS::kind()` instead.
368 kind: TyKind<'tcx>,
369 /// This field shouldn't be used directly and may be removed in the future.
370 /// Use `TyS::flags()` instead.
371 flags: TypeFlags,
e9174d1e 372
94b46f34
XL
373 /// This is a kind of confusing thing: it stores the smallest
374 /// binder such that
375 ///
376 /// (a) the binder itself captures nothing but
377 /// (b) all the late-bound things within the type are captured
378 /// by some sub-binder.
379 ///
380 /// So, for a type without any late-bound things, like `u32`, this
0731742a 381 /// will be *innermost*, because that is the innermost binder that
94b46f34 382 /// captures nothing. But for a type `&'D u32`, where `'D` is a
9fa01778 383 /// late-bound region with De Bruijn index `D`, this would be `D + 1`
0731742a
XL
384 /// -- the binder itself does not capture `D`, but `D` is captured
385 /// by an inner binder.
94b46f34 386 ///
0731742a 387 /// We call this concept an "exclusive" binder `D` because all
9fa01778 388 /// De Bruijn indices within the type are contained within `0..D`
0731742a 389 /// (exclusive).
94b46f34
XL
390 outer_exclusive_binder: ty::DebruijnIndex,
391}
392
fc512014
XL
393impl<'tcx> TyS<'tcx> {
394 /// A constructor used only for internal testing.
395 #[allow(rustc::usage_of_ty_tykind)]
396 pub fn make_for_test(
397 kind: TyKind<'tcx>,
398 flags: TypeFlags,
399 outer_exclusive_binder: ty::DebruijnIndex,
400 ) -> TyS<'tcx> {
401 TyS { kind, flags, outer_exclusive_binder }
402 }
403}
404
a1dfa0c6 405// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
6a06907d 406#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
cdc7bbd5 407static_assert_size!(TyS<'_>, 40);
a1dfa0c6 408
94b46f34
XL
409impl<'tcx> Ord for TyS<'tcx> {
410 fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
1b1a35ee 411 self.kind().cmp(other.kind())
94b46f34
XL
412 }
413}
414
415impl<'tcx> PartialOrd for TyS<'tcx> {
416 fn partial_cmp(&self, other: &TyS<'tcx>) -> Option<Ordering> {
1b1a35ee 417 Some(self.kind().cmp(other.kind()))
94b46f34 418 }
e9174d1e
SL
419}
420
421impl<'tcx> PartialEq for TyS<'tcx> {
422 #[inline]
423 fn eq(&self, other: &TyS<'tcx>) -> bool {
8faf50e0 424 ptr::eq(self, other)
e9174d1e
SL
425 }
426}
427impl<'tcx> Eq for TyS<'tcx> {}
428
429impl<'tcx> Hash for TyS<'tcx> {
430 fn hash<H: Hasher>(&self, s: &mut H) {
0bf4aa26 431 (self as *const TyS<'_>).hash(s)
e9174d1e
SL
432 }
433}
434
f035d41b 435impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TyS<'tcx> {
e74abb32 436 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
cc61c64b 437 let ty::TyS {
e74abb32 438 ref kind,
cc61c64b
XL
439
440 // The other fields just provide fast access to information that is
e74abb32 441 // also contained in `kind`, so no need to hash them.
cc61c64b 442 flags: _,
94b46f34
XL
443
444 outer_exclusive_binder: _,
cc61c64b
XL
445 } = *self;
446
e74abb32 447 kind.hash_stable(hcx, hasher);
cc61c64b
XL
448 }
449}
450
e74abb32 451#[rustc_diagnostic_item = "Ty"]
e9174d1e
SL
452pub type Ty<'tcx> = &'tcx TyS<'tcx>;
453
94b46f34 454impl ty::EarlyBoundRegion {
b7449926
XL
455 /// Does this early bound region have a name? Early bound regions normally
456 /// always have names except when using anonymous lifetimes (`'_`).
457 pub fn has_name(&self) -> bool {
e74abb32 458 self.name != kw::UnderscoreLifetime
b7449926 459 }
94b46f34 460}
ea8adc8c 461
f035d41b
XL
462#[derive(Debug)]
463crate struct PredicateInner<'tcx> {
cdc7bbd5 464 kind: Binder<'tcx, PredicateKind<'tcx>>,
f035d41b
XL
465 flags: TypeFlags,
466 /// See the comment for the corresponding field of [TyS].
467 outer_exclusive_binder: ty::DebruijnIndex,
468}
469
6a06907d 470#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
cdc7bbd5 471static_assert_size!(PredicateInner<'_>, 48);
f035d41b
XL
472
473#[derive(Clone, Copy, Lift)]
f9f354fc 474pub struct Predicate<'tcx> {
f035d41b 475 inner: &'tcx PredicateInner<'tcx>,
f9f354fc
XL
476}
477
478impl<'tcx> PartialEq for Predicate<'tcx> {
479 fn eq(&self, other: &Self) -> bool {
480 // `self.kind` is always interned.
f035d41b
XL
481 ptr::eq(self.inner, other.inner)
482 }
483}
484
485impl Hash for Predicate<'_> {
486 fn hash<H: Hasher>(&self, s: &mut H) {
487 (self.inner as *const PredicateInner<'_>).hash(s)
f9f354fc
XL
488 }
489}
490
491impl<'tcx> Eq for Predicate<'tcx> {}
492
493impl<'tcx> Predicate<'tcx> {
cdc7bbd5 494 /// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`.
6a06907d 495 #[inline]
cdc7bbd5 496 pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> {
5869c6ff 497 self.inner.kind
3dfed10e 498 }
3c0e092e
XL
499
500 /// Flips the polarity of a Predicate.
501 ///
502 /// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`.
503 pub fn flip_polarity(&self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> {
504 let kind = self
505 .inner
506 .kind
507 .map_bound(|kind| match kind {
508 PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => {
509 Some(PredicateKind::Trait(TraitPredicate {
510 trait_ref,
511 constness,
512 polarity: polarity.flip()?,
513 }))
514 }
515
516 _ => None,
517 })
518 .transpose()?;
519
520 Some(tcx.mk_predicate(kind))
521 }
f035d41b
XL
522}
523
524impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
525 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
526 let PredicateInner {
527 ref kind,
528
529 // The other fields just provide fast access to information that is
530 // also contained in `kind`, so no need to hash them.
531 flags: _,
532 outer_exclusive_binder: _,
533 } = self.inner;
534
535 kind.hash_stable(hcx, hasher);
f9f354fc
XL
536 }
537}
538
3dfed10e 539#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
60c5eb7d 540#[derive(HashStable, TypeFoldable)]
f9f354fc 541pub enum PredicateKind<'tcx> {
dc9dc135 542 /// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
e9174d1e 543 /// the `Self` type of the trait reference and `A`, `B`, and `C`
9e0c209e 544 /// would be the type parameters.
94222f64 545 Trait(TraitPredicate<'tcx>),
e9174d1e 546
dc9dc135 547 /// `where 'a: 'b`
3dfed10e 548 RegionOutlives(RegionOutlivesPredicate<'tcx>),
e9174d1e 549
dc9dc135 550 /// `where T: 'a`
3dfed10e 551 TypeOutlives(TypeOutlivesPredicate<'tcx>),
e9174d1e 552
dc9dc135 553 /// `where <T as TraitRef>::Name == X`, approximately.
a1dfa0c6 554 /// See the `ProjectionPredicate` struct for details.
3dfed10e 555 Projection(ProjectionPredicate<'tcx>),
e9174d1e 556
dc9dc135 557 /// No syntax: `T` well-formed.
f035d41b 558 WellFormed(GenericArg<'tcx>),
e9174d1e 559
dc9dc135 560 /// Trait must be object-safe.
e9174d1e 561 ObjectSafe(DefId),
a7813a04 562
a1dfa0c6
XL
563 /// No direct syntax. May be thought of as `where T: FnFoo<...>`
564 /// for some substitutions `...` and `T` being a closure type.
9e0c209e 565 /// Satisfied (or refuted) once we know the closure's kind.
e74abb32 566 ClosureKind(DefId, SubstsRef<'tcx>, ClosureKind),
cc61c64b
XL
567
568 /// `T1 <: T2`
94222f64
XL
569 ///
570 /// This obligation is created most often when we have two
571 /// unresolved type variables and hence don't have enough
572 /// information to process the subtyping obligation yet.
3dfed10e 573 Subtype(SubtypePredicate<'tcx>),
ea8adc8c 574
94222f64
XL
575 /// `T1` coerced to `T2`
576 ///
577 /// Like a subtyping obligation, this is created most often
578 /// when we have two unresolved type variables and hence
579 /// don't have enough information to process the coercion
580 /// obligation yet. At the moment, we actually process coercions
581 /// very much like subtyping and don't handle the full coercion
582 /// logic.
583 Coerce(CoercePredicate<'tcx>),
584
ea8adc8c 585 /// Constant initializer must evaluate successfully.
94222f64 586 ConstEvaluatable(ty::Unevaluated<'tcx, ()>),
f9f354fc
XL
587
588 /// Constants must be equal. The first component is the const that is expected.
589 ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
1b1a35ee
XL
590
591 /// Represents a type found in the environment that we can use for implied bounds.
592 ///
593 /// Only used for Chalk.
594 TypeWellFormedFromEnv(Ty<'tcx>),
e9174d1e
SL
595}
596
83c7162d
XL
597/// The crate outlives map is computed during typeck and contains the
598/// outlives of every item in the local crate. You should not use it
599/// directly, because to do so will make your pass dependent on the
600/// HIR of every item in the local crate. Instead, use
601/// `tcx.inferred_outlives_of()` to get the outlives for a *particular*
602/// item.
5869c6ff 603#[derive(HashStable, Debug)]
83c7162d
XL
604pub struct CratePredicatesMap<'tcx> {
605 /// For each struct with outlive bounds, maps to a vector of the
606 /// predicate of its outlive bounds. If an item has no outlives
607 /// bounds, it will have no entry.
3dfed10e 608 pub predicates: FxHashMap<DefId, &'tcx [(Predicate<'tcx>, Span)]>,
83c7162d
XL
609}
610
dc9dc135 611impl<'tcx> Predicate<'tcx> {
e9174d1e
SL
612 /// Performs a substitution suitable for going from a
613 /// poly-trait-ref to supertraits that must hold if that
614 /// poly-trait-ref holds. This is slightly different from a normal
9fa01778 615 /// substitution in terms of what happens with bound regions. See
e9174d1e 616 /// lengthy comment below for details.
dc9dc135 617 pub fn subst_supertrait(
f9f354fc 618 self,
dc9dc135
XL
619 tcx: TyCtxt<'tcx>,
620 trait_ref: &ty::PolyTraitRef<'tcx>,
3dfed10e 621 ) -> Predicate<'tcx> {
e9174d1e
SL
622 // The interaction between HRTB and supertraits is not entirely
623 // obvious. Let me walk you (and myself) through an example.
624 //
625 // Let's start with an easy case. Consider two traits:
626 //
a1dfa0c6 627 // trait Foo<'a>: Bar<'a,'a> { }
e9174d1e
SL
628 // trait Bar<'b,'c> { }
629 //
a1dfa0c6
XL
630 // Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
631 // we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
e9174d1e
SL
632 // knew that `Foo<'x>` (for any 'x) then we also know that
633 // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
634 // normal substitution.
635 //
636 // In terms of why this is sound, the idea is that whenever there
637 // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
638 // holds. So if there is an impl of `T:Foo<'a>` that applies to
639 // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
640 // `'a`.
641 //
642 // Another example to be careful of is this:
643 //
a1dfa0c6 644 // trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
e9174d1e
SL
645 // trait Bar1<'b,'c> { }
646 //
a1dfa0c6
XL
647 // Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
648 // The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
e9174d1e 649 // reason is similar to the previous example: any impl of
a1dfa0c6 650 // `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`. So
e9174d1e
SL
651 // basically we would want to collapse the bound lifetimes from
652 // the input (`trait_ref`) and the supertraits.
653 //
654 // To achieve this in practice is fairly straightforward. Let's
655 // consider the more complicated scenario:
656 //
a1dfa0c6
XL
657 // - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
658 // has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
e9174d1e
SL
659 // where both `'x` and `'b` would have a DB index of 1.
660 // The substitution from the input trait-ref is therefore going to be
661 // `'a => 'x` (where `'x` has a DB index of 1).
c295e0f8 662 // - The supertrait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
e9174d1e
SL
663 // early-bound parameter and `'b' is a late-bound parameter with a
664 // DB index of 1.
665 // - If we replace `'a` with `'x` from the input, it too will have
666 // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
667 // just as we wanted.
668 //
669 // There is only one catch. If we just apply the substitution `'a
670 // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
671 // adjust the DB index because we substituting into a binder (it
672 // tries to be so smart...) resulting in `for<'x> for<'b>
673 // Bar1<'x,'b>` (we have no syntax for this, so use your
674 // imagination). Basically the 'x will have DB index of 2 and 'b
675 // will have DB index of 1. Not quite what we want. So we apply
676 // the substitution to the *contents* of the trait reference,
677 // rather than the trait reference itself (put another way, the
678 // substitution code expects equal binding levels in the values
679 // from the substitution and the value being substituted into, and
680 // this trick achieves that).
cdc7bbd5
XL
681
682 // Working through the second example:
683 // trait_ref: for<'x> T: Foo1<'^0.0>; substs: [T, '^0.0]
684 // predicate: for<'b> Self: Bar1<'a, '^0.0>; substs: [Self, 'a, '^0.0]
685 // We want to end up with:
686 // for<'x, 'b> T: Bar1<'^0.0, '^0.1>
687 // To do this:
688 // 1) We must shift all bound vars in predicate by the length
689 // of trait ref's bound vars. So, we would end up with predicate like
690 // Self: Bar1<'a, '^0.1>
691 // 2) We can then apply the trait substs to this, ending up with
692 // T: Bar1<'^0.0, '^0.1>
693 // 3) Finally, to create the final bound vars, we concatenate the bound
694 // vars of the trait ref with those of the predicate:
695 // ['x, 'b]
696 let bound_pred = self.kind();
697 let pred_bound_vars = bound_pred.bound_vars();
698 let trait_bound_vars = trait_ref.bound_vars();
699 // 1) Self: Bar1<'a, '^0.0> -> Self: Bar1<'a, '^0.1>
700 let shifted_pred =
701 tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
702 // 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1>
703 let new = shifted_pred.subst(tcx, trait_ref.skip_binder().substs);
704 // 3) ['x] + ['b] -> ['x, 'b]
705 let bound_vars =
706 tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars));
707 tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars))
e9174d1e
SL
708 }
709}
710
3dfed10e 711#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
60c5eb7d 712#[derive(HashStable, TypeFoldable)]
e9174d1e 713pub struct TraitPredicate<'tcx> {
dfeec247 714 pub trait_ref: TraitRef<'tcx>,
94222f64
XL
715
716 pub constness: BoundConstness,
3c0e092e
XL
717
718 pub polarity: ImplPolarity,
e9174d1e 719}
a1dfa0c6 720
cdc7bbd5 721pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
e9174d1e
SL
722
723impl<'tcx> TraitPredicate<'tcx> {
f9f354fc 724 pub fn def_id(self) -> DefId {
e9174d1e
SL
725 self.trait_ref.def_id
726 }
727
f9f354fc 728 pub fn self_ty(self) -> Ty<'tcx> {
e9174d1e
SL
729 self.trait_ref.self_ty()
730 }
731}
732
733impl<'tcx> PolyTraitPredicate<'tcx> {
f9f354fc 734 pub fn def_id(self) -> DefId {
416331ca 735 // Ok to skip binder since trait `DefId` does not care about regions.
83c7162d 736 self.skip_binder().def_id()
e9174d1e 737 }
fc512014 738
cdc7bbd5 739 pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> {
fc512014
XL
740 self.map_bound(|trait_ref| trait_ref.self_ty())
741 }
e9174d1e
SL
742}
743
3dfed10e 744#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
60c5eb7d 745#[derive(HashStable, TypeFoldable)]
dc9dc135 746pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
dc9dc135
XL
747pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>;
748pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
cdc7bbd5
XL
749pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
750pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>;
e9174d1e 751
94222f64
XL
752/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
753/// whether the `a` type is the type that we should label as "expected" when
754/// presenting user diagnostics.
3dfed10e 755#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
60c5eb7d 756#[derive(HashStable, TypeFoldable)]
cc61c64b
XL
757pub struct SubtypePredicate<'tcx> {
758 pub a_is_expected: bool,
759 pub a: Ty<'tcx>,
dfeec247 760 pub b: Ty<'tcx>,
cc61c64b 761}
cdc7bbd5 762pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
cc61c64b 763
94222f64
XL
764/// Encodes that we have to coerce *from* the `a` type to the `b` type.
765#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
766#[derive(HashStable, TypeFoldable)]
767pub struct CoercePredicate<'tcx> {
768 pub a: Ty<'tcx>,
769 pub b: Ty<'tcx>,
770}
771pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
772
e9174d1e
SL
773/// This kind of predicate has no *direct* correspondent in the
774/// syntax, but it roughly corresponds to the syntactic forms:
775///
9fa01778 776/// 1. `T: TraitRef<..., Item = Type>`
e9174d1e
SL
777/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
778///
779/// In particular, form #1 is "desugared" to the combination of a
a1dfa0c6 780/// normal trait predicate (`T: TraitRef<...>`) and one of these
e9174d1e 781/// predicates. Form #2 is a broader form in that it also permits
ff7c6d11
XL
782/// equality between arbitrary types. Processing an instance of
783/// Form #2 eventually yields one of these `ProjectionPredicate`
e9174d1e 784/// instances to normalize the LHS.
3dfed10e 785#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
60c5eb7d 786#[derive(HashStable, TypeFoldable)]
e9174d1e
SL
787pub struct ProjectionPredicate<'tcx> {
788 pub projection_ty: ProjectionTy<'tcx>,
789 pub ty: Ty<'tcx>,
790}
791
cdc7bbd5 792pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
e9174d1e
SL
793
794impl<'tcx> PolyProjectionPredicate<'tcx> {
6a06907d
XL
795 /// Returns the `DefId` of the trait of the associated item being projected.
796 #[inline]
797 pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
798 self.skip_binder().projection_ty.trait_def_id(tcx)
799 }
800
6a06907d
XL
801 /// Get the [PolyTraitRef] required for this projection to be well formed.
802 /// Note that for generic associated types the predicates of the associated
803 /// type also need to be checked.
a1dfa0c6 804 #[inline]
6a06907d 805 pub fn required_poly_trait_ref(&self, tcx: TyCtxt<'tcx>) -> PolyTraitRef<'tcx> {
a1dfa0c6
XL
806 // Note: unlike with `TraitRef::to_poly_trait_ref()`,
807 // `self.0.trait_ref` is permitted to have escaping regions.
041b39d2
XL
808 // This is because here `self` has a `Binder` and so does our
809 // return value, so we are preserving the number of binding
810 // levels.
83c7162d 811 self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx))
e9174d1e 812 }
3b2f2976 813
cdc7bbd5 814 pub fn ty(&self) -> Binder<'tcx, Ty<'tcx>> {
83c7162d
XL
815 self.map_bound(|predicate| predicate.ty)
816 }
817
a1dfa0c6 818 /// The `DefId` of the `TraitItem` for the associated type.
83c7162d 819 ///
a1dfa0c6
XL
820 /// Note that this is not the `DefId` of the `TraitRef` containing this
821 /// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
83c7162d 822 pub fn projection_def_id(&self) -> DefId {
416331ca 823 // Ok to skip binder since trait `DefId` does not care about regions.
83c7162d 824 self.skip_binder().projection_ty.item_def_id
3b2f2976 825 }
e9174d1e
SL
826}
827
828pub trait ToPolyTraitRef<'tcx> {
829 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
830}
831
e9174d1e
SL
832impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
833 fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> {
7453a54e 834 self.map_bound_ref(|trait_pred| trait_pred.trait_ref)
e9174d1e
SL
835 }
836}
837
e9174d1e 838pub trait ToPredicate<'tcx> {
f035d41b 839 fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx>;
f9f354fc
XL
840}
841
cdc7bbd5 842impl ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
f9f354fc 843 #[inline(always)]
f035d41b
XL
844 fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
845 tcx.mk_predicate(self)
f9f354fc 846 }
e9174d1e
SL
847}
848
dfeec247 849impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
f035d41b 850 fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
cdc7bbd5
XL
851 self.value
852 .map_bound(|trait_ref| {
3c0e092e
XL
853 PredicateKind::Trait(ty::TraitPredicate {
854 trait_ref,
855 constness: self.constness,
856 polarity: ty::ImplPolarity::Positive,
857 })
cdc7bbd5
XL
858 })
859 .to_predicate(tcx)
dfeec247
XL
860 }
861}
862
94222f64 863impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
f035d41b 864 fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
94222f64 865 self.map_bound(PredicateKind::Trait).to_predicate(tcx)
e9174d1e
SL
866 }
867}
868
9e0c209e 869impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
f035d41b 870 fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
5869c6ff 871 self.map_bound(PredicateKind::RegionOutlives).to_predicate(tcx)
e9174d1e
SL
872 }
873}
874
875impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
f035d41b 876 fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
5869c6ff 877 self.map_bound(PredicateKind::TypeOutlives).to_predicate(tcx)
e9174d1e
SL
878 }
879}
880
881impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
f035d41b 882 fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
5869c6ff 883 self.map_bound(PredicateKind::Projection).to_predicate(tcx)
e9174d1e
SL
884 }
885}
886
887impl<'tcx> Predicate<'tcx> {
fc512014 888 pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
5869c6ff 889 let predicate = self.kind();
fc512014 890 match predicate.skip_binder() {
94222f64
XL
891 PredicateKind::Trait(t) => {
892 Some(ConstnessAnd { constness: t.constness, value: predicate.rebind(t.trait_ref) })
fc512014 893 }
5869c6ff
XL
894 PredicateKind::Projection(..)
895 | PredicateKind::Subtype(..)
94222f64 896 | PredicateKind::Coerce(..)
5869c6ff
XL
897 | PredicateKind::RegionOutlives(..)
898 | PredicateKind::WellFormed(..)
899 | PredicateKind::ObjectSafe(..)
900 | PredicateKind::ClosureKind(..)
901 | PredicateKind::TypeOutlives(..)
902 | PredicateKind::ConstEvaluatable(..)
903 | PredicateKind::ConstEquate(..)
904 | PredicateKind::TypeWellFormedFromEnv(..) => None,
e9174d1e
SL
905 }
906 }
abe05a73 907
f9f354fc 908 pub fn to_opt_type_outlives(self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
5869c6ff 909 let predicate = self.kind();
fc512014 910 match predicate.skip_binder() {
5869c6ff
XL
911 PredicateKind::TypeOutlives(data) => Some(predicate.rebind(data)),
912 PredicateKind::Trait(..)
913 | PredicateKind::Projection(..)
914 | PredicateKind::Subtype(..)
94222f64 915 | PredicateKind::Coerce(..)
5869c6ff
XL
916 | PredicateKind::RegionOutlives(..)
917 | PredicateKind::WellFormed(..)
918 | PredicateKind::ObjectSafe(..)
919 | PredicateKind::ClosureKind(..)
920 | PredicateKind::ConstEvaluatable(..)
921 | PredicateKind::ConstEquate(..)
922 | PredicateKind::TypeWellFormedFromEnv(..) => None,
abe05a73
XL
923 }
924 }
e9174d1e
SL
925}
926
927/// Represents the bounds declared on a particular set of type
9fa01778 928/// parameters. Should eventually be generalized into a flag list of
94222f64 929/// where-clauses. You can obtain an `InstantiatedPredicates` list from a
e9174d1e
SL
930/// `GenericPredicates` by using the `instantiate` method. Note that this method
931/// reflects an important semantic invariant of `InstantiatedPredicates`: while
932/// the `GenericPredicates` are expressed in terms of the bound type
933/// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
934/// represented a set of bounds for some particular instantiation,
935/// meaning that the generic parameters have been substituted with
936/// their values.
937///
938/// Example:
939///
dc9dc135 940/// struct Foo<T, U: Bar<T>> { ... }
e9174d1e
SL
941///
942/// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like
9fa01778 943/// `[[], [U:Bar<T>]]`. Now if there were some particular reference
e9174d1e
SL
944/// like `Foo<isize,usize>`, then the `InstantiatedPredicates` would be `[[],
945/// [usize:Bar<isize>]]`.
60c5eb7d 946#[derive(Clone, Debug, TypeFoldable)]
e9174d1e 947pub struct InstantiatedPredicates<'tcx> {
9e0c209e 948 pub predicates: Vec<Predicate<'tcx>>,
74b04a01 949 pub spans: Vec<Span>,
e9174d1e
SL
950}
951
952impl<'tcx> InstantiatedPredicates<'tcx> {
953 pub fn empty() -> InstantiatedPredicates<'tcx> {
74b04a01 954 InstantiatedPredicates { predicates: vec![], spans: vec![] }
e9174d1e
SL
955 }
956
957 pub fn is_empty(&self) -> bool {
958 self.predicates.is_empty()
959 }
960}
961
136023e0 962#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable, TypeFoldable)]
17df50a5
XL
963pub struct OpaqueTypeKey<'tcx> {
964 pub def_id: DefId,
965 pub substs: SubstsRef<'tcx>,
966}
967
e74abb32 968rustc_index::newtype_index! {
532ac7d7
XL
969 /// "Universes" are used during type- and trait-checking in the
970 /// presence of `for<..>` binders to control what sets of names are
971 /// visible. Universes are arranged into a tree: the root universe
972 /// contains names that are always visible. Each child then adds a new
973 /// set of names that are visible, in addition to those of its parent.
974 /// We say that the child universe "extends" the parent universe with
975 /// new names.
976 ///
977 /// To make this more concrete, consider this program:
978 ///
979 /// ```
980 /// struct Foo { }
981 /// fn bar<T>(x: T) {
982 /// let y: for<'a> fn(&'a u8, Foo) = ...;
983 /// }
984 /// ```
985 ///
986 /// The struct name `Foo` is in the root universe U0. But the type
987 /// parameter `T`, introduced on `bar`, is in an extended universe U1
988 /// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
989 /// of `bar`, we cannot name `T`. Then, within the type of `y`, the
990 /// region `'a` is in a universe U2 that extends U1, because we can
991 /// name it inside the fn type but not outside.
992 ///
993 /// Universes are used to do type- and trait-checking around these
994 /// "forall" binders (also called **universal quantification**). The
995 /// idea is that when, in the body of `bar`, we refer to `T` as a
996 /// type, we aren't referring to any type in particular, but rather a
997 /// kind of "fresh" type that is distinct from all other types we have
998 /// actually declared. This is called a **placeholder** type, and we
999 /// use universes to talk about this. In other words, a type name in
1000 /// universe 0 always corresponds to some "ground" type that the user
1001 /// declared, but a type name in a non-zero universe is a placeholder
1002 /// type -- an idealized representative of "types in general" that we
1003 /// use for checking generic functions.
0bf4aa26 1004 pub struct UniverseIndex {
60c5eb7d 1005 derive [HashStable]
0bf4aa26
XL
1006 DEBUG_FORMAT = "U{}",
1007 }
1008}
0531ce1d 1009
0bf4aa26 1010impl UniverseIndex {
ba9703b0 1011 pub const ROOT: UniverseIndex = UniverseIndex::from_u32(0);
8faf50e0 1012
0bf4aa26
XL
1013 /// Returns the "next" universe index in order -- this new index
1014 /// is considered to extend all previous universes. This
9fa01778 1015 /// corresponds to entering a `forall` quantifier. So, for
0bf4aa26 1016 /// example, suppose we have this type in universe `U`:
0531ce1d
XL
1017 ///
1018 /// ```
1019 /// for<'a> fn(&'a u32)
1020 /// ```
1021 ///
1022 /// Once we "enter" into this `for<'a>` quantifier, we are in a
0bf4aa26
XL
1023 /// new universe that extends `U` -- in this new universe, we can
1024 /// name the region `'a`, but that region was not nameable from
1025 /// `U` because it was not in scope there.
1026 pub fn next_universe(self) -> UniverseIndex {
1027 UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
8faf50e0
XL
1028 }
1029
a1dfa0c6 1030 /// Returns `true` if `self` can name a name from `other` -- in other words,
0bf4aa26 1031 /// if the set of names in `self` is a superset of those in
a1dfa0c6 1032 /// `other` (`self >= other`).
0bf4aa26
XL
1033 pub fn can_name(self, other: UniverseIndex) -> bool {
1034 self.private >= other.private
83c7162d 1035 }
a1dfa0c6
XL
1036
1037 /// Returns `true` if `self` cannot name some names from `other` -- in other
1038 /// words, if the set of names in `self` is a strict subset of
1039 /// those in `other` (`self < other`).
1040 pub fn cannot_name(self, other: UniverseIndex) -> bool {
1041 self.private < other.private
1042 }
83c7162d
XL
1043}
1044
fc512014
XL
1045/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are
1046/// identified by both a universe, as well as a name residing within that universe. Distinct bound
1047/// regions/types/consts within the same universe simply have an unknown relationship to one
0bf4aa26 1048/// another.
3dfed10e 1049#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
a1dfa0c6 1050pub struct Placeholder<T> {
0bf4aa26 1051 pub universe: UniverseIndex,
a1dfa0c6 1052 pub name: T,
0531ce1d
XL
1053}
1054
dc9dc135
XL
1055impl<'a, T> HashStable<StableHashingContext<'a>> for Placeholder<T>
1056where
1057 T: HashStable<StableHashingContext<'a>>,
a1dfa0c6 1058{
e74abb32 1059 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
a1dfa0c6
XL
1060 self.universe.hash_stable(hcx, hasher);
1061 self.name.hash_stable(hcx, hasher);
1062 }
1063}
1064
fc512014 1065pub type PlaceholderRegion = Placeholder<BoundRegionKind>;
a1dfa0c6
XL
1066
1067pub type PlaceholderType = Placeholder<BoundVar>;
1068
fc512014
XL
1069#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
1070#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)]
1071pub struct BoundConst<'tcx> {
1072 pub var: BoundVar,
1073 pub ty: Ty<'tcx>,
1074}
1075
1076pub type PlaceholderConst<'tcx> = Placeholder<BoundConst<'tcx>>;
48663c56 1077
fc512014
XL
1078/// A `DefId` which, in case it is a const argument, is potentially bundled with
1079/// the `DefId` of the generic parameter it instantiates.
3dfed10e 1080///
fc512014
XL
1081/// This is used to avoid calls to `type_of` for const arguments during typeck
1082/// which cause cycle errors.
3dfed10e
XL
1083///
1084/// ```rust
3dfed10e
XL
1085/// struct A;
1086/// impl A {
fc512014
XL
1087/// fn foo<const N: usize>(&self) -> [u8; N] { [0; N] }
1088/// // ^ const parameter
3dfed10e
XL
1089/// }
1090/// struct B;
1091/// impl B {
fc512014
XL
1092/// fn foo<const M: u8>(&self) -> usize { 42 }
1093/// // ^ const parameter
3dfed10e
XL
1094/// }
1095///
1096/// fn main() {
1097/// let a = A;
fc512014
XL
1098/// let _b = a.foo::<{ 3 + 7 }>();
1099/// // ^^^^^^^^^ const argument
3dfed10e
XL
1100/// }
1101/// ```
fc512014
XL
1102///
1103/// Let's look at the call `a.foo::<{ 3 + 7 }>()` here. We do not know
1104/// which `foo` is used until we know the type of `a`.
1105///
1106/// We only know the type of `a` once we are inside of `typeck(main)`.
1107/// We also end up normalizing the type of `_b` during `typeck(main)` which
1108/// requires us to evaluate the const argument.
1109///
1110/// To evaluate that const argument we need to know its type,
1111/// which we would get using `type_of(const_arg)`. This requires us to
1112/// resolve `foo` as it can be either `usize` or `u8` in this example.
1113/// However, resolving `foo` once again requires `typeck(main)` to get the type of `a`,
1114/// which results in a cycle.
1115///
1116/// In short we must not call `type_of(const_arg)` during `typeck(main)`.
1117///
1118/// When first creating the `ty::Const` of the const argument inside of `typeck` we have
1119/// already resolved `foo` so we know which const parameter this argument instantiates.
1120/// This means that we also know the expected result of `type_of(const_arg)` even if we
1121/// aren't allowed to call that query: it is equal to `type_of(const_param)` which is
1122/// trivial to compute.
1123///
1124/// If we now want to use that constant in a place which potentionally needs its type
1125/// we also pass the type of its `const_param`. This is the point of `WithOptConstParam`,
1126/// except that instead of a `Ty` we bundle the `DefId` of the const parameter.
1127/// Meaning that we need to use `type_of(const_param_did)` if `const_param_did` is `Some`
1128/// to get the type of `did`.
3dfed10e
XL
1129#[derive(Copy, Clone, Debug, TypeFoldable, Lift, TyEncodable, TyDecodable)]
1130#[derive(PartialEq, Eq, PartialOrd, Ord)]
1131#[derive(Hash, HashStable)]
1132pub struct WithOptConstParam<T> {
1133 pub did: T,
29967ef6 1134 /// The `DefId` of the corresponding generic parameter in case `did` is
3dfed10e
XL
1135 /// a const argument.
1136 ///
1137 /// Note that even if `did` is a const argument, this may still be `None`.
1138 /// All queries taking `WithOptConstParam` start by calling `tcx.opt_const_param_of(def.did)`
fc512014 1139 /// to potentially update `param_did` in the case it is `None`.
3dfed10e
XL
1140 pub const_param_did: Option<DefId>,
1141}
1142
1143impl<T> WithOptConstParam<T> {
1144 /// Creates a new `WithOptConstParam` setting `const_param_did` to `None`.
1145 #[inline(always)]
1146 pub fn unknown(did: T) -> WithOptConstParam<T> {
1147 WithOptConstParam { did, const_param_did: None }
1148 }
1149}
1150
1151impl WithOptConstParam<LocalDefId> {
1152 /// Returns `Some((did, param_did))` if `def_id` is a const argument,
1153 /// `None` otherwise.
1154 #[inline(always)]
1155 pub fn try_lookup(did: LocalDefId, tcx: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> {
1156 tcx.opt_const_param_of(did).map(|param_did| (did, param_did))
1157 }
1158
1159 /// In case `self` is unknown but `self.did` is a const argument, this returns
1160 /// a `WithOptConstParam` with the correct `const_param_did`.
1161 #[inline(always)]
1162 pub fn try_upgrade(self, tcx: TyCtxt<'_>) -> Option<WithOptConstParam<LocalDefId>> {
1163 if self.const_param_did.is_none() {
1164 if let const_param_did @ Some(_) = tcx.opt_const_param_of(self.did) {
1165 return Some(WithOptConstParam { did: self.did, const_param_did });
1166 }
1167 }
1168
1169 None
1170 }
1171
1172 pub fn to_global(self) -> WithOptConstParam<DefId> {
1173 WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did }
1174 }
1175
1176 pub fn def_id_for_type_of(self) -> DefId {
1177 if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() }
1178 }
1179}
1180
1181impl WithOptConstParam<DefId> {
1182 pub fn as_local(self) -> Option<WithOptConstParam<LocalDefId>> {
1183 self.did
1184 .as_local()
1185 .map(|did| WithOptConstParam { did, const_param_did: self.const_param_did })
1186 }
1187
1188 pub fn as_const_arg(self) -> Option<(LocalDefId, DefId)> {
1189 if let Some(param_did) = self.const_param_did {
1190 if let Some(did) = self.did.as_local() {
1191 return Some((did, param_did));
1192 }
1193 }
1194
1195 None
1196 }
1197
3dfed10e
XL
1198 pub fn is_local(self) -> bool {
1199 self.did.is_local()
1200 }
1201
1202 pub fn def_id_for_type_of(self) -> DefId {
1203 self.const_param_did.unwrap_or(self.did)
1204 }
1205}
1206
7cac9316
XL
1207/// When type checking, we use the `ParamEnv` to track
1208/// details about the set of where-clauses that are in scope at this
1209/// particular point.
3dfed10e 1210#[derive(Copy, Clone, Hash, PartialEq, Eq)]
7cac9316 1211pub struct ParamEnv<'tcx> {
3dfed10e
XL
1212 /// This packs both caller bounds and the reveal enum into one pointer.
1213 ///
1214 /// Caller bounds are `Obligation`s that the caller must satisfy. This is
1215 /// basically the set of bounds on the in-scope type parameters, translated
416331ca 1216 /// into `Obligation`s, and elaborated and normalized.
f035d41b 1217 ///
3dfed10e
XL
1218 /// Use the `caller_bounds()` method to access.
1219 ///
94b46f34 1220 /// Typically, this is `Reveal::UserFacing`, but during codegen we
f035d41b
XL
1221 /// want `Reveal::All`.
1222 ///
3dfed10e
XL
1223 /// Note: This is packed, use the reveal() method to access it.
1224 packed: CopyTaggedPtr<&'tcx List<Predicate<'tcx>>, traits::Reveal, true>,
7cac9316
XL
1225}
1226
3dfed10e
XL
1227unsafe impl rustc_data_structures::tagged_ptr::Tag for traits::Reveal {
1228 const BITS: usize = 1;
17df50a5 1229 #[inline]
3dfed10e
XL
1230 fn into_usize(self) -> usize {
1231 match self {
1232 traits::Reveal::UserFacing => 0,
1233 traits::Reveal::All => 1,
1234 }
1235 }
17df50a5 1236 #[inline]
3dfed10e
XL
1237 unsafe fn from_usize(ptr: usize) -> Self {
1238 match ptr {
1239 0 => traits::Reveal::UserFacing,
1240 1 => traits::Reveal::All,
1241 _ => std::hint::unreachable_unchecked(),
1242 }
1243 }
1244}
1245
f035d41b
XL
1246impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
1247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1248 f.debug_struct("ParamEnv")
1249 .field("caller_bounds", &self.caller_bounds())
1250 .field("reveal", &self.reveal())
f035d41b
XL
1251 .finish()
1252 }
1253}
1254
f035d41b
XL
1255impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
1256 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
1257 self.caller_bounds().hash_stable(hcx, hasher);
1258 self.reveal().hash_stable(hcx, hasher);
f035d41b
XL
1259 }
1260}
1261
1262impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
fc512014 1263 fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
1b1a35ee 1264 ParamEnv::new(self.caller_bounds().fold_with(folder), self.reveal().fold_with(folder))
f035d41b
XL
1265 }
1266
fc512014 1267 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
29967ef6
XL
1268 self.caller_bounds().visit_with(visitor)?;
1269 self.reveal().visit_with(visitor)
f035d41b
XL
1270 }
1271}
1272
7cac9316 1273impl<'tcx> ParamEnv<'tcx> {
0531ce1d 1274 /// Construct a trait environment suitable for contexts where
9fa01778 1275 /// there are no where-clauses in scope. Hidden types (like `impl
0531ce1d
XL
1276 /// Trait`) are left hidden, so this is suitable for ordinary
1277 /// type-checking.
a1dfa0c6 1278 #[inline]
0531ce1d 1279 pub fn empty() -> Self {
1b1a35ee 1280 Self::new(List::empty(), Reveal::UserFacing)
0531ce1d
XL
1281 }
1282
f035d41b 1283 #[inline]
3dfed10e
XL
1284 pub fn caller_bounds(self) -> &'tcx List<Predicate<'tcx>> {
1285 self.packed.pointer()
f035d41b
XL
1286 }
1287
1288 #[inline]
1289 pub fn reveal(self) -> traits::Reveal {
3dfed10e 1290 self.packed.tag()
f035d41b
XL
1291 }
1292
9fa01778 1293 /// Construct a trait environment with no where-clauses in scope
0531ce1d
XL
1294 /// where the values of all `impl Trait` and other hidden types
1295 /// are revealed. This is suitable for monomorphized, post-typeck
94b46f34 1296 /// environments like codegen or doing optimizations.
0531ce1d 1297 ///
9fa01778 1298 /// N.B., if you want to have predicates in scope, use `ParamEnv::new`,
0531ce1d 1299 /// or invoke `param_env.with_reveal_all()`.
a1dfa0c6 1300 #[inline]
0531ce1d 1301 pub fn reveal_all() -> Self {
1b1a35ee 1302 Self::new(List::empty(), Reveal::All)
0531ce1d
XL
1303 }
1304
1305 /// Construct a trait environment with the given set of predicates.
a1dfa0c6 1306 #[inline]
1b1a35ee
XL
1307 pub fn new(caller_bounds: &'tcx List<Predicate<'tcx>>, reveal: Reveal) -> Self {
1308 ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, reveal) }
f035d41b
XL
1309 }
1310
1311 pub fn with_user_facing(mut self) -> Self {
3dfed10e 1312 self.packed.set_tag(Reveal::UserFacing);
f035d41b 1313 self
0531ce1d
XL
1314 }
1315
1316 /// Returns a new parameter environment with the same clauses, but
1317 /// which "reveals" the true results of projections in all cases
9fa01778 1318 /// (even for associated types that are specializable). This is
94b46f34 1319 /// the desired behavior during codegen and certain other special
0531ce1d
XL
1320 /// contexts; normally though we want to use `Reveal::UserFacing`,
1321 /// which is the default.
3dfed10e
XL
1322 /// All opaque types in the caller_bounds of the `ParamEnv`
1323 /// will be normalized to their underlying types.
1324 /// See PR #65989 and issue #65918 for more details
1325 pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self {
1326 if self.packed.tag() == traits::Reveal::All {
1327 return self;
1328 }
1329
1b1a35ee 1330 ParamEnv::new(tcx.normalize_opaque_types(self.caller_bounds()), Reveal::All)
0531ce1d
XL
1331 }
1332
1333 /// Returns this same environment but with no caller bounds.
17df50a5 1334 #[inline]
0531ce1d 1335 pub fn without_caller_bounds(self) -> Self {
1b1a35ee 1336 Self::new(List::empty(), self.reveal())
0531ce1d
XL
1337 }
1338
7cac9316 1339 /// Creates a suitable environment in which to perform trait
0531ce1d
XL
1340 /// queries on the given value. When type-checking, this is simply
1341 /// the pair of the environment plus value. But when reveal is set to
1342 /// All, then if `value` does not reference any type parameters, we will
1343 /// pair it with the empty environment. This improves caching and is generally
1344 /// invisible.
e9174d1e 1345 ///
0731742a 1346 /// N.B., we preserve the environment when type-checking because it
0531ce1d 1347 /// is possible for the user to have wacky where-clauses like
7cac9316 1348 /// `where Box<u32>: Copy`, which are clearly never
0531ce1d
XL
1349 /// satisfiable. We generally want to behave as if they were true,
1350 /// although the surrounding function is never reachable.
7cac9316 1351 pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
f035d41b 1352 match self.reveal() {
dfeec247 1353 Reveal::UserFacing => ParamEnvAnd { param_env: self, value },
0531ce1d
XL
1354
1355 Reveal::All => {
94222f64 1356 if value.is_known_global() {
dfeec247 1357 ParamEnvAnd { param_env: self.without_caller_bounds(), value }
74b04a01
XL
1358 } else {
1359 ParamEnvAnd { param_env: self, value }
0531ce1d 1360 }
e9174d1e
SL
1361 }
1362 }
1363 }
1364}
1365
fc512014 1366#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
dfeec247 1367pub struct ConstnessAnd<T> {
94222f64 1368 pub constness: BoundConstness,
dfeec247
XL
1369 pub value: T,
1370}
1371
f9f354fc 1372// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate(tcx)` to ensure that
dfeec247
XL
1373// the constness of trait bounds is being propagated correctly.
1374pub trait WithConstness: Sized {
1375 #[inline]
94222f64 1376 fn with_constness(self, constness: BoundConstness) -> ConstnessAnd<Self> {
dfeec247
XL
1377 ConstnessAnd { constness, value: self }
1378 }
1379
1380 #[inline]
94222f64
XL
1381 fn with_const_if_const(self) -> ConstnessAnd<Self> {
1382 self.with_constness(BoundConstness::ConstIfConst)
dfeec247
XL
1383 }
1384
1385 #[inline]
1386 fn without_const(self) -> ConstnessAnd<Self> {
94222f64 1387 self.with_constness(BoundConstness::NotConst)
dfeec247
XL
1388 }
1389}
1390
1391impl<T> WithConstness for T {}
1392
60c5eb7d 1393#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
7cac9316
XL
1394pub struct ParamEnvAnd<'tcx, T> {
1395 pub param_env: ParamEnv<'tcx>,
1396 pub value: T,
1397}
1398
1399impl<'tcx, T> ParamEnvAnd<'tcx, T> {
1400 pub fn into_parts(self) -> (ParamEnv<'tcx>, T) {
1401 (self.param_env, self.value)
1402 }
1403}
1404
dc9dc135
XL
1405impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'tcx, T>
1406where
1407 T: HashStable<StableHashingContext<'a>>,
ea8adc8c 1408{
e74abb32 1409 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
dfeec247 1410 let ParamEnvAnd { ref param_env, ref value } = *self;
ea8adc8c
XL
1411
1412 param_env.hash_stable(hcx, hasher);
1413 value.hash_stable(hcx, hasher);
1414 }
1415}
1416
532ac7d7 1417#[derive(Copy, Clone, Debug, HashStable)]
8bb4bdeb 1418pub struct Destructor {
9fa01778 1419 /// The `DefId` of the destructor method
8bb4bdeb 1420 pub did: DefId,
c295e0f8
XL
1421 /// The constness of the destructor method
1422 pub constness: hir::Constness,
8bb4bdeb
XL
1423}
1424
b7449926 1425bitflags! {
532ac7d7 1426 #[derive(HashStable)]
b7449926
XL
1427 pub struct VariantFlags: u32 {
1428 const NO_VARIANT_FLAGS = 0;
1429 /// Indicates whether the field list of this variant is `#[non_exhaustive]`.
1430 const IS_FIELD_LIST_NON_EXHAUSTIVE = 1 << 0;
1b1a35ee
XL
1431 /// Indicates whether this variant was obtained as part of recovering from
1432 /// a syntactic error. May be incomplete or bogus.
1433 const IS_RECOVERED = 1 << 1;
e9174d1e
SL
1434 }
1435}
1436
94222f64 1437/// Definition of a variant -- a struct's fields or an enum variant.
60c5eb7d 1438#[derive(Debug, HashStable)]
476ff2be 1439pub struct VariantDef {
532ac7d7
XL
1440 /// `DefId` that identifies the variant itself.
1441 /// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
1442 pub def_id: DefId,
1443 /// `DefId` that identifies the variant's constructor.
1444 /// If this variant is a struct variant, then this is `None`.
1445 pub ctor_def_id: Option<DefId>,
1446 /// Variant or struct name.
60c5eb7d 1447 #[stable_hasher(project(name))]
532ac7d7
XL
1448 pub ident: Ident,
1449 /// Discriminant of this variant.
8bb4bdeb 1450 pub discr: VariantDiscr,
532ac7d7 1451 /// Fields of this variant.
476ff2be 1452 pub fields: Vec<FieldDef>,
532ac7d7 1453 /// Type of constructor of variant.
c30ab7b3 1454 pub ctor_kind: CtorKind,
532ac7d7 1455 /// Flags of the variant (e.g. is field list non-exhaustive)?
b7449926 1456 flags: VariantFlags,
e9174d1e
SL
1457}
1458
1b1a35ee 1459impl VariantDef {
9fa01778 1460 /// Creates a new `VariantDef`.
b7449926 1461 ///
532ac7d7
XL
1462 /// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
1463 /// represents an enum variant).
1464 ///
1465 /// `ctor_did` is the `DefId` that identifies the constructor of unit or
1466 /// tuple-variants/structs. If this is a `struct`-variant then this should be `None`.
0bf4aa26 1467 ///
532ac7d7
XL
1468 /// `parent_did` is the `DefId` of the `AdtDef` representing the enum or struct that
1469 /// owns this variant. It is used for checking if a struct has `#[non_exhaustive]` w/out having
1470 /// to go through the redirect of checking the ctor's attributes - but compiling a small crate
1471 /// requires loading the `AdtDef`s for all the structs in the universe (e.g., coherence for any
0bf4aa26
XL
1472 /// built-in trait), and we do not want to load attributes twice.
1473 ///
1474 /// If someone speeds up attribute loading to not be a performance concern, they can
9fa01778 1475 /// remove this hack and use the constructor `DefId` everywhere.
532ac7d7 1476 pub fn new(
532ac7d7
XL
1477 ident: Ident,
1478 variant_did: Option<DefId>,
1479 ctor_def_id: Option<DefId>,
1480 discr: VariantDiscr,
1481 fields: Vec<FieldDef>,
1482 ctor_kind: CtorKind,
1483 adt_kind: AdtKind,
1484 parent_did: DefId,
1485 recovered: bool,
3dfed10e 1486 is_field_list_non_exhaustive: bool,
532ac7d7
XL
1487 ) -> Self {
1488 debug!(
1489 "VariantDef::new(ident = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?},
1490 fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})",
dfeec247 1491 ident, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did,
532ac7d7
XL
1492 );
1493
b7449926 1494 let mut flags = VariantFlags::NO_VARIANT_FLAGS;
3dfed10e
XL
1495 if is_field_list_non_exhaustive {
1496 flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
b7449926 1497 }
532ac7d7 1498
1b1a35ee
XL
1499 if recovered {
1500 flags |= VariantFlags::IS_RECOVERED;
1501 }
1502
b7449926 1503 VariantDef {
532ac7d7
XL
1504 def_id: variant_did.unwrap_or(parent_did),
1505 ctor_def_id,
0731742a 1506 ident,
b7449926
XL
1507 discr,
1508 fields,
1509 ctor_kind,
532ac7d7 1510 flags,
b7449926
XL
1511 }
1512 }
1513
532ac7d7 1514 /// Is this field list non-exhaustive?
b7449926
XL
1515 #[inline]
1516 pub fn is_field_list_non_exhaustive(&self) -> bool {
1517 self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
1518 }
f035d41b 1519
1b1a35ee
XL
1520 /// Was this variant obtained as part of recovering from a syntactic error?
1521 #[inline]
1522 pub fn is_recovered(&self) -> bool {
1523 self.flags.intersects(VariantFlags::IS_RECOVERED)
f035d41b 1524 }
b7449926
XL
1525}
1526
3dfed10e 1527#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)]
8bb4bdeb 1528pub enum VariantDiscr {
0731742a 1529 /// Explicit value for this variant, i.e., `X = 123`.
8bb4bdeb
XL
1530 /// The `DefId` corresponds to the embedded constant.
1531 Explicit(DefId),
1532
1533 /// The previous variant's discriminant plus one.
1534 /// For efficiency reasons, the distance from the
1535 /// last `Explicit` discriminant is being stored,
1536 /// or `0` for the first variant, if it has none.
a1dfa0c6 1537 Relative(u32),
8bb4bdeb
XL
1538}
1539
532ac7d7 1540#[derive(Debug, HashStable)]
476ff2be 1541pub struct FieldDef {
e9174d1e 1542 pub did: DefId,
532ac7d7 1543 #[stable_hasher(project(name))]
94b46f34 1544 pub ident: Ident,
54a0048b 1545 pub vis: Visibility,
e9174d1e
SL
1546}
1547
cc61c64b 1548bitflags! {
3dfed10e 1549 #[derive(TyEncodable, TyDecodable, Default, HashStable)]
ea8adc8c
XL
1550 pub struct ReprFlags: u8 {
1551 const IS_C = 1 << 0;
83c7162d
XL
1552 const IS_SIMD = 1 << 1;
1553 const IS_TRANSPARENT = 1 << 2;
cc61c64b 1554 // Internal only for now. If true, don't reorder fields.
83c7162d 1555 const IS_LINEAR = 1 << 3;
74b04a01
XL
1556 // If true, don't expose any niche to type's context.
1557 const HIDE_NICHE = 1 << 4;
c295e0f8
XL
1558 // If true, the type's layout can be randomized using
1559 // the seed stored in `ReprOptions.layout_seed`
1560 const RANDOMIZE_LAYOUT = 1 << 5;
cc61c64b
XL
1561 // Any of these flags being set prevent field reordering optimisation.
1562 const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits |
cc61c64b 1563 ReprFlags::IS_SIMD.bits |
ea8adc8c 1564 ReprFlags::IS_LINEAR.bits;
cc61c64b
XL
1565 }
1566}
1567
8bb4bdeb 1568/// Represents the repr options provided by the user,
3dfed10e 1569#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Default, HashStable)]
8bb4bdeb 1570pub struct ReprOptions {
8bb4bdeb 1571 pub int: Option<attr::IntType>,
e1599b0c
XL
1572 pub align: Option<Align>,
1573 pub pack: Option<Align>,
cc61c64b 1574 pub flags: ReprFlags,
c295e0f8
XL
1575 /// The seed to be used for randomizing a type's layout
1576 ///
1577 /// Note: This could technically be a `[u8; 16]` (a `u128`) which would
1578 /// be the "most accurate" hash as it'd encompass the item and crate
1579 /// hash without loss, but it does pay the price of being larger.
1580 /// Everything's a tradeoff, a `u64` seed should be sufficient for our
1581 /// purposes (primarily `-Z randomize-layout`)
1582 pub field_shuffle_seed: u64,
8bb4bdeb
XL
1583}
1584
1585impl ReprOptions {
dc9dc135 1586 pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
cc61c64b
XL
1587 let mut flags = ReprFlags::empty();
1588 let mut size = None;
e1599b0c
XL
1589 let mut max_align: Option<Align> = None;
1590 let mut min_pack: Option<Align> = None;
c295e0f8
XL
1591
1592 // Generate a deterministically-derived seed from the item's path hash
1593 // to allow for cross-crate compilation to actually work
1594 let field_shuffle_seed = tcx.def_path_hash(did).0.to_smaller_hash();
1595
8bb4bdeb 1596 for attr in tcx.get_attrs(did).iter() {
3dfed10e 1597 for r in attr::find_repr_attrs(&tcx.sess, attr) {
cc61c64b 1598 flags.insert(match r {
2c00a5a8 1599 attr::ReprC => ReprFlags::IS_C,
83c7162d 1600 attr::ReprPacked(pack) => {
e1599b0c
XL
1601 let pack = Align::from_bytes(pack as u64).unwrap();
1602 min_pack = Some(if let Some(min_pack) = min_pack {
1603 min_pack.min(pack)
83c7162d
XL
1604 } else {
1605 pack
e1599b0c 1606 });
83c7162d 1607 ReprFlags::empty()
dfeec247 1608 }
2c00a5a8 1609 attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
74b04a01 1610 attr::ReprNoNiche => ReprFlags::HIDE_NICHE,
cc61c64b
XL
1611 attr::ReprSimd => ReprFlags::IS_SIMD,
1612 attr::ReprInt(i) => {
1613 size = Some(i);
1614 ReprFlags::empty()
dfeec247 1615 }
cc61c64b 1616 attr::ReprAlign(align) => {
e1599b0c 1617 max_align = max_align.max(Some(Align::from_bytes(align as u64).unwrap()));
cc61c64b 1618 ReprFlags::empty()
dfeec247 1619 }
cc61c64b 1620 });
8bb4bdeb
XL
1621 }
1622 }
1623
c295e0f8
XL
1624 // If `-Z randomize-layout` was enabled for the type definition then we can
1625 // consider performing layout randomization
1626 if tcx.sess.opts.debugging_opts.randomize_layout {
1627 flags.insert(ReprFlags::RANDOMIZE_LAYOUT);
1628 }
1629
cc61c64b 1630 // This is here instead of layout because the choice must make it into metadata.
532ac7d7 1631 if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.def_path_str(did))) {
cc61c64b
XL
1632 flags.insert(ReprFlags::IS_LINEAR);
1633 }
c295e0f8
XL
1634
1635 Self { int: size, align: max_align, pack: min_pack, flags, field_shuffle_seed }
8bb4bdeb
XL
1636 }
1637
cc61c64b 1638 #[inline]
dfeec247
XL
1639 pub fn simd(&self) -> bool {
1640 self.flags.contains(ReprFlags::IS_SIMD)
1641 }
c295e0f8 1642
cc61c64b 1643 #[inline]
dfeec247
XL
1644 pub fn c(&self) -> bool {
1645 self.flags.contains(ReprFlags::IS_C)
1646 }
c295e0f8 1647
cc61c64b 1648 #[inline]
dfeec247
XL
1649 pub fn packed(&self) -> bool {
1650 self.pack.is_some()
1651 }
c295e0f8 1652
cc61c64b 1653 #[inline]
dfeec247
XL
1654 pub fn transparent(&self) -> bool {
1655 self.flags.contains(ReprFlags::IS_TRANSPARENT)
1656 }
c295e0f8 1657
2c00a5a8 1658 #[inline]
dfeec247
XL
1659 pub fn linear(&self) -> bool {
1660 self.flags.contains(ReprFlags::IS_LINEAR)
1661 }
c295e0f8 1662
74b04a01
XL
1663 #[inline]
1664 pub fn hide_niche(&self) -> bool {
1665 self.flags.contains(ReprFlags::HIDE_NICHE)
1666 }
cc61c64b 1667
f9f354fc
XL
1668 /// Returns the discriminant type, given these `repr` options.
1669 /// This must only be called on enums!
8bb4bdeb 1670 pub fn discr_type(&self) -> attr::IntType {
2c00a5a8 1671 self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
8bb4bdeb
XL
1672 }
1673
a1dfa0c6 1674 /// Returns `true` if this `#[repr()]` should inhabit "smart enum
8bb4bdeb
XL
1675 /// layout" optimizations, such as representing `Foo<&T>` as a
1676 /// single pointer.
1677 pub fn inhibit_enum_layout_opt(&self) -> bool {
cc61c64b 1678 self.c() || self.int.is_some()
8bb4bdeb 1679 }
83c7162d 1680
a1dfa0c6 1681 /// Returns `true` if this `#[repr()]` should inhibit struct field reordering
9fa01778 1682 /// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`.
83c7162d 1683 pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
e1599b0c
XL
1684 if let Some(pack) = self.pack {
1685 if pack.bytes() == 1 {
1686 return true;
1687 }
1688 }
c295e0f8 1689
e1599b0c 1690 self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some()
83c7162d 1691 }
a1dfa0c6 1692
c295e0f8
XL
1693 /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
1694 /// was enabled for its declaration crate
1695 pub fn can_randomize_type_layout(&self) -> bool {
1696 !self.inhibit_struct_field_reordering_opt()
1697 && self.flags.contains(ReprFlags::RANDOMIZE_LAYOUT)
1698 }
1699
9fa01778 1700 /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
a1dfa0c6
XL
1701 pub fn inhibit_union_abi_opt(&self) -> bool {
1702 self.c()
1703 }
8bb4bdeb
XL
1704}
1705
dc9dc135 1706impl<'tcx> FieldDef {
c295e0f8
XL
1707 /// Returns the type of this field. The resulting type is not normalized. The `subst` is
1708 /// typically obtained via the second field of `TyKind::AdtDef`.
dc9dc135 1709 pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
7cac9316 1710 tcx.type_of(self.did).subst(tcx, subst)
e9174d1e 1711 }
e9174d1e
SL
1712}
1713
ba9703b0 1714pub type Attributes<'tcx> = &'tcx [ast::Attribute];
cc61c64b 1715
0731742a
XL
1716#[derive(Debug, PartialEq, Eq)]
1717pub enum ImplOverlapKind {
1718 /// These impls are always allowed to overlap.
dfeec247 1719 Permitted {
74b04a01 1720 /// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
dfeec247
XL
1721 marker: bool,
1722 },
0731742a
XL
1723 /// These impls are allowed to overlap, but that raises
1724 /// an issue #33140 future-compatibility warning.
1725 ///
1726 /// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
1727 /// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
1728 ///
1729 /// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
1730 /// that difference, making what reduces to the following set of impls:
1731 ///
1732 /// ```
1733 /// trait Trait {}
1734 /// impl Trait for dyn Send + Sync {}
1735 /// impl Trait for dyn Sync + Send {}
1736 /// ```
1737 ///
1738 /// Obviously, once we made these types be identical, that code causes a coherence
1739 /// error and a fairly big headache for us. However, luckily for us, the trait
1740 /// `Trait` used in this case is basically a marker trait, and therefore having
1741 /// overlapping impls for it is sound.
1742 ///
1743 /// To handle this, we basically regard the trait as a marker trait, with an additional
1744 /// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
1745 /// it has the following restrictions:
1746 ///
1747 /// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
1748 /// positive impls.
1749 /// 2. The trait-ref of both impls must be equal.
1750 /// 3. The trait-ref of both impls must be a trait object type consisting only of
1751 /// marker traits.
1752 /// 4. Neither of the impls can have any where-clauses.
1753 ///
1754 /// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
dfeec247 1755 Issue33140,
0731742a
XL
1756}
1757
dc9dc135 1758impl<'tcx> TyCtxt<'tcx> {
3dfed10e
XL
1759 pub fn typeck_body(self, body: hir::BodyId) -> &'tcx TypeckResults<'tcx> {
1760 self.typeck(self.hir().body_owner_def_id(body))
32a655c1
SL
1761 }
1762
74b04a01 1763 pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
476ff2be 1764 self.associated_items(id)
74b04a01 1765 .in_definition_order()
ba9703b0 1766 .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value())
e9174d1e
SL
1767 }
1768
29967ef6
XL
1769 fn item_name_from_hir(self, def_id: DefId) -> Option<Ident> {
1770 self.hir().get_if_local(def_id).and_then(|node| node.ident())
1771 }
1772
1773 fn item_name_from_def_id(self, def_id: DefId) -> Option<Symbol> {
1774 if def_id.index == CRATE_DEF_INDEX {
17df50a5 1775 Some(self.crate_name(def_id.krate))
29967ef6
XL
1776 } else {
1777 let def_key = self.def_key(def_id);
1778 match def_key.disambiguated_data.data {
1779 // The name of a constructor is that of its parent.
1780 rustc_hir::definitions::DefPathData::Ctor => self.item_name_from_def_id(DefId {
1781 krate: def_id.krate,
1782 index: def_key.parent.unwrap(),
1783 }),
1784 _ => def_key.disambiguated_data.data.get_opt_name(),
1785 }
1786 }
1787 }
1788
1789 /// Look up the name of an item across crates. This does not look at HIR.
1790 ///
1791 /// When possible, this function should be used for cross-crate lookups over
1792 /// [`opt_item_name`] to avoid invalidating the incremental cache. If you
1793 /// need to handle items without a name, or HIR items that will not be
1794 /// serialized cross-crate, or if you need the span of the item, use
1795 /// [`opt_item_name`] instead.
1796 ///
1797 /// [`opt_item_name`]: Self::opt_item_name
1798 pub fn item_name(self, id: DefId) -> Symbol {
1799 // Look at cross-crate items first to avoid invalidating the incremental cache
1800 // unless we have to.
1801 self.item_name_from_def_id(id).unwrap_or_else(|| {
1802 bug!("item_name: no name for {:?}", self.def_path(id));
1803 })
1804 }
1805
1806 /// Look up the name and span of an item or [`Node`].
1807 ///
1808 /// See [`item_name`][Self::item_name] for more information.
e1599b0c 1809 pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
29967ef6
XL
1810 // Look at the HIR first so the span will be correct if this is a local item.
1811 self.item_name_from_hir(def_id)
1812 .or_else(|| self.item_name_from_def_id(def_id).map(Ident::with_dummy_span))
e1599b0c
XL
1813 }
1814
f9f354fc 1815 pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> {
5869c6ff
XL
1816 if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
1817 Some(self.associated_item(def_id))
7cac9316 1818 } else {
5869c6ff
XL
1819 None
1820 }
e9174d1e
SL
1821 }
1822
3dfed10e
XL
1823 pub fn field_index(self, hir_id: hir::HirId, typeck_results: &TypeckResults<'_>) -> usize {
1824 typeck_results.field_indices().get(hir_id).cloned().expect("no index for a field")
83c7162d
XL
1825 }
1826
1827 pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option<usize> {
dfeec247 1828 variant.fields.iter().position(|field| self.hygienic_eq(ident, field.ident, variant.def_id))
83c7162d
XL
1829 }
1830
a1dfa0c6 1831 /// Returns `true` if the impls are the same polarity and the trait either
f9f354fc 1832 /// has no items or is annotated `#[marker]` and prevents item overrides.
dfeec247
XL
1833 pub fn impls_are_allowed_to_overlap(
1834 self,
1835 def_id1: DefId,
1836 def_id2: DefId,
1837 ) -> Option<ImplOverlapKind> {
e1599b0c
XL
1838 // If either trait impl references an error, they're allowed to overlap,
1839 // as one of them essentially doesn't exist.
dfeec247
XL
1840 if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error())
1841 || self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error())
1842 {
1843 return Some(ImplOverlapKind::Permitted { marker: false });
e1599b0c
XL
1844 }
1845
e74abb32 1846 match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) {
dfeec247 1847 (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => {
e74abb32 1848 // `#[rustc_reservation_impl]` impls don't overlap with anything
dfeec247
XL
1849 debug!(
1850 "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)",
1851 def_id1, def_id2
1852 );
1853 return Some(ImplOverlapKind::Permitted { marker: false });
e74abb32 1854 }
dfeec247
XL
1855 (ImplPolarity::Positive, ImplPolarity::Negative)
1856 | (ImplPolarity::Negative, ImplPolarity::Positive) => {
e74abb32 1857 // `impl AutoTrait for Type` + `impl !AutoTrait for Type`
dfeec247
XL
1858 debug!(
1859 "impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)",
1860 def_id1, def_id2
1861 );
e74abb32
XL
1862 return None;
1863 }
dfeec247
XL
1864 (ImplPolarity::Positive, ImplPolarity::Positive)
1865 | (ImplPolarity::Negative, ImplPolarity::Negative) => {}
e74abb32
XL
1866 };
1867
74b04a01 1868 let is_marker_overlap = {
0bf4aa26
XL
1869 let is_marker_impl = |def_id: DefId| -> bool {
1870 let trait_ref = self.impl_trait_ref(def_id);
1871 trait_ref.map_or(false, |tr| self.trait_def(tr.def_id).is_marker)
1872 };
e74abb32 1873 is_marker_impl(def_id1) && is_marker_impl(def_id2)
0731742a
XL
1874 };
1875
e74abb32 1876 if is_marker_overlap {
dfeec247
XL
1877 debug!(
1878 "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)",
1879 def_id1, def_id2
1880 );
1881 Some(ImplOverlapKind::Permitted { marker: true })
0bf4aa26 1882 } else {
0731742a
XL
1883 if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
1884 if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
1885 if self_ty1 == self_ty2 {
dfeec247
XL
1886 debug!(
1887 "impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK",
1888 def_id1, def_id2
1889 );
0731742a
XL
1890 return Some(ImplOverlapKind::Issue33140);
1891 } else {
dfeec247
XL
1892 debug!(
1893 "impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}",
1894 def_id1, def_id2, self_ty1, self_ty2
1895 );
0731742a
XL
1896 }
1897 }
1898 }
1899
dfeec247 1900 debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", def_id1, def_id2);
0731742a 1901 None
cc61c64b 1902 }
cc61c64b
XL
1903 }
1904
48663c56 1905 /// Returns `ty::VariantDef` if `res` refers to a struct,
532ac7d7 1906 /// or variant or their constructors, panics otherwise.
48663c56
XL
1907 pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef {
1908 match res {
1909 Res::Def(DefKind::Variant, did) => {
532ac7d7 1910 let enum_did = self.parent(did).unwrap();
7cac9316 1911 self.adt_def(enum_did).variant_with_id(did)
5bcae85e 1912 }
ba9703b0 1913 Res::Def(DefKind::Struct | DefKind::Union, did) => self.adt_def(did).non_enum_variant(),
48663c56 1914 Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => {
532ac7d7
XL
1915 let variant_did = self.parent(variant_ctor_did).unwrap();
1916 let enum_did = self.parent(variant_did).unwrap();
1917 self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did)
1918 }
48663c56 1919 Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => {
532ac7d7
XL
1920 let struct_did = self.parent(ctor_did).expect("struct ctor has no parent");
1921 self.adt_def(struct_did).non_enum_variant()
c30ab7b3 1922 }
dfeec247 1923 _ => bug!("expect_variant_res used with unexpected res {:?}", res),
5bcae85e
SL
1924 }
1925 }
1926
9fa01778 1927 /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
f9f354fc 1928 pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
cc61c64b 1929 match instance {
5869c6ff
XL
1930 ty::InstanceDef::Item(def) => match self.def_kind(def.did) {
1931 DefKind::Const
1932 | DefKind::Static
1933 | DefKind::AssocConst
1934 | DefKind::Ctor(..)
3c0e092e
XL
1935 | DefKind::AnonConst
1936 | DefKind::InlineConst => self.mir_for_ctfe_opt_const_arg(def),
5869c6ff
XL
1937 // If the caller wants `mir_for_ctfe` of a function they should not be using
1938 // `instance_mir`, so we'll assume const fn also wants the optimized version.
6a06907d
XL
1939 _ => {
1940 assert_eq!(def.const_param_did, None);
1941 self.optimized_mir(def.did)
1942 }
5869c6ff 1943 },
dfeec247
XL
1944 ty::InstanceDef::VtableShim(..)
1945 | ty::InstanceDef::ReifyShim(..)
1946 | ty::InstanceDef::Intrinsic(..)
1947 | ty::InstanceDef::FnPtrShim(..)
1948 | ty::InstanceDef::Virtual(..)
1949 | ty::InstanceDef::ClosureOnceShim { .. }
1950 | ty::InstanceDef::DropGlue(..)
f9f354fc 1951 | ty::InstanceDef::CloneShim(..) => self.mir_shims(instance),
cc61c64b
XL
1952 }
1953 }
1954
9fa01778 1955 /// Gets the attributes of a definition.
dc9dc135 1956 pub fn get_attrs(self, did: DefId) -> Attributes<'tcx> {
f9f354fc 1957 if let Some(did) = did.as_local() {
3dfed10e 1958 self.hir().attrs(self.hir().local_def_id_to_hir_id(did))
e9174d1e 1959 } else {
ba9703b0 1960 self.item_attrs(did)
e9174d1e
SL
1961 }
1962 }
1963
9fa01778 1964 /// Determines whether an item is annotated with an attribute.
48663c56 1965 pub fn has_attr(self, did: DefId, attr: Symbol) -> bool {
3dfed10e 1966 self.sess.contains_name(&self.get_attrs(did), attr)
e9174d1e
SL
1967 }
1968
c295e0f8
XL
1969 /// Determines whether an item is annotated with `doc(hidden)`.
1970 pub fn is_doc_hidden(self, did: DefId) -> bool {
1971 self.get_attrs(did)
1972 .iter()
1973 .filter_map(|attr| if attr.has_name(sym::doc) { attr.meta_item_list() } else { None })
1974 .any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
1975 }
1976
a1dfa0c6 1977 /// Returns `true` if this is an `auto trait`.
abe05a73
XL
1978 pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
1979 self.trait_def(trait_def_id).has_auto_impl
b039eaaf
SL
1980 }
1981
5869c6ff
XL
1982 /// Returns layout of a generator. Layout might be unavailable if the
1983 /// generator is tainted by errors.
1984 pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> {
6a06907d 1985 self.optimized_mir(def_id).generator_layout()
ea8adc8c
XL
1986 }
1987
9fa01778
XL
1988 /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.
1989 /// If it implements no trait, returns `None`.
a7813a04 1990 pub fn trait_id_of_impl(self, def_id: DefId) -> Option<DefId> {
e9174d1e
SL
1991 self.impl_trait_ref(def_id).map(|tr| tr.def_id)
1992 }
1993
9fa01778
XL
1994 /// If the given defid describes a method belonging to an impl, returns the
1995 /// `DefId` of the impl that the method belongs to; otherwise, returns `None`.
a7813a04 1996 pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
ba9703b0 1997 self.opt_associated_item(def_id).and_then(|trait_item| match trait_item.container {
dfeec247
XL
1998 TraitContainer(_) => None,
1999 ImplContainer(def_id) => Some(def_id),
2000 })
e9174d1e
SL
2001 }
2002
54a0048b
SL
2003 /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
2004 /// with the name of the crate containing the impl.
476ff2be 2005 pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
f9f354fc 2006 if let Some(impl_did) = impl_did.as_local() {
3dfed10e 2007 let hir_id = self.hir().local_def_id_to_hir_id(impl_did);
dc9dc135 2008 Ok(self.hir().span(hir_id))
54a0048b 2009 } else {
ea8adc8c 2010 Err(self.crate_name(impl_did.krate))
54a0048b
SL
2011 }
2012 }
7cac9316 2013
9fa01778
XL
2014 /// Hygienically compares a use-site name (`use_name`) for a field or an associated item with
2015 /// its supposed definition name (`def_name`). The method also needs `DefId` of the supposed
2016 /// definition's parent/scope to perform comparison.
8faf50e0 2017 pub fn hygienic_eq(self, use_name: Ident, def_name: Ident, def_parent_def_id: DefId) -> bool {
dc9dc135
XL
2018 // We could use `Ident::eq` here, but we deliberately don't. The name
2019 // comparison fails frequently, and we want to avoid the expensive
ba9703b0 2020 // `normalize_to_macros_2_0()` calls required for the span comparison whenever possible.
dfeec247
XL
2021 use_name.name == def_name.name
2022 && use_name
2023 .span
2024 .ctxt()
17df50a5 2025 .hygienic_eq(def_name.span.ctxt(), self.expn_that_defined(def_parent_def_id))
dc9dc135
XL
2026 }
2027
2028 pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
17df50a5 2029 ident.span.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope));
dc9dc135
XL
2030 ident
2031 }
2032
dfeec247
XL
2033 pub fn adjust_ident_and_get_scope(
2034 self,
2035 mut ident: Ident,
2036 scope: DefId,
2037 block: hir::HirId,
2038 ) -> (Ident, DefId) {
136023e0
XL
2039 let scope = ident
2040 .span
2041 .normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope))
2042 .and_then(|actual_expansion| actual_expansion.expn_data().parent_module)
2043 .unwrap_or_else(|| self.parent_module(block).to_def_id());
7cac9316
XL
2044 (ident, scope)
2045 }
a1dfa0c6 2046
74b04a01
XL
2047 pub fn is_object_safe(self, key: DefId) -> bool {
2048 self.object_safety_violations(key).is_empty()
a1dfa0c6
XL
2049 }
2050}
2051
a1dfa0c6 2052/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
dc9dc135 2053pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
f9f354fc 2054 if let Some(def_id) = def_id.as_local() {
3dfed10e 2055 if let Node::Item(item) = tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
e74abb32 2056 if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind {
416331ca 2057 return opaque_ty.impl_trait_fn;
8faf50e0
XL
2058 }
2059 }
2060 }
2061 None
2062}
2063
5869c6ff
XL
2064pub fn int_ty(ity: ast::IntTy) -> IntTy {
2065 match ity {
2066 ast::IntTy::Isize => IntTy::Isize,
2067 ast::IntTy::I8 => IntTy::I8,
2068 ast::IntTy::I16 => IntTy::I16,
2069 ast::IntTy::I32 => IntTy::I32,
2070 ast::IntTy::I64 => IntTy::I64,
2071 ast::IntTy::I128 => IntTy::I128,
2072 }
2073}
2074
2075pub fn uint_ty(uty: ast::UintTy) -> UintTy {
2076 match uty {
2077 ast::UintTy::Usize => UintTy::Usize,
2078 ast::UintTy::U8 => UintTy::U8,
2079 ast::UintTy::U16 => UintTy::U16,
2080 ast::UintTy::U32 => UintTy::U32,
2081 ast::UintTy::U64 => UintTy::U64,
2082 ast::UintTy::U128 => UintTy::U128,
2083 }
2084}
2085
2086pub fn float_ty(fty: ast::FloatTy) -> FloatTy {
2087 match fty {
2088 ast::FloatTy::F32 => FloatTy::F32,
2089 ast::FloatTy::F64 => FloatTy::F64,
2090 }
2091}
2092
2093pub fn ast_int_ty(ity: IntTy) -> ast::IntTy {
2094 match ity {
2095 IntTy::Isize => ast::IntTy::Isize,
2096 IntTy::I8 => ast::IntTy::I8,
2097 IntTy::I16 => ast::IntTy::I16,
2098 IntTy::I32 => ast::IntTy::I32,
2099 IntTy::I64 => ast::IntTy::I64,
2100 IntTy::I128 => ast::IntTy::I128,
2101 }
2102}
2103
2104pub fn ast_uint_ty(uty: UintTy) -> ast::UintTy {
2105 match uty {
2106 UintTy::Usize => ast::UintTy::Usize,
2107 UintTy::U8 => ast::UintTy::U8,
2108 UintTy::U16 => ast::UintTy::U16,
2109 UintTy::U32 => ast::UintTy::U32,
2110 UintTy::U64 => ast::UintTy::U64,
2111 UintTy::U128 => ast::UintTy::U128,
2112 }
2113}
2114
f035d41b 2115pub fn provide(providers: &mut ty::query::Providers) {
94222f64 2116 closure::provide(providers);
ea8adc8c 2117 context::provide(providers);
abe05a73 2118 erase_regions::provide(providers);
ff7c6d11 2119 layout::provide(providers);
3dfed10e 2120 util::provide(providers);
1b1a35ee 2121 print::provide(providers);
ba9703b0 2122 super::util::bug::provide(providers);
136023e0 2123 super::middle::provide(providers);
ba9703b0
XL
2124 *providers = ty::query::Providers {
2125 trait_impls_of: trait_def::trait_impls_of_provider,
5869c6ff 2126 type_uninhabited_from: inhabitedness::type_uninhabited_from,
cdc7bbd5 2127 const_param_default: consts::const_param_default,
dc3f5686 2128 vtable_allocation: vtable::vtable_allocation_provider,
ba9703b0
XL
2129 ..*providers
2130 };
cc61c64b
XL
2131}
2132
cc61c64b
XL
2133/// A map for the local crate mapping each type to a vector of its
2134/// inherent impls. This is not meant to be used outside of coherence;
2135/// rather, you should request the vector for a specific type via
7cac9316
XL
2136/// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
2137/// (constructing this map requires touching the entire crate).
532ac7d7 2138#[derive(Clone, Debug, Default, HashStable)]
cc61c64b 2139pub struct CrateInherentImpls {
17df50a5 2140 pub inherent_impls: LocalDefIdMap<Vec<DefId>>,
cc61c64b
XL
2141}
2142
3dfed10e
XL
2143#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, HashStable)]
2144pub struct SymbolName<'tcx> {
2145 /// `&str` gives a consistent ordering, which ensures reproducible builds.
2146 pub name: &'tcx str,
7cac9316
XL
2147}
2148
3dfed10e
XL
2149impl<'tcx> SymbolName<'tcx> {
2150 pub fn new(tcx: TyCtxt<'tcx>, name: &str) -> SymbolName<'tcx> {
2151 SymbolName {
2152 name: unsafe { str::from_utf8_unchecked(tcx.arena.alloc_slice(name.as_bytes())) },
2153 }
e74abb32
XL
2154 }
2155}
2156
3dfed10e 2157impl<'tcx> fmt::Display for SymbolName<'tcx> {
0bf4aa26 2158 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
7cac9316
XL
2159 fmt::Display::fmt(&self.name, fmt)
2160 }
2161}
0531ce1d 2162
3dfed10e 2163impl<'tcx> fmt::Debug for SymbolName<'tcx> {
0bf4aa26 2164 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
0531ce1d
XL
2165 fmt::Display::fmt(&self.name, fmt)
2166 }
2167}
c295e0f8
XL
2168
2169#[derive(Debug, Default, Copy, Clone)]
2170pub struct FoundRelationships {
2171 /// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
2172 /// obligation, where:
2173 ///
2174 /// * `Foo` is not `Sized`
2175 /// * `(): Foo` may be satisfied
2176 pub self_in_trait: bool,
2177 /// This is true if we identified that this Ty (`?T`) is found in a `<_ as
2178 /// _>::AssocType = ?T`
2179 pub output: bool,
2180}