Auto merge of #79956 - camelid:variant-field-vis, r=petrochenkov
Resolve enum field visibility correctly Fixes #79593. 🎉 Previously, this code treated enum fields' visibility as if they were struct fields. However, that's not correct because the visibility of a struct field with `ast::VisibilityKind::Inherited` is private to the module it's defined in, whereas the visibility of an *enum* field with `ast::VisibilityKind::Inherited` is the visibility of the enum it belongs to.
This commit is contained in:
commit
d149b6579f
@ -258,7 +258,16 @@ fn resolve_visibility_speculative<'ast>(
|
||||
Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)))
|
||||
}
|
||||
ast::VisibilityKind::Inherited => {
|
||||
Ok(ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id))
|
||||
if matches!(self.parent_scope.module.kind, ModuleKind::Def(DefKind::Enum, _, _)) {
|
||||
// Any inherited visibility resolved directly inside an enum
|
||||
// (e.g. variants or fields) inherits from the visibility of the enum.
|
||||
let parent_enum = self.parent_scope.module.def_id().unwrap().expect_local();
|
||||
Ok(self.r.visibilities[&parent_enum])
|
||||
} else {
|
||||
// If it's not in an enum, its visibility is restricted to the `mod` item
|
||||
// that it's defined in.
|
||||
Ok(ty::Visibility::Restricted(self.parent_scope.module.normal_ancestor_id))
|
||||
}
|
||||
}
|
||||
ast::VisibilityKind::Restricted { ref path, id, .. } => {
|
||||
// For visibilities we are not ready to provide correct implementation of "uniform
|
||||
|
@ -403,6 +403,7 @@ enum PathResult<'a> {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ModuleKind {
|
||||
/// An anonymous module; e.g., just a block.
|
||||
///
|
||||
|
@ -1248,7 +1248,7 @@ fn check_expr_struct_fields(
|
||||
if no_accessible_remaining_fields {
|
||||
self.report_no_accessible_fields(adt_ty, span);
|
||||
} else {
|
||||
self.report_missing_field(adt_ty, span, remaining_fields);
|
||||
self.report_missing_fields(adt_ty, span, remaining_fields);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1279,7 +1279,7 @@ fn check_struct_fields_on_error(
|
||||
///
|
||||
/// error: aborting due to previous error
|
||||
/// ```
|
||||
fn report_missing_field(
|
||||
fn report_missing_fields(
|
||||
&self,
|
||||
adt_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
|
29
src/test/ui/issues/issue-79593.rs
Normal file
29
src/test/ui/issues/issue-79593.rs
Normal file
@ -0,0 +1,29 @@
|
||||
mod foo {
|
||||
pub struct Pub { private: () }
|
||||
|
||||
pub enum Enum {
|
||||
Variant { x: (), y: () },
|
||||
Other
|
||||
}
|
||||
|
||||
fn correct() {
|
||||
Pub {};
|
||||
//~^ ERROR missing field `private` in initializer of `Pub`
|
||||
Enum::Variant { x: () };
|
||||
//~^ ERROR missing field `y` in initializer of `Enum`
|
||||
}
|
||||
}
|
||||
|
||||
fn correct() {
|
||||
foo::Pub {};
|
||||
//~^ ERROR cannot construct `Pub` with struct literal syntax due to inaccessible fields
|
||||
}
|
||||
|
||||
fn wrong() {
|
||||
foo::Enum::Variant { x: () };
|
||||
//~^ ERROR missing field `y` in initializer of `Enum`
|
||||
foo::Enum::Variant { };
|
||||
//~^ ERROR missing fields `x`, `y` in initializer of `Enum`
|
||||
}
|
||||
|
||||
fn main() {}
|
33
src/test/ui/issues/issue-79593.stderr
Normal file
33
src/test/ui/issues/issue-79593.stderr
Normal file
@ -0,0 +1,33 @@
|
||||
error[E0063]: missing field `private` in initializer of `Pub`
|
||||
--> $DIR/issue-79593.rs:10:9
|
||||
|
|
||||
LL | Pub {};
|
||||
| ^^^ missing `private`
|
||||
|
||||
error[E0063]: missing field `y` in initializer of `Enum`
|
||||
--> $DIR/issue-79593.rs:12:9
|
||||
|
|
||||
LL | Enum::Variant { x: () };
|
||||
| ^^^^^^^^^^^^^ missing `y`
|
||||
|
||||
error: cannot construct `Pub` with struct literal syntax due to inaccessible fields
|
||||
--> $DIR/issue-79593.rs:18:5
|
||||
|
|
||||
LL | foo::Pub {};
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0063]: missing field `y` in initializer of `Enum`
|
||||
--> $DIR/issue-79593.rs:23:5
|
||||
|
|
||||
LL | foo::Enum::Variant { x: () };
|
||||
| ^^^^^^^^^^^^^^^^^^ missing `y`
|
||||
|
||||
error[E0063]: missing fields `x`, `y` in initializer of `Enum`
|
||||
--> $DIR/issue-79593.rs:25:5
|
||||
|
|
||||
LL | foo::Enum::Variant { };
|
||||
| ^^^^^^^^^^^^^^^^^^ missing `x`, `y`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0063`.
|
Loading…
Reference in New Issue
Block a user