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