diff options
author | Florian Diebold <[email protected]> | 2019-04-21 13:21:58 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-04-21 14:01:17 +0100 |
commit | 787fb3e5ec56494f3856bb1ce33cbe296265d199 (patch) | |
tree | 1fdbd68757a878026c560cc133ddd3cc2672295e /crates/ra_hir/src/ty | |
parent | 7f94119171658523bc854e8c8b4b6da28378b468 (diff) |
Add HIR for where clauses & ignore impls with where clauses in trait resolution
This prevents any `impl<T> Trait for T where ...` from being treated as a
blanket impl while we don't handle where clauses yet.
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 9 |
2 files changed, 23 insertions, 3 deletions
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 86f18b487..a4c99528d 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2477,6 +2477,23 @@ fn test() { (&S).foo()<|>; } | |||
2477 | assert_eq!(t, "u128"); | 2477 | assert_eq!(t, "u128"); |
2478 | } | 2478 | } |
2479 | 2479 | ||
2480 | #[test] | ||
2481 | fn method_resolution_where_clause_not_met() { | ||
2482 | // The blanket impl shouldn't apply because we can't prove S: Clone | ||
2483 | let t = type_at( | ||
2484 | r#" | ||
2485 | //- /main.rs | ||
2486 | trait Clone {} | ||
2487 | trait Trait { fn foo(self) -> u128; } | ||
2488 | struct S; | ||
2489 | impl S { fn foo(self) -> i8 { 0 } } | ||
2490 | impl<T> Trait for T where T: Clone { fn foo(self) -> u128 { 0 } } | ||
2491 | fn test() { (&S).foo()<|>; } | ||
2492 | "#, | ||
2493 | ); | ||
2494 | assert_eq!(t, "i8"); | ||
2495 | } | ||
2496 | |||
2480 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { | 2497 | fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String { |
2481 | let file = db.parse(pos.file_id); | 2498 | let file = db.parse(pos.file_id); |
2482 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); | 2499 | 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 f8c3958bd..06f483899 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | //! Stuff that will probably mostly replaced by Chalk. | 1 | //! Stuff that will probably mostly replaced by Chalk. |
2 | use std::collections::HashMap; | 2 | use std::collections::HashMap; |
3 | 3 | ||
4 | use crate::db::HirDatabase; | 4 | use crate::{db::HirDatabase, generics::HasGenericParams}; |
5 | use super::{ TraitRef, Substs, infer::{ TypeVarId, InferTy}, Ty}; | 5 | use super::{TraitRef, Substs, infer::{TypeVarId, InferTy}, Ty}; |
6 | 6 | ||
7 | // Copied (and simplified) from Chalk | 7 | // Copied (and simplified) from Chalk |
8 | 8 | ||
@@ -59,7 +59,10 @@ pub(crate) fn implements(db: &impl HirDatabase, trait_ref: TraitRef) -> Option<S | |||
59 | None => return None, | 59 | None => return None, |
60 | }; | 60 | }; |
61 | let crate_impl_blocks = db.impls_in_crate(krate); | 61 | let crate_impl_blocks = db.impls_in_crate(krate); |
62 | let mut impl_blocks = crate_impl_blocks.lookup_impl_blocks_for_trait(&trait_ref.trait_); | 62 | let mut impl_blocks = crate_impl_blocks |
63 | .lookup_impl_blocks_for_trait(&trait_ref.trait_) | ||
64 | // we don't handle where clauses at all, waiting for Chalk for that | ||
65 | .filter(|impl_block| impl_block.generic_params(db).where_predicates.is_empty()); | ||
63 | impl_blocks | 66 | impl_blocks |
64 | .find_map(|impl_block| unify_trait_refs(&trait_ref, &impl_block.target_trait_ref(db)?)) | 67 | .find_map(|impl_block| unify_trait_refs(&trait_ref, &impl_block.target_trait_ref(db)?)) |
65 | } | 68 | } |