aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/item_tree
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/item_tree')
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs80
1 files changed, 66 insertions, 14 deletions
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}