aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/db.rs2
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs6
-rw-r--r--crates/ra_hir/src/ty/infer.rs3
-rw-r--r--crates/ra_hir/src/ty/infer/unify.rs12
-rw-r--r--crates/ra_hir/src/ty/tests.rs19
-rw-r--r--crates/ra_hir/src/ty/traits.rs15
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs15
7 files changed, 52 insertions, 20 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 9d46f9025..e0a37e13d 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -224,7 +224,7 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
224 fn normalize( 224 fn normalize(
225 &self, 225 &self,
226 krate: Crate, 226 krate: Crate,
227 goal: crate::ty::Canonical<crate::ty::ProjectionPredicate>, 227 goal: crate::ty::Canonical<crate::ty::InEnvironment<crate::ty::ProjectionPredicate>>,
228 ) -> Option<crate::ty::traits::Solution>; 228 ) -> Option<crate::ty::traits::Solution>;
229} 229}
230 230
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs
index 90c1ae630..214aa7d03 100644
--- a/crates/ra_hir/src/ty/autoderef.rs
+++ b/crates/ra_hir/src/ty/autoderef.rs
@@ -52,6 +52,8 @@ fn deref_by_trait(
52 52
53 // FIXME make the Canonical handling nicer 53 // FIXME make the Canonical handling nicer
54 54
55 let env = super::lower::trait_env(db, resolver);
56
55 let projection = super::traits::ProjectionPredicate { 57 let projection = super::traits::ProjectionPredicate {
56 ty: Ty::Bound(0), 58 ty: Ty::Bound(0),
57 projection_ty: super::ProjectionTy { 59 projection_ty: super::ProjectionTy {
@@ -60,7 +62,9 @@ fn deref_by_trait(
60 }, 62 },
61 }; 63 };
62 64
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 };
64 68
65 let solution = db.normalize(krate, canonical)?; 69 let solution = db.normalize(krate, canonical)?;
66 70
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index f8839ebd2..f6cf61ad2 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -356,7 +356,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
356 }; 356 };
357 } 357 }
358 Obligation::Projection(pr) => { 358 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);
360 let solution = self 361 let solution = self
361 .db 362 .db
362 .normalize(self.resolver.krate().unwrap(), canonicalized.value.clone()); 363 .normalize(self.resolver.krate().unwrap(), canonicalized.value.clone());
diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir/src/ty/infer/unify.rs
index ad2eefcaf..2ed326cd5 100644
--- a/crates/ra_hir/src/ty/infer/unify.rs
+++ b/crates/ra_hir/src/ty/infer/unify.rs
@@ -129,10 +129,14 @@ where
129 129
130 pub fn canonicalize_projection( 130 pub fn canonicalize_projection(
131 mut self, 131 mut self,
132 projection: ProjectionPredicate, 132 projection: InEnvironment<ProjectionPredicate>,
133 ) -> Canonicalized<ProjectionPredicate> { 133 ) -> Canonicalized<InEnvironment<ProjectionPredicate>> {
134 let result = self.do_canonicalize_projection_predicate(projection); 134 let result = self.do_canonicalize_projection_predicate(projection.value);
135 self.into_canonicalized(result) 135 // FIXME canonicalize env
136 self.into_canonicalized(InEnvironment {
137 value: result,
138 environment: projection.environment,
139 })
136 } 140 }
137} 141}
138 142
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 594e82af2..7340bb9bd 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -3010,6 +3010,25 @@ fn test<T>(t: T) { t.foo()<|>; }
3010 assert_eq!(t, "{unknown}"); 3010 assert_eq!(t, "{unknown}");
3011} 3011}
3012 3012
3013#[test]
3014fn generic_param_env_deref() {
3015 let t = type_at(
3016 r#"
3017//- /main.rs
3018#[lang = "deref"]
3019trait Deref {
3020 type Target;
3021}
3022trait Trait {}
3023impl<T> Deref for T where T: Trait {
3024 type Target = i128;
3025}
3026fn test<T: Trait>(t: T) { (*t)<|>; }
3027"#,
3028 );
3029 assert_eq!(t, "i128");
3030}
3031
3013fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { 3032fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
3014 let file = db.parse(pos.file_id).ok().unwrap(); 3033 let file = db.parse(pos.file_id).ok().unwrap();
3015 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); 3034 let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index e0c93550a..01f350bc1 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/traits.rs
@@ -134,20 +134,9 @@ pub(crate) fn implements_query(
134pub(crate) fn normalize_query( 134pub(crate) fn normalize_query(
135 db: &impl HirDatabase, 135 db: &impl HirDatabase,
136 krate: Crate, 136 krate: Crate,
137 projection: Canonical<ProjectionPredicate>, 137 projection: Canonical<InEnvironment<ProjectionPredicate>>,
138) -> Option<Solution> { 138) -> Option<Solution> {
139 let goal: chalk_ir::Goal = chalk_ir::Normalize { 139 let canonical = projection.to_chalk(db).cast();
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] };
151 // We currently don't deal with universes (I think / hope they're not yet 140 // We currently don't deal with universes (I think / hope they're not yet
152 // relevant for our use cases?) 141 // relevant for our use cases?)
153 let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; 142 let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 };
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs
index f36ff2fc6..32a45731d 100644
--- a/crates/ra_hir/src/ty/traits/chalk.rs
+++ b/crates/ra_hir/src/ty/traits/chalk.rs
@@ -218,6 +218,21 @@ impl ToChalk for ProjectionTy {
218 } 218 }
219} 219}
220 220
221impl 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
221impl<T> ToChalk for Canonical<T> 236impl<T> ToChalk for Canonical<T>
222where 237where
223 T: ToChalk, 238 T: ToChalk,