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