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