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 assumptions_on_binders(self) -> bool {
331        self.assumptions_on_binders()
332    }
333
334    fn coroutine_hidden_types(
335        self,
336        def_id: DefId,
337    ) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
338        self.coroutine_hidden_types(def_id)
339    }
340
341    fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
342        self.fn_sig(def_id)
343    }
344
345    fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
346        self.coroutine_movability(def_id)
347    }
348
349    fn coroutine_for_closure(self, def_id: DefId) -> DefId {
350        self.coroutine_for_closure(def_id)
351    }
352
353    fn generics_require_sized_self(self, def_id: DefId) -> bool {
354        self.generics_require_sized_self(def_id)
355    }
356
357    fn item_bounds(
358        self,
359        def_id: DefId,
360    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
361        self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
362    }
363
364    fn item_self_bounds(
365        self,
366        def_id: DefId,
367    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
368        self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
369    }
370
371    fn item_non_self_bounds(
372        self,
373        def_id: DefId,
374    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
375        self.item_non_self_bounds(def_id).map_bound(IntoIterator::into_iter)
376    }
377
378    fn predicates_of(
379        self,
380        def_id: DefId,
381    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
382        ty::EarlyBinder::bind(
383            self.predicates_of(def_id)
384                .instantiate_identity(self)
385                .predicates
386                .into_iter()
387                .map(Unnormalized::skip_normalization),
388        )
389    }
390
391    fn own_predicates_of(
392        self,
393        def_id: DefId,
394    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
395        ty::EarlyBinder::bind(
396            self.predicates_of(def_id)
397                .instantiate_own_identity()
398                .map(|(clause, _)| clause.skip_normalization()),
399        )
400    }
401
402    fn explicit_super_predicates_of(
403        self,
404        def_id: DefId,
405    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
406        self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
407    }
408
409    fn explicit_implied_predicates_of(
410        self,
411        def_id: DefId,
412    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
413        self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
414    }
415
416    fn impl_super_outlives(
417        self,
418        impl_def_id: DefId,
419    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
420        self.impl_super_outlives(impl_def_id)
421    }
422
423    fn impl_is_const(self, def_id: DefId) -> bool {
424        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 });
425        self.is_conditionally_const(def_id)
426    }
427
428    fn fn_is_const(self, def_id: DefId) -> bool {
429        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!(
430            self.def_kind(def_id),
431            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
432        );
433        self.is_conditionally_const(def_id)
434    }
435
436    fn closure_is_const(self, def_id: DefId) -> bool {
437        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);
438        self.constness(def_id) == hir::Constness::Const
439    }
440
441    fn alias_has_const_conditions(self, def_id: DefId) -> bool {
442        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);
443        self.is_conditionally_const(def_id)
444    }
445
446    fn const_conditions(
447        self,
448        def_id: DefId,
449    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
450        ty::EarlyBinder::bind(
451            self.const_conditions(def_id)
452                .instantiate_identity(self)
453                .into_iter()
454                .map(|(c, _)| c.skip_normalization()),
455        )
456    }
457
458    fn explicit_implied_const_bounds(
459        self,
460        def_id: DefId,
461    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
462        ty::EarlyBinder::bind(
463            self.explicit_implied_const_bounds(def_id)
464                .iter_identity_copied()
465                .map(Unnormalized::skip_normalization)
466                .map(|(c, _)| c),
467        )
468    }
469
470    fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
471        self.impl_self_is_guaranteed_unsized(impl_def_id)
472    }
473
474    fn has_target_features(self, def_id: DefId) -> bool {
475        !self.codegen_fn_attrs(def_id).target_features.is_empty()
476    }
477
478    fn require_projection_lang_item(self, lang_item: SolverProjectionLangItem) -> DefId {
479        self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP)
480    }
481
482    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId {
483        self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
484    }
485
486    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId {
487        self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP)
488    }
489
490    fn is_projection_lang_item(self, def_id: DefId, lang_item: SolverProjectionLangItem) -> bool {
491        self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item))
492    }
493
494    fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool {
495        self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item))
496    }
497
498    fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool {
499        self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item))
500    }
501
502    fn is_default_trait(self, def_id: DefId) -> bool {
503        self.is_default_trait(def_id)
504    }
505
506    fn is_sizedness_trait(self, def_id: DefId) -> bool {
507        self.is_sizedness_trait(def_id)
508    }
509
510    fn as_projection_lang_item(self, def_id: DefId) -> Option<SolverProjectionLangItem> {
511        lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
512    }
513
514    fn as_trait_lang_item(self, def_id: DefId) -> Option<SolverTraitLangItem> {
515        lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?)
516    }
517
518    fn as_adt_lang_item(self, def_id: DefId) -> Option<SolverAdtLangItem> {
519        lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?)
520    }
521
522    fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
523        self.associated_items(def_id)
524            .in_definition_order()
525            .filter(|assoc_item| assoc_item.is_type())
526            .map(|assoc_item| assoc_item.def_id)
527    }
528
529    // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
530    // since we want to skip over blanket impls for non-rigid aliases, and also we
531    // only want to consider types that *actually* unify with float/int vars.
532    fn for_each_relevant_impl<R: VisitorResult>(
533        self,
534        trait_def_id: DefId,
535        self_ty: Ty<'tcx>,
536        mut f: impl FnMut(DefId) -> R,
537    ) -> R {
538        macro_rules! ret {
539            ($e: expr) => {
540                match $e.branch() {
541                    ControlFlow::Break(b) => return R::from_residual(b),
542                    ControlFlow::Continue(()) => {}
543                }
544            };
545        }
546
547        let tcx = self;
548        let trait_impls = tcx.trait_impls_of(trait_def_id);
549        let mut consider_impls_for_simplified_type = |simp| {
550            if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
551                for &impl_def_id in impls_for_type {
552                    match f(impl_def_id).branch() {
    ControlFlow::Break(b) => return R::from_residual(b),
    ControlFlow::Continue(()) => {}
}ret!(f(impl_def_id))
553                }
554            }
555
556            R::output()
557        };
558
559        match self_ty.kind() {
560            ty::Bool
561            | ty::Char
562            | ty::Int(_)
563            | ty::Uint(_)
564            | ty::Float(_)
565            | ty::Adt(_, _)
566            | ty::Foreign(_)
567            | ty::Str
568            | ty::Array(_, _)
569            | ty::Pat(_, _)
570            | ty::Slice(_)
571            | ty::RawPtr(_, _)
572            | ty::Ref(_, _, _)
573            | ty::FnDef(_, _)
574            | ty::FnPtr(..)
575            | ty::Dynamic(_, _)
576            | ty::Closure(..)
577            | ty::CoroutineClosure(..)
578            | ty::Coroutine(_, _)
579            | ty::Never
580            | ty::Tuple(_)
581            | ty::UnsafeBinder(_) => {
582                if let Some(simp) = ty::fast_reject::simplify_type(
583                    tcx,
584                    self_ty,
585                    ty::fast_reject::TreatParams::AsRigid,
586                ) {
587                    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));
588                }
589            }
590
591            // HACK: For integer and float variables we have to manually look at all impls
592            // which have some integer or float as a self type.
593            ty::Infer(ty::IntVar(_)) => {
594                use ty::IntTy::*;
595                use ty::UintTy::*;
596                // This causes a compiler error if any new integer kinds are added.
597                let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
598                let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
599                let possible_integers = [
600                    // signed integers
601                    ty::SimplifiedType::Int(I8),
602                    ty::SimplifiedType::Int(I16),
603                    ty::SimplifiedType::Int(I32),
604                    ty::SimplifiedType::Int(I64),
605                    ty::SimplifiedType::Int(I128),
606                    ty::SimplifiedType::Int(Isize),
607                    // unsigned integers
608                    ty::SimplifiedType::Uint(U8),
609                    ty::SimplifiedType::Uint(U16),
610                    ty::SimplifiedType::Uint(U32),
611                    ty::SimplifiedType::Uint(U64),
612                    ty::SimplifiedType::Uint(U128),
613                    ty::SimplifiedType::Uint(Usize),
614                ];
615                for simp in possible_integers {
616                    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));
617                }
618            }
619
620            ty::Infer(ty::FloatVar(_)) => {
621                // This causes a compiler error if any new float kinds are added.
622                let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
623                let possible_floats = [
624                    ty::SimplifiedType::Float(ty::FloatTy::F16),
625                    ty::SimplifiedType::Float(ty::FloatTy::F32),
626                    ty::SimplifiedType::Float(ty::FloatTy::F64),
627                    ty::SimplifiedType::Float(ty::FloatTy::F128),
628                ];
629
630                for simp in possible_floats {
631                    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));
632                }
633            }
634
635            // The only traits applying to aliases and placeholders are blanket impls.
636            //
637            // Impls which apply to an alias after normalization are handled by
638            // `assemble_candidates_after_normalizing_self_ty`.
639            ty::Alias(_) | ty::Placeholder(..) | ty::Error(_) => (),
640
641            // FIXME: These should ideally not exist as a self type. It would be nice for
642            // the builtin auto trait impls of coroutines to instead directly recurse
643            // into the witness.
644            ty::CoroutineWitness(..) => (),
645
646            // These variants should not exist as a self type.
647            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
648            | ty::Param(_)
649            | ty::Bound(_, _) => crate::util::bug::bug_fmt(format_args!("unexpected self type: {0}", self_ty))bug!("unexpected self type: {self_ty}"),
650        }
651
652        #[allow(rustc::usage_of_type_ir_traits)]
653        self.for_each_blanket_impl(trait_def_id, f)
654    }
655    fn for_each_blanket_impl<R: VisitorResult>(
656        self,
657        trait_def_id: DefId,
658        mut f: impl FnMut(DefId) -> R,
659    ) -> R {
660        let trait_impls = self.trait_impls_of(trait_def_id);
661        for &impl_def_id in trait_impls.blanket_impls() {
662            match f(impl_def_id).branch() {
663                ControlFlow::Break(b) => return R::from_residual(b),
664                ControlFlow::Continue(()) => {}
665            }
666        }
667
668        R::output()
669    }
670
671    fn has_item_definition(self, def_id: DefId) -> bool {
672        self.defaultness(def_id).has_value()
673    }
674
675    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
676        self.specializes((impl_def_id, victim_def_id))
677    }
678
679    fn impl_is_default(self, impl_def_id: DefId) -> bool {
680        self.defaultness(impl_def_id).is_default()
681    }
682
683    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
684        self.impl_trait_ref(impl_def_id)
685    }
686
687    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
688        self.impl_polarity(impl_def_id)
689    }
690
691    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
692        self.trait_is_auto(trait_def_id)
693    }
694
695    fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
696        self.trait_is_coinductive(trait_def_id)
697    }
698
699    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
700        self.trait_is_alias(trait_def_id)
701    }
702
703    fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
704        self.is_dyn_compatible(trait_def_id)
705    }
706
707    fn trait_is_fundamental(self, def_id: DefId) -> bool {
708        self.trait_def(def_id).is_fundamental
709    }
710
711    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
712        self.trait_def(trait_def_id).safety.is_unsafe()
713    }
714
715    fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
716        self.is_impl_trait_in_trait(def_id)
717    }
718
719    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
720        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
721    }
722
723    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
724        self.is_general_coroutine(coroutine_def_id)
725    }
726
727    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
728        self.coroutine_is_async(coroutine_def_id)
729    }
730
731    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
732        self.coroutine_is_gen(coroutine_def_id)
733    }
734
735    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
736        self.coroutine_is_async_gen(coroutine_def_id)
737    }
738
739    type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
740    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
741        self.unsizing_params_for_adt(adt_def_id)
742    }
743
744    fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
745        self,
746        binder: ty::Binder<'tcx, T>,
747    ) -> ty::Binder<'tcx, T> {
748        self.anonymize_bound_vars(binder)
749    }
750
751    fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
752        self.opaque_types_defined_by(defining_anchor)
753    }
754
755    fn opaque_types_and_coroutines_defined_by(
756        self,
757        defining_anchor: Self::LocalDefId,
758    ) -> Self::LocalDefIds {
759        let coroutines_defined_by = self
760            .nested_bodies_within(defining_anchor)
761            .iter()
762            .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
763        self.mk_local_def_ids_from_iter(
764            self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
765        )
766    }
767
768    type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
769    fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
770        self.arena.alloc(probe)
771    }
772    fn evaluate_root_goal_for_proof_tree_raw(
773        self,
774        canonical_goal: CanonicalInput<'tcx>,
775    ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
776        self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
777    }
778
779    fn item_name(self, id: DefId) -> Symbol {
780        self.opt_item_name(id).unwrap_or_else(|| {
781            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));
782        })
783    }
784}
785
786/// Defines trivial conversion functions between the main [`LangItem`] enum,
787/// and some other lang-item enum that is a subset of it.
788macro_rules! bidirectional_lang_item_map {
789    (
790        $solver_ty:ident, fn $to_solver:ident, fn $from_solver:ident;
791        $($name:ident),+ $(,)?
792    ) => {
793        fn $from_solver(lang_item: $solver_ty) -> LangItem {
794            match lang_item {
795                $($solver_ty::$name => LangItem::$name,)+
796            }
797        }
798
799        fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
800            Some(match lang_item {
801                $(LangItem::$name => $solver_ty::$name,)+
802                _ => return None,
803            })
804        }
805    }
806}
807
808fn 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! {
809    SolverProjectionLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item;
810
811// tidy-alphabetical-start
812    AsyncFnKindUpvars,
813    AsyncFnOnceOutput,
814    CallOnceFuture,
815    CallRefFuture,
816    CoroutineReturn,
817    CoroutineYield,
818    FieldBase,
819    FieldType,
820    FutureOutput,
821    Metadata,
822// tidy-alphabetical-end
823}
824
825fn 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! {
826    SolverAdtLangItem, fn lang_item_to_solver_adt_lang_item, fn solver_adt_lang_item_to_lang_item;
827
828// tidy-alphabetical-start
829    DynMetadata,
830    Option,
831    Poll,
832// tidy-alphabetical-end
833}
834
835fn 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! {
836    SolverTraitLangItem, fn lang_item_to_solver_trait_lang_item, fn solver_trait_lang_item_to_lang_item;
837
838// tidy-alphabetical-start
839    AsyncFn,
840    AsyncFnKindHelper,
841    AsyncFnMut,
842    AsyncFnOnce,
843    AsyncIterator,
844    BikeshedGuaranteedNoDrop,
845    Clone,
846    Copy,
847    Coroutine,
848    Destruct,
849    DiscriminantKind,
850    Drop,
851    Field,
852    Fn,
853    FnMut,
854    FnOnce,
855    FnPtrTrait,
856    FusedIterator,
857    Future,
858    Iterator,
859    MetaSized,
860    PointeeSized,
861    PointeeTrait,
862    Sized,
863    TransmuteTrait,
864    TrivialClone,
865    Tuple,
866    Unpin,
867    Unsize,
868// tidy-alphabetical-end
869}