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