]> git.lizzy.rs Git - rust.git/commitdiff
Provide Chalk well-known traits
authorFlorian Diebold <flodiebold@gmail.com>
Fri, 22 May 2020 13:55:15 +0000 (15:55 +0200)
committerFlorian Diebold <florian.diebold@freiheit.com>
Fri, 22 May 2020 15:32:49 +0000 (17:32 +0200)
crates/ra_hir_def/src/lang_item.rs
crates/ra_hir_ty/src/traits/chalk.rs

index d96ac8c0ae1c4cda46f2174d859334f456cf1124..d962db3cc7923ad656ba75055709ce79bdc77c5d 100644 (file)
@@ -73,8 +73,8 @@ pub struct LangItems {
 }
 
 impl LangItems {
-    pub fn target<'a>(&'a self, item: &str) -> Option<&'a LangItemTarget> {
-        self.items.get(item)
+    pub fn target(&self, item: &str) -> Option<LangItemTarget> {
+        self.items.get(item).copied()
     }
 
     /// Salsa query. This will look for lang items in a specific crate.
@@ -163,9 +163,13 @@ fn collect_lang_item<T>(
     ) where
         T: Into<AttrDefId> + Copy,
     {
-        let attrs = db.attrs(item.into());
-        if let Some(lang_item_name) = attrs.by_key("lang").string_value() {
+        if let Some(lang_item_name) = lang_attr(db, item) {
             self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item));
         }
     }
 }
+
+pub fn lang_attr(db: &dyn DefDatabase, item: impl Into<AttrDefId> + Copy) -> Option<SmolStr> {
+    let attrs = db.attrs(item.into());
+    attrs.by_key("lang").string_value().cloned()
+}
index b80b67a7a1413b1dbd6df1bcc999fbd953e0d371..7d3ad6eb4d0c360d39abfe013e8f09576ee85287 100644 (file)
@@ -9,8 +9,9 @@
 };
 
 use hir_def::{
-    type_ref::Mutability, AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup,
-    TypeAliasId,
+    lang_item::{lang_attr, LangItemTarget},
+    type_ref::Mutability,
+    AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId,
 };
 use ra_db::{
     salsa::{InternId, InternKey},
@@ -26,6 +27,7 @@
     utils::generics,
     ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
 };
+use chalk_rust_ir::WellKnownTrait;
 
 pub(super) mod tls;
 
@@ -1057,10 +1059,15 @@ fn interner(&self) -> &Interner {
     }
     fn well_known_trait_id(
         &self,
-        _well_known_trait: chalk_rust_ir::WellKnownTrait,
+        well_known_trait: chalk_rust_ir::WellKnownTrait,
     ) -> Option<chalk_ir::TraitId<Interner>> {
-        // FIXME tell Chalk about well-known traits (here and in trait_datum)
-        None
+        let lang_attr = lang_attr_from_well_known_trait(well_known_trait);
+        let lang_items = self.db.crate_lang_items(self.krate);
+        let trait_ = match lang_items.target(lang_attr) {
+            Some(LangItemTarget::TraitId(trait_)) => trait_,
+            _ => return None,
+        };
+        Some(trait_.to_chalk(self.db))
     }
 
     fn program_clauses_for_env(
@@ -1162,7 +1169,8 @@ pub(crate) fn trait_datum_query(
     let associated_ty_ids =
         trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
     let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
-    let well_known = None; // FIXME set this (depending on lang items)
+    let well_known =
+        lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
     let trait_datum = TraitDatum {
         id: trait_id,
         binders: make_binders(trait_datum_bound, bound_vars.len()),
@@ -1173,6 +1181,25 @@ pub(crate) fn trait_datum_query(
     Arc::new(trait_datum)
 }
 
+fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {
+    Some(match name {
+        "sized" => WellKnownTrait::SizedTrait,
+        "copy" => WellKnownTrait::CopyTrait,
+        "clone" => WellKnownTrait::CloneTrait,
+        "drop" => WellKnownTrait::DropTrait,
+        _ => return None,
+    })
+}
+
+fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
+    match attr {
+        WellKnownTrait::SizedTrait => "sized",
+        WellKnownTrait::CopyTrait => "copy",
+        WellKnownTrait::CloneTrait => "clone",
+        WellKnownTrait::DropTrait => "drop",
+    }
+}
+
 pub(crate) fn struct_datum_query(
     db: &dyn HirDatabase,
     krate: CrateId,