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