Skip to main content

rustc_type_ir/
interner.rs

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