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