aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-10-09 19:42:17 +0100
committerJonas Schievink <[email protected]>2020-10-09 19:46:45 +0100
commit5dcbf03d0f114cab1ae1748dd3c3632a52f6f52d (patch)
treeadfcfe50433188eec4febbfe80fe432bcc32234f /crates/hir_def
parentcde189c5d5d77afd077b067a887bbc7e3adb4f80 (diff)
adt: correctly inherit field visibility from enum
Previously, "find all references" on a variant field wouldn't find any references outside the defining module. This is because variant fields were incorrectly assumed to be private, like struct fields without explicit visibility, but they actually inherit the enum's visibility.
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/adt.rs28
1 files changed, 19 insertions, 9 deletions
diff --git a/crates/hir_def/src/adt.rs b/crates/hir_def/src/adt.rs
index d69ff2fc7..6539959c3 100644
--- a/crates/hir_def/src/adt.rs
+++ b/crates/hir_def/src/adt.rs
@@ -14,7 +14,7 @@ use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree};
14use crate::{ 14use crate::{
15 body::{CfgExpander, LowerCtx}, 15 body::{CfgExpander, LowerCtx},
16 db::DefDatabase, 16 db::DefDatabase,
17 item_tree::{AttrOwner, Field, Fields, ItemTree, ModItem}, 17 item_tree::{AttrOwner, Field, Fields, ItemTree, ModItem, RawVisibilityId},
18 src::HasChildSource, 18 src::HasChildSource,
19 src::HasSource, 19 src::HasSource,
20 trace::Trace, 20 trace::Trace,
@@ -91,7 +91,7 @@ impl StructData {
91 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 91 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
92 92
93 let strukt = &item_tree[loc.id.value]; 93 let strukt = &item_tree[loc.id.value];
94 let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields); 94 let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields, None);
95 Arc::new(StructData { 95 Arc::new(StructData {
96 name: strukt.name.clone(), 96 name: strukt.name.clone(),
97 variant_data: Arc::new(variant_data), 97 variant_data: Arc::new(variant_data),
@@ -105,7 +105,7 @@ impl StructData {
105 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 105 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
106 106
107 let union = &item_tree[loc.id.value]; 107 let union = &item_tree[loc.id.value];
108 let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields); 108 let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields, None);
109 109
110 Arc::new(StructData { 110 Arc::new(StructData {
111 name: union.name.clone(), 111 name: union.name.clone(),
@@ -126,7 +126,8 @@ impl EnumData {
126 for var_id in enum_.variants.clone() { 126 for var_id in enum_.variants.clone() {
127 if item_tree.attrs(var_id.into()).is_cfg_enabled(&cfg_options) { 127 if item_tree.attrs(var_id.into()).is_cfg_enabled(&cfg_options) {
128 let var = &item_tree[var_id]; 128 let var = &item_tree[var_id];
129 let var_data = lower_fields(&item_tree, &cfg_options, &var.fields); 129 let var_data =
130 lower_fields(&item_tree, &cfg_options, &var.fields, Some(enum_.visibility));
130 131
131 variants.alloc(EnumVariantData { 132 variants.alloc(EnumVariantData {
132 name: var.name.clone(), 133 name: var.name.clone(),
@@ -296,13 +297,18 @@ fn lower_struct(
296 } 297 }
297} 298}
298 299
299fn lower_fields(item_tree: &ItemTree, cfg_options: &CfgOptions, fields: &Fields) -> VariantData { 300fn lower_fields(
301 item_tree: &ItemTree,
302 cfg_options: &CfgOptions,
303 fields: &Fields,
304 override_visibility: Option<RawVisibilityId>,
305) -> VariantData {
300 match fields { 306 match fields {
301 Fields::Record(flds) => { 307 Fields::Record(flds) => {
302 let mut arena = Arena::new(); 308 let mut arena = Arena::new();
303 for field_id in flds.clone() { 309 for field_id in flds.clone() {
304 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { 310 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) {
305 arena.alloc(lower_field(item_tree, &item_tree[field_id])); 311 arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
306 } 312 }
307 } 313 }
308 VariantData::Record(arena) 314 VariantData::Record(arena)
@@ -311,7 +317,7 @@ fn lower_fields(item_tree: &ItemTree, cfg_options: &CfgOptions, fields: &Fields)
311 let mut arena = Arena::new(); 317 let mut arena = Arena::new();
312 for field_id in flds.clone() { 318 for field_id in flds.clone() {
313 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { 319 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) {
314 arena.alloc(lower_field(item_tree, &item_tree[field_id])); 320 arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
315 } 321 }
316 } 322 }
317 VariantData::Tuple(arena) 323 VariantData::Tuple(arena)
@@ -320,10 +326,14 @@ fn lower_fields(item_tree: &ItemTree, cfg_options: &CfgOptions, fields: &Fields)
320 } 326 }
321} 327}
322 328
323fn lower_field(item_tree: &ItemTree, field: &Field) -> FieldData { 329fn lower_field(
330 item_tree: &ItemTree,
331 field: &Field,
332 override_visibility: Option<RawVisibilityId>,
333) -> FieldData {
324 FieldData { 334 FieldData {
325 name: field.name.clone(), 335 name: field.name.clone(),
326 type_ref: field.type_ref.clone(), 336 type_ref: field.type_ref.clone(),
327 visibility: item_tree[field.visibility].clone(), 337 visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(),
328 } 338 }
329} 339}