Handle auto traits & negative impls

We don't pass field types to Chalk yet though, so the auto trait inference won't
be correct.
This commit is contained in:
Florian Diebold 2019-05-07 18:53:16 +02:00
parent 7744cd41e2
commit d6dc75f9f2
5 changed files with 48 additions and 8 deletions

View File

@ -703,6 +703,10 @@ impl Trait {
TraitRef::for_trait(db, self)
}
pub fn is_auto(self, db: &impl DefDatabase) -> bool {
self.trait_data(db).is_auto()
}
pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
let r = self.module(db).resolver(db);
// add generic params, if present

View File

@ -93,6 +93,10 @@ impl ImplBlock {
db.impls_in_module(self.module).impls[self.impl_id].items().to_vec()
}
pub fn is_negative(&self, db: &impl DefDatabase) -> bool {
db.impls_in_module(self.module).impls[self.impl_id].negative
}
pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver {
let r = self.module().resolver(db);
// add generic params, if present
@ -108,6 +112,7 @@ pub struct ImplData {
target_trait: Option<TypeRef>,
target_type: TypeRef,
items: Vec<ImplItem>,
negative: bool,
}
impl ImplData {
@ -120,6 +125,7 @@ impl ImplData {
let target_trait = node.target_trait().map(TypeRef::from_ast);
let target_type = TypeRef::from_ast_opt(node.target_type());
let ctx = LocationCtx::new(db, module, file_id);
let negative = node.is_negative();
let items = if let Some(item_list) = node.item_list() {
item_list
.impl_items()
@ -132,7 +138,7 @@ impl ImplData {
} else {
Vec::new()
};
ImplData { target_trait, target_type, items }
ImplData { target_trait, target_type, items, negative }
}
pub fn target_trait(&self) -> Option<&TypeRef> {

View File

@ -11,6 +11,7 @@ use crate::{Function, Const, TypeAlias, Name, DefDatabase, Trait, ids::LocationC
pub struct TraitData {
name: Option<Name>,
items: Vec<TraitItem>,
auto: bool,
}
impl TraitData {
@ -19,6 +20,7 @@ impl TraitData {
let name = node.name().map(|n| n.as_name());
let module = tr.module(db);
let ctx = LocationCtx::new(db, module, file_id);
let auto = node.is_auto();
let items = if let Some(item_list) = node.item_list() {
item_list
.impl_items()
@ -31,7 +33,7 @@ impl TraitData {
} else {
Vec::new()
};
Arc::new(TraitData { name, items })
Arc::new(TraitData { name, items, auto })
}
pub(crate) fn name(&self) -> &Option<Name> {
@ -41,6 +43,10 @@ impl TraitData {
pub(crate) fn items(&self) -> &[TraitItem] {
&self.items
}
pub(crate) fn is_auto(&self) -> bool {
self.auto
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]

View File

@ -12,7 +12,9 @@ use ra_db::salsa::{InternId, InternKey};
use crate::{
Trait, HasGenericParams, ImplBlock,
db::HirDatabase,
ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate}, generics::GenericDef, ty::CallableDef,
ty::{TraitRef, Ty, ApplicationTy, TypeCtor, Substs, GenericPredicate, CallableDef},
ty::display::HirDisplay,
generics::GenericDef,
};
use super::ChalkContext;
@ -232,10 +234,10 @@ where
let bound_vars = Substs::bound_vars(&generic_params);
let trait_ref = trait_.trait_ref(self.db).subst(&bound_vars).to_chalk(self.db);
let flags = chalk_rust_ir::TraitFlags {
// FIXME set these flags correctly
auto: false,
marker: false,
auto: trait_.is_auto(self.db),
upstream: trait_.module(self.db).krate(self.db) != Some(self.krate),
// FIXME set these flags correctly
marker: false,
fundamental: false,
};
let where_clauses = convert_where_clauses(self.db, trait_.into(), &bound_vars);
@ -329,9 +331,21 @@ where
chalk_rust_ir::ImplType::External
};
let where_clauses = convert_where_clauses(self.db, impl_block.into(), &bound_vars);
let negative = impl_block.is_negative(self.db);
debug!(
"impl {:?}: {}{} where {:?}",
impl_id,
if negative { "!" } else { "" },
trait_ref.display(self.db),
where_clauses
);
let trait_ref = trait_ref.to_chalk(self.db);
let impl_datum_bound = chalk_rust_ir::ImplDatumBound {
// FIXME handle negative impls (impl !Sync for Foo)
trait_ref: chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref.to_chalk(self.db)),
trait_ref: if negative {
chalk_rust_ir::PolarizedTraitRef::Negative(trait_ref)
} else {
chalk_rust_ir::PolarizedTraitRef::Positive(trait_ref)
},
where_clauses,
associated_ty_values: Vec::new(), // FIXME add associated type values
impl_type,

View File

@ -170,6 +170,10 @@ impl ast::ImplBlock {
let second = types.next();
(first, second)
}
pub fn is_negative(&self) -> bool {
self.syntax().children_with_tokens().any(|t| t.kind() == EXCL)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
@ -348,3 +352,9 @@ impl ast::WherePred {
.find(|it| it.kind() == LIFETIME)
}
}
impl ast::TraitDef {
pub fn is_auto(&self) -> bool {
self.syntax().children_with_tokens().any(|t| t.kind() == AUTO_KW)
}
}