Skip to content

Commit 15862fc

Browse files
committed
Use environment for associated type normalization as well
1 parent b1b1207 commit 15862fc

File tree

7 files changed

+52
-20
lines changed

7 files changed

+52
-20
lines changed

crates/ra_hir/src/db.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
224224
fn normalize(
225225
&self,
226226
krate: Crate,
227-
goal: crate::ty::Canonical<crate::ty::ProjectionPredicate>,
227+
goal: crate::ty::Canonical<crate::ty::InEnvironment<crate::ty::ProjectionPredicate>>,
228228
) -> Option<crate::ty::traits::Solution>;
229229
}
230230

crates/ra_hir/src/ty/autoderef.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ fn deref_by_trait(
5252

5353
// FIXME make the Canonical handling nicer
5454

55+
let env = super::lower::trait_env(db, resolver);
56+
5557
let projection = super::traits::ProjectionPredicate {
5658
ty: Ty::Bound(0),
5759
projection_ty: super::ProjectionTy {
@@ -60,7 +62,9 @@ fn deref_by_trait(
6062
},
6163
};
6264

63-
let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: projection };
65+
let in_env = super::traits::InEnvironment { value: projection, environment: env };
66+
67+
let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env };
6468

6569
let solution = db.normalize(krate, canonical)?;
6670

crates/ra_hir/src/ty/infer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
356356
};
357357
}
358358
Obligation::Projection(pr) => {
359-
let canonicalized = self.canonicalizer().canonicalize_projection(pr.clone());
359+
let in_env = InEnvironment::new(self.trait_env.clone(), pr.clone());
360+
let canonicalized = self.canonicalizer().canonicalize_projection(in_env);
360361
let solution = self
361362
.db
362363
.normalize(self.resolver.krate().unwrap(), canonicalized.value.clone());

crates/ra_hir/src/ty/infer/unify.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,14 @@ where
129129

130130
pub fn canonicalize_projection(
131131
mut self,
132-
projection: ProjectionPredicate,
133-
) -> Canonicalized<ProjectionPredicate> {
134-
let result = self.do_canonicalize_projection_predicate(projection);
135-
self.into_canonicalized(result)
132+
projection: InEnvironment<ProjectionPredicate>,
133+
) -> Canonicalized<InEnvironment<ProjectionPredicate>> {
134+
let result = self.do_canonicalize_projection_predicate(projection.value);
135+
// FIXME canonicalize env
136+
self.into_canonicalized(InEnvironment {
137+
value: result,
138+
environment: projection.environment,
139+
})
136140
}
137141
}
138142

crates/ra_hir/src/ty/tests.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3010,6 +3010,25 @@ fn test<T>(t: T) { t.foo()<|>; }
30103010
assert_eq!(t, "{unknown}");
30113011
}
30123012

3013+
#[test]
3014+
fn generic_param_env_deref() {
3015+
let t = type_at(
3016+
r#"
3017+
//- /main.rs
3018+
#[lang = "deref"]
3019+
trait Deref {
3020+
type Target;
3021+
}
3022+
trait Trait {}
3023+
impl<T> Deref for T where T: Trait {
3024+
type Target = i128;
3025+
}
3026+
fn test<T: Trait>(t: T) { (*t)<|>; }
3027+
"#,
3028+
);
3029+
assert_eq!(t, "i128");
3030+
}
3031+
30133032
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
30143033
let file = db.parse(pos.file_id).ok().unwrap();
30153034
let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();

crates/ra_hir/src/ty/traits.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -134,20 +134,9 @@ pub(crate) fn implements_query(
134134
pub(crate) fn normalize_query(
135135
db: &impl HirDatabase,
136136
krate: Crate,
137-
projection: Canonical<ProjectionPredicate>,
137+
projection: Canonical<InEnvironment<ProjectionPredicate>>,
138138
) -> Option<Solution> {
139-
let goal: chalk_ir::Goal = chalk_ir::Normalize {
140-
projection: projection.value.projection_ty.to_chalk(db),
141-
ty: projection.value.ty.to_chalk(db),
142-
}
143-
.cast();
144-
debug!("goal: {:?}", goal);
145-
// FIXME unify with `implements`
146-
let env = chalk_ir::Environment::new();
147-
let in_env = chalk_ir::InEnvironment::new(&env, goal);
148-
let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT);
149-
let canonical =
150-
chalk_ir::Canonical { value: in_env, binders: vec![parameter; projection.num_vars] };
139+
let canonical = projection.to_chalk(db).cast();
151140
// We currently don't deal with universes (I think / hope they're not yet
152141
// relevant for our use cases?)
153142
let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 };

crates/ra_hir/src/ty/traits/chalk.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,21 @@ impl ToChalk for ProjectionTy {
218218
}
219219
}
220220

221+
impl ToChalk for super::ProjectionPredicate {
222+
type Chalk = chalk_ir::Normalize;
223+
224+
fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize {
225+
chalk_ir::Normalize {
226+
projection: self.projection_ty.to_chalk(db),
227+
ty: self.ty.to_chalk(db),
228+
}
229+
}
230+
231+
fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self {
232+
unimplemented!()
233+
}
234+
}
235+
221236
impl<T> ToChalk for Canonical<T>
222237
where
223238
T: ToChalk,

0 commit comments

Comments
 (0)