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:
parent
7744cd41e2
commit
d6dc75f9f2
@ -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
|
||||
|
@ -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> {
|
||||
|
@ -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)]
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user