diff options
author | Florian Diebold <[email protected]> | 2019-05-07 17:53:16 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-05-11 15:21:20 +0100 |
commit | d6dc75f9f22b73faf8c526be69ca43e52d6db1bf (patch) | |
tree | f17b35ab78b5dc123e55a69f065dc47d08ef3ff8 /crates/ra_hir | |
parent | 7744cd41e2ad79c1b36d3d9fccd3bc0dbfd9e2d9 (diff) |
Handle auto traits & negative impls
We don't pass field types to Chalk yet though, so the auto trait inference won't
be correct.
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/traits.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 24 |
4 files changed, 37 insertions, 7 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 55e1793c5..0c4a80bfa 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -703,6 +703,10 @@ impl Trait { | |||
703 | TraitRef::for_trait(db, self) | 703 | TraitRef::for_trait(db, self) |
704 | } | 704 | } |
705 | 705 | ||
706 | pub fn is_auto(self, db: &impl DefDatabase) -> bool { | ||
707 | self.trait_data(db).is_auto() | ||
708 | } | ||
709 | |||
706 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { | 710 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { |
707 | let r = self.module(db).resolver(db); | 711 | let r = self.module(db).resolver(db); |
708 | // add generic params, if present | 712 | // add generic params, if present |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index a8a466e43..b7dd775f1 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -93,6 +93,10 @@ impl ImplBlock { | |||
93 | db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() | 93 | db.impls_in_module(self.module).impls[self.impl_id].items().to_vec() |
94 | } | 94 | } |
95 | 95 | ||
96 | pub fn is_negative(&self, db: &impl DefDatabase) -> bool { | ||
97 | db.impls_in_module(self.module).impls[self.impl_id].negative | ||
98 | } | ||
99 | |||
96 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { | 100 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { |
97 | let r = self.module().resolver(db); | 101 | let r = self.module().resolver(db); |
98 | // add generic params, if present | 102 | // add generic params, if present |
@@ -108,6 +112,7 @@ pub struct ImplData { | |||
108 | target_trait: Option<TypeRef>, | 112 | target_trait: Option<TypeRef>, |
109 | target_type: TypeRef, | 113 | target_type: TypeRef, |
110 | items: Vec<ImplItem>, | 114 | items: Vec<ImplItem>, |
115 | negative: bool, | ||
111 | } | 116 | } |
112 | 117 | ||
113 | impl ImplData { | 118 | impl ImplData { |
@@ -120,6 +125,7 @@ impl ImplData { | |||
120 | let target_trait = node.target_trait().map(TypeRef::from_ast); | 125 | let target_trait = node.target_trait().map(TypeRef::from_ast); |
121 | let target_type = TypeRef::from_ast_opt(node.target_type()); | 126 | let target_type = TypeRef::from_ast_opt(node.target_type()); |
122 | let ctx = LocationCtx::new(db, module, file_id); | 127 | let ctx = LocationCtx::new(db, module, file_id); |
128 | let negative = node.is_negative(); | ||
123 | let items = if let Some(item_list) = node.item_list() { | 129 | let items = if let Some(item_list) = node.item_list() { |
124 | item_list | 130 | item_list |
125 | .impl_items() | 131 | .impl_items() |
@@ -132,7 +138,7 @@ impl ImplData { | |||
132 | } else { | 138 | } else { |
133 | Vec::new() | 139 | Vec::new() |
134 | }; | 140 | }; |
135 | ImplData { target_trait, target_type, items } | 141 | ImplData { target_trait, target_type, items, negative } |
136 | } | 142 | } |
137 | 143 | ||
138 | pub fn target_trait(&self) -> Option<&TypeRef> { | 144 | pub fn target_trait(&self) -> Option<&TypeRef> { |
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs index 15f0977b7..dfe883fa4 100644 --- a/crates/ra_hir/src/traits.rs +++ b/crates/ra_hir/src/traits.rs | |||
@@ -11,6 +11,7 @@ use crate::{Function, Const, TypeAlias, Name, DefDatabase, Trait, ids::LocationC | |||
11 | pub struct TraitData { | 11 | pub struct TraitData { |
12 | name: Option<Name>, | 12 | name: Option<Name>, |
13 | items: Vec<TraitItem>, | 13 | items: Vec<TraitItem>, |
14 | auto: bool, | ||
14 | } | 15 | } |
15 | 16 | ||
16 | impl TraitData { | 17 | impl TraitData { |
@@ -19,6 +20,7 @@ impl TraitData { | |||
19 | let name = node.name().map(|n| n.as_name()); | 20 | let name = node.name().map(|n| n.as_name()); |
20 | let module = tr.module(db); | 21 | let module = tr.module(db); |
21 | let ctx = LocationCtx::new(db, module, file_id); | 22 | let ctx = LocationCtx::new(db, module, file_id); |
23 | let auto = node.is_auto(); | ||
22 | let items = if let Some(item_list) = node.item_list() { | 24 | let items = if let Some(item_list) = node.item_list() { |
23 | item_list | 25 | item_list |
24 | .impl_items() | 26 | .impl_items() |
@@ -31,7 +33,7 @@ impl TraitData { | |||
31 | } else { | 33 | } else { |
32 | Vec::new() | 34 | Vec::new() |
33 | }; | 35 | }; |
34 | Arc::new(TraitData { name, items }) | 36 | Arc::new(TraitData { name, items, auto }) |
35 | } | 37 | } |
36 | 38 | ||
37 | pub(crate) fn name(&self) -> &Option<Name> { | 39 | pub(crate) fn name(&self) -> &Option<Name> { |
@@ -41,6 +43,10 @@ impl TraitData { | |||
41 | pub(crate) fn items(&self) -> &[TraitItem] { | 43 | pub(crate) fn items(&self) -> &[TraitItem] { |
42 | &self.items | 44 | &self.items |
43 | } | 45 | } |
46 | |||
47 | pub(crate) fn is_auto(&self) -> bool { | ||
48 | self.auto | ||
49 | } | ||
44 | } | 50 | } |
45 | 51 | ||
46 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 52 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 8fa0ba7a5..027c5ec4c 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -12,7 +12,9 @@ use ra_db::salsa::{InternId, InternKey}; | |||
12 | use crate::{ | 12 | use crate::{ |
13 | Trait, HasGenericParams, ImplBlock, | 13 | Trait, HasGenericParams, ImplBlock, |
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef, ty::CallableDef, | 15 | ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef}, |
16 | ty::display::HirDisplay, | ||
17 | generics::GenericDef, | ||
16 | }; | 18 | }; |
17 | use super::ChalkContext; | 19 | use super::ChalkContext; |
18 | 20 | ||
@@ -232,10 +234,10 @@ where | |||
232 | let bound_vars = Substs::bound_vars(&generic_params); | 234 | let bound_vars = Substs::bound_vars(&generic_params); |
233 | let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db); | 235 | let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db); |
234 | let flags = chalk_rust_ir::TraitFlags { | 236 | let flags = chalk_rust_ir::TraitFlags { |
237 | auto: trait_.is_auto(self.db), | ||
238 | upstream: trait_.module(self.db).krate(self.db) != Some(self.krate), | ||
235 | // FIXME set these flags correctly | 239 | // FIXME set these flags correctly |
236 | auto: false, | ||
237 | marker: false, | 240 | marker: false, |
238 | upstream: trait_.module(self.db).krate(self.db) != Some(self.krate), | ||
239 | fundamental: false, | 241 | fundamental: false, |
240 | }; | 242 | }; |
241 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); | 243 | let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars); |
@@ -329,9 +331,21 @@ where | |||
329 | chalk_rust_ir::ImplType::External | 331 | chalk_rust_ir::ImplType::External |
330 | }; | 332 | }; |
331 | let where_clauses = convert_where_clauses(self.db, impl_block.into(), &bound_vars); | 333 | let where_clauses = convert_where_clauses(self.db, impl_block.into(), &bound_vars); |
334 | let negative = impl_block.is_negative(self.db); | ||
335 | debug!( | ||
336 | "impl {:?}: {}{} where {:?}", | ||
337 | impl_id, | ||
338 | if negative { "!" } else { "" }, | ||
339 | trait_ref.display(self.db), | ||
340 | where_clauses | ||
341 | ); | ||
342 | let trait_ref = trait_ref.to_chalk(self.db); | ||
332 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { | 343 | let impl_datum_bound = chalk_rust_ir::ImplDatumBound { |
333 | // FIXME handle negative impls (impl !Sync for Foo) | 344 | trait_ref: if negative { |
334 | trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)), | 345 | chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref) |
346 | } else { | ||
347 | chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref) | ||
348 | }, | ||
335 | where_clauses, | 349 | where_clauses, |
336 | associated_ty_values: Vec::new(), // FIXME add associated type values | 350 | associated_ty_values: Vec::new(), // FIXME add associated type values |
337 | impl_type, | 351 | impl_type, |