Skip to main content

rustc_type_ir/
interner.rs

1use std::borrow::Borrow;
2use std::fmt::{Debug, Display};
3use std::hash::Hash;
4use std::ops::Deref;
5
6use rustc_ast_ir::Movability;
7use rustc_ast_ir::visit::VisitorResult;
8#[cfg(feature = "nightly")]
9use rustc_data_structures::stable_hash::StableHash;
10use rustc_index::bit_set::DenseBitSet;
11
12use crate::fold::TypeFoldable;
13use crate::inherent::*;
14use crate::intern::Interned;
15use crate::ir_print::IrPrint;
16use crate::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
17use crate::relate::Relate;
18use crate::search_graph::RequiredDepth;
19use crate::solve::{
20    AccessedOpaques, CanonicalInputData, Certainty, ExternalConstraintsData, QueryResult, inspect,
21};
22use crate::visit::{Flags, TypeVisitable};
23use crate::{
24    self as ty, AliasTermKind, BoundRegion, BoundVar, CanonicalParamEnvCache, Const, ConstKind,
25    DebruijnIndex, Region, RegionKind, RegionVid, TraitRef, ValTreeKind, WithCachedTypeInfo,
26    search_graph,
27};
28
29/// The central trait in the shared abstraction layer, specifying all implementation-specific
30/// details for rustc and rust-analyzer.
31///
32/// Among its essential responsibilities:
33/// - it specifies the concrete types used by each implementation via its associated types; these
34///   form the backbone of how each compiler frontend instantiates the shared IR.
35/// - it provides the context required by the solver (e.g., querying lang items, enumerating all
36///   blanket impls for a trait)
37/// - it implements [IrPrint] for formatting and tracing.
38///
39/// In rustc, it is [implemented by TyCtxt][interner-impl-doc]. In rust-analyzer, the implementing
40/// type is named [DbInterner][dbinterner-code] (as it performs most interning through the salsa
41/// database).
42///
43/// More information can also be found in the dedicated chapter in the dev-guide, in [this
44/// section][dev-guide].
45///
46/// [interner-impl-doc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#impl-Interner-for-TyCtxt%3C'tcx%3E
47/// [dbinterner-code]: https://github.com/rust-lang/rust-analyzer/blob/a50c1ccc9cf3dab1afdc857a965a9992fbad7a53/crates/hir-ty/src/next_solver/interner.rs#L272
48/// [dev-guide]: https://rustc-dev-guide.rust-lang.org/solve/sharing-crates-with-rust-analyzer.html#trait-interner
49#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_interner")]
50pub trait Interner:
51    Sized
52    + Copy
53    + IrPrint<ty::AliasTy<Self>>
54    + IrPrint<ty::AliasTerm<Self>>
55    + IrPrint<ty::TraitRef<Self>>
56    + IrPrint<ty::TraitClause<Self>>
57    + IrPrint<ty::HostEffectClause<Self>>
58    + IrPrint<ty::ExistentialTraitRef<Self>>
59    + IrPrint<ty::ExistentialProjection<Self>>
60    + IrPrint<ty::ProjectionClause<Self>>
61    + IrPrint<ty::NormalizesTo<Self>>
62    + IrPrint<ty::SubtypePredicate<Self>>
63    + IrPrint<ty::CoercePredicate<Self>>
64    + IrPrint<ty::FnSig<Self>>
65    + IrPrint<ty::PatternKind<Self>>
66{
67    fn next_trait_solver_globally(self) -> bool {
68        true
69    }
70
71    type DefId: DefId<Self>;
72    type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
73    // Various more specific `DefId`s.
74    //
75    // rustc just defines them all to be `DefId`, but rust-analyzer uses different types so this is convenient for it.
76    //
77    // Note: The `TryFrom<DefId>` always succeeds (in rustc), so don't use it to check if some `DefId`
78    // is of some specific type!
79    type TraitId: SpecificDefId<Self>;
80    type ForeignId: SpecificDefId<Self>;
81    type FunctionId: SpecificDefId<Self>;
82    type ClosureId: SpecificDefId<Self>;
83    type CoroutineClosureId: SpecificDefId<Self>;
84    type CoroutineId: SpecificDefId<Self>;
85    type AdtId: SpecificDefId<Self>;
86    type ImplId: SpecificDefId<Self>;
87    type AnonConstId: SpecificDefId<Self>;
88    type TraitAssocTyId: SpecificDefId<Self>
89        + Into<Self::TraitAssocTermId>
90        + TryFrom<Self::TraitAssocTermId, Error: Debug>;
91    type TraitAssocConstId: SpecificDefId<Self>
92        + Into<Self::TraitAssocTermId>
93        + TryFrom<Self::TraitAssocTermId, Error: Debug>;
94    type TraitAssocTermId: SpecificDefId<Self>;
95    type OpaqueTyId: SpecificDefId<Self, Self::LocalOpaqueTyId>;
96    type LocalOpaqueTyId: Copy
97        + Debug
98        + Hash
99        + Eq
100        + Into<Self::OpaqueTyId>
101        + Into<Self::LocalDefId>
102        + Into<Self::DefId>
103        + TypeFoldable<Self>;
104    type FreeTyAliasId: SpecificDefId<Self> + Into<Self::FreeTermAliasId>;
105    type FreeConstAliasId: SpecificDefId<Self> + Into<Self::FreeTermAliasId>;
106    type FreeTermAliasId: SpecificDefId<Self>;
107    type ImplOrTraitAssocTyId: SpecificDefId<Self> + Into<Self::ImplOrTraitAssocTermId>;
108    type ImplOrTraitAssocConstId: SpecificDefId<Self> + Into<Self::ImplOrTraitAssocTermId>;
109    type ImplOrTraitAssocTermId: SpecificDefId<Self>;
110    type InherentAssocTyId: SpecificDefId<Self> + Into<Self::InherentAssocTermId>;
111    type InherentAssocConstId: SpecificDefId<Self> + Into<Self::InherentAssocTermId>;
112    type InherentAssocTermId: SpecificDefId<Self>;
113    type Span: Span<Self>;
114
115    type GenericArgs: GenericArgs<Self>;
116    type GenericArgsSlice<'a>: Copy + Debug + Hash + Eq + SliceLike<Item = Self::GenericArg>
117    where
118        Self: 'a;
119    type GenericArg: GenericArg<Self>;
120    type Term: Term<Self>;
121
122    type BoundVarKinds: BoundVarKinds<Self>;
123    type TypingEnv: TypingEnv<Self>;
124
125    type PredefinedOpaques: Copy
126        + Debug
127        + Hash
128        + Eq
129        + TypeFoldable<Self>
130        + SliceLike<Item = (ty::OpaqueTypeKey<Self>, Self::Ty)>;
131    fn mk_predefined_opaques_in_body(
132        self,
133        data: &[(ty::OpaqueTypeKey<Self>, Self::Ty)],
134    ) -> Self::PredefinedOpaques;
135
136    type LocalDefIds: Copy
137        + Debug
138        + Hash
139        + Default
140        + Eq
141        + TypeVisitable<Self>
142        + SliceLike<Item = Self::LocalDefId>;
143
144    type CanonicalVarKinds: Copy
145        + Debug
146        + Hash
147        + Eq
148        + SliceLike<Item = ty::CanonicalVarKind<Self>>
149        + Default;
150    fn mk_canonical_var_kinds(
151        self,
152        kinds: &[ty::CanonicalVarKind<Self>],
153    ) -> Self::CanonicalVarKinds;
154
155    type ExternalConstraints: Copy
156        + Debug
157        + Hash
158        + Eq
159        + TypeFoldable<Self>
160        + Deref<Target = ExternalConstraintsData<Self>>;
161    fn mk_external_constraints(
162        self,
163        data: ExternalConstraintsData<Self>,
164    ) -> Self::ExternalConstraints;
165
166    type DepNodeIndex;
167    type Tracked<T: Debug + Clone>: Debug;
168    fn mk_tracked<T: Debug + Clone>(
169        self,
170        data: T,
171        dep_node: Self::DepNodeIndex,
172    ) -> Self::Tracked<T>;
173    fn get_tracked<T: Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T;
174    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, Self::DepNodeIndex);
175
176    // Kinds of tys
177    type Ty: Ty<Self>;
178    type Tys: Tys<Self>;
179    type FnInputTys: Copy + Debug + Hash + Eq + SliceLike<Item = Self::Ty> + TypeVisitable<Self>;
180    type ParamTy: ParamLike;
181    type Symbol: Symbol<Self>;
182
183    // Things stored inside of tys
184
185    // `TypeVisitable<Self>` is required to prevent a problem where the flags
186    // on `Const` indicated that an error was present, as the visitor could no
187    // longer reach the corresponding ErrorGuaranteed
188    type ErrorGuaranteed: Copy + Debug + Hash + Eq + TypeVisitable<Self>;
189    type BoundExistentialPredicates: BoundExistentialPredicates<Self>;
190    type AllocId: Copy + Debug + Hash + Eq;
191    type Pat: Copy
192        + Debug
193        + Hash
194        + Eq
195        + Debug
196        + Relate<Self>
197        + Flags
198        + IntoKind<Kind = ty::PatternKind<Self>>;
199    type PatList: Copy
200        + Debug
201        + Hash
202        + Default
203        + Eq
204        + TypeVisitable<Self>
205        + SliceLike<Item = Self::Pat>;
206    type Safety: Safety<Self>;
207
208    // Kinds of consts
209    type Consts: Copy + Debug + Hash + Eq + SliceLike<Item = Const<Self>> + Default;
210    type ParamConst: Copy + Debug + Hash + Eq + ParamLike;
211    type ValueConst: ValueConst<Self> + TypeFoldable<Self> + Display;
212    type ExprConst: ExprConst<Self>;
213    type ValTree: Copy + Debug + Hash + Eq + IntoKind<Kind = ty::ValTreeKind<Self>>;
214    type ScalarInt: ScalarInt<Self>;
215    type Scalar: Copy + Debug + Hash + Eq;
216
217    // Kinds of regions
218    /// (2026/08/13)
219    /// Do not uplift, the underlying types differ between r-a and rustc.
220    ///
221    /// See <https://github.com/rust-lang/rust/pull/160986#issuecomment-5269817932>.
222    type EarlyParamRegion: ParamLike + RegionName<Self>;
223    /// (2026/08/13)
224    /// Do not uplift, the underlying types differ between r-a and rustc.
225    ///
226    /// See <https://github.com/rust-lang/rust/pull/160986#issuecomment-5269817932>.
227    #[cfg(feature = "nightly")]
228    type LateParamRegionKind: Clone
229        + Copy
230        + Debug
231        + PartialEq
232        + Eq
233        + Hash
234        + StableHash
235        + DefIdGetter<Self>
236        + RegionName<Self>;
237
238    #[cfg(not(feature = "nightly"))]
239    type LateParamRegionKind: Clone
240        + Copy
241        + Debug
242        + PartialEq
243        + Eq
244        + Hash
245        + DefIdGetter<Self>
246        + RegionName<Self>;
247
248    type InternedRegionKind: Interned<Self, Value = RegionKind<Self>>;
249    type InternedConstKind: Interned<Self, Value = WithCachedTypeInfo<ConstKind<Self>>>;
250
251    type RegionAssumptions: Copy
252        + Debug
253        + Hash
254        + Eq
255        + SliceLike<Item = ty::OutlivesClause<Self, Self::GenericArg>>
256        + TypeFoldable<Self>;
257
258    // Predicates
259    type ParamEnv: ParamEnv<Self>;
260    type Predicate: Predicate<Self>;
261    type Clause: Clause<Self>;
262    type Clauses: Clauses<Self>;
263
264    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R;
265
266    fn with_canonical_param_env_cache<R>(
267        self,
268        f: impl FnOnce(&mut CanonicalParamEnvCache<Self>) -> R,
269    ) -> R;
270
271    /// Useful for testing. If a cache entry is replaced, this should
272    /// (in theory) only happen when concurrent.
273    fn assert_evaluation_is_concurrent(&self);
274
275    fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
276
277    type GenericsOf: GenericsOf<Self>;
278    fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
279
280    type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>;
281    fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
282
283    fn opt_alias_variances(
284        self,
285        kind: impl Into<ty::AliasTermKind<Self>>,
286    ) -> Option<Self::VariancesOf>;
287
288    fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
289    fn type_of_opaque_hir_typeck(
290        self,
291        def_id: Self::LocalOpaqueTyId,
292    ) -> ty::EarlyBinder<Self, Self::Ty>;
293    fn is_direct_const(self, alias: ty::AliasConstKind<Self>) -> bool;
294    fn const_of_item(
295        self,
296        alias: ty::AliasConstKind<Self>,
297    ) -> Option<ty::EarlyBinder<Self, Const<Self>>>;
298    fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind;
299
300    fn def_span(self, def_id: Self::DefId) -> Self::Span;
301
302    type AdtDef: AdtDef<Self>;
303    fn adt_def(self, adt_def_id: Self::AdtId) -> Self::AdtDef;
304
305    fn trait_ref_and_own_args_for_alias<'a>(
306        self,
307        def_id: Self::TraitAssocTermId,
308        args: &'a Self::GenericArgs,
309    ) -> (ty::TraitRef<Self>, Self::GenericArgsSlice<'a>);
310
311    fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
312
313    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
314    where
315        I: Iterator<Item = T>,
316        T: CollectAndApply<Self::GenericArg, Self::GenericArgs>;
317
318    fn check_alias_term_args_compatible(
319        self,
320        term_kind: AliasTermKind<Self>,
321        args: Self::GenericArgs,
322    ) -> bool;
323
324    fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
325    fn debug_assert_alias_term_args_compatible(
326        self,
327        term_kind: AliasTermKind<Self>,
328        args: Self::GenericArgs,
329    );
330
331    /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
332    /// are compatible with the `DefId`.
333    fn debug_assert_existential_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
334
335    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
336    where
337        I: Iterator<Item = T>,
338        T: CollectAndApply<Self::Ty, Self::Tys>;
339
340    fn mk_ct_from_kind(self, kind: ConstKind<Self>) -> Const<Self>;
341
342    fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId;
343
344    /// This can be an impl, or a trait if this is a defaulted term.
345    fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTermId) -> Self::DefId;
346
347    fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId;
348
349    fn recursion_limit(self) -> usize;
350
351    type Features: Features<Self>;
352    fn features(self) -> Self::Features;
353
354    fn assumptions_on_binders(self) -> bool;
355
356    fn renormalize_rigid_aliases(self) -> bool;
357
358    fn erase_and_anonymize_regions<T: TypeFoldable<Self>>(self, value: T) -> T;
359
360    fn const_eval_resolve_for_typeck(
361        self,
362        typing_env: Self::TypingEnv,
363        ct: ty::AliasConst<Self>,
364        span: Self::Span,
365    ) -> ty::ConstEvalResult<Self>;
366
367    fn coroutine_hidden_types(
368        self,
369        def_id: Self::CoroutineId,
370    ) -> ty::EarlyBinder<Self, ty::Binder<Self, ty::CoroutineWitnessTypes<Self>>>;
371
372    fn fn_sig(
373        self,
374        def_id: Self::FunctionId,
375    ) -> ty::EarlyBinder<Self, ty::Binder<Self, ty::FnSig<Self>>>;
376
377    fn coroutine_movability(self, def_id: Self::CoroutineId) -> Movability;
378
379    fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId;
380
381    fn generics_require_sized_self(self, def_id: Self::DefId) -> bool;
382
383    fn item_bounds(
384        self,
385        def_id: Self::DefId,
386    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
387
388    fn item_self_bounds(
389        self,
390        def_id: Self::DefId,
391    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
392
393    fn item_non_self_bounds(
394        self,
395        def_id: Self::DefId,
396    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
397
398    fn clauses_of(
399        self,
400        def_id: Self::DefId,
401    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
402
403    fn own_clauses_of(
404        self,
405        def_id: Self::DefId,
406    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
407
408    fn explicit_super_clauses_of(
409        self,
410        def_id: Self::TraitId,
411    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
412
413    fn explicit_implied_clauses_of(
414        self,
415        def_id: Self::DefId,
416    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
417
418    /// This is equivalent to computing the super-clauses of the trait for this impl
419    /// and filtering them to the outlives clauses. This is purely for performance.
420    fn impl_super_outlives(
421        self,
422        impl_def_id: Self::ImplId,
423    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
424
425    fn supertrait_def_ids(self, trait_def_id: Self::TraitId)
426    -> impl Iterator<Item = Self::TraitId>;
427
428    fn impl_is_const(self, def_id: Self::ImplId) -> bool;
429    fn fn_is_const(self, def_id: Self::FunctionId) -> bool;
430    fn closure_is_const(self, def_id: Self::ClosureId) -> bool;
431    fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool;
432    fn const_conditions(
433        self,
434        def_id: Self::DefId,
435    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
436    fn explicit_implied_const_bounds(
437        self,
438        def_id: Self::DefId,
439    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
440
441    fn impl_self_is_guaranteed_unsized(self, def_id: Self::ImplId) -> bool;
442
443    fn has_target_features(self, def_id: Self::FunctionId) -> bool;
444
445    fn require_projection_lang_item(
446        self,
447        lang_item: SolverProjectionLangItem,
448    ) -> Self::TraitAssocTyId;
449
450    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> Self::TraitId;
451
452    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> Self::AdtId;
453
454    fn is_projection_lang_item(
455        self,
456        def_id: Self::TraitAssocTyId,
457        lang_item: SolverProjectionLangItem,
458    ) -> bool;
459
460    fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool;
461
462    fn is_default_trait(self, def_id: Self::TraitId) -> bool;
463
464    fn is_implicit_trait(
465        self,
466        def_id: Self::TraitId,
467        including_sized: IncludeSizedImplicitBounds,
468    ) -> bool;
469
470    fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool;
471
472    fn as_projection_lang_item(
473        self,
474        def_id: Self::TraitAssocTyId,
475    ) -> Option<SolverProjectionLangItem>;
476
477    fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem>;
478
479    fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem>;
480
481    fn associated_type_def_ids(
482        self,
483        def_id: Self::TraitId,
484    ) -> impl IntoIterator<Item = Self::DefId>;
485
486    fn for_each_relevant_impl<R: VisitorResult>(
487        self,
488        trait_ref: TraitRef<Self>,
489        f: impl FnMut(Self::ImplId) -> R,
490    ) -> R;
491    fn for_each_blanket_impl<R: VisitorResult>(
492        self,
493        trait_def_id: Self::TraitId,
494        f: impl FnMut(Self::ImplId) -> R,
495    ) -> R;
496
497    fn has_item_definition(self, def_id: Self::ImplOrTraitAssocTermId) -> bool;
498
499    fn impl_specializes(self, impl_def_id: Self::ImplId, victim_def_id: Self::ImplId) -> bool;
500
501    fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool;
502
503    fn impl_trait_ref(self, impl_def_id: Self::ImplId)
504    -> ty::EarlyBinder<Self, ty::TraitRef<Self>>;
505
506    fn impl_polarity(self, impl_def_id: Self::ImplId) -> ty::ImplPolarity;
507
508    fn is_fully_generic_for_reflection(self, impl_def_id: Self::ImplId) -> bool;
509
510    fn trait_is_auto(self, trait_def_id: Self::TraitId) -> bool;
511
512    fn trait_is_marker(self, trait_def_id: Self::TraitId) -> bool;
513
514    fn trait_is_coinductive(self, trait_def_id: Self::TraitId) -> bool;
515
516    fn trait_is_alias(self, trait_def_id: Self::TraitId) -> bool;
517
518    fn trait_is_dyn_compatible(self, trait_def_id: Self::TraitId) -> bool;
519
520    fn trait_is_fundamental(self, def_id: Self::TraitId) -> bool;
521
522    /// Returns `true` if this is an `unsafe trait`.
523    fn trait_is_unsafe(self, trait_def_id: Self::TraitId) -> bool;
524
525    fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed;
526    fn span_delayed_bug(self, span: Self::Span, msg: impl ToString) -> Self::ErrorGuaranteed;
527
528    fn is_general_coroutine(self, coroutine_def_id: Self::CoroutineId) -> bool;
529    fn coroutine_is_async(self, coroutine_def_id: Self::CoroutineId) -> bool;
530    fn coroutine_is_gen(self, coroutine_def_id: Self::CoroutineId) -> bool;
531    fn coroutine_is_async_gen(self, coroutine_def_id: Self::CoroutineId) -> bool;
532
533    type UnsizingParams: Deref<Target = DenseBitSet<u32>>;
534    fn unsizing_params_for_adt(self, adt_def_id: Self::AdtId) -> Self::UnsizingParams;
535
536    fn anonymize_bound_vars<T: TypeFoldable<Self>>(
537        self,
538        binder: ty::Binder<Self, T>,
539    ) -> ty::Binder<Self, T>;
540
541    fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds;
542
543    fn opaque_types_and_coroutines_defined_by(
544        self,
545        defining_anchor: Self::LocalDefId,
546    ) -> Self::LocalDefIds;
547
548    type Probe: Debug + Hash + Eq + Borrow<inspect::Probe<Self>>;
549    fn mk_probe(self, probe: inspect::Probe<Self>) -> Self::Probe;
550    fn evaluate_root_goal_for_proof_tree_raw(
551        self,
552        canonical_goal: Self::CanonicalInput,
553        root_depth: usize,
554    ) -> (QueryResult<Self>, Self::Probe, RequiredDepth);
555
556    fn item_name(self, item_index: Self::DefId) -> Self::Symbol;
557
558    fn get_re_static_lifetime(self) -> Region<Self>;
559
560    fn intern_re_var(self, rv: RegionVid) -> Region<Self>;
561
562    fn intern_region(self, region_kind: RegionKind<Self>) -> Region<Self>;
563
564    fn intern_bound_region(
565        self,
566        debruijn: DebruijnIndex,
567        bound_region: BoundRegion<Self>,
568    ) -> Region<Self>;
569
570    fn intern_canonical_bound(self, var: BoundVar) -> Region<Self>;
571
572    fn intern_valtree(self, valtree_kind: ValTreeKind<Self>) -> Self::ValTree;
573
574    type CanonicalInput: Copy + Debug + Hash + Eq + Deref<Target = CanonicalInputData<Self>>;
575    fn mk_canonical_input(self, data: CanonicalInputData<Self>) -> Self::CanonicalInput;
576
577    fn const_zst(self) -> Self::ValTree;
578}
579
580macro_rules! declare_lift_into {
581    ($($assoc:ident),* $(,)?) => {
582        /// An interner whose associated types can be lifted into another interner `J`.
583        ///
584        /// These are associated type bounds rather than `where` clauses so a caller with
585        /// `I: LiftInto<J>` can rely on the individual associated type `Lift` bounds being
586        /// implied.
587        pub trait LiftInto<J>: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>
588        where
589            J: Interner,
590        {}
591
592        impl<I, J> LiftInto<J> for I
593        where
594            J: Interner,
595            I: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>,
596        {}
597    };
598}
599
600/// An interner whose associated types can be lifted into another interner `J`.
///
/// These are associated type bounds rather than `where` clauses so a caller with
/// `I: LiftInto<J>` can rely on the individual associated type `Lift` bounds being
/// implied.
pub trait LiftInto<J>: Interner<BoundVarKinds
    : crate::lift::Lift<J, Lifted = J::BoundVarKinds>, DefId
    : crate::lift::Lift<J, Lifted = J::DefId>, EarlyParamRegion
    : crate::lift::Lift<J, Lifted = J::EarlyParamRegion>, ErrorGuaranteed
    : crate::lift::Lift<J, Lifted = J::ErrorGuaranteed>, FreeConstAliasId
    : crate::lift::Lift<J, Lifted = J::FreeConstAliasId>, FreeTyAliasId
    : crate::lift::Lift<J, Lifted = J::FreeTyAliasId>, GenericArg
    : crate::lift::Lift<J, Lifted = J::GenericArg>, GenericArgs
    : crate::lift::Lift<J, Lifted = J::GenericArgs>, InherentAssocConstId
    : crate::lift::Lift<J, Lifted = J::InherentAssocConstId>,
    InherentAssocTyId : crate::lift::Lift<J, Lifted = J::InherentAssocTyId>,
    InternedConstKind : crate::lift::Lift<J, Lifted = J::InternedConstKind>,
    InternedRegionKind : crate::lift::Lift<J, Lifted = J::InternedRegionKind>,
    OpaqueTyId : crate::lift::Lift<J, Lifted = J::OpaqueTyId>, ParamEnv
    : crate::lift::Lift<J, Lifted = J::ParamEnv>, PatList
    : crate::lift::Lift<J, Lifted = J::PatList>, RegionAssumptions
    : crate::lift::Lift<J, Lifted = J::RegionAssumptions>, Symbol
    : crate::lift::Lift<J, Lifted = J::Symbol>, Term
    : crate::lift::Lift<J, Lifted = J::Term>, TraitAssocConstId
    : crate::lift::Lift<J, Lifted = J::TraitAssocConstId>, TraitAssocTermId
    : crate::lift::Lift<J, Lifted = J::TraitAssocTermId>, TraitAssocTyId
    : crate::lift::Lift<J, Lifted = J::TraitAssocTyId>, TraitId
    : crate::lift::Lift<J, Lifted = J::TraitId>, Ty
    : crate::lift::Lift<J, Lifted = J::Ty>, Tys
    : crate::lift::Lift<J, Lifted = J::Tys>, AnonConstId
    : crate::lift::Lift<J, Lifted = J::AnonConstId>> where J: Interner {
}
impl<I, J> LiftInto<J> for I where J: Interner,
    I: Interner<BoundVarKinds
    : crate::lift::Lift<J, Lifted = J::BoundVarKinds>, DefId
    : crate::lift::Lift<J, Lifted = J::DefId>, EarlyParamRegion
    : crate::lift::Lift<J, Lifted = J::EarlyParamRegion>, ErrorGuaranteed
    : crate::lift::Lift<J, Lifted = J::ErrorGuaranteed>, FreeConstAliasId
    : crate::lift::Lift<J, Lifted = J::FreeConstAliasId>, FreeTyAliasId
    : crate::lift::Lift<J, Lifted = J::FreeTyAliasId>, GenericArg
    : crate::lift::Lift<J, Lifted = J::GenericArg>, GenericArgs
    : crate::lift::Lift<J, Lifted = J::GenericArgs>, InherentAssocConstId
    : crate::lift::Lift<J, Lifted = J::InherentAssocConstId>,
    InherentAssocTyId : crate::lift::Lift<J, Lifted = J::InherentAssocTyId>,
    InternedConstKind : crate::lift::Lift<J, Lifted = J::InternedConstKind>,
    InternedRegionKind : crate::lift::Lift<J, Lifted = J::InternedRegionKind>,
    OpaqueTyId : crate::lift::Lift<J, Lifted = J::OpaqueTyId>, ParamEnv
    : crate::lift::Lift<J, Lifted = J::ParamEnv>, PatList
    : crate::lift::Lift<J, Lifted = J::PatList>, RegionAssumptions
    : crate::lift::Lift<J, Lifted = J::RegionAssumptions>, Symbol
    : crate::lift::Lift<J, Lifted = J::Symbol>, Term
    : crate::lift::Lift<J, Lifted = J::Term>, TraitAssocConstId
    : crate::lift::Lift<J, Lifted = J::TraitAssocConstId>, TraitAssocTermId
    : crate::lift::Lift<J, Lifted = J::TraitAssocTermId>, TraitAssocTyId
    : crate::lift::Lift<J, Lifted = J::TraitAssocTyId>, TraitId
    : crate::lift::Lift<J, Lifted = J::TraitId>, Ty
    : crate::lift::Lift<J, Lifted = J::Ty>, Tys
    : crate::lift::Lift<J, Lifted = J::Tys>, AnonConstId
    : crate::lift::Lift<J, Lifted = J::AnonConstId>> {}declare_lift_into! {
601    BoundVarKinds,
602    DefId,
603    EarlyParamRegion,
604    ErrorGuaranteed,
605    FreeConstAliasId,
606    FreeTyAliasId,
607    GenericArg,
608    GenericArgs,
609    InherentAssocConstId,
610    InherentAssocTyId,
611    InternedConstKind,
612    InternedRegionKind,
613    OpaqueTyId,
614    ParamEnv,
615    PatList,
616    RegionAssumptions,
617    Symbol,
618    Term,
619    TraitAssocConstId,
620    TraitAssocTermId,
621    TraitAssocTyId,
622    TraitId,
623    Ty,
624    Tys,
625    AnonConstId,
626}
627
628/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
629/// that produces `T` items. You could combine them with
630/// `f(&iter.collect::<Vec<_>>())`, but this requires allocating memory for the
631/// `Vec`.
632///
633/// This trait allows for faster implementations, intended for cases where the
634/// number of items produced by the iterator is small. There is a blanket impl
635/// for `T` items, but there is also a fallible impl for `Result<T, E>` items.
636pub trait CollectAndApply<T, R>: Sized {
637    type Output;
638
639    /// Produce a result of type `Self::Output` from `iter`. The result will
640    /// typically be produced by applying `f` on the elements produced by
641    /// `iter`, though this may not happen in some impls, e.g. if an error
642    /// occurred during iteration.
643    fn collect_and_apply<I, F>(iter: I, f: F) -> Self::Output
644    where
645        I: Iterator<Item = Self>,
646        F: FnOnce(&[T]) -> R;
647}
648
649/// The blanket impl that always collects all elements and applies `f`.
650impl<T, R> CollectAndApply<T, R> for T {
651    type Output = R;
652
653    /// Equivalent to `f(&iter.collect::<Vec<_>>())`.
654    fn collect_and_apply<I, F>(mut iter: I, f: F) -> R
655    where
656        I: Iterator<Item = T>,
657        F: FnOnce(&[T]) -> R,
658    {
659        // This code is hot enough that it's worth specializing for the most
660        // common length lists, to avoid the overhead of `Vec` creation.
661
662        let Some(t0) = iter.next() else {
663            return f(&[]);
664        };
665
666        let Some(t1) = iter.next() else {
667            return f(&[t0]);
668        };
669
670        let Some(t2) = iter.next() else {
671            return f(&[t0, t1]);
672        };
673
674        let Some(t3) = iter.next() else {
675            return f(&[t0, t1, t2]);
676        };
677
678        let Some(t4) = iter.next() else {
679            return f(&[t0, t1, t2, t3]);
680        };
681
682        let Some(t5) = iter.next() else {
683            return f(&[t0, t1, t2, t3, t4]);
684        };
685
686        let Some(t6) = iter.next() else {
687            return f(&[t0, t1, t2, t3, t4, t5]);
688        };
689
690        let Some(t7) = iter.next() else {
691            return f(&[t0, t1, t2, t3, t4, t5, t6]);
692        };
693
694        let Some(t8) = iter.next() else {
695            return f(&[t0, t1, t2, t3, t4, t5, t6, t7]);
696        };
697
698        f(&[t0, t1, t2, t3, t4, t5, t6, t7, t8].into_iter().chain(iter).collect::<Vec<_>>())
699    }
700}
701
702/// A fallible impl that will fail, without calling `f`, if there are any
703/// errors during collection.
704impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
705    type Output = Result<R, E>;
706
707    /// Equivalent to `Ok(f(&iter.collect::<Result<Vec<_>>>()?))`.
708    fn collect_and_apply<I, F>(mut iter: I, f: F) -> Result<R, E>
709    where
710        I: Iterator<Item = Result<T, E>>,
711        F: FnOnce(&[T]) -> R,
712    {
713        // This code is hot enough that it's worth specializing for the most
714        // common length lists, to avoid the overhead of `Vec` creation.
715
716        let Some(t0) = iter.next() else {
717            return Ok(f(&[]));
718        };
719        let t0 = t0?;
720
721        let Some(t1) = iter.next() else {
722            return Ok(f(&[t0]));
723        };
724        let t1 = t1?;
725
726        let Some(t2) = iter.next() else {
727            return Ok(f(&[t0, t1]));
728        };
729        let t2 = t2?;
730
731        let Some(t3) = iter.next() else {
732            return Ok(f(&[t0, t1, t2]));
733        };
734        let t3 = t3?;
735
736        let Some(t4) = iter.next() else {
737            return Ok(f(&[t0, t1, t2, t3]));
738        };
739        let t4 = t4?;
740
741        let Some(t5) = iter.next() else {
742            return Ok(f(&[t0, t1, t2, t3, t4]));
743        };
744        let t5 = t5?;
745
746        let Some(t6) = iter.next() else {
747            return Ok(f(&[t0, t1, t2, t3, t4, t5]));
748        };
749        let t6 = t6?;
750
751        let Some(t7) = iter.next() else {
752            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6]));
753        };
754        let t7 = t7?;
755
756        let Some(t8) = iter.next() else {
757            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6, t7]));
758        };
759        let t8 = t8?;
760
761        Ok(f(&[Ok(t0), Ok(t1), Ok(t2), Ok(t3), Ok(t4), Ok(t5), Ok(t6), Ok(t7), Ok(t8)]
762            .into_iter()
763            .chain(iter)
764            .collect::<Result<Vec<_>, _>>()?))
765    }
766}
767
768impl<I: Interner> search_graph::Cx for I {
769    type Input = I::CanonicalInput;
770    type Result = (QueryResult<I>, AccessedOpaques<I>);
771    type AmbiguityKind = Certainty;
772
773    type DepNodeIndex = I::DepNodeIndex;
774    type Tracked<T: Debug + Clone> = I::Tracked<T>;
775    fn mk_tracked<T: Debug + Clone>(
776        self,
777        data: T,
778        dep_node_index: I::DepNodeIndex,
779    ) -> I::Tracked<T> {
780        I::mk_tracked(self, data, dep_node_index)
781    }
782    fn get_tracked<T: Debug + Clone>(self, tracked: &I::Tracked<T>) -> T {
783        I::get_tracked(self, tracked)
784    }
785    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, I::DepNodeIndex) {
786        I::with_cached_task(self, task)
787    }
788    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
789        I::with_global_cache(self, f)
790    }
791    fn assert_evaluation_is_concurrent(&self) {
792        self.assert_evaluation_is_concurrent()
793    }
794}
795
796pub enum IncludeSizedImplicitBounds {
797    Yes,
798    No,
799}