diff options
-rw-r--r-- | crates/assists/src/handlers/fix_visibility.rs | 10 | ||||
-rw-r--r-- | crates/hir_def/src/adt.rs | 28 | ||||
-rw-r--r-- | crates/ide/src/references.rs | 24 |
3 files changed, 47 insertions, 15 deletions
diff --git a/crates/assists/src/handlers/fix_visibility.rs b/crates/assists/src/handlers/fix_visibility.rs index 7cd76ea06..d505e9444 100644 --- a/crates/assists/src/handlers/fix_visibility.rs +++ b/crates/assists/src/handlers/fix_visibility.rs | |||
@@ -324,14 +324,14 @@ pub struct Foo { pub bar: () } | |||
324 | 324 | ||
325 | #[test] | 325 | #[test] |
326 | fn fix_visibility_of_enum_variant_field() { | 326 | fn fix_visibility_of_enum_variant_field() { |
327 | check_assist( | 327 | // Enum variants, as well as their fields, always get the enum's visibility. In fact, rustc |
328 | // rejects any visibility specifiers on them, so this assist should never fire on them. | ||
329 | check_assist_not_applicable( | ||
328 | fix_visibility, | 330 | fix_visibility, |
329 | r"mod foo { pub enum Foo { Bar { bar: () } } } | 331 | r"mod foo { pub enum Foo { Bar { bar: () } } } |
330 | fn main() { foo::Foo::Bar { <|>bar: () }; } ", | 332 | fn main() { foo::Foo::Bar { <|>bar: () }; } ", |
331 | r"mod foo { pub enum Foo { Bar { $0pub(crate) bar: () } } } | ||
332 | fn main() { foo::Foo::Bar { bar: () }; } ", | ||
333 | ); | 333 | ); |
334 | check_assist( | 334 | check_assist_not_applicable( |
335 | fix_visibility, | 335 | fix_visibility, |
336 | r" | 336 | r" |
337 | //- /lib.rs | 337 | //- /lib.rs |
@@ -340,8 +340,6 @@ fn main() { foo::Foo::Bar { <|>bar: () }; } | |||
340 | //- /foo.rs | 340 | //- /foo.rs |
341 | pub enum Foo { Bar { bar: () } } | 341 | pub enum Foo { Bar { bar: () } } |
342 | ", | 342 | ", |
343 | r"pub enum Foo { Bar { $0pub(crate) bar: () } } | ||
344 | ", | ||
345 | ); | 343 | ); |
346 | check_assist_not_applicable( | 344 | check_assist_not_applicable( |
347 | fix_visibility, | 345 | fix_visibility, |
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}; | |||
14 | use crate::{ | 14 | use 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 | ||
299 | fn lower_fields(item_tree: &ItemTree, cfg_options: &CfgOptions, fields: &Fields) -> VariantData { | 300 | fn 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 | ||
323 | fn lower_field(item_tree: &ItemTree, field: &Field) -> FieldData { | 329 | fn 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 | } |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 571dd5452..9315f7354 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -732,6 +732,30 @@ fn f(e: En) { | |||
732 | ); | 732 | ); |
733 | } | 733 | } |
734 | 734 | ||
735 | #[test] | ||
736 | fn test_find_all_refs_enum_var_privacy() { | ||
737 | check( | ||
738 | r#" | ||
739 | mod m { | ||
740 | pub enum En { | ||
741 | Variant { | ||
742 | field<|>: u8, | ||
743 | } | ||
744 | } | ||
745 | } | ||
746 | |||
747 | fn f() -> m::En { | ||
748 | m::En::Variant { field: 0 } | ||
749 | } | ||
750 | "#, | ||
751 | expect![[r#" | ||
752 | field RECORD_FIELD FileId(0) 56..65 56..61 Other | ||
753 | |||
754 | FileId(0) 125..130 Other Read | ||
755 | "#]], | ||
756 | ); | ||
757 | } | ||
758 | |||
735 | fn check(ra_fixture: &str, expect: Expect) { | 759 | fn check(ra_fixture: &str, expect: Expect) { |
736 | check_with_scope(ra_fixture, None, expect) | 760 | check_with_scope(ra_fixture, None, expect) |
737 | } | 761 | } |