Skip to main content

rustc_middle/ty/context/
impl_interner.rs

1//! Implementation of [`rustc_type_ir::Interner`] for [`TyCtxt`].
2
3use std::ops::ControlFlow;
4use std::{debug_assert_matches, fmt};
5
6use rustc_data_structures::Limit;
7use rustc_data_structures::intern::Interned;
8use rustc_errors::ErrorGuaranteed;
9use rustc_hir as hir;
10use rustc_hir::def::{CtorKind, DefKind, Namespace};
11use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
12use rustc_hir::{CRATE_HIR_ID, LangItem};
13use rustc_span::{DUMMY_SP, Span, Symbol};
14use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem};
15use rustc_type_ir::{
16    BoundVar, CollectAndApply, DebruijnIndex, Interner, TypeFoldable, Unnormalized, VisitorResult,
17    search_graph,
18};
19
20use crate::dep_graph::{DepKind, DepNodeIndex};
21use crate::infer::canonical::CanonicalVarKinds;
22use crate::traits::cache::WithDepNode;
23use crate::traits::solve::{
24    self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect,
25};
26use crate::ty::print::{FmtPrinter, Print};
27use crate::ty::{
28    self, BoundRegion, Clause, Const, List, ParamTy, Pattern, PolyExistentialPredicate, Predicate,
29    Region, RegionKind, Ty, TyCtxt,
30};
31
32#[allow(rustc::usage_of_ty_tykind)]
33impl<'tcx> Interner for TyCtxt<'tcx> {
34    fn next_trait_solver_globally(self) -> bool {
35        self.next_trait_solver_globally()
36    }
37
38    type DefId = DefId;
39    type LocalDefId = LocalDefId;
40    type TraitId = DefId;
41    type ForeignId = DefId;
42    type FunctionId = DefId;
43    type ClosureId = DefId;
44    type CoroutineClosureId = DefId;
45    type CoroutineId = DefId;
46    type AdtId = DefId;
47    type ImplId = DefId;
48    type AnonConstId = DefId;
49    type TraitAssocTyId = DefId;
50    type TraitAssocConstId = DefId;
51    type TraitAssocTermId = DefId;
52    type OpaqueTyId = DefId;
53    type LocalOpaqueTyId = LocalDefId;
54    type FreeTyAliasId = DefId;
55    type FreeConstAliasId = DefId;
56    type FreeTermAliasId = DefId;
57    type ImplOrTraitAssocTyId = DefId;
58    type ImplOrTraitAssocConstId = DefId;
59    type ImplOrTraitAssocTermId = DefId;
60    type InherentAssocTyId = DefId;
61    type InherentAssocConstId = DefId;
62    type InherentAssocTermId = DefId;
63    type Span = Span;
64
65    type GenericArgs = ty::GenericArgsRef<'tcx>;
66
67    type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
68    type GenericArg = ty::GenericArg<'tcx>;
69    type Term = ty::Term<'tcx>;
70    type BoundVarKinds = &'tcx List<ty::BoundVariableKind<'tcx>>;
71
72    type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
73
74    fn mk_predefined_opaques_in_body(
75        self,
76        data: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
77    ) -> Self::PredefinedOpaques {
78        self.mk_predefined_opaques_in_body(data)
79    }
80    type LocalDefIds = &'tcx ty::List<LocalDefId>;
81    type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
82    fn mk_canonical_var_kinds(
83        self,
84        kinds: &[ty::CanonicalVarKind<Self>],
85    ) -> Self::CanonicalVarKinds {
86        self.mk_canonical_var_kinds(kinds)
87    }
88
89    type ExternalConstraints = ExternalConstraints<'tcx>;
90    fn mk_external_constraints(
91        self,
92        data: ExternalConstraintsData<Self>,
93    ) -> ExternalConstraints<'tcx> {
94        self.mk_external_constraints(data)
95    }
96    type DepNodeIndex = DepNodeIndex;
97    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
98        self.dep_graph.with_anon_task(self, DepKind::TraitSelect, task)
99    }
100    type Ty = Ty<'tcx>;
101    type Tys = &'tcx List<Ty<'tcx>>;
102
103    type FnInputTys = &'tcx [Ty<'tcx>];
104    type ParamTy = ParamTy;
105    type Symbol = Symbol;
106
107    type ErrorGuaranteed = ErrorGuaranteed;
108    type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
109
110    type AllocId = crate::mir::interpret::AllocId;
111    type Pat = Pattern<'tcx>;
112    type PatList = &'tcx List<Pattern<'tcx>>;
113    type Safety = hir::Safety;
114    type Const = ty::Const<'tcx>;
115    type Consts = &'tcx List<Self::Const>;
116
117    type ParamConst = ty::ParamConst;
118    type ValueConst = ty::Value<'tcx>;
119    type ExprConst = ty::Expr<'tcx>;
120    type ValTree = ty::ValTree<'tcx>;
121    type ScalarInt = ty::ScalarInt;
122    type InternedRegionKind = Interned<'tcx, ty::RegionKind<'tcx>>;
123    type EarlyParamRegion = ty::EarlyParamRegion;
124    type LateParamRegion = ty::LateParamRegion;
125
126    type RegionAssumptions = &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>;
127
128    type ParamEnv = ty::ParamEnv<'tcx>;
129    type Predicate = Predicate<'tcx>;
130
131    type Clause = Clause<'tcx>;
132    type Clauses = ty::Clauses<'tcx>;
133
134    type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
135    fn mk_tracked<T: fmt::Debug + Clone>(
136        self,
137        data: T,
138        dep_node: DepNodeIndex,
139    ) -> Self::Tracked<T> {
140        WithDepNode::new(dep_node, data)
141    }
142    fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
143        tracked.get(self)
144    }
145
146    fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
147        f(&mut *self.new_solver_evaluation_cache.lock())
148    }
149
150    fn canonical_param_env_cache_get_or_insert<R>(
151        self,
152        param_env: ty::ParamEnv<'tcx>,
153        f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
154        from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
155    ) -> R {
156        let mut cache = self.new_solver_canonical_param_env_cache.lock();
157        let entry = cache.entry(param_env).or_insert_with(f);
158        from_entry(entry)
159    }
160
161    fn assert_evaluation_is_concurrent(&self) {
162        // Turns out, the assumption for this function isn't perfect.
163        // See trait-system-refactor-initiative#234.
164    }
165
166    fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
167        self.expand_abstract_consts(t)
168    }
169
170    type GenericsOf = &'tcx ty::Generics;
171
172    fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
173        self.generics_of(def_id)
174    }
175
176    type VariancesOf = &'tcx [ty::Variance];
177
178    fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
179        self.variances_of(def_id)
180    }
181
182    fn opt_alias_variances(
183        self,
184        kind: impl Into<ty::AliasTermKind<'tcx>>,
185    ) -> Option<&'tcx [ty::Variance]> {
186        self.opt_alias_variances(kind)
187    }
188
189    fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
190        self.type_of(def_id)
191    }
192    fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
193        self.type_of_opaque_hir_typeck(def_id)
194    }
195    fn is_type_const(self, def_id: DefId) -> bool {
196        self.is_type_const(def_id)
197    }
198    fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
199        self.const_of_item(def_id)
200    }
201    fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind {
202        self.anon_const_kind(def_id)
203    }
204
205    fn def_span(self, def_id: DefId) -> Span {
206        self.def_span(def_id)
207    }
208
209    type AdtDef = ty::AdtDef<'tcx>;
210    fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
211        self.adt_def(adt_def_id)
212    }
213
214    fn alias_const_kind_from_def_id(self, def_id: Self::DefId) -> ty::AliasConstKind<'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::AliasConstKind::Inherent { def_id }
219                } else {
220                    ty::AliasConstKind::Projection { def_id }
221                }
222            }
223            DefKind::Const { .. } => ty::AliasConstKind::Free { def_id },
224            DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
225                ty::AliasConstKind::Anon { def_id }
226            }
227            kind => crate::util::bug::bug_fmt(format_args!("unexpected DefKind in AliasConst: {0:?}",
        kind))bug!("unexpected DefKind in AliasConst: {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 clauses_of(
392        self,
393        def_id: DefId,
394    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
395        ty::EarlyBinder::bind_iter(
396            self.clauses_of(def_id)
397                .instantiate_identity(self)
398                .clauses
399                .into_iter()
400                .map(Unnormalized::skip_normalization),
401        )
402    }
403
404    fn own_clauses_of(
405        self,
406        def_id: DefId,
407    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
408        ty::EarlyBinder::bind_iter(
409            self.clauses_of(def_id)
410                .instantiate_own_identity()
411                .map(|(clause, _)| clause.skip_normalization()),
412        )
413    }
414
415    fn explicit_super_clauses_of(
416        self,
417        def_id: DefId,
418    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
419        self.explicit_super_clauses_of(def_id).map_bound(|preds| preds.into_iter().copied())
420    }
421
422    fn explicit_implied_clauses_of(
423        self,
424        def_id: DefId,
425    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
426        self.explicit_implied_clauses_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 signature is a bit different from `TyCtxt::for_each_relevant_impl`.
543    // While rustc only needs self_ty, rust-analyzer's impl needs to use all the args.
544    fn for_each_relevant_impl<R: VisitorResult>(
545        self,
546        trait_ref: ty::TraitRef<'tcx>,
547        f: impl FnMut(DefId) -> R,
548    ) -> R {
549        let self_ty = trait_ref.args.type_at(0);
550        if true {
    if !!#[allow(non_exhaustive_omitted_patterns)] match self_ty.kind() {
                    ty::Infer(ty::TyVar(_)) | ty::Param(_) | ty::Bound(_, _) =>
                        true,
                    _ => false,
                } {
        {
            ::core::panicking::panic_fmt(format_args!("we should not have them as self ty in the next solver"));
        }
    };
};debug_assert!(
551            !matches!(self_ty.kind(), ty::Infer(ty::TyVar(_)) | ty::Param(_) | ty::Bound(_, _)),
552            "we should not have them as self ty in the next solver"
553        );
554        TyCtxt::for_each_relevant_impl(self, trait_ref.def_id, self_ty, f)
555    }
556    fn for_each_blanket_impl<R: VisitorResult>(
557        self,
558        trait_def_id: DefId,
559        mut f: impl FnMut(DefId) -> R,
560    ) -> R {
561        let trait_impls = self.trait_impls_of(trait_def_id);
562        for &impl_def_id in trait_impls.blanket_impls() {
563            match f(impl_def_id).branch() {
564                ControlFlow::Break(b) => return R::from_residual(b),
565                ControlFlow::Continue(()) => {}
566            }
567        }
568
569        R::output()
570    }
571
572    fn has_item_definition(self, def_id: DefId) -> bool {
573        self.defaultness(def_id).has_value()
574    }
575
576    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
577        self.specializes((impl_def_id, victim_def_id))
578    }
579
580    fn impl_is_default(self, impl_def_id: DefId) -> bool {
581        self.defaultness(impl_def_id).is_default()
582    }
583
584    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
585        self.impl_trait_ref(impl_def_id)
586    }
587
588    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
589        self.impl_polarity(impl_def_id)
590    }
591
592    fn is_fully_generic_for_reflection(self, impl_def_id: Self::ImplId) -> bool {
593        self.impl_is_fully_generic_for_reflection(impl_def_id)
594    }
595
596    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
597        self.trait_is_auto(trait_def_id)
598    }
599
600    fn trait_is_coinductive(self, trait_def_id: DefId) -> bool {
601        self.trait_is_coinductive(trait_def_id)
602    }
603
604    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
605        self.trait_is_alias(trait_def_id)
606    }
607
608    fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
609        self.is_dyn_compatible(trait_def_id)
610    }
611
612    fn trait_is_fundamental(self, def_id: DefId) -> bool {
613        self.trait_def(def_id).is_fundamental
614    }
615
616    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
617        self.trait_def(trait_def_id).safety.is_unsafe()
618    }
619
620    fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
621        self.is_impl_trait_in_trait(def_id)
622    }
623
624    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
625        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
626    }
627
628    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
629        self.is_general_coroutine(coroutine_def_id)
630    }
631
632    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
633        self.coroutine_is_async(coroutine_def_id)
634    }
635
636    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
637        self.coroutine_is_gen(coroutine_def_id)
638    }
639
640    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
641        self.coroutine_is_async_gen(coroutine_def_id)
642    }
643
644    type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
645    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
646        self.unsizing_params_for_adt(adt_def_id)
647    }
648
649    fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
650        self,
651        binder: ty::Binder<'tcx, T>,
652    ) -> ty::Binder<'tcx, T> {
653        self.anonymize_bound_vars(binder)
654    }
655
656    fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
657        self.opaque_types_defined_by(defining_anchor)
658    }
659
660    fn opaque_types_and_coroutines_defined_by(
661        self,
662        defining_anchor: Self::LocalDefId,
663    ) -> Self::LocalDefIds {
664        let coroutines_defined_by = self
665            .nested_bodies_within(defining_anchor)
666            .iter()
667            .filter(|def_id| self.is_coroutine(def_id.to_def_id()));
668        self.mk_local_def_ids_from_iter(
669            self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
670        )
671    }
672
673    type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
674    fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
675        self.arena.alloc(probe)
676    }
677    fn evaluate_root_goal_for_proof_tree_raw(
678        self,
679        canonical_goal: CanonicalInput<'tcx>,
680        root_depth: usize,
681    ) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
682        self.evaluate_root_goal_for_proof_tree_raw((canonical_goal, root_depth))
683    }
684
685    fn emit_next_solver_overflow_fcw(self, predicate: ty::Predicate<'tcx>, span: Span) {
686        self.emit_node_span_lint(
687            rustc_session::lint::builtin::RECURSION_DEPTH_EXCEEDING_LIMIT,
688            CRATE_HIR_ID,
689            span,
690            rustc_errors::DiagDecorator(|diag| {
691                // FIXME: share this with overflow error in fulfillment instead of duplicating.
692                let pred_str = {
693                    let s = predicate.to_string();
694                    if s.len() > 50 {
695                        let mut p: FmtPrinter<'_, '_> =
696                            FmtPrinter::new_with_limit(self, Namespace::TypeNS, Limit(6));
697                        predicate.print(&mut p).unwrap();
698                        p.into_buffer()
699                    } else {
700                        s
701                    }
702                };
703                diag.primary_message(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("overflow evaluating the requirement `{0}`",
                pred_str))
    })format!(
704                    "overflow evaluating the requirement `{pred_str}`",
705                ));
706                diag.help(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("consider increasing the recursion limit by adding a `#![recursion_limit = \"{0}\"]` attribute to your crate (`{1}`)",
                self.recursion_limit() * 2, self.crate_name(LOCAL_CRATE)))
    })format!(
707                    "consider increasing the recursion limit by adding a \
708                     `#![recursion_limit = \"{}\"]` attribute to your crate (`{}`)",
709                    self.recursion_limit() * 2,
710                    self.crate_name(LOCAL_CRATE),
711                ));
712                diag.help(
713                    "or consider adding a manual `impl` of auto traits like `Send` for intermediate types, if auto traits are involved",
714                );
715                diag.note("this lint is attached to the whole crate and can't be disabled on a per-function basis");
716            }),
717        )
718    }
719
720    fn item_name(self, id: DefId) -> Symbol {
721        self.opt_item_name(id).unwrap_or_else(|| {
722            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));
723        })
724    }
725
726    fn get_anon_re_bounds_lifetime(self, idx: usize, var_idx: usize) -> Option<Region<'tcx>> {
727        if let Some(inner) = self.lifetimes.anon_re_bounds.get(idx) {
728            inner.get(var_idx).copied()
729        } else {
730            None
731        }
732    }
733
734    fn get_anon_re_canonical_bounds_lifetime(self, idx: usize) -> Option<Region<'tcx>> {
735        self.lifetimes.anon_re_canonical_bounds.get(idx).copied()
736    }
737
738    fn get_re_static_lifetime(self) -> Region<'tcx> {
739        self.lifetimes.re_static
740    }
741
742    fn intern_region(self, region_kind: RegionKind<'tcx>) -> Region<'tcx> {
743        self.intern_region(region_kind)
744    }
745
746    fn intern_bound_region(
747        self,
748        debruijn: DebruijnIndex,
749        bound_region: BoundRegion<'tcx>,
750    ) -> Region<'tcx> {
751        // Use a pre-interned one when possible.
752        if let ty::BoundRegion { var, kind: ty::BoundRegionKind::Anon } = bound_region
753            && let Some(inner) = self.lifetimes.anon_re_bounds.get(debruijn.as_usize())
754            && let Some(re) = inner.get(var.as_usize()).copied()
755        {
756            re
757        } else {
758            self.intern_region(ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), bound_region))
759        }
760    }
761
762    fn intern_canonical_bound(self, var: BoundVar) -> Region<'tcx> {
763        // Use a pre-interned one when possible.
764        if let Some(re) = self.lifetimes.anon_re_canonical_bounds.get(var.as_usize()).copied() {
765            re
766        } else {
767            self.intern_region(ty::ReBound(
768                ty::BoundVarIndexKind::Canonical,
769                BoundRegion { var, kind: ty::BoundRegionKind::Anon },
770            ))
771        }
772    }
773}
774
775impl<'tcx, T: std::fmt::Debug + Clone + Copy> rustc_type_ir::intern::Interned<TyCtxt<'tcx>>
776    for Interned<'tcx, T>
777{
778    type Value = T;
779    fn get(self) -> T {
780        *self.0
781    }
782}
783
784/// Defines trivial conversion functions between the main [`LangItem`] enum,
785/// and some other lang-item enum that is a subset of it.
786macro_rules! bidirectional_lang_item_map {
787    (
788        $solver_ty:ident, fn $to_solver:ident, fn $from_solver:ident;
789        $($name:ident),+ $(,)?
790    ) => {
791        fn $from_solver(lang_item: $solver_ty) -> LangItem {
792            match lang_item {
793                $($solver_ty::$name => LangItem::$name,)+
794            }
795        }
796
797        fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
798            Some(match lang_item {
799                $(LangItem::$name => $solver_ty::$name,)+
800                _ => return None,
801            })
802        }
803    }
804}
805
806fn 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! {
807    SolverProjectionLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item;
808
809// tidy-alphabetical-start
810    AsyncFnKindUpvars,
811    AsyncFnOnceOutput,
812    CallOnceFuture,
813    CallRefFuture,
814    CoroutineReturn,
815    CoroutineYield,
816    FieldBase,
817    FieldType,
818    FutureOutput,
819    Metadata,
820// tidy-alphabetical-end
821}
822
823fn solver_adt_lang_item_to_lang_item(lang_item: SolverAdtLangItem)
    -> LangItem {
    match lang_item {
        SolverAdtLangItem::DynMetadata => LangItem::DynMetadata,
        SolverAdtLangItem::Option => LangItem::Option,
        SolverAdtLangItem::OwnedBox => LangItem::OwnedBox,
        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::OwnedBox => SolverAdtLangItem::OwnedBox,
            LangItem::Poll => SolverAdtLangItem::Poll,
            _ => return None,
        })
}bidirectional_lang_item_map! {
824    SolverAdtLangItem, fn lang_item_to_solver_adt_lang_item, fn solver_adt_lang_item_to_lang_item;
825
826// tidy-alphabetical-start
827    DynMetadata,
828    Option,
829    OwnedBox,
830    Poll,
831// tidy-alphabetical-end
832}
833
834fn 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::TryAsDyn => LangItem::TryAsDyn,
        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::TryAsDyn => SolverTraitLangItem::TryAsDyn,
            LangItem::Tuple => SolverTraitLangItem::Tuple,
            LangItem::Unpin => SolverTraitLangItem::Unpin,
            LangItem::Unsize => SolverTraitLangItem::Unsize,
            _ => return None,
        })
}bidirectional_lang_item_map! {
835    SolverTraitLangItem, fn lang_item_to_solver_trait_lang_item, fn solver_trait_lang_item_to_lang_item;
836
837// tidy-alphabetical-start
838    AsyncFn,
839    AsyncFnKindHelper,
840    AsyncFnMut,
841    AsyncFnOnce,
842    AsyncIterator,
843    BikeshedGuaranteedNoDrop,
844    Clone,
845    Copy,
846    Coroutine,
847    Destruct,
848    DiscriminantKind,
849    Drop,
850    Field,
851    Fn,
852    FnMut,
853    FnOnce,
854    FnPtrTrait,
855    FusedIterator,
856    Future,
857    Iterator,
858    MetaSized,
859    PointeeSized,
860    PointeeTrait,
861    Sized,
862    TransmuteTrait,
863    TrivialClone,
864    TryAsDyn,
865    Tuple,
866    Unpin,
867    Unsize,
868// tidy-alphabetical-end
869}