Provide Chalk well-known traits

This commit is contained in:
Florian Diebold 2020-05-22 15:55:15 +02:00 committed by Florian Diebold
parent e81c76a95a
commit 02c2beaa8c
2 changed files with 41 additions and 10 deletions

View 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 @@ impl LangItems {
) 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()
}

View file

@ -9,8 +9,9 @@ use chalk_ir::{
};
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 @@ use crate::{
utils::generics,
ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
};
use chalk_rust_ir::WellKnownTrait;
pub(super) mod tls;
@ -1057,10 +1059,15 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
}
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,