diff options
author | Florian Diebold <[email protected]> | 2019-07-07 17:14:56 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-07-08 20:20:17 +0100 |
commit | 15862fc04183c7f9b3f3af666336a594a6a52cd9 (patch) | |
tree | 3593ee969c943d4881839e527e4305a1c3db2991 /crates/ra_hir/src | |
parent | b1b12072eddaf989fb08ed7a2e39ec2dbbb83dde (diff) |
Use environment for associated type normalization as well
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/db.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/autoderef.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/unify.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 15 |
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] | ||
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 | |||
3013 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 3032 | fn 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( | |||
134 | pub(crate) fn normalize_query( | 134 | pub(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 | ||
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 | |||
221 | impl<T> ToChalk for Canonical<T> | 236 | impl<T> ToChalk for Canonical<T> |
222 | where | 237 | where |
223 | T: ToChalk, | 238 | T: ToChalk, |