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