hir_ty/next_solver/infer/canonical/
instantiate.rs1use crate::next_solver::BoundConst;
10use crate::next_solver::{
11 AliasTy, Binder, BoundRegion, BoundTy, Canonical, CanonicalVarValues, Const, DbInterner, Goal,
12 ParamEnv, Predicate, PredicateKind, Region, Ty, TyKind,
13 fold::FnMutDelegate,
14 infer::{
15 DefineOpaqueTypes, InferCtxt, TypeTrace,
16 traits::{Obligation, PredicateObligations},
17 },
18};
19use rustc_type_ir::{
20 AliasRelationDirection, AliasTyKind, BoundVar, GenericArgKind, InferTy, TypeFoldable, Upcast,
21 Variance,
22 inherent::{IntoKind, SliceLike},
23 relate::{
24 Relate, TypeRelation, VarianceDiagInfo,
25 combine::{super_combine_consts, super_combine_tys},
26 },
27};
28
29pub trait CanonicalExt<'db, V> {
30 fn instantiate(&self, tcx: DbInterner<'db>, var_values: &CanonicalVarValues<'db>) -> V
31 where
32 V: TypeFoldable<DbInterner<'db>>;
33 fn instantiate_projected<T>(
34 &self,
35 tcx: DbInterner<'db>,
36 var_values: &CanonicalVarValues<'db>,
37 projection_fn: impl FnOnce(&V) -> T,
38 ) -> T
39 where
40 T: TypeFoldable<DbInterner<'db>>;
41}
42
43impl<'db, V> CanonicalExt<'db, V> for Canonical<'db, V> {
46 fn instantiate(&self, tcx: DbInterner<'db>, var_values: &CanonicalVarValues<'db>) -> V
49 where
50 V: TypeFoldable<DbInterner<'db>>,
51 {
52 self.instantiate_projected(tcx, var_values, |value| value.clone())
53 }
54
55 fn instantiate_projected<T>(
62 &self,
63 tcx: DbInterner<'db>,
64 var_values: &CanonicalVarValues<'db>,
65 projection_fn: impl FnOnce(&V) -> T,
66 ) -> T
67 where
68 T: TypeFoldable<DbInterner<'db>>,
69 {
70 assert_eq!(self.variables.len(), var_values.len());
71 let value = projection_fn(&self.value);
72 instantiate_value(tcx, var_values, value)
73 }
74}
75
76pub(super) fn instantiate_value<'db, T>(
80 tcx: DbInterner<'db>,
81 var_values: &CanonicalVarValues<'db>,
82 value: T,
83) -> T
84where
85 T: TypeFoldable<DbInterner<'db>>,
86{
87 if var_values.var_values.is_empty() {
88 value
89 } else {
90 let delegate = FnMutDelegate {
91 regions: &mut |br: BoundRegion| match var_values[br.var].kind() {
92 GenericArgKind::Lifetime(l) => l,
93 r => panic!("{br:?} is a region but value is {r:?}"),
94 },
95 types: &mut |bound_ty: BoundTy| match var_values[bound_ty.var].kind() {
96 GenericArgKind::Type(ty) => ty,
97 r => panic!("{bound_ty:?} is a type but value is {r:?}"),
98 },
99 consts: &mut |bound_ct: BoundConst| match var_values[bound_ct.var].kind() {
100 GenericArgKind::Const(ct) => ct,
101 c => panic!("{bound_ct:?} is a const but value is {c:?}"),
102 },
103 };
104
105 tcx.replace_escaping_bound_vars_uncached(value, delegate)
106 }
107}