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::InlineConst | 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_ref: ty::TraitRef<'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 trait_def_id = trait_ref.def_id;
557        let self_ty = trait_ref.self_ty();
558        let tcx = self;
559        let trait_impls = tcx.trait_impls_of(trait_def_id);
560        let mut consider_impls_for_simplified_type = |simp| {
561            if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
562                for &impl_def_id in impls_for_type {
563                    match f(impl_def_id).branch() {
    ControlFlow::Break(b) => return R::from_residual(b),
    ControlFlow::Continue(()) => {}
}ret!(f(impl_def_id))
564                }
565            }
566
567            R::output()
568        };
569
570        match self_ty.kind() {
571            ty::Bool
572            | ty::Char
573            | ty::Int(_)
574            | ty::Uint(_)
575            | ty::Float(_)
576            | ty::Adt(_, _)
577            | ty::Foreign(_)
578            | ty::Str
579            | ty::Array(_, _)
580            | ty::Pat(_, _)
581            | ty::Slice(_)
582            | ty::RawPtr(_, _)
583            | ty::Ref(_, _, _)
584            | ty::FnDef(_, _)
585            | ty::FnPtr(..)
586            | ty::Dynamic(_, _)
587            | ty::Closure(..)
588            | ty::CoroutineClosure(..)
589            | ty::Coroutine(_, _)
590            | ty::Never
591            | ty::Tuple(_)
592            | ty::UnsafeBinder(_) => {
593                if let Some(simp) = ty::fast_reject::simplify_type(
594                    tcx,
595                    self_ty,
596                    ty::fast_reject::TreatParams::AsRigid,
597                ) {
598                    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));
599                }
600            }
601
602            // HACK: For integer and float variables we have to manually look at all impls
603            // which have some integer or float as a self type.
604            ty::Infer(ty::IntVar(_)) => {
605                use ty::IntTy::*;
606                use ty::UintTy::*;
607                // This causes a compiler error if any new integer kinds are added.
608                let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
609                let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
610                let possible_integers = [
611                    // signed integers
612                    ty::SimplifiedType::Int(I8),
613                    ty::SimplifiedType::Int(I16),
614                    ty::SimplifiedType::Int(I32),
615                    ty::SimplifiedType::Int(I64),
616                    ty::SimplifiedType::Int(I128),
617                    ty::SimplifiedType::Int(Isize),
618                    // unsigned integers
619                    ty::SimplifiedType::Uint(U8),
620                    ty::SimplifiedType::Uint(U16),
621                    ty::SimplifiedType::Uint(U32),
622                    ty::SimplifiedType::Uint(U64),
623                    ty::SimplifiedType::Uint(U128),
624                    ty::SimplifiedType::Uint(Usize),
625                ];
626                for simp in possible_integers {
627                    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));
628                }
629            }
630
631            ty::Infer(ty::FloatVar(_)) => {
632                // This causes a compiler error if any new float kinds are added.
633                let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
634                let possible_floats = [
635                    ty::SimplifiedType::Float(ty::FloatTy::F16),
636                    ty::SimplifiedType::Float(ty::FloatTy::F32),
637                    ty::SimplifiedType::Float(ty::FloatTy::F64),
638                    ty::SimplifiedType::Float(ty::FloatTy::F128),
639                ];
640
641                for simp in possible_floats {
642                    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));
643                }
644            }
645
646            // The only traits applying to aliases and placeholders are blanket impls.
647            //
648            // Impls which apply to an alias after normalization are handled by
649            // `assemble_candidates_after_normalizing_self_ty`.
650            ty::Alias(ty::IsRigid::Yes, _) | ty::Placeholder(..) | ty::Error(_) => (),
651            // FIXME(-Znext-solver=no): Need to support aliases not marked as
652            // rigid for the old solver.
653            ty::Alias(ty::IsRigid::No, _) => (),
654
655            // FIXME: These should ideally not exist as a self type. It would be nice for
656            // the builtin auto trait impls of coroutines to instead directly recurse
657            // into the witness.
658            ty::CoroutineWitness(..) => (),
659
660            // These variants should not exist as a self type.
661            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
662            | ty::Param(_)
663            | ty::Bound(_, _) => crate::util::bug::bug_fmt(format_args!("unexpected self type: {0}", self_ty))bug!("unexpected self type: {self_ty}"),
664        }
665
666        #[allow(rustc::usage_of_type_ir_traits)]
667        self.for_each_blanket_impl(trait_def_id, f)
668    }
669    fn for_each_blanket_impl<R: VisitorResult>(
670        self,
671        trait_def_id: DefId,
672        mut f: impl FnMut(DefId) -> R,
673    ) -> R {
674        let trait_impls = self.trait_impls_of(trait_def_id);
675        for &impl_def_id in trait_impls.blanket_impls() {
676            match f(impl_def_id).branch() {
677                ControlFlow::Break(b) => return R::from_residual(b),
678                ControlFlow::Continue(()) => {}
679            }
680        }
681
682        R::output()
683    }
684
685    fn has_item_definition(self, def_id: DefId) -> bool {
686        self.defaultness(def_id).has_value()
687    }
688
689    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
690        self.specializes((impl_def_id, victim_def_id))
691    }
692
693    fn impl_is_default(self, impl_def_id: DefId) -> bool {
694        self.defaultness(impl_def_id).is_default()
695    }
696
697    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
698        self.impl_trait_ref(impl_def_id)
699    }
700
701    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
702        self.impl_polarity(impl_def_id)
703    }
704
705    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
706        self.trait_is_auto(trait_def_id)
707    }
708
709    fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
710        self.trait_is_coinductive(trait_def_id)
711    }
712
713    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
714        self.trait_is_alias(trait_def_id)
715    }
716
717    fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
718        self.is_dyn_compatible(trait_def_id)
719    }
720
721    fn trait_is_fundamental(self, def_id: DefId) -> bool {
722        self.trait_def(def_id).is_fundamental
723    }
724
725    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
726        self.trait_def(trait_def_id).safety.is_unsafe()
727    }
728
729    fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
730        self.is_impl_trait_in_trait(def_id)
731    }
732
733    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
734        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
735    }
736
737    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
738        self.is_general_coroutine(coroutine_def_id)
739    }
740
741    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
742        self.coroutine_is_async(coroutine_def_id)
743    }
744
745    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
746        self.coroutine_is_gen(coroutine_def_id)
747    }
748
749    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
750        self.coroutine_is_async_gen(coroutine_def_id)
751    }
752
753    type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
754    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
755        self.unsizing_params_for_adt(adt_def_id)
756    }
757
758    fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
759        self,
760        binder: ty::Binder<'tcx, T>,
761    ) -> ty::Binder<'tcx, T> {
762        self.anonymize_bound_vars(binder)
763    }
764
765    fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
766        self.opaque_types_defined_by(defining_anchor)
767    }
768
769    fn opaque_types_and_coroutines_defined_by(
770        self,
771        defining_anchor: Self::LocalDefId,
772    ) -> Self::LocalDefIds {
773        let coroutines_defined_by = self
774            .nested_bodies_within(defining_anchor)
775            .iter()
776            .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
777        self.mk_local_def_ids_from_iter(
778            self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
779        )
780    }
781
782    type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
783    fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
784        self.arena.alloc(probe)
785    }
786    fn evaluate_root_goal_for_proof_tree_raw(
787        self,
788        canonical_goal: CanonicalInput<'tcx>,
789    ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
790        self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
791    }
792
793    fn item_name(self, id: DefId) -> Symbol {
794        self.opt_item_name(id).unwrap_or_else(|| {
795            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));
796        })
797    }
798}
799
800/// Defines trivial conversion functions between the main [`LangItem`] enum,
801/// and some other lang-item enum that is a subset of it.
802macro_rules! bidirectional_lang_item_map {
803    (
804        $solver_ty:ident, fn $to_solver:ident, fn $from_solver:ident;
805        $($name:ident),+ $(,)?
806    ) => {
807        fn $from_solver(lang_item: $solver_ty) -> LangItem {
808            match lang_item {
809                $($solver_ty::$name => LangItem::$name,)+
810            }
811        }
812
813        fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
814            Some(match lang_item {
815                $(LangItem::$name => $solver_ty::$name,)+
816                _ => return None,
817            })
818        }
819    }
820}
821
822fn 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! {
823    SolverProjectionLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item;
824
825// tidy-alphabetical-start
826    AsyncFnKindUpvars,
827    AsyncFnOnceOutput,
828    CallOnceFuture,
829    CallRefFuture,
830    CoroutineReturn,
831    CoroutineYield,
832    FieldBase,
833    FieldType,
834    FutureOutput,
835    Metadata,
836// tidy-alphabetical-end
837}
838
839fn 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! {
840    SolverAdtLangItem, fn lang_item_to_solver_adt_lang_item, fn solver_adt_lang_item_to_lang_item;
841
842// tidy-alphabetical-start
843    DynMetadata,
844    Option,
845    Poll,
846// tidy-alphabetical-end
847}
848
849fn 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! {
850    SolverTraitLangItem, fn lang_item_to_solver_trait_lang_item, fn solver_trait_lang_item_to_lang_item;
851
852// tidy-alphabetical-start
853    AsyncFn,
854    AsyncFnKindHelper,
855    AsyncFnMut,
856    AsyncFnOnce,
857    AsyncIterator,
858    BikeshedGuaranteedNoDrop,
859    Clone,
860    Copy,
861    Coroutine,
862    Destruct,
863    DiscriminantKind,
864    Drop,
865    Field,
866    Fn,
867    FnMut,
868    FnOnce,
869    FnPtrTrait,
870    FusedIterator,
871    Future,
872    Iterator,
873    MetaSized,
874    PointeeSized,
875    PointeeTrait,
876    Sized,
877    TransmuteTrait,
878    TrivialClone,
879    Tuple,
880    Unpin,
881    Unsize,
882// tidy-alphabetical-end
883}