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