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