Skip to main content

rustc_middle/ty/context/
impl_interner.rs

1//! Implementation of [`rustc_type_ir::Interner`] for [`TyCtxt`].
2
3use std::ops::ControlFlow;
4use std::{debug_assert_matches, fmt};
5
6use rustc_errors::ErrorGuaranteed;
7use rustc_hir as hir;
8use rustc_hir::def::{CtorKind, CtorOf, DefKind};
9use rustc_hir::def_id::{DefId, LocalDefId};
10use rustc_hir::lang_items::LangItem;
11use rustc_span::{DUMMY_SP, Span, Symbol};
12use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
13use rustc_type_ir::{
14    CollectAndApply, Interner, TypeFoldable, Unnormalized, VisitorResult, search_graph,
15};
16
17use crate::dep_graph::{DepKind, DepNodeIndex};
18use crate::infer::canonical::CanonicalVarKinds;
19use crate::traits::cache::WithDepNode;
20use crate::traits::solve::{
21    self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect,
22};
23use crate::ty::{
24    self, Clause, Const, List, ParamTy, Pattern, PolyExistentialPredicate, Predicate, Region, Ty,
25    TyCtxt,
26};
27
28#[allow(rustc::usage_of_ty_tykind)]
29impl<'tcx> Interner for TyCtxt<'tcx> {
30    fn next_trait_solver_globally(self) -> bool {
31        self.next_trait_solver_globally()
32    }
33
34    type DefId = DefId;
35    type LocalDefId = LocalDefId;
36    type TraitId = DefId;
37    type ForeignId = DefId;
38    type FunctionId = DefId;
39    type ClosureId = DefId;
40    type CoroutineClosureId = DefId;
41    type CoroutineId = DefId;
42    type AdtId = DefId;
43    type ImplId = DefId;
44    type UnevaluatedConstId = DefId;
45    type TraitAssocTyId = DefId;
46    type TraitAssocConstId = DefId;
47    type TraitAssocTermId = DefId;
48    type OpaqueTyId = DefId;
49    type LocalOpaqueTyId = LocalDefId;
50    type FreeTyAliasId = DefId;
51    type FreeConstAliasId = DefId;
52    type FreeTermAliasId = DefId;
53    type ImplOrTraitAssocTyId = DefId;
54    type ImplOrTraitAssocConstId = DefId;
55    type ImplOrTraitAssocTermId = DefId;
56    type InherentAssocTyId = DefId;
57    type InherentAssocConstId = DefId;
58    type InherentAssocTermId = DefId;
59    type Span = Span;
60
61    type GenericArgs = ty::GenericArgsRef<'tcx>;
62
63    type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
64    type GenericArg = ty::GenericArg<'tcx>;
65    type Term = ty::Term<'tcx>;
66    type BoundVarKinds = &'tcx List<ty::BoundVariableKind<'tcx>>;
67
68    type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
69
70    fn mk_predefined_opaques_in_body(
71        self,
72        data: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
73    ) -> Self::PredefinedOpaques {
74        self.mk_predefined_opaques_in_body(data)
75    }
76    type LocalDefIds = &'tcx ty::List<LocalDefId>;
77    type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
78    fn mk_canonical_var_kinds(
79        self,
80        kinds: &[ty::CanonicalVarKind<Self>],
81    ) -> Self::CanonicalVarKinds {
82        self.mk_canonical_var_kinds(kinds)
83    }
84
85    type ExternalConstraints = ExternalConstraints<'tcx>;
86    fn mk_external_constraints(
87        self,
88        data: ExternalConstraintsData<Self>,
89    ) -> ExternalConstraints<'tcx> {
90        self.mk_external_constraints(data)
91    }
92    type DepNodeIndex = DepNodeIndex;
93    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
94        self.dep_graph.with_anon_task(self, DepKind::TraitSelect, task)
95    }
96    type Ty = Ty<'tcx>;
97    type Tys = &'tcx List<Ty<'tcx>>;
98
99    type FnInputTys = &'tcx [Ty<'tcx>];
100    type ParamTy = ParamTy;
101    type Symbol = Symbol;
102
103    type ErrorGuaranteed = ErrorGuaranteed;
104    type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
105
106    type AllocId = crate::mir::interpret::AllocId;
107    type Pat = Pattern<'tcx>;
108    type PatList = &'tcx List<Pattern<'tcx>>;
109    type Safety = hir::Safety;
110    type Const = ty::Const<'tcx>;
111    type Consts = &'tcx List<Self::Const>;
112
113    type ParamConst = ty::ParamConst;
114    type ValueConst = ty::Value<'tcx>;
115    type ExprConst = ty::Expr<'tcx>;
116    type ValTree = ty::ValTree<'tcx>;
117    type ScalarInt = ty::ScalarInt;
118
119    type Region = Region<'tcx>;
120    type EarlyParamRegion = ty::EarlyParamRegion;
121    type LateParamRegion = ty::LateParamRegion;
122
123    type RegionAssumptions = &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>;
124
125    type ParamEnv = ty::ParamEnv<'tcx>;
126    type Predicate = Predicate<'tcx>;
127
128    type Clause = Clause<'tcx>;
129    type Clauses = ty::Clauses<'tcx>;
130
131    type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
132    fn mk_tracked<T: fmt::Debug + Clone>(
133        self,
134        data: T,
135        dep_node: DepNodeIndex,
136    ) -> Self::Tracked<T> {
137        WithDepNode::new(dep_node, data)
138    }
139    fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
140        tracked.get(self)
141    }
142
143    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
144        f(&mut *self.new_solver_evaluation_cache.lock())
145    }
146
147    fn canonical_param_env_cache_get_or_insert<R>(
148        self,
149        param_env: ty::ParamEnv<'tcx>,
150        f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
151        from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
152    ) -> R {
153        let mut cache = self.new_solver_canonical_param_env_cache.lock();
154        let entry = cache.entry(param_env).or_insert_with(f);
155        from_entry(entry)
156    }
157
158    fn assert_evaluation_is_concurrent(&self) {
159        // Turns out, the assumption for this function isn't perfect.
160        // See trait-system-refactor-initiative#234.
161    }
162
163    fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
164        self.expand_abstract_consts(t)
165    }
166
167    type GenericsOf = &'tcx ty::Generics;
168
169    fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
170        self.generics_of(def_id)
171    }
172
173    type VariancesOf = &'tcx [ty::Variance];
174
175    fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
176        self.variances_of(def_id)
177    }
178
179    fn opt_alias_variances(
180        self,
181        kind: impl Into<ty::AliasTermKind<'tcx>>,
182    ) -> Option<&'tcx [ty::Variance]> {
183        self.opt_alias_variances(kind)
184    }
185
186    fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
187        self.type_of(def_id)
188    }
189    fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
190        self.type_of_opaque_hir_typeck(def_id)
191    }
192    fn is_type_const(self, def_id: DefId) -> bool {
193        self.is_type_const(def_id)
194    }
195    fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
196        self.const_of_item(def_id)
197    }
198    fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind {
199        self.anon_const_kind(def_id)
200    }
201
202    type AdtDef = ty::AdtDef<'tcx>;
203    fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
204        self.adt_def(adt_def_id)
205    }
206
207    fn alias_ty_kind_from_def_id(self, def_id: DefId) -> ty::AliasTyKind<'tcx> {
208        match self.def_kind(def_id) {
209            DefKind::AssocTy
210                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) =>
211            {
212                ty::Inherent { def_id }
213            }
214            DefKind::AssocTy => ty::Projection { def_id },
215
216            DefKind::OpaqueTy => ty::Opaque { def_id },
217            DefKind::TyAlias => ty::Free { def_id },
218            kind => crate::util::bug::bug_fmt(format_args!("unexpected DefKind in AliasTy: {0:?}",
        kind))bug!("unexpected DefKind in AliasTy: {kind:?}"),
219        }
220    }
221
222    fn alias_term_kind_from_def_id(self, def_id: DefId) -> ty::AliasTermKind<'tcx> {
223        match self.def_kind(def_id) {
224            DefKind::AssocTy => {
225                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) {
226                    ty::AliasTermKind::InherentTy { def_id }
227                } else {
228                    ty::AliasTermKind::ProjectionTy { def_id }
229                }
230            }
231            DefKind::AssocConst { .. } => {
232                if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) {
233                    ty::AliasTermKind::InherentConst { def_id }
234                } else {
235                    ty::AliasTermKind::ProjectionConst { def_id }
236                }
237            }
238            DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy { def_id },
239            DefKind::TyAlias => ty::AliasTermKind::FreeTy { def_id },
240            DefKind::Const { .. } => ty::AliasTermKind::FreeConst { def_id },
241            DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
242                ty::AliasTermKind::UnevaluatedConst { def_id }
243            }
244            kind => crate::util::bug::bug_fmt(format_args!("unexpected DefKind in AliasTy: {0:?}",
        kind))bug!("unexpected DefKind in AliasTy: {kind:?}"),
245        }
246    }
247
248    fn trait_ref_and_own_args_for_alias(
249        self,
250        def_id: DefId,
251        args: ty::GenericArgsRef<'tcx>,
252    ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
253        if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocTy | DefKind::AssocConst { .. } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocTy | DefKind::AssocConst { .. }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst { .. });
254        let trait_def_id = self.parent(def_id);
255        if true {
    {
        match self.def_kind(trait_def_id) {
            DefKind::Trait => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Trait", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
256        let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args);
257        (trait_ref, &args[trait_ref.args.len()..])
258    }
259
260    fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
261        self.mk_args(args)
262    }
263
264    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
265    where
266        I: Iterator<Item = T>,
267        T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
268    {
269        self.mk_args_from_iter(args)
270    }
271
272    fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
273        self.check_args_compatible(def_id, args)
274    }
275
276    fn debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
277        self.debug_assert_args_compatible(def_id, args);
278    }
279
280    /// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
281    /// are compatible with the `DefId`. Since we're missing a `Self` type, stick on
282    /// a dummy self type and forward to `debug_assert_args_compatible`.
283    fn debug_assert_existential_args_compatible(
284        self,
285        def_id: Self::DefId,
286        args: Self::GenericArgs,
287    ) {
288        // FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible`
289        // to avoid needing to reintern the set of args...
290        if truecfg!(debug_assertions) {
291            self.debug_assert_args_compatible(
292                def_id,
293                self.mk_args_from_iter(
294                    [self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
295                ),
296            );
297        }
298    }
299
300    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
301    where
302        I: Iterator<Item = T>,
303        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
304    {
305        self.mk_type_list_from_iter(args)
306    }
307
308    fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId {
309        self.parent(def_id)
310    }
311
312    fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTyId) -> DefId {
313        self.parent(def_id)
314    }
315
316    fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId {
317        self.parent(def_id)
318    }
319
320    fn recursion_limit(self) -> usize {
321        self.recursion_limit().0
322    }
323
324    type Features = &'tcx rustc_feature::Features;
325
326    fn features(self) -> Self::Features {
327        self.features()
328    }
329
330    fn coroutine_hidden_types(
331        self,
332        def_id: DefId,
333    ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
334        self.coroutine_hidden_types(def_id)
335    }
336
337    fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
338        self.fn_sig(def_id)
339    }
340
341    fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
342        self.coroutine_movability(def_id)
343    }
344
345    fn coroutine_for_closure(self, def_id: DefId) -> DefId {
346        self.coroutine_for_closure(def_id)
347    }
348
349    fn generics_require_sized_self(self, def_id: DefId) -> bool {
350        self.generics_require_sized_self(def_id)
351    }
352
353    fn item_bounds(
354        self,
355        def_id: DefId,
356    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
357        self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
358    }
359
360    fn item_self_bounds(
361        self,
362        def_id: DefId,
363    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
364        self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
365    }
366
367    fn item_non_self_bounds(
368        self,
369        def_id: DefId,
370    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
371        self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
372    }
373
374    fn predicates_of(
375        self,
376        def_id: DefId,
377    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
378        ty::EarlyBinder::bind(
379            self.predicates_of(def_id)
380                .instantiate_identity(self)
381                .predicates
382                .into_iter()
383                .map(Unnormalized::skip_normalization),
384        )
385    }
386
387    fn own_predicates_of(
388        self,
389        def_id: DefId,
390    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
391        ty::EarlyBinder::bind(
392            self.predicates_of(def_id)
393                .instantiate_own_identity()
394                .map(|(clause, _)| clause.skip_normalization()),
395        )
396    }
397
398    fn explicit_super_predicates_of(
399        self,
400        def_id: DefId,
401    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
402        self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
403    }
404
405    fn explicit_implied_predicates_of(
406        self,
407        def_id: DefId,
408    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
409        self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
410    }
411
412    fn impl_super_outlives(
413        self,
414        impl_def_id: DefId,
415    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
416        self.impl_super_outlives(impl_def_id)
417    }
418
419    fn impl_is_const(self, def_id: DefId) -> bool {
420        if true {
    {
        match self.def_kind(def_id) {
            DefKind::Impl { of_trait: true } => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Impl { of_trait: true }",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
421        self.is_conditionally_const(def_id)
422    }
423
424    fn fn_is_const(self, def_id: DefId) -> bool {
425        if true {
    {
        match self.def_kind(def_id) {
            DefKind::Fn | DefKind::AssocFn |
                DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(
426            self.def_kind(def_id),
427            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
428        );
429        self.is_conditionally_const(def_id)
430    }
431
432    fn closure_is_const(self, def_id: DefId) -> bool {
433        if true {
    {
        match self.def_kind(def_id) {
            DefKind::Closure => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::Closure", ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::Closure);
434        self.constness(def_id) == hir::Constness::Const
435    }
436
437    fn alias_has_const_conditions(self, def_id: DefId) -> bool {
438        if true {
    {
        match self.def_kind(def_id) {
            DefKind::AssocTy | DefKind::OpaqueTy => {}
            ref left_val => {
                ::core::panicking::assert_matches_failed(left_val,
                    "DefKind::AssocTy | DefKind::OpaqueTy",
                    ::core::option::Option::None);
            }
        }
    };
};debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
439        self.is_conditionally_const(def_id)
440    }
441
442    fn const_conditions(
443        self,
444        def_id: DefId,
445    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
446        ty::EarlyBinder::bind(
447            self.const_conditions(def_id)
448                .instantiate_identity(self)
449                .into_iter()
450                .map(|(c, _)| c.skip_normalization()),
451        )
452    }
453
454    fn explicit_implied_const_bounds(
455        self,
456        def_id: DefId,
457    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
458        ty::EarlyBinder::bind(
459            self.explicit_implied_const_bounds(def_id)
460                .iter_identity_copied()
461                .map(Unnormalized::skip_normalization)
462                .map(|(c, _)| c),
463        )
464    }
465
466    fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
467        self.impl_self_is_guaranteed_unsized(impl_def_id)
468    }
469
470    fn has_target_features(self, def_id: DefId) -> bool {
471        !self.codegen_fn_attrs(def_id).target_features.is_empty()
472    }
473
474    fn require_projection_lang_item(self, lang_item: SolverProjectionLangItem) -> DefId {
475        self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP)
476    }
477
478    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId {
479        self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
480    }
481
482    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId {
483        self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP)
484    }
485
486    fn is_projection_lang_item(self, def_id: DefId, lang_item: SolverProjectionLangItem) -> bool {
487        self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item))
488    }
489
490    fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool {
491        self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item))
492    }
493
494    fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool {
495        self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item))
496    }
497
498    fn is_default_trait(self, def_id: DefId) -> bool {
499        self.is_default_trait(def_id)
500    }
501
502    fn is_sizedness_trait(self, def_id: DefId) -> bool {
503        self.is_sizedness_trait(def_id)
504    }
505
506    fn as_projection_lang_item(self, def_id: DefId) -> Option<SolverProjectionLangItem> {
507        lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
508    }
509
510    fn as_trait_lang_item(self, def_id: DefId) -> Option<SolverTraitLangItem> {
511        lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?)
512    }
513
514    fn as_adt_lang_item(self, def_id: DefId) -> Option<SolverAdtLangItem> {
515        lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?)
516    }
517
518    fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
519        self.associated_items(def_id)
520            .in_definition_order()
521            .filter(|assoc_item| assoc_item.is_type())
522            .map(|assoc_item| assoc_item.def_id)
523    }
524
525    // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
526    // since we want to skip over blanket impls for non-rigid aliases, and also we
527    // only want to consider types that *actually* unify with float/int vars.
528    fn for_each_relevant_impl<R: VisitorResult>(
529        self,
530        trait_def_id: DefId,
531        self_ty: Ty<'tcx>,
532        mut f: impl FnMut(DefId) -> R,
533    ) -> R {
534        macro_rules! ret {
535            ($e: expr) => {
536                match $e.branch() {
537                    ControlFlow::Break(b) => return R::from_residual(b),
538                    ControlFlow::Continue(()) => {}
539                }
540            };
541        }
542
543        let tcx = self;
544        let trait_impls = tcx.trait_impls_of(trait_def_id);
545        let mut consider_impls_for_simplified_type = |simp| {
546            if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
547                for &impl_def_id in impls_for_type {
548                    match f(impl_def_id).branch() {
    ControlFlow::Break(b) => return R::from_residual(b),
    ControlFlow::Continue(()) => {}
}ret!(f(impl_def_id))
549                }
550            }
551
552            R::output()
553        };
554
555        match self_ty.kind() {
556            ty::Bool
557            | ty::Char
558            | ty::Int(_)
559            | ty::Uint(_)
560            | ty::Float(_)
561            | ty::Adt(_, _)
562            | ty::Foreign(_)
563            | ty::Str
564            | ty::Array(_, _)
565            | ty::Pat(_, _)
566            | ty::Slice(_)
567            | ty::RawPtr(_, _)
568            | ty::Ref(_, _, _)
569            | ty::FnDef(_, _)
570            | ty::FnPtr(..)
571            | ty::Dynamic(_, _)
572            | ty::Closure(..)
573            | ty::CoroutineClosure(..)
574            | ty::Coroutine(_, _)
575            | ty::Never
576            | ty::Tuple(_)
577            | ty::UnsafeBinder(_) => {
578                if let Some(simp) = ty::fast_reject::simplify_type(
579                    tcx,
580                    self_ty,
581                    ty::fast_reject::TreatParams::AsRigid,
582                ) {
583                    match consider_impls_for_simplified_type(simp).branch() {
    ControlFlow::Break(b) => return R::from_residual(b),
    ControlFlow::Continue(()) => {}
};ret!(consider_impls_for_simplified_type(simp));
584                }
585            }
586
587            // HACK: For integer and float variables we have to manually look at all impls
588            // which have some integer or float as a self type.
589            ty::Infer(ty::IntVar(_)) => {
590                use ty::IntTy::*;
591                use ty::UintTy::*;
592                // This causes a compiler error if any new integer kinds are added.
593                let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
594                let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
595                let possible_integers = [
596                    // signed integers
597                    ty::SimplifiedType::Int(I8),
598                    ty::SimplifiedType::Int(I16),
599                    ty::SimplifiedType::Int(I32),
600                    ty::SimplifiedType::Int(I64),
601                    ty::SimplifiedType::Int(I128),
602                    ty::SimplifiedType::Int(Isize),
603                    // unsigned integers
604                    ty::SimplifiedType::Uint(U8),
605                    ty::SimplifiedType::Uint(U16),
606                    ty::SimplifiedType::Uint(U32),
607                    ty::SimplifiedType::Uint(U64),
608                    ty::SimplifiedType::Uint(U128),
609                    ty::SimplifiedType::Uint(Usize),
610                ];
611                for simp in possible_integers {
612                    match consider_impls_for_simplified_type(simp).branch() {
    ControlFlow::Break(b) => return R::from_residual(b),
    ControlFlow::Continue(()) => {}
};ret!(consider_impls_for_simplified_type(simp));
613                }
614            }
615
616            ty::Infer(ty::FloatVar(_)) => {
617                // This causes a compiler error if any new float kinds are added.
618                let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
619                let possible_floats = [
620                    ty::SimplifiedType::Float(ty::FloatTy::F16),
621                    ty::SimplifiedType::Float(ty::FloatTy::F32),
622                    ty::SimplifiedType::Float(ty::FloatTy::F64),
623                    ty::SimplifiedType::Float(ty::FloatTy::F128),
624                ];
625
626                for simp in possible_floats {
627                    match consider_impls_for_simplified_type(simp).branch() {
    ControlFlow::Break(b) => return R::from_residual(b),
    ControlFlow::Continue(()) => {}
};ret!(consider_impls_for_simplified_type(simp));
628                }
629            }
630
631            // The only traits applying to aliases and placeholders are blanket impls.
632            //
633            // Impls which apply to an alias after normalization are handled by
634            // `assemble_candidates_after_normalizing_self_ty`.
635            ty::Alias(_) | ty::Placeholder(..) | ty::Error(_) => (),
636
637            // FIXME: These should ideally not exist as a self type. It would be nice for
638            // the builtin auto trait impls of coroutines to instead directly recurse
639            // into the witness.
640            ty::CoroutineWitness(..) => (),
641
642            // These variants should not exist as a self type.
643            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
644            | ty::Param(_)
645            | ty::Bound(_, _) => crate::util::bug::bug_fmt(format_args!("unexpected self type: {0}", self_ty))bug!("unexpected self type: {self_ty}"),
646        }
647
648        #[allow(rustc::usage_of_type_ir_traits)]
649        self.for_each_blanket_impl(trait_def_id, f)
650    }
651    fn for_each_blanket_impl<R: VisitorResult>(
652        self,
653        trait_def_id: DefId,
654        mut f: impl FnMut(DefId) -> R,
655    ) -> R {
656        let trait_impls = self.trait_impls_of(trait_def_id);
657        for &impl_def_id in trait_impls.blanket_impls() {
658            match f(impl_def_id).branch() {
659                ControlFlow::Break(b) => return R::from_residual(b),
660                ControlFlow::Continue(()) => {}
661            }
662        }
663
664        R::output()
665    }
666
667    fn has_item_definition(self, def_id: DefId) -> bool {
668        self.defaultness(def_id).has_value()
669    }
670
671    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
672        self.specializes((impl_def_id, victim_def_id))
673    }
674
675    fn impl_is_default(self, impl_def_id: DefId) -> bool {
676        self.defaultness(impl_def_id).is_default()
677    }
678
679    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
680        self.impl_trait_ref(impl_def_id)
681    }
682
683    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
684        self.impl_polarity(impl_def_id)
685    }
686
687    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
688        self.trait_is_auto(trait_def_id)
689    }
690
691    fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
692        self.trait_is_coinductive(trait_def_id)
693    }
694
695    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
696        self.trait_is_alias(trait_def_id)
697    }
698
699    fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
700        self.is_dyn_compatible(trait_def_id)
701    }
702
703    fn trait_is_fundamental(self, def_id: DefId) -> bool {
704        self.trait_def(def_id).is_fundamental
705    }
706
707    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
708        self.trait_def(trait_def_id).safety.is_unsafe()
709    }
710
711    fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
712        self.is_impl_trait_in_trait(def_id)
713    }
714
715    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
716        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
717    }
718
719    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
720        self.is_general_coroutine(coroutine_def_id)
721    }
722
723    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
724        self.coroutine_is_async(coroutine_def_id)
725    }
726
727    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
728        self.coroutine_is_gen(coroutine_def_id)
729    }
730
731    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
732        self.coroutine_is_async_gen(coroutine_def_id)
733    }
734
735    type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
736    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
737        self.unsizing_params_for_adt(adt_def_id)
738    }
739
740    fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
741        self,
742        binder: ty::Binder<'tcx, T>,
743    ) -> ty::Binder<'tcx, T> {
744        self.anonymize_bound_vars(binder)
745    }
746
747    fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
748        self.opaque_types_defined_by(defining_anchor)
749    }
750
751    fn opaque_types_and_coroutines_defined_by(
752        self,
753        defining_anchor: Self::LocalDefId,
754    ) -> Self::LocalDefIds {
755        let coroutines_defined_by = self
756            .nested_bodies_within(defining_anchor)
757            .iter()
758            .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
759        self.mk_local_def_ids_from_iter(
760            self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
761        )
762    }
763
764    type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
765    fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
766        self.arena.alloc(probe)
767    }
768    fn evaluate_root_goal_for_proof_tree_raw(
769        self,
770        canonical_goal: CanonicalInput<'tcx>,
771    ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
772        self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
773    }
774
775    fn item_name(self, id: DefId) -> Symbol {
776        self.opt_item_name(id).unwrap_or_else(|| {
777            crate::util::bug::bug_fmt(format_args!("item_name: no name for {0:?}",
        self.def_path(id)));bug!("item_name: no name for {:?}", self.def_path(id));
778        })
779    }
780}
781
782/// Defines trivial conversion functions between the main [`LangItem`] enum,
783/// and some other lang-item enum that is a subset of it.
784macro_rules! bidirectional_lang_item_map {
785    (
786        $solver_ty:ident, fn $to_solver:ident, fn $from_solver:ident;
787        $($name:ident),+ $(,)?
788    ) => {
789        fn $from_solver(lang_item: $solver_ty) -> LangItem {
790            match lang_item {
791                $($solver_ty::$name => LangItem::$name,)+
792            }
793        }
794
795        fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
796            Some(match lang_item {
797                $(LangItem::$name => $solver_ty::$name,)+
798                _ => return None,
799            })
800        }
801    }
802}
803
804fn solver_lang_item_to_lang_item(lang_item: SolverProjectionLangItem)
    -> LangItem {
    match lang_item {
        SolverProjectionLangItem::AsyncFnKindUpvars =>
            LangItem::AsyncFnKindUpvars,
        SolverProjectionLangItem::AsyncFnOnceOutput =>
            LangItem::AsyncFnOnceOutput,
        SolverProjectionLangItem::CallOnceFuture => LangItem::CallOnceFuture,
        SolverProjectionLangItem::CallRefFuture => LangItem::CallRefFuture,
        SolverProjectionLangItem::CoroutineReturn =>
            LangItem::CoroutineReturn,
        SolverProjectionLangItem::CoroutineYield => LangItem::CoroutineYield,
        SolverProjectionLangItem::FieldBase => LangItem::FieldBase,
        SolverProjectionLangItem::FieldType => LangItem::FieldType,
        SolverProjectionLangItem::FutureOutput => LangItem::FutureOutput,
        SolverProjectionLangItem::Metadata => LangItem::Metadata,
    }
}
fn lang_item_to_solver_lang_item(lang_item: LangItem)
    -> Option<SolverProjectionLangItem> {
    Some(match lang_item {
            LangItem::AsyncFnKindUpvars =>
                SolverProjectionLangItem::AsyncFnKindUpvars,
            LangItem::AsyncFnOnceOutput =>
                SolverProjectionLangItem::AsyncFnOnceOutput,
            LangItem::CallOnceFuture =>
                SolverProjectionLangItem::CallOnceFuture,
            LangItem::CallRefFuture =>
                SolverProjectionLangItem::CallRefFuture,
            LangItem::CoroutineReturn =>
                SolverProjectionLangItem::CoroutineReturn,
            LangItem::CoroutineYield =>
                SolverProjectionLangItem::CoroutineYield,
            LangItem::FieldBase => SolverProjectionLangItem::FieldBase,
            LangItem::FieldType => SolverProjectionLangItem::FieldType,
            LangItem::FutureOutput => SolverProjectionLangItem::FutureOutput,
            LangItem::Metadata => SolverProjectionLangItem::Metadata,
            _ => return None,
        })
}bidirectional_lang_item_map! {
805    SolverProjectionLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item;
806
807// tidy-alphabetical-start
808    AsyncFnKindUpvars,
809    AsyncFnOnceOutput,
810    CallOnceFuture,
811    CallRefFuture,
812    CoroutineReturn,
813    CoroutineYield,
814    FieldBase,
815    FieldType,
816    FutureOutput,
817    Metadata,
818// tidy-alphabetical-end
819}
820
821fn solver_adt_lang_item_to_lang_item(lang_item: SolverAdtLangItem)
    -> LangItem {
    match lang_item {
        SolverAdtLangItem::DynMetadata => LangItem::DynMetadata,
        SolverAdtLangItem::Option => LangItem::Option,
        SolverAdtLangItem::Poll => LangItem::Poll,
    }
}
fn lang_item_to_solver_adt_lang_item(lang_item: LangItem)
    -> Option<SolverAdtLangItem> {
    Some(match lang_item {
            LangItem::DynMetadata => SolverAdtLangItem::DynMetadata,
            LangItem::Option => SolverAdtLangItem::Option,
            LangItem::Poll => SolverAdtLangItem::Poll,
            _ => return None,
        })
}bidirectional_lang_item_map! {
822    SolverAdtLangItem, fn lang_item_to_solver_adt_lang_item, fn solver_adt_lang_item_to_lang_item;
823
824// tidy-alphabetical-start
825    DynMetadata,
826    Option,
827    Poll,
828// tidy-alphabetical-end
829}
830
831fn solver_trait_lang_item_to_lang_item(lang_item: SolverTraitLangItem)
    -> LangItem {
    match lang_item {
        SolverTraitLangItem::AsyncFn => LangItem::AsyncFn,
        SolverTraitLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper,
        SolverTraitLangItem::AsyncFnMut => LangItem::AsyncFnMut,
        SolverTraitLangItem::AsyncFnOnce => LangItem::AsyncFnOnce,
        SolverTraitLangItem::AsyncIterator => LangItem::AsyncIterator,
        SolverTraitLangItem::BikeshedGuaranteedNoDrop =>
            LangItem::BikeshedGuaranteedNoDrop,
        SolverTraitLangItem::Clone => LangItem::Clone,
        SolverTraitLangItem::Copy => LangItem::Copy,
        SolverTraitLangItem::Coroutine => LangItem::Coroutine,
        SolverTraitLangItem::Destruct => LangItem::Destruct,
        SolverTraitLangItem::DiscriminantKind => LangItem::DiscriminantKind,
        SolverTraitLangItem::Drop => LangItem::Drop,
        SolverTraitLangItem::Field => LangItem::Field,
        SolverTraitLangItem::Fn => LangItem::Fn,
        SolverTraitLangItem::FnMut => LangItem::FnMut,
        SolverTraitLangItem::FnOnce => LangItem::FnOnce,
        SolverTraitLangItem::FnPtrTrait => LangItem::FnPtrTrait,
        SolverTraitLangItem::FusedIterator => LangItem::FusedIterator,
        SolverTraitLangItem::Future => LangItem::Future,
        SolverTraitLangItem::Iterator => LangItem::Iterator,
        SolverTraitLangItem::MetaSized => LangItem::MetaSized,
        SolverTraitLangItem::PointeeSized => LangItem::PointeeSized,
        SolverTraitLangItem::PointeeTrait => LangItem::PointeeTrait,
        SolverTraitLangItem::Sized => LangItem::Sized,
        SolverTraitLangItem::TransmuteTrait => LangItem::TransmuteTrait,
        SolverTraitLangItem::TrivialClone => LangItem::TrivialClone,
        SolverTraitLangItem::Tuple => LangItem::Tuple,
        SolverTraitLangItem::Unpin => LangItem::Unpin,
        SolverTraitLangItem::Unsize => LangItem::Unsize,
    }
}
fn lang_item_to_solver_trait_lang_item(lang_item: LangItem)
    -> Option<SolverTraitLangItem> {
    Some(match lang_item {
            LangItem::AsyncFn => SolverTraitLangItem::AsyncFn,
            LangItem::AsyncFnKindHelper =>
                SolverTraitLangItem::AsyncFnKindHelper,
            LangItem::AsyncFnMut => SolverTraitLangItem::AsyncFnMut,
            LangItem::AsyncFnOnce => SolverTraitLangItem::AsyncFnOnce,
            LangItem::AsyncIterator => SolverTraitLangItem::AsyncIterator,
            LangItem::BikeshedGuaranteedNoDrop =>
                SolverTraitLangItem::BikeshedGuaranteedNoDrop,
            LangItem::Clone => SolverTraitLangItem::Clone,
            LangItem::Copy => SolverTraitLangItem::Copy,
            LangItem::Coroutine => SolverTraitLangItem::Coroutine,
            LangItem::Destruct => SolverTraitLangItem::Destruct,
            LangItem::DiscriminantKind =>
                SolverTraitLangItem::DiscriminantKind,
            LangItem::Drop => SolverTraitLangItem::Drop,
            LangItem::Field => SolverTraitLangItem::Field,
            LangItem::Fn => SolverTraitLangItem::Fn,
            LangItem::FnMut => SolverTraitLangItem::FnMut,
            LangItem::FnOnce => SolverTraitLangItem::FnOnce,
            LangItem::FnPtrTrait => SolverTraitLangItem::FnPtrTrait,
            LangItem::FusedIterator => SolverTraitLangItem::FusedIterator,
            LangItem::Future => SolverTraitLangItem::Future,
            LangItem::Iterator => SolverTraitLangItem::Iterator,
            LangItem::MetaSized => SolverTraitLangItem::MetaSized,
            LangItem::PointeeSized => SolverTraitLangItem::PointeeSized,
            LangItem::PointeeTrait => SolverTraitLangItem::PointeeTrait,
            LangItem::Sized => SolverTraitLangItem::Sized,
            LangItem::TransmuteTrait => SolverTraitLangItem::TransmuteTrait,
            LangItem::TrivialClone => SolverTraitLangItem::TrivialClone,
            LangItem::Tuple => SolverTraitLangItem::Tuple,
            LangItem::Unpin => SolverTraitLangItem::Unpin,
            LangItem::Unsize => SolverTraitLangItem::Unsize,
            _ => return None,
        })
}bidirectional_lang_item_map! {
832    SolverTraitLangItem, fn lang_item_to_solver_trait_lang_item, fn solver_trait_lang_item_to_lang_item;
833
834// tidy-alphabetical-start
835    AsyncFn,
836    AsyncFnKindHelper,
837    AsyncFnMut,
838    AsyncFnOnce,
839    AsyncIterator,
840    BikeshedGuaranteedNoDrop,
841    Clone,
842    Copy,
843    Coroutine,
844    Destruct,
845    DiscriminantKind,
846    Drop,
847    Field,
848    Fn,
849    FnMut,
850    FnOnce,
851    FnPtrTrait,
852    FusedIterator,
853    Future,
854    Iterator,
855    MetaSized,
856    PointeeSized,
857    PointeeTrait,
858    Sized,
859    TransmuteTrait,
860    TrivialClone,
861    Tuple,
862    Unpin,
863    Unsize,
864// tidy-alphabetical-end
865}