From 02c2beaa8c54201863ab4713f6f42cd98ae3951c Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 22 May 2020 15:55:15 +0200 Subject: [PATCH] Provide Chalk well-known traits --- crates/ra_hir_def/src/lang_item.rs | 12 ++++++--- 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 d96ac8c0ae1..d962db3cc79 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 { } impl LangItems { - pub fn target<'a>(&'a self, item: &str) -> Option<&'a LangItemTarget> { - self.items.get(item) + pub fn target(&self, item: &str) -> Option { + 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( ) where T: Into + 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 + Copy) -> Option { + let attrs = db.attrs(item.into()); + attrs.by_key("lang").string_value().cloned() +} diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index b80b67a7a14..7d3ad6eb4d0 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -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> { - // 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 { + 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, -- 2.44.0