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 renormalize_rigid_aliases(self) -> bool;
296
297    fn coroutine_hidden_types(
298        self,
299        def_id: Self::CoroutineId,
300    ) -> ty::EarlyBinder<Self, ty::Binder<Self, ty::CoroutineWitnessTypes<Self>>>;
301
302    fn fn_sig(
303        self,
304        def_id: Self::FunctionId,
305    ) -> ty::EarlyBinder<Self, ty::Binder<Self, ty::FnSig<Self>>>;
306
307    fn coroutine_movability(self, def_id: Self::CoroutineId) -> Movability;
308
309    fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId;
310
311    fn generics_require_sized_self(self, def_id: Self::DefId) -> bool;
312
313    fn item_bounds(
314        self,
315        def_id: Self::DefId,
316    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
317
318    fn item_self_bounds(
319        self,
320        def_id: Self::DefId,
321    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
322
323    fn item_non_self_bounds(
324        self,
325        def_id: Self::DefId,
326    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
327
328    fn predicates_of(
329        self,
330        def_id: Self::DefId,
331    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
332
333    fn own_predicates_of(
334        self,
335        def_id: Self::DefId,
336    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
337
338    fn explicit_super_predicates_of(
339        self,
340        def_id: Self::TraitId,
341    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
342
343    fn explicit_implied_predicates_of(
344        self,
345        def_id: Self::DefId,
346    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
347
348    /// This is equivalent to computing the super-predicates of the trait for this impl
349    /// and filtering them to the outlives predicates. This is purely for performance.
350    fn impl_super_outlives(
351        self,
352        impl_def_id: Self::ImplId,
353    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
354
355    fn impl_is_const(self, def_id: Self::ImplId) -> bool;
356    fn fn_is_const(self, def_id: Self::FunctionId) -> bool;
357    fn closure_is_const(self, def_id: Self::ClosureId) -> bool;
358    fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool;
359    fn const_conditions(
360        self,
361        def_id: Self::DefId,
362    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
363    fn explicit_implied_const_bounds(
364        self,
365        def_id: Self::DefId,
366    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
367
368    fn impl_self_is_guaranteed_unsized(self, def_id: Self::ImplId) -> bool;
369
370    fn has_target_features(self, def_id: Self::FunctionId) -> bool;
371
372    fn require_projection_lang_item(
373        self,
374        lang_item: SolverProjectionLangItem,
375    ) -> Self::TraitAssocTyId;
376
377    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> Self::TraitId;
378
379    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> Self::AdtId;
380
381    fn is_projection_lang_item(
382        self,
383        def_id: Self::TraitAssocTyId,
384        lang_item: SolverProjectionLangItem,
385    ) -> bool;
386
387    fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool;
388
389    fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool;
390
391    fn is_default_trait(self, def_id: Self::TraitId) -> bool;
392
393    fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool;
394
395    fn as_projection_lang_item(
396        self,
397        def_id: Self::TraitAssocTyId,
398    ) -> Option<SolverProjectionLangItem>;
399
400    fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem>;
401
402    fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem>;
403
404    fn associated_type_def_ids(
405        self,
406        def_id: Self::TraitId,
407    ) -> impl IntoIterator<Item = Self::DefId>;
408
409    fn for_each_relevant_impl<R: VisitorResult>(
410        self,
411        trait_def_id: Self::TraitId,
412        self_ty: Self::Ty,
413        f: impl FnMut(Self::ImplId) -> R,
414    ) -> R;
415    fn for_each_blanket_impl<R: VisitorResult>(
416        self,
417        trait_def_id: Self::TraitId,
418        f: impl FnMut(Self::ImplId) -> R,
419    ) -> R;
420
421    fn has_item_definition(self, def_id: Self::ImplOrTraitAssocTermId) -> bool;
422
423    fn impl_specializes(self, impl_def_id: Self::ImplId, victim_def_id: Self::ImplId) -> bool;
424
425    fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool;
426
427    fn impl_trait_ref(self, impl_def_id: Self::ImplId)
428    -> ty::EarlyBinder<Self, ty::TraitRef<Self>>;
429
430    fn impl_polarity(self, impl_def_id: Self::ImplId) -> ty::ImplPolarity;
431
432    fn trait_is_auto(self, trait_def_id: Self::TraitId) -> bool;
433
434    fn trait_is_coinductive(self, trait_def_id: Self::TraitId) -> bool;
435
436    fn trait_is_alias(self, trait_def_id: Self::TraitId) -> bool;
437
438    fn trait_is_dyn_compatible(self, trait_def_id: Self::TraitId) -> bool;
439
440    fn trait_is_fundamental(self, def_id: Self::TraitId) -> bool;
441
442    /// Returns `true` if this is an `unsafe trait`.
443    fn trait_is_unsafe(self, trait_def_id: Self::TraitId) -> bool;
444
445    fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool;
446
447    fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed;
448
449    fn is_general_coroutine(self, coroutine_def_id: Self::CoroutineId) -> bool;
450    fn coroutine_is_async(self, coroutine_def_id: Self::CoroutineId) -> bool;
451    fn coroutine_is_gen(self, coroutine_def_id: Self::CoroutineId) -> bool;
452    fn coroutine_is_async_gen(self, coroutine_def_id: Self::CoroutineId) -> bool;
453
454    type UnsizingParams: Deref<Target = DenseBitSet<u32>>;
455    fn unsizing_params_for_adt(self, adt_def_id: Self::AdtId) -> Self::UnsizingParams;
456
457    fn anonymize_bound_vars<T: TypeFoldable<Self>>(
458        self,
459        binder: ty::Binder<Self, T>,
460    ) -> ty::Binder<Self, T>;
461
462    fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds;
463
464    fn opaque_types_and_coroutines_defined_by(
465        self,
466        defining_anchor: Self::LocalDefId,
467    ) -> Self::LocalDefIds;
468
469    type Probe: Debug + Hash + Eq + Borrow<inspect::Probe<Self>>;
470    fn mk_probe(self, probe: inspect::Probe<Self>) -> Self::Probe;
471    fn evaluate_root_goal_for_proof_tree_raw(
472        self,
473        canonical_goal: CanonicalInput<Self>,
474    ) -> (QueryResult<Self>, Self::Probe);
475
476    fn item_name(self, item_index: Self::DefId) -> Self::Symbol;
477}
478
479macro_rules! declare_lift_into {
480    ($($assoc:ident),* $(,)?) => {
481        /// An interner whose associated types can be lifted into another interner `J`.
482        ///
483        /// These are associated type bounds rather than `where` clauses so a caller with
484        /// `I: LiftInto<J>` can rely on the individual associated type `Lift` bounds being
485        /// implied.
486        pub trait LiftInto<J>: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>
487        where
488            J: Interner,
489        {}
490
491        impl<I, J> LiftInto<J> for I
492        where
493            J: Interner,
494            I: Interner<$($assoc: crate::lift::Lift<J, Lifted = J::$assoc>,)*>,
495        {}
496    };
497}
498
499/// 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! {
500    BoundVarKinds,
501    Const,
502    DefId,
503    FreeConstAliasId,
504    FreeTyAliasId,
505    GenericArg,
506    GenericArgs,
507    InherentAssocConstId,
508    InherentAssocTyId,
509    OpaqueTyId,
510    ParamEnv,
511    PatList,
512    Region,
513    RegionAssumptions,
514    Symbol,
515    Term,
516    TraitAssocConstId,
517    TraitAssocTermId,
518    TraitAssocTyId,
519    TraitId,
520    Ty,
521    Tys,
522    UnevaluatedConstId,
523}
524
525/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
526/// that produces `T` items. You could combine them with
527/// `f(&iter.collect::<Vec<_>>())`, but this requires allocating memory for the
528/// `Vec`.
529///
530/// This trait allows for faster implementations, intended for cases where the
531/// number of items produced by the iterator is small. There is a blanket impl
532/// for `T` items, but there is also a fallible impl for `Result<T, E>` items.
533pub trait CollectAndApply<T, R>: Sized {
534    type Output;
535
536    /// Produce a result of type `Self::Output` from `iter`. The result will
537    /// typically be produced by applying `f` on the elements produced by
538    /// `iter`, though this may not happen in some impls, e.g. if an error
539    /// occurred during iteration.
540    fn collect_and_apply<I, F>(iter: I, f: F) -> Self::Output
541    where
542        I: Iterator<Item = Self>,
543        F: FnOnce(&[T]) -> R;
544}
545
546/// The blanket impl that always collects all elements and applies `f`.
547impl<T, R> CollectAndApply<T, R> for T {
548    type Output = R;
549
550    /// Equivalent to `f(&iter.collect::<Vec<_>>())`.
551    fn collect_and_apply<I, F>(mut iter: I, f: F) -> R
552    where
553        I: Iterator<Item = T>,
554        F: FnOnce(&[T]) -> R,
555    {
556        // This code is hot enough that it's worth specializing for the most
557        // common length lists, to avoid the overhead of `Vec` creation.
558
559        let Some(t0) = iter.next() else {
560            return f(&[]);
561        };
562
563        let Some(t1) = iter.next() else {
564            return f(&[t0]);
565        };
566
567        let Some(t2) = iter.next() else {
568            return f(&[t0, t1]);
569        };
570
571        let Some(t3) = iter.next() else {
572            return f(&[t0, t1, t2]);
573        };
574
575        let Some(t4) = iter.next() else {
576            return f(&[t0, t1, t2, t3]);
577        };
578
579        let Some(t5) = iter.next() else {
580            return f(&[t0, t1, t2, t3, t4]);
581        };
582
583        let Some(t6) = iter.next() else {
584            return f(&[t0, t1, t2, t3, t4, t5]);
585        };
586
587        let Some(t7) = iter.next() else {
588            return f(&[t0, t1, t2, t3, t4, t5, t6]);
589        };
590
591        let Some(t8) = iter.next() else {
592            return f(&[t0, t1, t2, t3, t4, t5, t6, t7]);
593        };
594
595        f(&[t0, t1, t2, t3, t4, t5, t6, t7, t8].into_iter().chain(iter).collect::<Vec<_>>())
596    }
597}
598
599/// A fallible impl that will fail, without calling `f`, if there are any
600/// errors during collection.
601impl<T, R, E> CollectAndApply<T, R> for Result<T, E> {
602    type Output = Result<R, E>;
603
604    /// Equivalent to `Ok(f(&iter.collect::<Result<Vec<_>>>()?))`.
605    fn collect_and_apply<I, F>(mut iter: I, f: F) -> Result<R, E>
606    where
607        I: Iterator<Item = Result<T, E>>,
608        F: FnOnce(&[T]) -> R,
609    {
610        // This code is hot enough that it's worth specializing for the most
611        // common length lists, to avoid the overhead of `Vec` creation.
612
613        let Some(t0) = iter.next() else {
614            return Ok(f(&[]));
615        };
616        let t0 = t0?;
617
618        let Some(t1) = iter.next() else {
619            return Ok(f(&[t0]));
620        };
621        let t1 = t1?;
622
623        let Some(t2) = iter.next() else {
624            return Ok(f(&[t0, t1]));
625        };
626        let t2 = t2?;
627
628        let Some(t3) = iter.next() else {
629            return Ok(f(&[t0, t1, t2]));
630        };
631        let t3 = t3?;
632
633        let Some(t4) = iter.next() else {
634            return Ok(f(&[t0, t1, t2, t3]));
635        };
636        let t4 = t4?;
637
638        let Some(t5) = iter.next() else {
639            return Ok(f(&[t0, t1, t2, t3, t4]));
640        };
641        let t5 = t5?;
642
643        let Some(t6) = iter.next() else {
644            return Ok(f(&[t0, t1, t2, t3, t4, t5]));
645        };
646        let t6 = t6?;
647
648        let Some(t7) = iter.next() else {
649            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6]));
650        };
651        let t7 = t7?;
652
653        let Some(t8) = iter.next() else {
654            return Ok(f(&[t0, t1, t2, t3, t4, t5, t6, t7]));
655        };
656        let t8 = t8?;
657
658        Ok(f(&[Ok(t0), Ok(t1), Ok(t2), Ok(t3), Ok(t4), Ok(t5), Ok(t6), Ok(t7), Ok(t8)]
659            .into_iter()
660            .chain(iter)
661            .collect::<Result<Vec<_>, _>>()?))
662    }
663}
664
665impl<I: Interner> search_graph::Cx for I {
666    type Input = CanonicalInput<I>;
667    type Result = (QueryResult<I>, AccessedOpaques<I>);
668    type AmbiguityInfo = Certainty;
669
670    type DepNodeIndex = I::DepNodeIndex;
671    type Tracked<T: Debug + Clone> = I::Tracked<T>;
672    fn mk_tracked<T: Debug + Clone>(
673        self,
674        data: T,
675        dep_node_index: I::DepNodeIndex,
676    ) -> I::Tracked<T> {
677        I::mk_tracked(self, data, dep_node_index)
678    }
679    fn get_tracked<T: Debug + Clone>(self, tracked: &I::Tracked<T>) -> T {
680        I::get_tracked(self, tracked)
681    }
682    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, I::DepNodeIndex) {
683        I::with_cached_task(self, task)
684    }
685    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
686        I::with_global_cache(self, f)
687    }
688    fn assert_evaluation_is_concurrent(&self) {
689        self.assert_evaluation_is_concurrent()
690    }
691}