From 93aa166748eef9560df2435391dc3f3b53f8262d Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 24 Jan 2020 19:35:09 +0100 Subject: wip lower impl trait to type args --- crates/ra_hir_def/src/generics.rs | 45 ++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_def/src/generics.rs') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index e9c28c730..7553d8a87 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -27,8 +27,16 @@ use crate::{ /// Data about a generic parameter (to a function, struct, impl, ...). #[derive(Clone, PartialEq, Eq, Debug)] pub struct TypeParamData { - pub name: Name, + pub name: Option, pub default: Option, + pub provenance: TypeParamProvenance, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum TypeParamProvenance { + TypeParamList, + TraitSelf, + ArgumentImplTrait, } /// Data about the generic parameters of a function, struct, impl, etc. @@ -68,6 +76,11 @@ impl GenericParams { GenericDefId::FunctionId(it) => { let src = it.lookup(db).source(db); generics.fill(&mut sm, &src.value); + // lower `impl Trait` in arguments + let data = db.function_data(it); + for param in &data.params { + generics.fill_implicit_impl_trait_args(param); + } src.file_id } GenericDefId::AdtId(AdtId::StructId(it)) => { @@ -89,8 +102,11 @@ impl GenericParams { let src = it.lookup(db).source(db); // traits get the Self type as an implicit first type parameter - let self_param_id = - generics.types.alloc(TypeParamData { name: name![Self], default: None }); + let self_param_id = generics.types.alloc(TypeParamData { + name: Some(name![Self]), + default: None, + provenance: TypeParamProvenance::TraitSelf, + }); sm.insert(self_param_id, Either::Left(src.value.clone())); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar @@ -142,7 +158,11 @@ impl GenericParams { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` let default = type_param.default_type().map(TypeRef::from_ast); - let param = TypeParamData { name: name.clone(), default }; + let param = TypeParamData { + name: Some(name.clone()), + default, + provenance: TypeParamProvenance::TypeParamList, + }; let param_id = self.types.alloc(param); sm.insert(param_id, Either::Right(type_param.clone())); @@ -173,8 +193,23 @@ impl GenericParams { self.where_predicates.push(WherePredicate { type_ref, bound }); } + fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { + type_ref.walk(&mut |type_ref| { + if let TypeRef::ImplTrait(_) = type_ref { + let param = TypeParamData { + name: None, + default: None, + provenance: TypeParamProvenance::ArgumentImplTrait, + }; + let _param_id = self.types.alloc(param); + } + }); + } + pub fn find_by_name(&self, name: &Name) -> Option { - self.types.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) + self.types + .iter() + .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) } } -- cgit v1.2.3 From dbc14f9d570e5bc1ddae05e9ccd8f163082b3cac Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 31 Jan 2020 15:17:48 +0100 Subject: First stab at desugaring bounds for APIT --- crates/ra_hir_def/src/generics.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src/generics.rs') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 7553d8a87..e4e616519 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -53,10 +53,17 @@ pub struct GenericParams { /// associated type bindings like `Iterator`. #[derive(Clone, PartialEq, Eq, Debug)] pub struct WherePredicate { - pub type_ref: TypeRef, + pub target: WherePredicateTarget, pub bound: TypeBound, } +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum WherePredicateTarget { + TypeRef(TypeRef), + /// For desugared where predicates that can directly refer to a type param. + TypeParam(LocalTypeParamId) +} + type SourceMap = ArenaMap>; impl GenericParams { @@ -190,18 +197,24 @@ impl GenericParams { return; } let bound = TypeBound::from_ast(bound); - self.where_predicates.push(WherePredicate { type_ref, bound }); + self.where_predicates.push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); } fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { type_ref.walk(&mut |type_ref| { - if let TypeRef::ImplTrait(_) = type_ref { + if let TypeRef::ImplTrait(bounds) = type_ref { let param = TypeParamData { name: None, default: None, provenance: TypeParamProvenance::ArgumentImplTrait, }; - let _param_id = self.types.alloc(param); + let param_id = self.types.alloc(param); + for bound in bounds { + self.where_predicates.push(WherePredicate { + target: WherePredicateTarget::TypeParam(param_id), + bound: bound.clone() + }); + } } }); } @@ -211,6 +224,12 @@ impl GenericParams { .iter() .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) } + + pub fn find_trait_self_param(&self) -> Option { + self.types + .iter() + .find_map(|(id, p)| if p.provenance == TypeParamProvenance::TraitSelf { Some(id) } else { None }) + } } impl HasChildSource for GenericDefId { -- cgit v1.2.3 From dded90a748737c3661aad043524f2248e324c867 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 7 Feb 2020 15:13:15 +0100 Subject: Formatting --- crates/ra_hir_def/src/generics.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_def/src/generics.rs') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index e4e616519..f765e6edc 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -61,7 +61,7 @@ pub struct WherePredicate { pub enum WherePredicateTarget { TypeRef(TypeRef), /// For desugared where predicates that can directly refer to a type param. - TypeParam(LocalTypeParamId) + TypeParam(LocalTypeParamId), } type SourceMap = ArenaMap>; @@ -197,7 +197,8 @@ impl GenericParams { return; } let bound = TypeBound::from_ast(bound); - self.where_predicates.push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); + self.where_predicates + .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); } fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { @@ -212,7 +213,7 @@ impl GenericParams { for bound in bounds { self.where_predicates.push(WherePredicate { target: WherePredicateTarget::TypeParam(param_id), - bound: bound.clone() + bound: bound.clone(), }); } } @@ -226,9 +227,13 @@ impl GenericParams { } pub fn find_trait_self_param(&self) -> Option { - self.types - .iter() - .find_map(|(id, p)| if p.provenance == TypeParamProvenance::TraitSelf { Some(id) } else { None }) + self.types.iter().find_map(|(id, p)| { + if p.provenance == TypeParamProvenance::TraitSelf { + Some(id) + } else { + None + } + }) } } -- cgit v1.2.3