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