Skip to content

Commit f25c1e7

Browse files
Merge #8356
8356: Align more methods to Chalk r=flodiebold a=flodiebold Related to #8313. Move some inherent methods that don't exist in Chalk to an extension trait, remove some others. Co-authored-by: Florian Diebold <flodiebold@gmail.com>
2 parents 8c96a7d + b67148d commit f25c1e7

File tree

11 files changed

+108
-112
lines changed

11 files changed

+108
-112
lines changed

crates/hir/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use hir_ty::{
5555
autoderef, could_unify,
5656
method_resolution::{self, TyFingerprint},
5757
primitive::UintTy,
58+
subst_prefix,
5859
traits::FnTrait,
5960
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
6061
DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution,
@@ -1503,7 +1504,7 @@ impl TypeParam {
15031504
let krate = self.id.parent.module(db.upcast()).krate();
15041505
let ty = params.get(local_idx)?.clone();
15051506
let subst = TyBuilder::type_params_subst(db, self.id.parent);
1506-
let ty = ty.substitute(&Interner, &subst.prefix(local_idx));
1507+
let ty = ty.substitute(&Interner, &subst_prefix(&subst, local_idx));
15071508
Some(Type::new_with_resolver_inner(db, krate, &resolver, ty))
15081509
}
15091510
}

crates/hir_ty/src/autoderef.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use log::{info, warn};
1313

1414
use crate::{
1515
db::HirDatabase, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex,
16-
InEnvironment, Interner, Solution, Ty, TyBuilder, TyKind,
16+
InEnvironment, Interner, ProjectionTyExt, Solution, Ty, TyBuilder, TyKind,
1717
};
1818

1919
const AUTODEREF_RECURSION_LIMIT: usize = 10;

crates/hir_ty/src/chalk_ext.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
//! Various extensions traits for Chalk types.
22
3-
use crate::{Interner, Ty, TyKind};
3+
use hir_def::{AssocContainerId, Lookup, TraitId};
4+
5+
use crate::{
6+
db::HirDatabase, from_assoc_type_id, to_chalk_trait_id, Interner, ProjectionTy, TraitRef, Ty,
7+
TyKind,
8+
};
49

510
pub trait TyExt {
611
fn is_unit(&self) -> bool;
@@ -11,3 +16,24 @@ impl TyExt for Ty {
1116
matches!(self.kind(&Interner), TyKind::Tuple(0, _))
1217
}
1318
}
19+
20+
pub trait ProjectionTyExt {
21+
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef;
22+
fn trait_(&self, db: &dyn HirDatabase) -> TraitId;
23+
}
24+
25+
impl ProjectionTyExt for ProjectionTy {
26+
fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
27+
TraitRef {
28+
trait_id: to_chalk_trait_id(self.trait_(db)),
29+
substitution: self.substitution.clone(),
30+
}
31+
}
32+
33+
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
34+
match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
35+
AssocContainerId::TraitId(it) => it,
36+
_ => panic!("projection ty without parent trait"),
37+
}
38+
}
39+
}

crates/hir_ty/src/display.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ use hir_expand::name::Name;
1919

2020
use crate::{
2121
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx,
22-
lt_from_placeholder_idx, primitive, to_assoc_type_id, traits::chalk::from_chalk,
22+
lt_from_placeholder_idx, primitive, subst_prefix, to_assoc_type_id, traits::chalk::from_chalk,
2323
utils::generics, AdtId, AliasEq, AliasTy, CallableDefId, CallableSig, DomainGoal, GenericArg,
2424
ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives, Mutability, OpaqueTy,
25-
ProjectionTy, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind, WhereClause,
25+
ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar, TraitRef, Ty, TyExt, TyKind,
26+
WhereClause,
2627
};
2728

2829
pub struct HirFormatter<'a> {
@@ -483,9 +484,11 @@ impl HirDisplay for Ty {
483484
default_from = i + 1;
484485
}
485486
(_, Some(default_parameter)) => {
486-
let actual_default = default_parameter
487-
.clone()
488-
.substitute(&Interner, &parameters.prefix(i));
487+
let actual_default =
488+
default_parameter.clone().substitute(
489+
&Interner,
490+
&subst_prefix(parameters, i),
491+
);
489492
if parameter.assert_ty_ref(&Interner) != &actual_default
490493
{
491494
default_from = i + 1;

crates/hir_ty/src/infer/expr.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use crate::{
2222
to_chalk_trait_id,
2323
traits::{chalk::from_chalk, FnTrait},
2424
utils::{generics, variant_data, Generics},
25-
AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, Rawness, Scalar,
26-
Substitution, TraitRef, Ty, TyBuilder, TyKind,
25+
AdtId, Binders, CallableDefId, FnPointer, FnSig, InEnvironment, Interner, ProjectionTyExt,
26+
Rawness, Scalar, Substitution, TraitRef, Ty, TyBuilder, TyKind,
2727
};
2828

2929
use super::{
@@ -180,7 +180,8 @@ impl<'a> InferenceContext<'a> {
180180
let inner_ty = self.infer_expr(*body, &Expectation::none());
181181
let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
182182
let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
183-
TyKind::OpaqueType(opaque_ty_id, Substitution::single(inner_ty)).intern(&Interner)
183+
TyKind::OpaqueType(opaque_ty_id, Substitution::from1(&Interner, inner_ty))
184+
.intern(&Interner)
184185
}
185186
Expr::Loop { body, label } => {
186187
self.breakables.push(BreakableContext {
@@ -266,7 +267,8 @@ impl<'a> InferenceContext<'a> {
266267
.intern(&Interner);
267268
let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
268269
let closure_ty =
269-
TyKind::Closure(closure_id, Substitution::single(sig_ty)).intern(&Interner);
270+
TyKind::Closure(closure_id, Substitution::from1(&Interner, sig_ty))
271+
.intern(&Interner);
270272

271273
// Eagerly try to relate the closure type with the expected
272274
// type, otherwise we often won't have enough information to
@@ -962,8 +964,10 @@ impl<'a> InferenceContext<'a> {
962964
if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
963965
{
964966
// construct a TraitRef
965-
let substs =
966-
parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
967+
let substs = crate::subst_prefix(
968+
&*parameters,
969+
generics(self.db.upcast(), trait_.into()).len(),
970+
);
967971
self.push_obligation(
968972
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
969973
.cast(&Interner),

crates/hir_ty/src/lib.rs

Lines changed: 10 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ mod test_db;
3131
use std::sync::Arc;
3232

3333
use itertools::Itertools;
34-
use smallvec::SmallVec;
3534

3635
use base_db::salsa;
3736
use hir_def::{
@@ -43,22 +42,20 @@ use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
4342

4443
pub use autoderef::autoderef;
4544
pub use builder::TyBuilder;
46-
pub use chalk_ext::TyExt;
45+
pub use chalk_ext::{ProjectionTyExt, TyExt};
4746
pub use infer::{could_unify, InferenceResult, InferenceVar};
4847
pub use lower::{
4948
associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
5049
TyDefId, TyLoweringContext, ValueTyDefId,
5150
};
52-
pub use traits::TraitEnvironment;
51+
pub use traits::{chalk::Interner, TraitEnvironment};
5352
pub use types::*;
5453
pub use walk::TypeWalk;
5554

5655
pub use chalk_ir::{
5756
cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
5857
};
5958

60-
pub use crate::traits::chalk::Interner;
61-
6259
pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
6360
pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
6461
pub type FnDefId = chalk_ir::FnDefId<Interner>;
@@ -76,69 +73,23 @@ pub type LifetimeOutlives = chalk_ir::LifetimeOutlives<Interner>;
7673

7774
pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
7875

79-
impl ProjectionTy {
80-
pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
81-
TraitRef {
82-
trait_id: to_chalk_trait_id(self.trait_(db)),
83-
substitution: self.substitution.clone(),
84-
}
85-
}
86-
87-
pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
88-
&self.substitution.interned()[0].assert_ty_ref(interner)
89-
}
90-
91-
fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
92-
match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
93-
AssocContainerId::TraitId(it) => it,
94-
_ => panic!("projection ty without parent trait"),
95-
}
96-
}
97-
}
98-
9976
pub type FnSig = chalk_ir::FnSig<Interner>;
10077

101-
impl Substitution {
102-
pub fn single(ty: Ty) -> Substitution {
103-
Substitution::intern({
104-
let mut v = SmallVec::new();
105-
v.push(ty.cast(&Interner));
106-
v
107-
})
108-
}
109-
110-
pub fn prefix(&self, n: usize) -> Substitution {
111-
Substitution::intern(self.interned()[..std::cmp::min(self.len(&Interner), n)].into())
112-
}
113-
114-
pub fn suffix(&self, n: usize) -> Substitution {
115-
Substitution::intern(
116-
self.interned()[self.len(&Interner) - std::cmp::min(self.len(&Interner), n)..].into(),
117-
)
118-
}
78+
// FIXME: get rid of this
79+
pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
80+
Substitution::intern(s.interned()[..std::cmp::min(s.len(&Interner), n)].into())
11981
}
12082

12183
/// Return an index of a parameter in the generic type parameter list by it's id.
12284
pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
12385
generics(db.upcast(), id.parent).param_idx(id)
12486
}
12587

126-
impl<T> Binders<T> {
127-
pub fn wrap_empty(value: T) -> Self
128-
where
129-
T: TypeWalk,
130-
{
131-
Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE))
132-
}
133-
}
134-
135-
impl<T: TypeWalk> Binders<T> {
136-
/// Substitutes all variables.
137-
pub fn substitute(self, interner: &Interner, subst: &Substitution) -> T {
138-
let (value, binders) = self.into_value_and_skipped_binders();
139-
assert_eq!(subst.len(interner), binders.len(interner));
140-
value.subst_bound_vars(subst)
141-
}
88+
pub fn wrap_empty_binders<T>(value: T) -> Binders<T>
89+
where
90+
T: TypeWalk,
91+
{
92+
Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE))
14293
}
14394

14495
pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> {
@@ -153,31 +104,11 @@ pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> {
153104
}
154105

155106
impl TraitRef {
156-
pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
157-
&self.substitution.at(interner, 0).assert_ty_ref(interner)
158-
}
159-
160107
pub fn hir_trait_id(&self) -> TraitId {
161108
from_chalk_trait_id(self.trait_id)
162109
}
163110
}
164111

165-
impl WhereClause {
166-
pub fn is_implemented(&self) -> bool {
167-
matches!(self, WhereClause::Implemented(_))
168-
}
169-
170-
pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
171-
match self {
172-
WhereClause::Implemented(tr) => Some(tr.clone()),
173-
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
174-
Some(proj.trait_ref(db))
175-
}
176-
WhereClause::AliasEq(_) => None,
177-
}
178-
}
179-
}
180-
181112
impl<T> Canonical<T> {
182113
pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
183114
let kinds = kinds.into_iter().map(|tk| {

crates/hir_ty/src/lower.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,9 @@ impl<'a> TyLoweringContext<'a> {
384384
1,
385385
QuantifiedWhereClauses::from_iter(
386386
&Interner,
387-
Some(Binders::wrap_empty(WhereClause::Implemented(trait_ref))),
387+
Some(crate::wrap_empty_binders(WhereClause::Implemented(
388+
trait_ref,
389+
))),
388390
),
389391
),
390392
};
@@ -720,7 +722,7 @@ impl<'a> TyLoweringContext<'a> {
720722
let trait_ref = match bound {
721723
TypeBound::Path(path) => {
722724
bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
723-
bindings.clone().map(WhereClause::Implemented).map(|b| Binders::wrap_empty(b))
725+
bindings.clone().map(WhereClause::Implemented).map(|b| crate::wrap_empty_binders(b))
724726
}
725727
TypeBound::Lifetime(_) => None,
726728
TypeBound::Error => None,
@@ -767,7 +769,7 @@ impl<'a> TyLoweringContext<'a> {
767769
let ty = self.lower_ty(type_ref);
768770
let alias_eq =
769771
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
770-
preds.push(Binders::wrap_empty(WhereClause::AliasEq(alias_eq)));
772+
preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
771773
}
772774
for bound in &binding.bounds {
773775
preds.extend(self.lower_type_bound(

crates/hir_ty/src/method_resolution.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,9 @@ pub(crate) fn inherent_impl_substs(
709709
) -> Option<Substitution> {
710710
// we create a var for each type parameter of the impl; we need to keep in
711711
// mind here that `self_ty` might have vars of its own
712+
let self_ty_vars = self_ty.binders.len(&Interner);
712713
let vars = TyBuilder::subst_for_def(db, impl_id)
713-
.fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty.binders.len(&Interner))
714+
.fill_with_bound_vars(DebruijnIndex::INNERMOST, self_ty_vars)
714715
.build();
715716
let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(&Interner, &vars);
716717
let mut kinds = self_ty.binders.interned().to_vec();
@@ -725,14 +726,15 @@ pub(crate) fn inherent_impl_substs(
725726
binders: CanonicalVarKinds::from_iter(&Interner, kinds),
726727
value: (self_ty_with_vars, self_ty.value.clone()),
727728
};
728-
let substs = super::infer::unify(&tys);
729+
let substs = super::infer::unify(&tys)?;
729730
// We only want the substs for the vars we added, not the ones from self_ty.
730731
// Also, if any of the vars we added are still in there, we replace them by
731732
// Unknown. I think this can only really happen if self_ty contained
732733
// Unknown, and in that case we want the result to contain Unknown in those
733734
// places again.
734-
substs
735-
.map(|s| fallback_bound_vars(s.suffix(vars.len(&Interner)), self_ty.binders.len(&Interner)))
735+
let suffix =
736+
Substitution::from_iter(&Interner, substs.iter(&Interner).cloned().skip(self_ty_vars));
737+
Some(fallback_bound_vars(suffix, self_ty_vars))
736738
}
737739

738740
/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past

crates/hir_ty/src/traits/chalk.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
220220
let impl_bound = WhereClause::Implemented(TraitRef {
221221
trait_id: to_chalk_trait_id(future_trait),
222222
// Self type as the first parameter.
223-
substitution: Substitution::single(
223+
substitution: Substitution::from1(
224+
&Interner,
224225
TyKind::BoundVar(BoundVar {
225226
debruijn: DebruijnIndex::INNERMOST,
226227
index: 0,
@@ -232,7 +233,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
232233
alias: AliasTy::Projection(ProjectionTy {
233234
associated_ty_id: to_assoc_type_id(future_output),
234235
// Self type as the first parameter.
235-
substitution: Substitution::single(
236+
substitution: Substitution::from1(
237+
&Interner,
236238
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
237239
.intern(&Interner),
238240
),
@@ -244,8 +246,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
244246
let bound = OpaqueTyDatumBound {
245247
bounds: make_binders(
246248
vec![
247-
wrap_in_empty_binders(impl_bound).to_chalk(self.db),
248-
wrap_in_empty_binders(proj_bound).to_chalk(self.db),
249+
crate::wrap_empty_binders(impl_bound).to_chalk(self.db),
250+
crate::wrap_empty_binders(proj_bound).to_chalk(self.db),
249251
],
250252
1,
251253
),
@@ -721,7 +723,3 @@ impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
721723
chalk_ir::ClosureId(id.as_intern_id())
722724
}
723725
}
724-
725-
fn wrap_in_empty_binders<T: crate::TypeWalk>(value: T) -> crate::Binders<T> {
726-
crate::Binders::wrap_empty(value)
727-
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ use base_db::salsa::InternKey;
1010
use hir_def::{GenericDefId, TypeAliasId};
1111

1212
use crate::{
13-
db::HirDatabase, primitive::UintTy, AliasTy, CallableDefId, Canonical, DomainGoal, FnPointer,
14-
GenericArg, InEnvironment, OpaqueTy, ProjectionTy, QuantifiedWhereClause, Scalar, Substitution,
15-
TraitRef, Ty, TypeWalk, WhereClause,
13+
chalk_ext::ProjectionTyExt, db::HirDatabase, primitive::UintTy, AliasTy, CallableDefId,
14+
Canonical, DomainGoal, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy,
15+
QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
1616
};
1717

1818
use super::interner::*;

0 commit comments

Comments
 (0)