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 clauses_of(
324        self,
325        def_id: Self::DefId,
326    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
327
328    fn own_clauses_of(
329        self,
330        def_id: Self::DefId,
331    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
332
333    fn explicit_super_clauses_of(
334        self,
335        def_id: Self::TraitId,
336    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
337
338    fn explicit_implied_clauses_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 is_fully_generic_for_reflection(self, impl_def_id: Self::ImplId) -> bool;
427
428    fn trait_is_auto(self, trait_def_id: Self::TraitId) -> bool;
429
430    fn trait_is_coinductive(self, trait_def_id: Self::TraitId) -> bool;
431
432    fn trait_is_alias(self, trait_def_id: Self::TraitId) -> bool;
433
434    fn trait_is_dyn_compatible(self, trait_def_id: Self::TraitId) -> bool;
435
436    fn trait_is_fundamental(self, def_id: Self::TraitId) -> bool;
437
438    /// Returns `true` if this is an `unsafe trait`.
439    fn trait_is_unsafe(self, trait_def_id: Self::TraitId) -> bool;
440
441    fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool;
442
443    fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed;
444
445    fn is_general_coroutine(self, coroutine_def_id: Self::CoroutineId) -> bool;
446    fn coroutine_is_async(self, coroutine_def_id: Self::CoroutineId) -> bool;
447    fn coroutine_is_gen(self, coroutine_def_id: Self::CoroutineId) -> bool;
448    fn coroutine_is_async_gen(self, coroutine_def_id: Self::CoroutineId) -> bool;
449
450    type UnsizingParams: Deref<Target = DenseBitSet<u32>>;
451    fn unsizing_params_for_adt(self, adt_def_id: Self::AdtId) -> Self::UnsizingParams;
452
453    fn anonymize_bound_vars<T: TypeFoldable<Self>>(
454        self,
455        binder: ty::Binder<Self, T>,
456    ) -> ty::Binder<Self, T>;
457
458    fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds;
459
460    fn opaque_types_and_coroutines_defined_by(
461        self,
462        defining_anchor: Self::LocalDefId,
463    ) -> Self::LocalDefIds;
464
465    type Probe: Debug + Hash + Eq + Borrow<inspect::Probe<Self>>;
466    fn mk_probe(self, probe: inspect::Probe<Self>) -> Self::Probe;
467    fn evaluate_root_goal_for_proof_tree_raw(
468        self,
469        canonical_goal: CanonicalInput<Self>,
470        root_depth: usize,
471    ) -> (QueryResult<Self>, Self::Probe);
472
473    fn emit_next_solver_overflow_fcw(self, predicate: Self::Predicate, span: Self::Span);
474
475    fn item_name(self, item_index: Self::DefId) -> Self::Symbol;
476
477    fn get_anon_re_bounds_lifetime(self, idx: usize, var_idx: usize) -> Option<Region<Self>>;
478
479    fn get_anon_re_canonical_bounds_lifetime(self, idx: usize) -> Option<Region<Self>>;
480
481    fn get_re_static_lifetime(self) -> Region<Self>;
482
483    fn intern_region(self, region_kind: RegionKind<Self>) -> Region<Self>;
484
485    fn intern_bound_region(
486        self,
487        debruijn: DebruijnIndex,
488        bound_region: BoundRegion<Self>,
489    ) -> Region<Self>;
490
491    fn intern_canonical_bound(self, var: BoundVar) -> Region<Self>;
492}
493
494macro_rules! declare_lift_into {
495    ($($assoc:ident),* $(,)?) => {
496        /// An interner whose associated types can be lifted into another interner `J`.
497        ///
498        /// These are associated type bounds rather than `where` clauses so a caller with
499        /// `I: LiftInto<J>` can rely on the individual associated type `Lift` bounds being
500        /// implied.
501        pub trait LiftInto<J>: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>
502        where
503            J: Interner,
504        {}
505
506        impl<I, J> LiftInto<J> for I
507        where
508            J: Interner,
509            I: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>,
510        {}
511    };
512}
513
514/// 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! {
515    BoundVarKinds,
516    Const,
517    DefId,
518    EarlyParamRegion,
519    ErrorGuaranteed,
520    FreeConstAliasId,
521    FreeTyAliasId,
522    GenericArg,
523    GenericArgs,
524    InherentAssocConstId,
525    InherentAssocTyId,
526    InternedRegionKind,
527    LateParamRegion,
528    OpaqueTyId,
529    ParamEnv,
530    PatList,
531    RegionAssumptions,
532    Symbol,
533    Term,
534    TraitAssocConstId,
535    TraitAssocTermId,
536    TraitAssocTyId,
537    TraitId,
538    Ty,
539    Tys,
540    AnonConstId,
541}
542
543/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
544/// that produces `T` items. You could combine them with
545/// `f(&iter.collect::<Vec<_>>())`, but this requires allocating memory for the
546/// `Vec`.
547///
548/// This trait allows for faster implementations, intended for cases where the
549/// number of items produced by the iterator is small. There is a blanket impl
550/// for `T` items, but there is also a fallible impl for `Result<T, E>` items.
551pub trait CollectAndApply<T, R>: Sized {
552    type Output;
553
554    /// Produce a result of type `Self::Output` from `iter`. The result will
555    /// typically be produced by applying `f` on the elements produced by
556    /// `iter`, though this may not happen in some impls, e.g. if an error
557    /// occurred during iteration.
558    fn collect_and_apply<I, F>(iter: I, f: F) -> Self::Output
559    where
560        I: Iterator<Item = Self>,
561        F: FnOnce(&[T]) -> R;
562}
563
564/// The blanket impl that always collects all elements and applies `f`.
565impl<T, R> CollectAndApply<T, R> for T {
566    type Output = R;
567
568    /// Equivalent to `f(&iter.collect::<Vec<_>>())`.
569    fn collect_and_apply<I, F>(mut iter: I, f: F) -> R
570    where
571        I: Iterator<Item = T>,
572        F: FnOnce(&[T]) -> R,
573    {
574        // This code is hot enough that it's worth specializing for the most
575        // common length lists, to avoid the overhead of `Vec` creation.
576
577        let Some(t0) = iter.next() else {
578            return f(&[]);
579        };
580
581        let Some(t1) = iter.next() else {
582            return f(&[t0]);
583        };
584
585        let Some(t2) = iter.next() else {
586            return f(&[t0, t1]);
587        };
588
589        let Some(t3) = iter.next() else {
590            return f(&[t0, t1, t2]);
591        };
592
593        let Some(t4) = iter.next() else {
594            return f(&[t0, t1, t2, t3]);
595        };
596
597        let Some(t5) = iter.next() else {
598            return f(&[t0, t1, t2, t3, t4]);
599        };
600
601        let Some(t6) = iter.next() else {
602            return f(&[t0, t1, t2, t3, t4, t5]);
603        };
604
605        let Some(t7) = iter.next() else {
606            return f(&[t0, t1, t2, t3, t4, t5, t6]);
607        };
608
609        let Some(t8) = iter.next() else {
610            return f(&[t0, t1, t2, t3, t4, t5, t6, t7]);
611        };
612
613        f(&[t0, t1, t2, t3, t4, t5, t6, t7, t8].into_iter().chain(iter).collect::<Vec<_>>())
614    }
615}
616
617/// A fallible impl that will fail, without calling `f`, if there are any
618/// errors during collection.
619impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
620    type Output = Result<R, E>;
621
622    /// Equivalent to `Ok(f(&iter.collect::<Result<Vec<_>>>()?))`.
623    fn collect_and_apply<I, F>(mut iter: I, f: F) -> Result<R, E>
624    where
625        I: Iterator<Item = Result<T, E>>,
626        F: FnOnce(&[T]) -> R,
627    {
628        // This code is hot enough that it's worth specializing for the most
629        // common length lists, to avoid the overhead of `Vec` creation.
630
631        let Some(t0) = iter.next() else {
632            return Ok(f(&[]));
633        };
634        let t0 = t0?;
635
636        let Some(t1) = iter.next() else {
637            return Ok(f(&[t0]));
638        };
639        let t1 = t1?;
640
641        let Some(t2) = iter.next() else {
642            return Ok(f(&[t0, t1]));
643        };
644        let t2 = t2?;
645
646        let Some(t3) = iter.next() else {
647            return Ok(f(&[t0, t1, t2]));
648        };
649        let t3 = t3?;
650
651        let Some(t4) = iter.next() else {
652            return Ok(f(&[t0, t1, t2, t3]));
653        };
654        let t4 = t4?;
655
656        let Some(t5) = iter.next() else {
657            return Ok(f(&[t0, t1, t2, t3, t4]));
658        };
659        let t5 = t5?;
660
661        let Some(t6) = iter.next() else {
662            return Ok(f(&[t0, t1, t2, t3, t4, t5]));
663        };
664        let t6 = t6?;
665
666        let Some(t7) = iter.next() else {
667            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6]));
668        };
669        let t7 = t7?;
670
671        let Some(t8) = iter.next() else {
672            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6, t7]));
673        };
674        let t8 = t8?;
675
676        Ok(f(&[Ok(t0), Ok(t1), Ok(t2), Ok(t3), Ok(t4), Ok(t5), Ok(t6), Ok(t7), Ok(t8)]
677            .into_iter()
678            .chain(iter)
679            .collect::<Result<Vec<_>, _>>()?))
680    }
681}
682
683impl<I: Interner> search_graph::Cx for I {
684    type Input = CanonicalInput<I>;
685    type Result = (QueryResult<I>, AccessedOpaques<I>);
686    type AmbiguityKind = Certainty;
687
688    type DepNodeIndex = I::DepNodeIndex;
689    type Tracked<T: Debug + Clone> = I::Tracked<T>;
690    fn mk_tracked<T: Debug + Clone>(
691        self,
692        data: T,
693        dep_node_index: I::DepNodeIndex,
694    ) -> I::Tracked<T> {
695        I::mk_tracked(self, data, dep_node_index)
696    }
697    fn get_tracked<T: Debug + Clone>(self, tracked: &I::Tracked<T>) -> T {
698        I::get_tracked(self, tracked)
699    }
700    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, I::DepNodeIndex) {
701        I::with_cached_task(self, task)
702    }
703    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
704        I::with_global_cache(self, f)
705    }
706    fn assert_evaluation_is_concurrent(&self) {
707        self.assert_evaluation_is_concurrent()
708    }
709}