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