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