diff options
-rw-r--r-- | crates/ra_hir_def/src/lang_item.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 39 |
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 | ||
75 | impl LangItems { | 75 | impl 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 | |||
172 | pub 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 | ||
11 | use hir_def::{ | 11 | use 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 | }; |
15 | use ra_db::{ | 16 | use 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 | }; |
30 | use chalk_rust_ir::WellKnownTrait; | ||
29 | 31 | ||
30 | pub(super) mod tls; | 32 | pub(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 | ||
1184 | fn 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 | |||
1194 | fn 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 | |||
1176 | pub(crate) fn struct_datum_query( | 1203 | pub(crate) fn struct_datum_query( |
1177 | db: &dyn HirDatabase, | 1204 | db: &dyn HirDatabase, |
1178 | krate: CrateId, | 1205 | krate: CrateId, |