aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/item_tree/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/item_tree/lower.rs')
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs51
1 files changed, 42 insertions, 9 deletions
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs
index f2b8a9418..42af8bb5e 100644
--- a/crates/ra_hir_def/src/item_tree/lower.rs
+++ b/crates/ra_hir_def/src/item_tree/lower.rs
@@ -36,6 +36,7 @@ pub(super) struct Ctx {
36 source_ast_id_map: Arc<AstIdMap>, 36 source_ast_id_map: Arc<AstIdMap>,
37 body_ctx: crate::body::LowerCtx, 37 body_ctx: crate::body::LowerCtx,
38 inner_items: Vec<ModItem>, 38 inner_items: Vec<ModItem>,
39 forced_visibility: Option<RawVisibility>,
39} 40}
40 41
41impl Ctx { 42impl Ctx {
@@ -47,6 +48,7 @@ impl Ctx {
47 source_ast_id_map: db.ast_id_map(file), 48 source_ast_id_map: db.ast_id_map(file),
48 body_ctx: crate::body::LowerCtx::new(db, file), 49 body_ctx: crate::body::LowerCtx::new(db, file),
49 inner_items: Vec::new(), 50 inner_items: Vec::new(),
51 forced_visibility: None,
50 } 52 }
51 } 53 }
52 54
@@ -117,6 +119,7 @@ impl Ctx {
117 } 119 }
118 120
119 fn collect_inner_items(&mut self, container: &SyntaxNode) { 121 fn collect_inner_items(&mut self, container: &SyntaxNode) {
122 let forced_vis = self.forced_visibility.take();
120 let mut inner_items = mem::replace(&mut self.tree.inner_items, FxHashMap::default()); 123 let mut inner_items = mem::replace(&mut self.tree.inner_items, FxHashMap::default());
121 inner_items.extend( 124 inner_items.extend(
122 container.descendants().skip(1).filter_map(ast::ModuleItem::cast).filter_map(|item| { 125 container.descendants().skip(1).filter_map(ast::ModuleItem::cast).filter_map(|item| {
@@ -125,6 +128,7 @@ impl Ctx {
125 }), 128 }),
126 ); 129 );
127 self.tree.inner_items = inner_items; 130 self.tree.inner_items = inner_items;
131 self.forced_visibility = forced_vis;
128 } 132 }
129 133
130 fn lower_assoc_item(&mut self, item: &ast::ModuleItem) -> Option<AssocItem> { 134 fn lower_assoc_item(&mut self, item: &ast::ModuleItem) -> Option<AssocItem> {
@@ -304,6 +308,7 @@ impl Ctx {
304 visibility, 308 visibility,
305 generic_params: GenericParams::default(), 309 generic_params: GenericParams::default(),
306 has_self_param, 310 has_self_param,
311 is_unsafe: func.unsafe_token().is_some(),
307 params, 312 params,
308 ret_type, 313 ret_type,
309 ast_id, 314 ast_id,
@@ -320,9 +325,10 @@ impl Ctx {
320 let name = type_alias.name()?.as_name(); 325 let name = type_alias.name()?.as_name();
321 let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it)); 326 let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it));
322 let visibility = self.lower_visibility(type_alias); 327 let visibility = self.lower_visibility(type_alias);
328 let bounds = self.lower_type_bounds(type_alias);
323 let generic_params = self.lower_generic_params(GenericsOwner::TypeAlias, type_alias); 329 let generic_params = self.lower_generic_params(GenericsOwner::TypeAlias, type_alias);
324 let ast_id = self.source_ast_id_map.ast_id(type_alias); 330 let ast_id = self.source_ast_id_map.ast_id(type_alias);
325 let res = TypeAlias { name, visibility, generic_params, type_ref, ast_id }; 331 let res = TypeAlias { name, visibility, bounds, generic_params, type_ref, ast_id };
326 Some(id(self.tree.type_aliases.alloc(res))) 332 Some(id(self.tree.type_aliases.alloc(res)))
327 } 333 }
328 334
@@ -330,8 +336,9 @@ impl Ctx {
330 let name = static_.name()?.as_name(); 336 let name = static_.name()?.as_name();
331 let type_ref = self.lower_type_ref_opt(static_.ascribed_type()); 337 let type_ref = self.lower_type_ref_opt(static_.ascribed_type());
332 let visibility = self.lower_visibility(static_); 338 let visibility = self.lower_visibility(static_);
339 let mutable = static_.mut_token().is_some();
333 let ast_id = self.source_ast_id_map.ast_id(static_); 340 let ast_id = self.source_ast_id_map.ast_id(static_);
334 let res = Static { name, visibility, type_ref, ast_id }; 341 let res = Static { name, visibility, mutable, type_ref, ast_id };
335 Some(id(self.tree.statics.alloc(res))) 342 Some(id(self.tree.statics.alloc(res)))
336 } 343 }
337 344
@@ -376,12 +383,14 @@ impl Ctx {
376 let generic_params = self.lower_generic_params(GenericsOwner::Trait(trait_def), trait_def); 383 let generic_params = self.lower_generic_params(GenericsOwner::Trait(trait_def), trait_def);
377 let auto = trait_def.auto_token().is_some(); 384 let auto = trait_def.auto_token().is_some();
378 let items = trait_def.item_list().map(|list| { 385 let items = trait_def.item_list().map(|list| {
379 list.items() 386 self.with_inherited_visibility(visibility.clone(), |this| {
380 .flat_map(|item| { 387 list.items()
381 self.collect_inner_items(item.syntax()); 388 .flat_map(|item| {
382 self.lower_assoc_item(&item) 389 this.collect_inner_items(item.syntax());
383 }) 390 this.lower_assoc_item(&item)
384 .collect() 391 })
392 .collect()
393 })
385 }); 394 });
386 let ast_id = self.source_ast_id_map.ast_id(trait_def); 395 let ast_id = self.source_ast_id_map.ast_id(trait_def);
387 let res = Trait { 396 let res = Trait {
@@ -549,11 +558,23 @@ impl Ctx {
549 generics 558 generics
550 } 559 }
551 560
561 fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec<TypeBound> {
562 if let Some(bound_list) = node.type_bound_list() {
563 bound_list.bounds().map(|it| TypeBound::from_ast(&self.body_ctx, it)).collect()
564 } else {
565 Vec::new()
566 }
567 }
568
552 fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { 569 fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
553 Attrs::new(item, &self.hygiene) 570 Attrs::new(item, &self.hygiene)
554 } 571 }
555 fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility { 572 fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility {
556 RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene) 573 if let Some(vis) = self.forced_visibility.as_ref() {
574 vis.clone()
575 } else {
576 RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene)
577 }
557 } 578 }
558 fn lower_type_ref(&self, type_ref: &ast::TypeRef) -> TypeRef { 579 fn lower_type_ref(&self, type_ref: &ast::TypeRef) -> TypeRef {
559 TypeRef::from_ast(&self.body_ctx, type_ref.clone()) 580 TypeRef::from_ast(&self.body_ctx, type_ref.clone())
@@ -562,6 +583,18 @@ impl Ctx {
562 TypeRef::from_ast_opt(&self.body_ctx, type_ref) 583 TypeRef::from_ast_opt(&self.body_ctx, type_ref)
563 } 584 }
564 585
586 /// Forces the visibility `vis` to be used for all items lowered during execution of `f`.
587 fn with_inherited_visibility<R>(
588 &mut self,
589 vis: RawVisibility,
590 f: impl FnOnce(&mut Self) -> R,
591 ) -> R {
592 let old = mem::replace(&mut self.forced_visibility, Some(vis));
593 let res = f(self);
594 self.forced_visibility = old;
595 res
596 }
597
565 fn next_field_idx(&self) -> Idx<Field> { 598 fn next_field_idx(&self) -> Idx<Field> {
566 Idx::from_raw(RawId::from(self.tree.fields.len() as u32)) 599 Idx::from_raw(RawId::from(self.tree.fields.len() as u32))
567 } 600 }