aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-05-07 17:53:16 +0100
committerFlorian Diebold <[email protected]>2019-05-11 15:21:20 +0100
commitd6dc75f9f22b73faf8c526be69ca43e52d6db1bf (patch)
treef17b35ab78b5dc123e55a69f065dc47d08ef3ff8 /crates/ra_hir
parent7744cd41e2ad79c1b36d3d9fccd3bc0dbfd9e2d9 (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.rs4
-rw-r--r--crates/ra_hir/src/impl_block.rs8
-rw-r--r--crates/ra_hir/src/traits.rs8
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs24
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
113impl ImplData { 118impl 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
11pub struct TraitData { 11pub 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
16impl TraitData { 17impl 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};
12use crate::{ 12use 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};
17use super::ChalkContext; 19use 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,