aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-05-22 14:55:15 +0100
committerFlorian Diebold <[email protected]>2020-05-22 16:32:49 +0100
commit02c2beaa8c54201863ab4713f6f42cd98ae3951c (patch)
treed233663548482248784c032d9af9ec6d9797906d
parente81c76a95ae180e7c5cf2d5af3658cbfc2d8b4ef (diff)
Provide Chalk well-known traits
-rw-r--r--crates/ra_hir_def/src/lang_item.rs12
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs39
2 files changed, 41 insertions, 10 deletions
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index d96ac8c0a..d962db3cc 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -73,8 +73,8 @@ pub struct LangItems {
73} 73}
74 74
75impl LangItems { 75impl LangItems {
76 pub fn target<'a>(&'a self, item: &str) -> Option<&'a LangItemTarget> { 76 pub fn target(&self, item: &str) -> Option<LangItemTarget> {
77 self.items.get(item) 77 self.items.get(item).copied()
78 } 78 }
79 79
80 /// Salsa query. This will look for lang items in a specific crate. 80 /// Salsa query. This will look for lang items in a specific crate.
@@ -163,9 +163,13 @@ impl LangItems {
163 ) where 163 ) where
164 T: Into<AttrDefId> + Copy, 164 T: Into<AttrDefId> + Copy,
165 { 165 {
166 let attrs = db.attrs(item.into()); 166 if let Some(lang_item_name) = lang_attr(db, item) {
167 if let Some(lang_item_name) = attrs.by_key("lang").string_value() {
168 self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item)); 167 self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item));
169 } 168 }
170 } 169 }
171} 170}
171
172pub fn lang_attr(db: &dyn DefDatabase, item: impl Into<AttrDefId> + Copy) -> Option<SmolStr> {
173 let attrs = db.attrs(item.into());
174 attrs.by_key("lang").string_value().cloned()
175}
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index b80b67a7a..7d3ad6eb4 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -9,8 +9,9 @@ use chalk_ir::{
9}; 9};
10 10
11use hir_def::{ 11use hir_def::{
12 type_ref::Mutability, AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, 12 lang_item::{lang_attr, LangItemTarget},
13 TypeAliasId, 13 type_ref::Mutability,
14 AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId,
14}; 15};
15use ra_db::{ 16use ra_db::{
16 salsa::{InternId, InternKey}, 17 salsa::{InternId, InternKey},
@@ -26,6 +27,7 @@ use crate::{
26 utils::generics, 27 utils::generics,
27 ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 28 ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
28}; 29};
30use chalk_rust_ir::WellKnownTrait;
29 31
30pub(super) mod tls; 32pub(super) mod tls;
31 33
@@ -1057,10 +1059,15 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
1057 } 1059 }
1058 fn well_known_trait_id( 1060 fn well_known_trait_id(
1059 &self, 1061 &self,
1060 _well_known_trait: chalk_rust_ir::WellKnownTrait, 1062 well_known_trait: chalk_rust_ir::WellKnownTrait,
1061 ) -> Option<chalk_ir::TraitId<Interner>> { 1063 ) -> Option<chalk_ir::TraitId<Interner>> {
1062 // FIXME tell Chalk about well-known traits (here and in trait_datum) 1064 let lang_attr = lang_attr_from_well_known_trait(well_known_trait);
1063 None 1065 let lang_items = self.db.crate_lang_items(self.krate);
1066 let trait_ = match lang_items.target(lang_attr) {
1067 Some(LangItemTarget::TraitId(trait_)) => trait_,
1068 _ => return None,
1069 };
1070 Some(trait_.to_chalk(self.db))
1064 } 1071 }
1065 1072
1066 fn program_clauses_for_env( 1073 fn program_clauses_for_env(
@@ -1162,7 +1169,8 @@ pub(crate) fn trait_datum_query(
1162 let associated_ty_ids = 1169 let associated_ty_ids =
1163 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect(); 1170 trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
1164 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses }; 1171 let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
1165 let well_known = None; // FIXME set this (depending on lang items) 1172 let well_known =
1173 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
1166 let trait_datum = TraitDatum { 1174 let trait_datum = TraitDatum {
1167 id: trait_id, 1175 id: trait_id,
1168 binders: make_binders(trait_datum_bound, bound_vars.len()), 1176 binders: make_binders(trait_datum_bound, bound_vars.len()),
@@ -1173,6 +1181,25 @@ pub(crate) fn trait_datum_query(
1173 Arc::new(trait_datum) 1181 Arc::new(trait_datum)
1174} 1182}
1175 1183
1184fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {
1185 Some(match name {
1186 "sized" => WellKnownTrait::SizedTrait,
1187 "copy" => WellKnownTrait::CopyTrait,
1188 "clone" => WellKnownTrait::CloneTrait,
1189 "drop" => WellKnownTrait::DropTrait,
1190 _ => return None,
1191 })
1192}
1193
1194fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
1195 match attr {
1196 WellKnownTrait::SizedTrait => "sized",
1197 WellKnownTrait::CopyTrait => "copy",
1198 WellKnownTrait::CloneTrait => "clone",
1199 WellKnownTrait::DropTrait => "drop",
1200 }
1201}
1202
1176pub(crate) fn struct_datum_query( 1203pub(crate) fn struct_datum_query(
1177 db: &dyn HirDatabase, 1204 db: &dyn HirDatabase,
1178 krate: CrateId, 1205 krate: CrateId,