More trait infrastructure

- make it possible to get parent trait from method
 - add 'obligation' machinery for checking that a type implements a
   trait (and inferring facts about type variables from that)
 - handle type parameters of traits (to a certain degree)
 - improve the hacky implements check to cover enough cases to exercise the
   handling of traits with type parameters
 - basic canonicalization (will probably also be done by Chalk)
This commit is contained in:
Florian Diebold 2019-03-31 20:02:16 +02:00
parent 413c87f155
commit a1ed53a4f1
11 changed files with 333 additions and 51 deletions

View file

@ -45,12 +45,16 @@ impl GenericParams {
) -> Arc<GenericParams> {
let mut generics = GenericParams::default();
let parent = match def {
GenericDef::Function(it) => it.impl_block(db),
GenericDef::TypeAlias(it) => it.impl_block(db),
// FIXME abstract over containers (trait/impl)
GenericDef::Function(it) => it
.impl_block(db)
.map(GenericDef::from)
.or_else(|| it.parent_trait(db).map(GenericDef::from)),
GenericDef::TypeAlias(it) => it.impl_block(db).map(GenericDef::from),
GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None,
GenericDef::ImplBlock(_) => None,
};
generics.parent_params = parent.map(|p| p.generic_params(db));
generics.parent_params = parent.map(|p| db.generic_params(p));
let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
match def {
GenericDef::Function(it) => generics.fill(&*it.source(db).1, start),