Skip to content

Commit c91b537

Browse files
Merge #8348
8348: Make `Binders` more like Chalk r=flodiebold a=flodiebold Working towards #8313. - hide `value` - use `VariableKinds` - adjust `subst` to be like Chalk's `substitute` - also clean up some other `TypeWalk` stuff to prepare for it being replaced by Chalk's `Fold` Co-authored-by: Florian Diebold <[email protected]>
2 parents 467a5c6 + a316d58 commit c91b537

File tree

20 files changed

+296
-228
lines changed

20 files changed

+296
-228
lines changed

crates/hir/src/display.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use hir_ty::display::{
99
write_bounds_like_dyn_trait_with_prefix, write_visibility, HirDisplay, HirDisplayError,
1010
HirFormatter,
1111
};
12+
use hir_ty::Interner;
1213
use syntax::ast::{self, NameOwner};
1314

1415
use crate::{
@@ -235,7 +236,8 @@ impl HirDisplay for TypeParam {
235236
write!(f, "{}", self.name(f.db))?;
236237
let bounds = f.db.generic_predicates_for_param(self.id);
237238
let substs = TyBuilder::type_params_subst(f.db, self.id.parent);
238-
let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>();
239+
let predicates =
240+
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect::<Vec<_>>();
239241
if !(predicates.is_empty() || f.omit_verbose_types()) {
240242
write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?;
241243
}

crates/hir/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ impl Field {
516516
VariantDef::Variant(it) => it.parent.id.into(),
517517
};
518518
let substs = TyBuilder::type_params_subst(db, generic_def_id);
519-
let ty = db.field_types(var_id)[self.id].clone().subst(&substs);
519+
let ty = db.field_types(var_id)[self.id].clone().substitute(&Interner, &substs);
520520
Type::new(db, self.parent.module(db).id.krate(), var_id, ty)
521521
}
522522

@@ -702,7 +702,7 @@ impl_from!(Struct, Union, Enum for Adt);
702702
impl Adt {
703703
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
704704
let subst = db.generic_defaults(self.into());
705-
subst.iter().any(|ty| ty.value.is_unknown())
705+
subst.iter().any(|ty| ty.skip_binders().is_unknown())
706706
}
707707

708708
/// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -1089,7 +1089,7 @@ pub struct TypeAlias {
10891089
impl TypeAlias {
10901090
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
10911091
let subst = db.generic_defaults(self.id.into());
1092-
subst.iter().any(|ty| ty.value.is_unknown())
1092+
subst.iter().any(|ty| ty.skip_binders().is_unknown())
10931093
}
10941094

10951095
pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -1503,7 +1503,7 @@ impl TypeParam {
15031503
let krate = self.id.parent.module(db.upcast()).krate();
15041504
let ty = params.get(local_idx)?.clone();
15051505
let subst = TyBuilder::type_params_subst(db, self.id.parent);
1506-
let ty = ty.subst(&subst.prefix(local_idx));
1506+
let ty = ty.substitute(&Interner, &subst.prefix(local_idx));
15071507
Some(Type::new_with_resolver_inner(db, krate, &resolver, ty))
15081508
}
15091509
}
@@ -1916,7 +1916,7 @@ impl Type {
19161916
.iter()
19171917
.map(|(local_id, ty)| {
19181918
let def = Field { parent: variant_id.into(), id: local_id };
1919-
let ty = ty.clone().subst(substs);
1919+
let ty = ty.clone().substitute(&Interner, substs);
19201920
(def, self.derived(ty))
19211921
})
19221922
.collect()

crates/hir/src/semantics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,9 @@ impl<'db> SemanticsImpl<'db> {
494494
fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
495495
// FIXME: this erases Substs
496496
let func = self.resolve_method_call(call)?;
497-
let ty = self.db.value_ty(func.into());
497+
let (ty, _) = self.db.value_ty(func.into()).into_value_and_skipped_binders();
498498
let resolver = self.analyze(call.syntax()).resolver;
499-
let ty = Type::new_with_resolver(self.db, &resolver, ty.value)?;
499+
let ty = Type::new_with_resolver(self.db, &resolver, ty)?;
500500
let mut res = ty.as_callable(self.db)?;
501501
res.is_bound_method = true;
502502
Some(res)

crates/hir/src/source_analyzer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use hir_def::{
2020
use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
2121
use hir_ty::{
2222
diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
23-
InferenceResult, Substitution, TyLoweringContext,
23+
InferenceResult, Interner, Substitution, TyLoweringContext,
2424
};
2525
use syntax::{
2626
ast::{self, AstNode},
@@ -339,7 +339,7 @@ impl SourceAnalyzer {
339339
.into_iter()
340340
.map(|local_id| {
341341
let field = FieldId { parent: variant, local_id };
342-
let ty = field_types[local_id].clone().subst(substs);
342+
let ty = field_types[local_id].clone().substitute(&Interner, substs);
343343
(field.into(), Type::new_with_resolver_inner(db, krate, &self.resolver, ty))
344344
})
345345
.collect()

crates/hir_ty/src/builder.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ impl TyBuilder<hir_def::AdtId> {
139139
} else {
140140
// each default can depend on the previous parameters
141141
let subst_so_far = Substitution::intern(self.vec.clone());
142-
self.vec.push(default_ty.clone().subst(&subst_so_far).cast(&Interner));
142+
self.vec
143+
.push(default_ty.clone().substitute(&Interner, &subst_so_far).cast(&Interner));
143144
}
144145
}
145146
self
@@ -194,13 +195,13 @@ impl TyBuilder<TypeAliasId> {
194195

195196
impl<T: TypeWalk + HasInterner<Interner = Interner>> TyBuilder<Binders<T>> {
196197
fn subst_binders(b: Binders<T>) -> Self {
197-
let param_count = b.num_binders;
198+
let param_count = b.binders.len(&Interner);
198199
TyBuilder::new(b, param_count)
199200
}
200201

201202
pub fn build(self) -> T {
202203
let (b, subst) = self.build_internal();
203-
b.subst(&subst)
204+
b.substitute(&Interner, &subst)
204205
}
205206
}
206207

crates/hir_ty/src/diagnostics/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
245245
Some(callee) => callee,
246246
None => return,
247247
};
248-
let sig = db.callable_item_signature(callee.into()).value;
248+
let sig =
249+
db.callable_item_signature(callee.into()).into_value_and_skipped_binders().0;
249250

250251
(sig, args)
251252
}

crates/hir_ty/src/display.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ impl HirDisplay for Ty {
352352
let data = (*datas)
353353
.as_ref()
354354
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
355-
let bounds = data.subst(parameters);
356-
bounds.value
355+
let bounds = data.substitute(&Interner, parameters);
356+
bounds.into_value_and_skipped_binders().0
357357
} else {
358358
Vec::new()
359359
}
@@ -397,7 +397,7 @@ impl HirDisplay for Ty {
397397
}
398398
TyKind::FnDef(def, parameters) => {
399399
let def = from_chalk(f.db, *def);
400-
let sig = f.db.callable_item_signature(def).subst(parameters);
400+
let sig = f.db.callable_item_signature(def).substitute(&Interner, parameters);
401401
match def {
402402
CallableDefId::FunctionId(ff) => {
403403
write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -482,7 +482,7 @@ impl HirDisplay for Ty {
482482
(_, Some(default_parameter)) => {
483483
let actual_default = default_parameter
484484
.clone()
485-
.subst(&parameters.prefix(i));
485+
.substitute(&Interner, &parameters.prefix(i));
486486
if parameter.assert_ty_ref(&Interner) != &actual_default
487487
{
488488
default_from = i + 1;
@@ -542,8 +542,8 @@ impl HirDisplay for Ty {
542542
let data = (*datas)
543543
.as_ref()
544544
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
545-
let bounds = data.subst(&parameters);
546-
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
545+
let bounds = data.substitute(&Interner, &parameters);
546+
write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
547547
// FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
548548
}
549549
ImplTraitId::AsyncBlockTypeImplTrait(..) => {
@@ -595,7 +595,7 @@ impl HirDisplay for Ty {
595595
let bounds =
596596
f.db.generic_predicates(id.parent)
597597
.into_iter()
598-
.map(|pred| pred.clone().subst(&substs))
598+
.map(|pred| pred.clone().substitute(&Interner, &substs))
599599
.filter(|wc| match &wc.skip_binders() {
600600
WhereClause::Implemented(tr) => {
601601
tr.self_type_parameter(&Interner) == self
@@ -629,8 +629,8 @@ impl HirDisplay for Ty {
629629
let data = (*datas)
630630
.as_ref()
631631
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
632-
let bounds = data.subst(&opaque_ty.substitution);
633-
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
632+
let bounds = data.substitute(&Interner, &opaque_ty.substitution);
633+
write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
634634
}
635635
ImplTraitId::AsyncBlockTypeImplTrait(..) => {
636636
write!(f, "{{async block}}")?;

crates/hir_ty/src/infer.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,25 +470,25 @@ impl<'a> InferenceContext<'a> {
470470
TypeNs::AdtId(AdtId::StructId(strukt)) => {
471471
let substs = ctx.substs_from_path(path, strukt.into(), true);
472472
let ty = self.db.ty(strukt.into());
473-
let ty = self.insert_type_vars(ty.subst(&substs));
473+
let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
474474
forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
475475
}
476476
TypeNs::AdtId(AdtId::UnionId(u)) => {
477477
let substs = ctx.substs_from_path(path, u.into(), true);
478478
let ty = self.db.ty(u.into());
479-
let ty = self.insert_type_vars(ty.subst(&substs));
479+
let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
480480
forbid_unresolved_segments((ty, Some(u.into())), unresolved)
481481
}
482482
TypeNs::EnumVariantId(var) => {
483483
let substs = ctx.substs_from_path(path, var.into(), true);
484484
let ty = self.db.ty(var.parent.into());
485-
let ty = self.insert_type_vars(ty.subst(&substs));
485+
let ty = self.insert_type_vars(ty.substitute(&Interner, &substs));
486486
forbid_unresolved_segments((ty, Some(var.into())), unresolved)
487487
}
488488
TypeNs::SelfType(impl_id) => {
489489
let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
490490
let substs = generics.type_params_subst(self.db);
491-
let ty = self.db.impl_self_ty(impl_id).subst(&substs);
491+
let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
492492
match unresolved {
493493
None => {
494494
let variant = ty_variant(&ty);

crates/hir_ty/src/infer/expr.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ impl<'a> InferenceContext<'a> {
419419
self.result.record_field_resolutions.insert(field.expr, field_def);
420420
}
421421
let field_ty = field_def.map_or(self.err_ty(), |it| {
422-
field_types[it.local_id].clone().subst(&substs)
422+
field_types[it.local_id].clone().substitute(&Interner, &substs)
423423
});
424424
self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
425425
}
@@ -462,7 +462,7 @@ impl<'a> InferenceContext<'a> {
462462
Some(
463463
self.db.field_types((*s).into())[field.local_id]
464464
.clone()
465-
.subst(&parameters),
465+
.substitute(&Interner, &parameters),
466466
)
467467
} else {
468468
None
@@ -476,7 +476,7 @@ impl<'a> InferenceContext<'a> {
476476
Some(
477477
self.db.field_types((*u).into())[field.local_id]
478478
.clone()
479-
.subst(&parameters),
479+
.substitute(&Interner, &parameters),
480480
)
481481
} else {
482482
None
@@ -849,10 +849,10 @@ impl<'a> InferenceContext<'a> {
849849
self.write_method_resolution(tgt_expr, func);
850850
(ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
851851
}
852-
None => (receiver_ty, Binders::new(0, self.err_ty()), None),
852+
None => (receiver_ty, Binders::empty(&Interner, self.err_ty()), None),
853853
};
854854
let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
855-
let method_ty = method_ty.subst(&substs);
855+
let method_ty = method_ty.substitute(&Interner, &substs);
856856
let method_ty = self.insert_type_vars(method_ty);
857857
self.register_obligations_for_call(&method_ty);
858858
let (expected_receiver_ty, param_tys, ret_ty) = match method_ty.callable_sig(self.db) {
@@ -949,9 +949,11 @@ impl<'a> InferenceContext<'a> {
949949
let def: CallableDefId = from_chalk(self.db, *fn_def);
950950
let generic_predicates = self.db.generic_predicates(def.into());
951951
for predicate in generic_predicates.iter() {
952-
let (predicate, binders) =
953-
predicate.clone().subst(parameters).into_value_and_skipped_binders();
954-
always!(binders == 0); // quantified where clauses not yet handled
952+
let (predicate, binders) = predicate
953+
.clone()
954+
.substitute(&Interner, parameters)
955+
.into_value_and_skipped_binders();
956+
always!(binders.len(&Interner) == 0); // quantified where clauses not yet handled
955957
self.push_obligation(predicate.cast(&Interner));
956958
}
957959
// add obligation for trait implementation, if this is a trait method

crates/hir_ty/src/infer/pat.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ impl<'a> InferenceContext<'a> {
4949
let expected_ty = var_data
5050
.as_ref()
5151
.and_then(|d| d.field(&Name::new_tuple_field(i)))
52-
.map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
52+
.map_or(self.err_ty(), |field| {
53+
field_tys[field].clone().substitute(&Interner, &substs)
54+
});
5355
let expected_ty = self.normalize_associated_types_in(expected_ty);
5456
self.infer_pat(subpat, &expected_ty, default_bm);
5557
}
@@ -83,8 +85,9 @@ impl<'a> InferenceContext<'a> {
8385
self.result.record_pat_field_resolutions.insert(subpat.pat, field_def);
8486
}
8587

86-
let expected_ty = matching_field
87-
.map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
88+
let expected_ty = matching_field.map_or(self.err_ty(), |field| {
89+
field_tys[field].clone().substitute(&Interner, &substs)
90+
});
8891
let expected_ty = self.normalize_associated_types_in(expected_ty);
8992
self.infer_pat(subpat.pat, &expected_ty, default_bm);
9093
}

crates/hir_ty/src/infer/path.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ impl<'a> InferenceContext<'a> {
8181
ValueNs::ImplSelf(impl_id) => {
8282
let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
8383
let substs = generics.type_params_subst(self.db);
84-
let ty = self.db.impl_self_ty(impl_id).subst(&substs);
84+
let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
8585
if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
86-
let ty = self.db.value_ty(struct_id.into()).subst(&substs);
86+
let ty = self.db.value_ty(struct_id.into()).substitute(&Interner, &substs);
8787
return Some(ty);
8888
} else {
8989
// FIXME: diagnostic, invalid Self reference
@@ -243,7 +243,8 @@ impl<'a> InferenceContext<'a> {
243243
let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
244244
.fill(iter::repeat_with(|| self.table.new_type_var()))
245245
.build();
246-
let impl_self_ty = self.db.impl_self_ty(impl_id).subst(&impl_substs);
246+
let impl_self_ty =
247+
self.db.impl_self_ty(impl_id).substitute(&Interner, &impl_substs);
247248
self.unify(&impl_self_ty, &ty);
248249
Some(impl_substs)
249250
}

crates/hir_ty/src/infer/unify.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,22 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
108108
}
109109

110110
impl<T> Canonicalized<T> {
111-
pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
112-
ty.walk_mut_binders(
111+
pub(super) fn decanonicalize_ty(&self, ty: Ty) -> Ty {
112+
ty.fold_binders(
113113
&mut |ty, binders| {
114-
if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
114+
if let TyKind::BoundVar(bound) = ty.kind(&Interner) {
115115
if bound.debruijn >= binders {
116116
let (v, k) = self.free_vars[bound.index];
117-
*ty = TyKind::InferenceVar(v, k).intern(&Interner);
117+
TyKind::InferenceVar(v, k).intern(&Interner)
118+
} else {
119+
ty
118120
}
121+
} else {
122+
ty
119123
}
120124
},
121125
DebruijnIndex::INNERMOST,
122-
);
123-
ty
126+
)
124127
}
125128

126129
pub(super) fn apply_solution(
@@ -149,7 +152,7 @@ impl<T> Canonicalized<T> {
149152
// eagerly replace projections in the type; we may be getting types
150153
// e.g. from where clauses where this hasn't happened yet
151154
let ty = ctx.normalize_associated_types_in(
152-
ty.assert_ty_ref(&Interner).clone().subst_bound_vars(&new_vars),
155+
new_vars.apply(ty.assert_ty_ref(&Interner).clone(), &Interner),
153156
);
154157
ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
155158
}
@@ -170,8 +173,8 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substitution> {
170173
// fallback to Unknown in the end (kind of hacky, as below)
171174
.map(|_| table.new_type_var()),
172175
);
173-
let ty1_with_vars = tys.value.0.clone().subst_bound_vars(&vars);
174-
let ty2_with_vars = tys.value.1.clone().subst_bound_vars(&vars);
176+
let ty1_with_vars = vars.apply(tys.value.0.clone(), &Interner);
177+
let ty2_with_vars = vars.apply(tys.value.1.clone(), &Interner);
175178
if !table.unify(&ty1_with_vars, &ty2_with_vars) {
176179
return None;
177180
}

0 commit comments

Comments
 (0)