Skip to content

Commit 69714d3

Browse files
committed
Hide Binders internals more
1 parent 6e9798a commit 69714d3

File tree

11 files changed

+108
-88
lines changed

11 files changed

+108
-88
lines changed

crates/hir/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {

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_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: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ impl HirDisplay for Ty {
353353
.as_ref()
354354
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
355355
let bounds = data.subst(parameters);
356-
bounds.value
356+
bounds.into_value_and_skipped_binders().0
357357
} else {
358358
Vec::new()
359359
}
@@ -543,7 +543,7 @@ impl HirDisplay for Ty {
543543
.as_ref()
544544
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
545545
let bounds = data.subst(&parameters);
546-
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
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(..) => {
@@ -630,7 +630,7 @@ impl HirDisplay for Ty {
630630
.as_ref()
631631
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
632632
let bounds = data.subst(&opaque_ty.substitution);
633-
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
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/lib.rs

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -118,49 +118,27 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
118118
}
119119

120120
impl<T> Binders<T> {
121-
pub fn new(num_binders: usize, value: T) -> Self {
122-
Self { num_binders, value }
123-
}
124-
125121
pub fn wrap_empty(value: T) -> Self
126122
where
127123
T: TypeWalk,
128124
{
129-
Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) }
130-
}
131-
132-
pub fn as_ref(&self) -> Binders<&T> {
133-
Binders { num_binders: self.num_binders, value: &self.value }
134-
}
135-
136-
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
137-
Binders { num_binders: self.num_binders, value: f(self.value) }
138-
}
139-
140-
pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
141-
Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
142-
}
143-
144-
pub fn skip_binders(&self) -> &T {
145-
&self.value
146-
}
147-
148-
pub fn into_value_and_skipped_binders(self) -> (T, usize) {
149-
(self.value, self.num_binders)
125+
Binders::empty(&Interner, value.shift_bound_vars(DebruijnIndex::ONE))
150126
}
151127
}
152128

153129
impl<T: Clone> Binders<&T> {
154130
pub fn cloned(&self) -> Binders<T> {
155-
Binders { num_binders: self.num_binders, value: self.value.clone() }
131+
let (value, binders) = self.into_value_and_skipped_binders();
132+
Binders::new(binders, value.clone())
156133
}
157134
}
158135

159136
impl<T: TypeWalk> Binders<T> {
160137
/// Substitutes all variables.
161138
pub fn subst(self, subst: &Substitution) -> T {
162-
assert_eq!(subst.len(&Interner), self.num_binders);
163-
self.value.subst_bound_vars(subst)
139+
let (value, binders) = self.into_value_and_skipped_binders();
140+
assert_eq!(subst.len(&Interner), binders);
141+
value.subst_bound_vars(subst)
164142
}
165143
}
166144

@@ -334,12 +312,12 @@ impl Ty {
334312
/// If this is a `dyn Trait` type, this returns the `Trait` part.
335313
fn dyn_trait_ref(&self) -> Option<&TraitRef> {
336314
match self.kind(&Interner) {
337-
TyKind::Dyn(dyn_ty) => {
338-
dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
315+
TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| {
316+
match b.skip_binders() {
339317
WhereClause::Implemented(trait_ref) => Some(trait_ref),
340318
_ => None,
341-
})
342-
}
319+
}
320+
}),
343321
_ => None,
344322
}
345323
}
@@ -459,7 +437,7 @@ impl Ty {
459437
ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
460438
};
461439

462-
predicates.map(|it| it.value)
440+
predicates.map(|it| it.into_value_and_skipped_binders().0)
463441
}
464442
TyKind::Placeholder(idx) => {
465443
let id = from_placeholder_idx(db, *idx);

crates/hir_ty/src/lower.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -832,12 +832,15 @@ pub fn associated_type_shorthand_candidates<R>(
832832

833833
match res {
834834
// FIXME: how to correctly handle higher-ranked bounds here?
835-
TypeNs::SelfType(impl_id) => {
836-
search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE))
837-
}
835+
TypeNs::SelfType(impl_id) => search(
836+
db.impl_trait(impl_id)?
837+
.into_value_and_skipped_binders()
838+
.0
839+
.shift_bound_vars_out(DebruijnIndex::ONE),
840+
),
838841
TypeNs::GenericParam(param_id) => {
839842
let predicates = db.generic_predicates_for_param(param_id);
840-
let res = predicates.iter().find_map(|pred| match &pred.value.value {
843+
let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
841844
// FIXME: how to correctly handle higher-ranked bounds here?
842845
WhereClause::Implemented(tr) => {
843846
search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
@@ -1088,8 +1091,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
10881091
let ctx =
10891092
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
10901093
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1091-
let ret = type_for_adt(db, def.into());
1092-
Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1094+
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
1095+
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
10931096
}
10941097

10951098
/// Build the type of a tuple struct constructor.
@@ -1114,8 +1117,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
11141117
let ctx =
11151118
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
11161119
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1117-
let ret = type_for_adt(db, def.parent.into());
1118-
Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1120+
let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
1121+
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
11191122
}
11201123

11211124
/// Build the type of a tuple enum variant constructor.
@@ -1267,9 +1270,9 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
12671270
let resolver = impl_id.resolver(db.upcast());
12681271
let ctx =
12691272
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1270-
let self_ty = db.impl_self_ty(impl_id);
1273+
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
12711274
let target_trait = impl_data.target_trait.as_ref()?;
1272-
Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?))
1275+
Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
12731276
}
12741277

12751278
pub(crate) fn return_type_impl_traits(

crates/hir_ty/src/method_resolution.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ impl TraitImpls {
102102
for (_module_id, module_data) in crate_def_map.modules() {
103103
for impl_id in module_data.scope.impls() {
104104
let target_trait = match db.impl_trait(impl_id) {
105-
Some(tr) => tr.value.hir_trait_id(),
105+
Some(tr) => tr.skip_binders().hir_trait_id(),
106106
None => continue,
107107
};
108108
let self_ty = db.impl_self_ty(impl_id);
109-
let self_ty_fp = TyFingerprint::for_impl(&self_ty.value);
109+
let self_ty_fp = TyFingerprint::for_impl(self_ty.skip_binders());
110110
impls
111111
.map
112112
.entry(target_trait)
@@ -201,7 +201,7 @@ impl InherentImpls {
201201
}
202202

203203
let self_ty = db.impl_self_ty(impl_id);
204-
if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) {
204+
if let Some(fp) = TyFingerprint::for_impl(self_ty.skip_binders()) {
205205
map.entry(fp).or_default().push(impl_id);
206206
}
207207
}
@@ -774,7 +774,7 @@ fn transform_receiver_ty(
774774
AssocContainerId::ModuleId(_) => unreachable!(),
775775
};
776776
let sig = db.callable_item_signature(function_id.into());
777-
Some(sig.value.params()[0].clone().subst_bound_vars(&substs))
777+
Some(sig.map(|s| s.params()[0].clone()).subst(&substs))
778778
}
779779

780780
pub fn implements_trait(

crates/hir_ty/src/traits/chalk.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,15 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
184184
.db
185185
.return_type_impl_traits(func)
186186
.expect("impl trait id without impl traits");
187-
let data = &datas.value.impl_traits[idx as usize];
187+
let data = &datas.skip_binders().impl_traits[idx as usize];
188188
let bound = OpaqueTyDatumBound {
189189
bounds: make_binders(
190-
data.bounds.value.iter().cloned().map(|b| b.to_chalk(self.db)).collect(),
190+
data.bounds
191+
.skip_binders()
192+
.iter()
193+
.cloned()
194+
.map(|b| b.to_chalk(self.db))
195+
.collect(),
191196
1,
192197
),
193198
where_clauses: make_binders(vec![], 0),
@@ -535,7 +540,8 @@ fn impl_def_datum(
535540
.impl_trait(impl_id)
536541
// ImplIds for impls where the trait ref can't be resolved should never reach Chalk
537542
.expect("invalid impl passed to Chalk")
538-
.value;
543+
.into_value_and_skipped_binders()
544+
.0;
539545
let impl_data = db.impl_data(impl_id);
540546

541547
let generic_params = generics(db.upcast(), impl_id.into());
@@ -605,18 +611,22 @@ fn type_alias_associated_ty_value(
605611
_ => panic!("assoc ty value should be in impl"),
606612
};
607613

608-
let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved
614+
let trait_ref = db
615+
.impl_trait(impl_id)
616+
.expect("assoc ty value should not exist")
617+
.into_value_and_skipped_binders()
618+
.0; // we don't return any assoc ty values if the impl'd trait can't be resolved
609619

610620
let assoc_ty = db
611621
.trait_data(trait_ref.hir_trait_id())
612622
.associated_type_by_name(&type_alias_data.name)
613623
.expect("assoc ty value should not exist"); // validated when building the impl data as well
614-
let ty = db.ty(type_alias.into());
615-
let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
624+
let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders();
625+
let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
616626
let value = rust_ir::AssociatedTyValue {
617627
impl_id: impl_id.to_chalk(db),
618628
associated_ty_id: to_assoc_type_id(assoc_ty),
619-
value: make_binders(value_bound, ty.num_binders),
629+
value: make_binders(value_bound, binders),
620630
};
621631
Arc::new(value)
622632
}
@@ -628,20 +638,15 @@ pub(crate) fn fn_def_datum_query(
628638
) -> Arc<FnDefDatum> {
629639
let callable_def: CallableDefId = from_chalk(db, fn_def_id);
630640
let generic_params = generics(db.upcast(), callable_def.into());
631-
let sig = db.callable_item_signature(callable_def);
641+
let (sig, binders) = db.callable_item_signature(callable_def).into_value_and_skipped_binders();
632642
let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
633643
let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
634644
let bound = rust_ir::FnDefDatumBound {
635645
// Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
636646
inputs_and_output: make_binders(
637647
rust_ir::FnDefInputsAndOutputDatum {
638-
argument_types: sig
639-
.value
640-
.params()
641-
.iter()
642-
.map(|ty| ty.clone().to_chalk(db))
643-
.collect(),
644-
return_type: sig.value.ret().clone().to_chalk(db),
648+
argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(),
649+
return_type: sig.ret().clone().to_chalk(db),
645650
}
646651
.shifted_in(&Interner),
647652
0,
@@ -650,12 +655,8 @@ pub(crate) fn fn_def_datum_query(
650655
};
651656
let datum = FnDefDatum {
652657
id: fn_def_id,
653-
sig: chalk_ir::FnSig {
654-
abi: (),
655-
safety: chalk_ir::Safety::Safe,
656-
variadic: sig.value.is_varargs,
657-
},
658-
binders: make_binders(bound, sig.num_binders),
658+
sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs },
659+
binders: make_binders(bound, binders),
659660
};
660661
Arc::new(datum)
661662
}

crates/hir_ty/src/traits/chalk/mapping.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,13 @@ impl ToChalk for Ty {
9393
TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
9494
TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
9595
TyKind::Dyn(dyn_ty) => {
96+
let (bounds, binders) = dyn_ty.bounds.into_value_and_skipped_binders();
9697
let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
9798
&Interner,
98-
dyn_ty.bounds.value.interned().iter().cloned().map(|p| p.to_chalk(db)),
99+
bounds.interned().iter().cloned().map(|p| p.to_chalk(db)),
99100
);
100101
let bounded_ty = chalk_ir::DynTy {
101-
bounds: make_binders(where_clauses, 1),
102+
bounds: make_binders(where_clauses, binders),
102103
lifetime: LifetimeData::Static.intern(&Interner),
103104
};
104105
chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
@@ -486,13 +487,14 @@ where
486487
type Chalk = chalk_ir::Binders<T::Chalk>;
487488

488489
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
490+
let (value, binders) = self.into_value_and_skipped_binders();
489491
chalk_ir::Binders::new(
490492
chalk_ir::VariableKinds::from_iter(
491493
&Interner,
492494
std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
493-
.take(self.num_binders),
495+
.take(binders),
494496
),
495-
self.value.to_chalk(db),
497+
value.to_chalk(db),
496498
)
497499
}
498500

@@ -537,7 +539,8 @@ pub(super) fn generic_predicate_to_inline_bound(
537539
// An InlineBound is like a GenericPredicate, except the self type is left out.
538540
// We don't have a special type for this, but Chalk does.
539541
let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE);
540-
match &pred.value {
542+
let (pred, binders) = pred.as_ref().into_value_and_skipped_binders();
543+
match pred {
541544
WhereClause::Implemented(trait_ref) => {
542545
if trait_ref.self_type_parameter(&Interner) != &self_ty_shifted_in {
543546
// we can only convert predicates back to type bounds if they
@@ -549,7 +552,7 @@ pub(super) fn generic_predicate_to_inline_bound(
549552
.map(|ty| ty.clone().to_chalk(db).cast(&Interner))
550553
.collect();
551554
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
552-
Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders))
555+
Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), binders))
553556
}
554557
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
555558
if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in {
@@ -566,7 +569,7 @@ pub(super) fn generic_predicate_to_inline_bound(
566569
associated_ty_id: projection_ty.associated_ty_id,
567570
parameters: Vec::new(), // FIXME we don't support generic associated types yet
568571
};
569-
Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders))
572+
Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), binders))
570573
}
571574
_ => None,
572575
}

0 commit comments

Comments
 (0)