aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-06-17 11:24:05 +0100
committerJonas Schievink <[email protected]>2020-06-24 15:53:16 +0100
commitc12f7b610be49901190cde994dfe4f594150dbf9 (patch)
treedcbcf0f72f8fb23601f415fb390561dff94ffb9a /crates
parent864b650f92388f4e82d130713b2de9afe637102f (diff)
Lower generics
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_def/src/generics.rs13
-rw-r--r--crates/ra_hir_def/src/item_tree.rs16
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs80
3 files changed, 83 insertions, 26 deletions
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 09a5241f7..ed4f60c66 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -42,7 +42,7 @@ pub enum TypeParamProvenance {
42} 42}
43 43
44/// Data about the generic parameters of a function, struct, impl, etc. 44/// Data about the generic parameters of a function, struct, impl, etc.
45#[derive(Clone, PartialEq, Eq, Debug)] 45#[derive(Clone, PartialEq, Eq, Debug, Default)]
46pub struct GenericParams { 46pub struct GenericParams {
47 pub types: Arena<TypeParamData>, 47 pub types: Arena<TypeParamData>,
48 // lifetimes: Arena<LocalLifetimeParamId, LifetimeParamData>, 48 // lifetimes: Arena<LocalLifetimeParamId, LifetimeParamData>,
@@ -156,7 +156,12 @@ impl GenericParams {
156 (generics, InFile::new(file_id, sm)) 156 (generics, InFile::new(file_id, sm))
157 } 157 }
158 158
159 fn fill(&mut self, lower_ctx: &LowerCtx, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { 159 pub(crate) fn fill(
160 &mut self,
161 lower_ctx: &LowerCtx,
162 sm: &mut SourceMap,
163 node: &dyn TypeParamsOwner,
164 ) {
160 if let Some(params) = node.type_param_list() { 165 if let Some(params) = node.type_param_list() {
161 self.fill_params(lower_ctx, sm, params) 166 self.fill_params(lower_ctx, sm, params)
162 } 167 }
@@ -165,7 +170,7 @@ impl GenericParams {
165 } 170 }
166 } 171 }
167 172
168 fn fill_bounds( 173 pub(crate) fn fill_bounds(
169 &mut self, 174 &mut self,
170 lower_ctx: &LowerCtx, 175 lower_ctx: &LowerCtx,
171 node: &dyn ast::TypeBoundsOwner, 176 node: &dyn ast::TypeBoundsOwner,
@@ -229,7 +234,7 @@ impl GenericParams {
229 .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); 234 .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound });
230 } 235 }
231 236
232 fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { 237 pub(crate) fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) {
233 type_ref.walk(&mut |type_ref| { 238 type_ref.walk(&mut |type_ref| {
234 if let TypeRef::ImplTrait(bounds) = type_ref { 239 if let TypeRef::ImplTrait(bounds) = type_ref {
235 let param = TypeParamData { 240 let param = TypeParamData {
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs
index 9656f845e..c3990c2eb 100644
--- a/crates/ra_hir_def/src/item_tree.rs
+++ b/crates/ra_hir_def/src/item_tree.rs
@@ -26,7 +26,7 @@ use test_utils::mark;
26use crate::{ 26use crate::{
27 attr::Attrs, 27 attr::Attrs,
28 db::DefDatabase, 28 db::DefDatabase,
29 generics, 29 generics::GenericParams,
30 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path}, 30 path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path},
31 type_ref::{Mutability, TypeBound, TypeRef}, 31 type_ref::{Mutability, TypeBound, TypeRef},
32 visibility::RawVisibility, 32 visibility::RawVisibility,
@@ -230,7 +230,7 @@ pub struct Function {
230 pub name: Name, 230 pub name: Name,
231 pub attrs: Attrs, 231 pub attrs: Attrs,
232 pub visibility: RawVisibility, 232 pub visibility: RawVisibility,
233 pub generic_params: generics::GenericParams, 233 pub generic_params: GenericParams,
234 pub has_self_param: bool, 234 pub has_self_param: bool,
235 pub params: Vec<TypeRef>, 235 pub params: Vec<TypeRef>,
236 pub ret_type: TypeRef, 236 pub ret_type: TypeRef,
@@ -243,7 +243,7 @@ pub struct Struct {
243 pub name: Name, 243 pub name: Name,
244 pub attrs: Attrs, 244 pub attrs: Attrs,
245 pub visibility: RawVisibility, 245 pub visibility: RawVisibility,
246 pub generic_params: generics::GenericParams, 246 pub generic_params: GenericParams,
247 pub fields: Fields, 247 pub fields: Fields,
248 pub ast_id: FileAstId<ast::StructDef>, 248 pub ast_id: FileAstId<ast::StructDef>,
249 pub kind: StructDefKind, 249 pub kind: StructDefKind,
@@ -264,7 +264,7 @@ pub struct Union {
264 pub name: Name, 264 pub name: Name,
265 pub attrs: Attrs, 265 pub attrs: Attrs,
266 pub visibility: RawVisibility, 266 pub visibility: RawVisibility,
267 pub generic_params: generics::GenericParams, 267 pub generic_params: GenericParams,
268 pub fields: Fields, 268 pub fields: Fields,
269 pub ast_id: FileAstId<ast::UnionDef>, 269 pub ast_id: FileAstId<ast::UnionDef>,
270} 270}
@@ -274,7 +274,7 @@ pub struct Enum {
274 pub name: Name, 274 pub name: Name,
275 pub attrs: Attrs, 275 pub attrs: Attrs,
276 pub visibility: RawVisibility, 276 pub visibility: RawVisibility,
277 pub generic_params: generics::GenericParams, 277 pub generic_params: GenericParams,
278 pub variants: Range<Idx<Variant>>, 278 pub variants: Range<Idx<Variant>>,
279 pub ast_id: FileAstId<ast::EnumDef>, 279 pub ast_id: FileAstId<ast::EnumDef>,
280} 280}
@@ -300,7 +300,7 @@ pub struct Static {
300pub struct Trait { 300pub struct Trait {
301 pub name: Name, 301 pub name: Name,
302 pub visibility: RawVisibility, 302 pub visibility: RawVisibility,
303 pub generic_params: generics::GenericParams, 303 pub generic_params: GenericParams,
304 pub auto: bool, 304 pub auto: bool,
305 pub items: Vec<AssocItem>, 305 pub items: Vec<AssocItem>,
306 pub ast_id: FileAstId<ast::TraitDef>, 306 pub ast_id: FileAstId<ast::TraitDef>,
@@ -308,7 +308,7 @@ pub struct Trait {
308 308
309#[derive(Debug, Eq, PartialEq)] 309#[derive(Debug, Eq, PartialEq)]
310pub struct Impl { 310pub struct Impl {
311 pub generic_params: generics::GenericParams, 311 pub generic_params: GenericParams,
312 pub target_trait: Option<TypeRef>, 312 pub target_trait: Option<TypeRef>,
313 pub target_type: TypeRef, 313 pub target_type: TypeRef,
314 pub is_negative: bool, 314 pub is_negative: bool,
@@ -320,7 +320,7 @@ pub struct Impl {
320pub struct TypeAlias { 320pub struct TypeAlias {
321 pub name: Name, 321 pub name: Name,
322 pub visibility: RawVisibility, 322 pub visibility: RawVisibility,
323 pub generic_params: generics::GenericParams, 323 pub generic_params: GenericParams,
324 pub type_ref: Option<TypeRef>, 324 pub type_ref: Option<TypeRef>,
325 pub ast_id: FileAstId<ast::TypeAliasDef>, 325 pub ast_id: FileAstId<ast::TypeAliasDef>,
326} 326}
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs
index 0c9454848..737a69c30 100644
--- a/crates/ra_hir_def/src/item_tree/lower.rs
+++ b/crates/ra_hir_def/src/item_tree/lower.rs
@@ -1,6 +1,12 @@
1//! AST -> `ItemTree` lowering code.
2
1use super::*; 3use super::*;
2use crate::attr::Attrs; 4use crate::{
5 attr::Attrs,
6 generics::{GenericParams, TypeParamData, TypeParamProvenance},
7};
3use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, HirFileId}; 8use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, HirFileId};
9use ra_arena::map::ArenaMap;
4use ra_syntax::ast::{self, ModuleItemOwner}; 10use ra_syntax::ast::{self, ModuleItemOwner};
5use smallvec::SmallVec; 11use smallvec::SmallVec;
6use std::sync::Arc; 12use std::sync::Arc;
@@ -123,7 +129,7 @@ impl Ctx {
123 let attrs = self.lower_attrs(strukt); 129 let attrs = self.lower_attrs(strukt);
124 let visibility = self.lower_visibility(strukt); 130 let visibility = self.lower_visibility(strukt);
125 let name = strukt.name()?.as_name(); 131 let name = strukt.name()?.as_name();
126 let generic_params = self.lower_generic_params(strukt); 132 let generic_params = self.lower_generic_params(GenericsOwner::Struct, strukt);
127 let fields = self.lower_fields(&strukt.kind()); 133 let fields = self.lower_fields(&strukt.kind());
128 let ast_id = self.source_ast_id_map.ast_id(strukt); 134 let ast_id = self.source_ast_id_map.ast_id(strukt);
129 let kind = match strukt.kind() { 135 let kind = match strukt.kind() {
@@ -191,7 +197,7 @@ impl Ctx {
191 let attrs = self.lower_attrs(union); 197 let attrs = self.lower_attrs(union);
192 let visibility = self.lower_visibility(union); 198 let visibility = self.lower_visibility(union);
193 let name = union.name()?.as_name(); 199 let name = union.name()?.as_name();
194 let generic_params = self.lower_generic_params(union); 200 let generic_params = self.lower_generic_params(GenericsOwner::Union, union);
195 let fields = match union.record_field_def_list() { 201 let fields = match union.record_field_def_list() {
196 Some(record_field_def_list) => { 202 Some(record_field_def_list) => {
197 self.lower_fields(&StructKind::Record(record_field_def_list)) 203 self.lower_fields(&StructKind::Record(record_field_def_list))
@@ -207,7 +213,7 @@ impl Ctx {
207 let attrs = self.lower_attrs(enum_); 213 let attrs = self.lower_attrs(enum_);
208 let visibility = self.lower_visibility(enum_); 214 let visibility = self.lower_visibility(enum_);
209 let name = enum_.name()?.as_name(); 215 let name = enum_.name()?.as_name();
210 let generic_params = self.lower_generic_params(enum_); 216 let generic_params = self.lower_generic_params(GenericsOwner::Enum, enum_);
211 let variants = match &enum_.variant_list() { 217 let variants = match &enum_.variant_list() {
212 Some(variant_list) => self.lower_variants(variant_list), 218 Some(variant_list) => self.lower_variants(variant_list),
213 None => self.next_variant_idx()..self.next_variant_idx(), 219 None => self.next_variant_idx()..self.next_variant_idx(),
@@ -239,7 +245,6 @@ impl Ctx {
239 let attrs = self.lower_attrs(func); 245 let attrs = self.lower_attrs(func);
240 let visibility = self.lower_visibility(func); 246 let visibility = self.lower_visibility(func);
241 let name = func.name()?.as_name(); 247 let name = func.name()?.as_name();
242 let generic_params = self.lower_generic_params(func);
243 248
244 let mut params = Vec::new(); 249 let mut params = Vec::new();
245 let mut has_self_param = false; 250 let mut has_self_param = false;
@@ -281,16 +286,17 @@ impl Ctx {
281 }; 286 };
282 287
283 let ast_id = self.source_ast_id_map.ast_id(func); 288 let ast_id = self.source_ast_id_map.ast_id(func);
284 let res = Function { 289 let mut res = Function {
285 name, 290 name,
286 attrs, 291 attrs,
287 visibility, 292 visibility,
288 generic_params, 293 generic_params: GenericParams::default(),
289 has_self_param, 294 has_self_param,
290 params, 295 params,
291 ret_type, 296 ret_type,
292 ast_id, 297 ast_id,
293 }; 298 };
299 res.generic_params = self.lower_generic_params(GenericsOwner::Function(&res), func);
294 Some(res) 300 Some(res)
295 } 301 }
296 302
@@ -298,7 +304,7 @@ impl Ctx {
298 let name = type_alias.name()?.as_name(); 304 let name = type_alias.name()?.as_name();
299 let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it)); 305 let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it));
300 let visibility = self.lower_visibility(type_alias); 306 let visibility = self.lower_visibility(type_alias);
301 let generic_params = self.lower_generic_params(type_alias); 307 let generic_params = self.lower_generic_params(GenericsOwner::TypeAlias, type_alias);
302 let ast_id = self.source_ast_id_map.ast_id(type_alias); 308 let ast_id = self.source_ast_id_map.ast_id(type_alias);
303 let res = TypeAlias { name, visibility, generic_params, type_ref, ast_id }; 309 let res = TypeAlias { name, visibility, generic_params, type_ref, ast_id };
304 Some(res) 310 Some(res)
@@ -349,7 +355,7 @@ impl Ctx {
349 fn lower_trait(&mut self, trait_def: &ast::TraitDef) -> Option<Trait> { 355 fn lower_trait(&mut self, trait_def: &ast::TraitDef) -> Option<Trait> {
350 let name = trait_def.name()?.as_name(); 356 let name = trait_def.name()?.as_name();
351 let visibility = self.lower_visibility(trait_def); 357 let visibility = self.lower_visibility(trait_def);
352 let generic_params = self.lower_generic_params(trait_def); 358 let generic_params = self.lower_generic_params(GenericsOwner::Trait(trait_def), trait_def);
353 let auto = trait_def.auto_token().is_some(); 359 let auto = trait_def.auto_token().is_some();
354 let items = trait_def.item_list().map(|list| { 360 let items = trait_def.item_list().map(|list| {
355 // FIXME: Does not handle macros 361 // FIXME: Does not handle macros
@@ -367,7 +373,7 @@ impl Ctx {
367 } 373 }
368 374
369 fn lower_impl(&mut self, impl_def: &ast::ImplDef) -> Option<Impl> { 375 fn lower_impl(&mut self, impl_def: &ast::ImplDef) -> Option<Impl> {
370 let generic_params = self.lower_generic_params(impl_def); 376 let generic_params = self.lower_generic_params(GenericsOwner::Impl, impl_def);
371 let target_trait = impl_def.target_trait().map(|tr| self.lower_type_ref(&tr)); 377 let target_trait = impl_def.target_trait().map(|tr| self.lower_type_ref(&tr));
372 let target_type = self.lower_type_ref(&impl_def.target_type()?); 378 let target_type = self.lower_type_ref(&impl_def.target_type()?);
373 let is_negative = impl_def.excl_token().is_some(); 379 let is_negative = impl_def.excl_token().is_some();
@@ -465,10 +471,43 @@ impl Ctx {
465 471
466 fn lower_generic_params( 472 fn lower_generic_params(
467 &mut self, 473 &mut self,
468 _item: &impl ast::TypeParamsOwner, 474 owner: GenericsOwner<'_>,
469 ) -> generics::GenericParams { 475 node: &impl ast::TypeParamsOwner,
470 // TODO 476 ) -> GenericParams {
471 generics::GenericParams { types: Arena::new(), where_predicates: Vec::new() } 477 let mut sm = &mut ArenaMap::default();
478 let mut generics = GenericParams::default();
479 match owner {
480 GenericsOwner::Function(func) => {
481 generics.fill(&self.body_ctx, sm, node);
482 // lower `impl Trait` in arguments
483 for param in &func.params {
484 generics.fill_implicit_impl_trait_args(param);
485 }
486 }
487 GenericsOwner::Struct
488 | GenericsOwner::Enum
489 | GenericsOwner::Union
490 | GenericsOwner::TypeAlias => {
491 generics.fill(&self.body_ctx, sm, node);
492 }
493 GenericsOwner::Trait(trait_def) => {
494 // traits get the Self type as an implicit first type parameter
495 let self_param_id = generics.types.alloc(TypeParamData {
496 name: Some(name![Self]),
497 default: None,
498 provenance: TypeParamProvenance::TraitSelf,
499 });
500 sm.insert(self_param_id, Either::Left(trait_def.clone()));
501 // add super traits as bounds on Self
502 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
503 let self_param = TypeRef::Path(name![Self].into());
504 generics.fill_bounds(&self.body_ctx, trait_def, self_param);
505
506 generics.fill(&self.body_ctx, &mut sm, node);
507 }
508 GenericsOwner::Impl => {}
509 }
510 generics
472 } 511 }
473 512
474 fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { 513 fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
@@ -503,3 +542,16 @@ fn desugar_future_path(orig: TypeRef) -> Path {
503 542
504 Path::from_known_path(path, generic_args) 543 Path::from_known_path(path, generic_args)
505} 544}
545
546enum GenericsOwner<'a> {
547 /// We need access to the partially-lowered `Function` for lowering `impl Trait` in argument
548 /// position.
549 Function(&'a Function),
550 Struct,
551 Enum,
552 Union,
553 /// The `TraitDef` is needed to fill the source map for the implicit `Self` parameter.
554 Trait(&'a ast::TraitDef),
555 TypeAlias,
556 Impl,
557}