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