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