Skip to content

Commit 87b3ae3

Browse files
committed
Make "unneccesary visibility qualifier" error much more clear
1 parent cf7ada2 commit 87b3ae3

File tree

4 files changed

+51
-32
lines changed

4 files changed

+51
-32
lines changed

compiler/rustc_ast_passes/messages.ftl

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ ast_passes_keyword_lifetime =
1717
ast_passes_invalid_label =
1818
invalid label name `{$name}`
1919
20-
ast_passes_invalid_visibility =
21-
unnecessary visibility qualifier
22-
.implied = `pub` not permitted here because it's implied
20+
ast_passes_visibility_not_permitted =
21+
visibility qualifiers are not permitted here
22+
.enum_variant = enum variants and their fields always share the visibility of the enum they are in
23+
.trait_impl = trait items always share the visibility of their trait
2324
.individual_impl_items = place qualifiers on individual impl items instead
2425
.individual_foreign_items = place qualifiers on individual foreign items instead
2526

compiler/rustc_ast_passes/src/ast_validation.rs

+19-14
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,12 @@ impl<'a> AstValidator<'a> {
240240
}
241241
}
242242

243-
fn invalid_visibility(&self, vis: &Visibility, note: Option<errors::InvalidVisibilityNote>) {
243+
fn visibility_not_permitted(&self, vis: &Visibility, note: errors::VisibilityNotPermittedNote) {
244244
if let VisibilityKind::Inherited = vis.kind {
245245
return;
246246
}
247247

248-
self.session.emit_err(errors::InvalidVisibility {
249-
span: vis.span,
250-
implied: vis.kind.is_pub().then_some(vis.span),
251-
note,
252-
});
248+
self.session.emit_err(errors::VisibilityNotPermitted { span: vis.span, note });
253249
}
254250

255251
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
@@ -819,7 +815,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
819815
items,
820816
}) => {
821817
self.with_in_trait_impl(true, Some(*constness), |this| {
822-
this.invalid_visibility(&item.vis, None);
818+
this.visibility_not_permitted(
819+
&item.vis,
820+
errors::VisibilityNotPermittedNote::TraitImpl,
821+
);
823822
if let TyKind::Err = self_ty.kind {
824823
this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span });
825824
}
@@ -866,9 +865,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
866865
only_trait: only_trait.then_some(()),
867866
};
868867

869-
self.invalid_visibility(
868+
self.visibility_not_permitted(
870869
&item.vis,
871-
Some(errors::InvalidVisibilityNote::IndividualImplItems),
870+
errors::VisibilityNotPermittedNote::IndividualImplItems,
872871
);
873872
if let &Unsafe::Yes(span) = unsafety {
874873
self.err_handler().emit_err(errors::InherentImplCannotUnsafe {
@@ -924,9 +923,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
924923
}
925924
ItemKind::ForeignMod(ForeignMod { abi, unsafety, .. }) => {
926925
let old_item = mem::replace(&mut self.extern_mod, Some(item));
927-
self.invalid_visibility(
926+
self.visibility_not_permitted(
928927
&item.vis,
929-
Some(errors::InvalidVisibilityNote::IndividualForeignItems),
928+
errors::VisibilityNotPermittedNote::IndividualForeignItems,
930929
);
931930
if let &Unsafe::Yes(span) = unsafety {
932931
self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" });
@@ -940,9 +939,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
940939
}
941940
ItemKind::Enum(def, _) => {
942941
for variant in &def.variants {
943-
self.invalid_visibility(&variant.vis, None);
942+
self.visibility_not_permitted(
943+
&variant.vis,
944+
errors::VisibilityNotPermittedNote::EnumVariant,
945+
);
944946
for field in variant.data.fields() {
945-
self.invalid_visibility(&field.vis, None);
947+
self.visibility_not_permitted(
948+
&field.vis,
949+
errors::VisibilityNotPermittedNote::EnumVariant,
950+
);
946951
}
947952
}
948953
}
@@ -1303,7 +1308,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13031308
}
13041309

13051310
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
1306-
self.invalid_visibility(&item.vis, None);
1311+
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
13071312
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
13081313
self.check_trait_fn_not_const(sig.header.constness);
13091314
}

compiler/rustc_ast_passes/src/errors.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,20 @@ pub struct InvalidLabel {
4242
}
4343

4444
#[derive(Diagnostic)]
45-
#[diag(ast_passes_invalid_visibility, code = "E0449")]
46-
pub struct InvalidVisibility {
45+
#[diag(ast_passes_visibility_not_permitted, code = "E0449")]
46+
pub struct VisibilityNotPermitted {
4747
#[primary_span]
4848
pub span: Span,
49-
#[label(ast_passes_implied)]
50-
pub implied: Option<Span>,
5149
#[subdiagnostic]
52-
pub note: Option<InvalidVisibilityNote>,
50+
pub note: VisibilityNotPermittedNote,
5351
}
5452

5553
#[derive(Subdiagnostic)]
56-
pub enum InvalidVisibilityNote {
54+
pub enum VisibilityNotPermittedNote {
55+
#[note(ast_passes_enum_variant)]
56+
EnumVariant,
57+
#[note(ast_passes_trait_impl)]
58+
TraitImpl,
5759
#[note(ast_passes_individual_impl_items)]
5860
IndividualImplItems,
5961
#[note(ast_passes_individual_foreign_items)]

compiler/rustc_error_codes/src/error_codes/E0449.md

+20-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
A visibility qualifier was used when it was unnecessary.
1+
A visibility qualifier was used where one is not permitted. Visibility
2+
qualifiers are not permitted on enum variants, trait items, impl blocks, and
3+
extern blocks, as they already share the visibility of the parent item.
24

35
Erroneous code examples:
46

@@ -9,15 +11,18 @@ trait Foo {
911
fn foo();
1012
}
1113
12-
pub impl Bar {} // error: unnecessary visibility qualifier
14+
enum Baz {
15+
pub Qux, // error: visibility qualifiers are not permitted here
16+
}
17+
18+
pub impl Bar {} // error: visibility qualifiers are not permitted here
1319
14-
pub impl Foo for Bar { // error: unnecessary visibility qualifier
15-
pub fn foo() {} // error: unnecessary visibility qualifier
20+
pub impl Foo for Bar { // error: visibility qualifiers are not permitted here
21+
pub fn foo() {} // error: visibility qualifiers are not permitted here
1622
}
1723
```
1824

19-
To fix this error, please remove the visibility qualifier when it is not
20-
required. Example:
25+
To fix this error, simply remove the visibility qualifier. Example:
2126

2227
```
2328
struct Bar;
@@ -26,12 +31,18 @@ trait Foo {
2631
fn foo();
2732
}
2833
34+
enum Baz {
35+
// Enum variants share the visibility of the enum they are in, so
36+
// `pub` is not allowed here
37+
Qux,
38+
}
39+
2940
// Directly implemented methods share the visibility of the type itself,
30-
// so `pub` is unnecessary here
41+
// so `pub` is not allowed here
3142
impl Bar {}
3243
33-
// Trait methods share the visibility of the trait, so `pub` is
34-
// unnecessary in either case
44+
// Trait methods share the visibility of the trait, so `pub` is not
45+
// allowed in either case
3546
impl Foo for Bar {
3647
fn foo() {}
3748
}

0 commit comments

Comments
 (0)