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