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