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, CanonicalParamEnvCache, DebruijnIndex, Region, RegionKind,
22    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::HostEffectClause<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::OutlivesClause<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 with_canonical_param_env_cache<R>(
208        self,
209        f: impl FnOnce(&mut CanonicalParamEnvCache<Self>) -> R,
210    ) -> R;
211
212    /// Useful for testing. If a cache entry is replaced, this should
213    /// (in theory) only happen when concurrent.
214    fn assert_evaluation_is_concurrent(&self);
215
216    fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
217
218    type GenericsOf: GenericsOf<Self>;
219    fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
220
221    type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>;
222    fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
223
224    fn opt_alias_variances(
225        self,
226        kind: impl Into<ty::AliasTermKind<Self>>,
227    ) -> Option<Self::VariancesOf>;
228
229    fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
230    fn type_of_opaque_hir_typeck(
231        self,
232        def_id: Self::LocalOpaqueTyId,
233    ) -> ty::EarlyBinder<Self, Self::Ty>;
234    fn is_type_const(self, def_id: Self::DefId) -> bool;
235    fn const_of_item(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Const>;
236    fn anon_const_kind(self, def_id: Self::DefId) -> ty::AnonConstKind;
237
238    fn def_span(self, def_id: Self::DefId) -> Self::Span;
239
240    type AdtDef: AdtDef<Self>;
241    fn adt_def(self, adt_def_id: Self::AdtId) -> Self::AdtDef;
242
243    fn alias_const_kind_from_def_id(self, def_id: Self::DefId) -> ty::AliasConstKind<Self>;
244
245    // FIXME: remove in favor of explicit construction
246    fn alias_term_kind_from_def_id(self, def_id: Self::DefId) -> ty::AliasTermKind<Self>;
247
248    fn trait_ref_and_own_args_for_alias(
249        self,
250        def_id: Self::TraitAssocTermId,
251        args: Self::GenericArgs,
252    ) -> (ty::TraitRef<Self>, Self::GenericArgsSlice);
253
254    fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
255
256    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
257    where
258        I: Iterator<Item = T>,
259        T: CollectAndApply<Self::GenericArg, Self::GenericArgs>;
260
261    fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool;
262
263    fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
264
265    /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
266    /// are compatible with the `DefId`.
267    fn debug_assert_existential_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs);
268
269    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
270    where
271        I: Iterator<Item = T>,
272        T: CollectAndApply<Self::Ty, Self::Tys>;
273
274    fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId;
275
276    /// This can be an impl, or a trait if this is a defaulted term.
277    fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTermId) -> Self::DefId;
278
279    fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId;
280
281    fn recursion_limit(self) -> usize;
282
283    type Features: Features<Self>;
284    fn features(self) -> Self::Features;
285
286    fn assumptions_on_binders(self) -> bool;
287
288    fn renormalize_rigid_aliases(self) -> bool;
289
290    fn coroutine_hidden_types(
291        self,
292        def_id: Self::CoroutineId,
293    ) -> ty::EarlyBinder<Self, ty::Binder<Self, ty::CoroutineWitnessTypes<Self>>>;
294
295    fn fn_sig(
296        self,
297        def_id: Self::FunctionId,
298    ) -> ty::EarlyBinder<Self, ty::Binder<Self, ty::FnSig<Self>>>;
299
300    fn coroutine_movability(self, def_id: Self::CoroutineId) -> Movability;
301
302    fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId;
303
304    fn generics_require_sized_self(self, def_id: Self::DefId) -> bool;
305
306    fn item_bounds(
307        self,
308        def_id: Self::DefId,
309    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
310
311    fn item_self_bounds(
312        self,
313        def_id: Self::DefId,
314    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
315
316    fn item_non_self_bounds(
317        self,
318        def_id: Self::DefId,
319    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
320
321    fn clauses_of(
322        self,
323        def_id: Self::DefId,
324    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
325
326    fn own_clauses_of(
327        self,
328        def_id: Self::DefId,
329    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
330
331    fn explicit_super_clauses_of(
332        self,
333        def_id: Self::TraitId,
334    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
335
336    fn explicit_implied_clauses_of(
337        self,
338        def_id: Self::DefId,
339    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
340
341    /// This is equivalent to computing the super-clauses of the trait for this impl
342    /// and filtering them to the outlives clauses. This is purely for performance.
343    fn impl_super_outlives(
344        self,
345        impl_def_id: Self::ImplId,
346    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
347
348    fn impl_is_const(self, def_id: Self::ImplId) -> bool;
349    fn fn_is_const(self, def_id: Self::FunctionId) -> bool;
350    fn closure_is_const(self, def_id: Self::ClosureId) -> bool;
351    fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool;
352    fn const_conditions(
353        self,
354        def_id: Self::DefId,
355    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
356    fn explicit_implied_const_bounds(
357        self,
358        def_id: Self::DefId,
359    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
360
361    fn impl_self_is_guaranteed_unsized(self, def_id: Self::ImplId) -> bool;
362
363    fn has_target_features(self, def_id: Self::FunctionId) -> bool;
364
365    fn require_projection_lang_item(
366        self,
367        lang_item: SolverProjectionLangItem,
368    ) -> Self::TraitAssocTyId;
369
370    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> Self::TraitId;
371
372    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> Self::AdtId;
373
374    fn is_projection_lang_item(
375        self,
376        def_id: Self::TraitAssocTyId,
377        lang_item: SolverProjectionLangItem,
378    ) -> bool;
379
380    fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool;
381
382    fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool;
383
384    fn is_default_trait(self, def_id: Self::TraitId) -> bool;
385
386    fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool;
387
388    fn as_projection_lang_item(
389        self,
390        def_id: Self::TraitAssocTyId,
391    ) -> Option<SolverProjectionLangItem>;
392
393    fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem>;
394
395    fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem>;
396
397    fn associated_type_def_ids(
398        self,
399        def_id: Self::TraitId,
400    ) -> impl IntoIterator<Item = Self::DefId>;
401
402    fn for_each_relevant_impl<R: VisitorResult>(
403        self,
404        trait_ref: TraitRef<Self>,
405        f: impl FnMut(Self::ImplId) -> R,
406    ) -> R;
407    fn for_each_blanket_impl<R: VisitorResult>(
408        self,
409        trait_def_id: Self::TraitId,
410        f: impl FnMut(Self::ImplId) -> R,
411    ) -> R;
412
413    fn has_item_definition(self, def_id: Self::ImplOrTraitAssocTermId) -> bool;
414
415    fn impl_specializes(self, impl_def_id: Self::ImplId, victim_def_id: Self::ImplId) -> bool;
416
417    fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool;
418
419    fn impl_trait_ref(self, impl_def_id: Self::ImplId)
420    -> ty::EarlyBinder<Self, ty::TraitRef<Self>>;
421
422    fn impl_polarity(self, impl_def_id: Self::ImplId) -> ty::ImplPolarity;
423
424    fn is_fully_generic_for_reflection(self, impl_def_id: Self::ImplId) -> bool;
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        root_depth: usize,
469    ) -> (QueryResult<Self>, Self::Probe);
470
471    fn emit_next_solver_overflow_fcw(self, predicate: Self::Predicate, span: Self::Span);
472
473    fn item_name(self, item_index: Self::DefId) -> Self::Symbol;
474
475    fn get_anon_re_bounds_lifetime(self, idx: usize, var_idx: usize) -> Option<Region<Self>>;
476
477    fn get_anon_re_canonical_bounds_lifetime(self, idx: usize) -> Option<Region<Self>>;
478
479    fn get_re_static_lifetime(self) -> Region<Self>;
480
481    fn intern_region(self, region_kind: RegionKind<Self>) -> Region<Self>;
482
483    fn intern_bound_region(
484        self,
485        debruijn: DebruijnIndex,
486        bound_region: BoundRegion<Self>,
487    ) -> Region<Self>;
488
489    fn intern_canonical_bound(self, var: BoundVar) -> Region<Self>;
490}
491
492macro_rules! declare_lift_into {
493    ($($assoc:ident),* $(,)?) => {
494        /// An interner whose associated types can be lifted into another interner `J`.
495        ///
496        /// These are associated type bounds rather than `where` clauses so a caller with
497        /// `I: LiftInto<J>` can rely on the individual associated type `Lift` bounds being
498        /// implied.
499        pub trait LiftInto<J>: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>
500        where
501            J: Interner,
502        {}
503
504        impl<I, J> LiftInto<J> for I
505        where
506            J: Interner,
507            I: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>,
508        {}
509    };
510}
511
512/// 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! {
513    BoundVarKinds,
514    Const,
515    DefId,
516    EarlyParamRegion,
517    ErrorGuaranteed,
518    FreeConstAliasId,
519    FreeTyAliasId,
520    GenericArg,
521    GenericArgs,
522    InherentAssocConstId,
523    InherentAssocTyId,
524    InternedRegionKind,
525    LateParamRegion,
526    OpaqueTyId,
527    ParamEnv,
528    PatList,
529    RegionAssumptions,
530    Symbol,
531    Term,
532    TraitAssocConstId,
533    TraitAssocTermId,
534    TraitAssocTyId,
535    TraitId,
536    Ty,
537    Tys,
538    AnonConstId,
539}
540
541/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
542/// that produces `T` items. You could combine them with
543/// `f(&iter.collect::<Vec<_>>())`, but this requires allocating memory for the
544/// `Vec`.
545///
546/// This trait allows for faster implementations, intended for cases where the
547/// number of items produced by the iterator is small. There is a blanket impl
548/// for `T` items, but there is also a fallible impl for `Result<T, E>` items.
549pub trait CollectAndApply<T, R>: Sized {
550    type Output;
551
552    /// Produce a result of type `Self::Output` from `iter`. The result will
553    /// typically be produced by applying `f` on the elements produced by
554    /// `iter`, though this may not happen in some impls, e.g. if an error
555    /// occurred during iteration.
556    fn collect_and_apply<I, F>(iter: I, f: F) -> Self::Output
557    where
558        I: Iterator<Item = Self>,
559        F: FnOnce(&[T]) -> R;
560}
561
562/// The blanket impl that always collects all elements and applies `f`.
563impl<T, R> CollectAndApply<T, R> for T {
564    type Output = R;
565
566    /// Equivalent to `f(&iter.collect::<Vec<_>>())`.
567    fn collect_and_apply<I, F>(mut iter: I, f: F) -> R
568    where
569        I: Iterator<Item = T>,
570        F: FnOnce(&[T]) -> R,
571    {
572        // This code is hot enough that it's worth specializing for the most
573        // common length lists, to avoid the overhead of `Vec` creation.
574
575        let Some(t0) = iter.next() else {
576            return f(&[]);
577        };
578
579        let Some(t1) = iter.next() else {
580            return f(&[t0]);
581        };
582
583        let Some(t2) = iter.next() else {
584            return f(&[t0, t1]);
585        };
586
587        let Some(t3) = iter.next() else {
588            return f(&[t0, t1, t2]);
589        };
590
591        let Some(t4) = iter.next() else {
592            return f(&[t0, t1, t2, t3]);
593        };
594
595        let Some(t5) = iter.next() else {
596            return f(&[t0, t1, t2, t3, t4]);
597        };
598
599        let Some(t6) = iter.next() else {
600            return f(&[t0, t1, t2, t3, t4, t5]);
601        };
602
603        let Some(t7) = iter.next() else {
604            return f(&[t0, t1, t2, t3, t4, t5, t6]);
605        };
606
607        let Some(t8) = iter.next() else {
608            return f(&[t0, t1, t2, t3, t4, t5, t6, t7]);
609        };
610
611        f(&[t0, t1, t2, t3, t4, t5, t6, t7, t8].into_iter().chain(iter).collect::<Vec<_>>())
612    }
613}
614
615/// A fallible impl that will fail, without calling `f`, if there are any
616/// errors during collection.
617impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
618    type Output = Result<R, E>;
619
620    /// Equivalent to `Ok(f(&iter.collect::<Result<Vec<_>>>()?))`.
621    fn collect_and_apply<I, F>(mut iter: I, f: F) -> Result<R, E>
622    where
623        I: Iterator<Item = Result<T, E>>,
624        F: FnOnce(&[T]) -> R,
625    {
626        // This code is hot enough that it's worth specializing for the most
627        // common length lists, to avoid the overhead of `Vec` creation.
628
629        let Some(t0) = iter.next() else {
630            return Ok(f(&[]));
631        };
632        let t0 = t0?;
633
634        let Some(t1) = iter.next() else {
635            return Ok(f(&[t0]));
636        };
637        let t1 = t1?;
638
639        let Some(t2) = iter.next() else {
640            return Ok(f(&[t0, t1]));
641        };
642        let t2 = t2?;
643
644        let Some(t3) = iter.next() else {
645            return Ok(f(&[t0, t1, t2]));
646        };
647        let t3 = t3?;
648
649        let Some(t4) = iter.next() else {
650            return Ok(f(&[t0, t1, t2, t3]));
651        };
652        let t4 = t4?;
653
654        let Some(t5) = iter.next() else {
655            return Ok(f(&[t0, t1, t2, t3, t4]));
656        };
657        let t5 = t5?;
658
659        let Some(t6) = iter.next() else {
660            return Ok(f(&[t0, t1, t2, t3, t4, t5]));
661        };
662        let t6 = t6?;
663
664        let Some(t7) = iter.next() else {
665            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6]));
666        };
667        let t7 = t7?;
668
669        let Some(t8) = iter.next() else {
670            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6, t7]));
671        };
672        let t8 = t8?;
673
674        Ok(f(&[Ok(t0), Ok(t1), Ok(t2), Ok(t3), Ok(t4), Ok(t5), Ok(t6), Ok(t7), Ok(t8)]
675            .into_iter()
676            .chain(iter)
677            .collect::<Result<Vec<_>, _>>()?))
678    }
679}
680
681impl<I: Interner> search_graph::Cx for I {
682    type Input = CanonicalInput<I>;
683    type Result = (QueryResult<I>, AccessedOpaques<I>);
684    type AmbiguityKind = Certainty;
685
686    type DepNodeIndex = I::DepNodeIndex;
687    type Tracked<T: Debug + Clone> = I::Tracked<T>;
688    fn mk_tracked<T: Debug + Clone>(
689        self,
690        data: T,
691        dep_node_index: I::DepNodeIndex,
692    ) -> I::Tracked<T> {
693        I::mk_tracked(self, data, dep_node_index)
694    }
695    fn get_tracked<T: Debug + Clone>(self, tracked: &I::Tracked<T>) -> T {
696        I::get_tracked(self, tracked)
697    }
698    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, I::DepNodeIndex) {
699        I::with_cached_task(self, task)
700    }
701    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
702        I::with_global_cache(self, f)
703    }
704    fn assert_evaluation_is_concurrent(&self) {
705        self.assert_evaluation_is_concurrent()
706    }
707}