Make "unneccesary visibility qualifier" error much more clear
This commit is contained in:
parent
cf7ada217c
commit
87b3ae3909
4 changed files with 51 additions and 32 deletions
|
@ -17,9 +17,10 @@ ast_passes_keyword_lifetime =
|
||||||
ast_passes_invalid_label =
|
ast_passes_invalid_label =
|
||||||
invalid label name `{$name}`
|
invalid label name `{$name}`
|
||||||
|
|
||||||
ast_passes_invalid_visibility =
|
ast_passes_visibility_not_permitted =
|
||||||
unnecessary visibility qualifier
|
visibility qualifiers are not permitted here
|
||||||
.implied = `pub` not permitted here because it's implied
|
.enum_variant = enum variants and their fields always share the visibility of the enum they are in
|
||||||
|
.trait_impl = trait items always share the visibility of their trait
|
||||||
.individual_impl_items = place qualifiers on individual impl items instead
|
.individual_impl_items = place qualifiers on individual impl items instead
|
||||||
.individual_foreign_items = place qualifiers on individual foreign items instead
|
.individual_foreign_items = place qualifiers on individual foreign items instead
|
||||||
|
|
||||||
|
|
|
@ -240,16 +240,12 @@ impl<'a> AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invalid_visibility(&self, vis: &Visibility, note: Option<errors::InvalidVisibilityNote>) {
|
fn visibility_not_permitted(&self, vis: &Visibility, note: errors::VisibilityNotPermittedNote) {
|
||||||
if let VisibilityKind::Inherited = vis.kind {
|
if let VisibilityKind::Inherited = vis.kind {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.session.emit_err(errors::InvalidVisibility {
|
self.session.emit_err(errors::VisibilityNotPermitted { span: vis.span, note });
|
||||||
span: vis.span,
|
|
||||||
implied: vis.kind.is_pub().then_some(vis.span),
|
|
||||||
note,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
|
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> {
|
||||||
items,
|
items,
|
||||||
}) => {
|
}) => {
|
||||||
self.with_in_trait_impl(true, Some(*constness), |this| {
|
self.with_in_trait_impl(true, Some(*constness), |this| {
|
||||||
this.invalid_visibility(&item.vis, None);
|
this.visibility_not_permitted(
|
||||||
|
&item.vis,
|
||||||
|
errors::VisibilityNotPermittedNote::TraitImpl,
|
||||||
|
);
|
||||||
if let TyKind::Err = self_ty.kind {
|
if let TyKind::Err = self_ty.kind {
|
||||||
this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span });
|
this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span });
|
||||||
}
|
}
|
||||||
|
@ -866,9 +865,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
only_trait: only_trait.then_some(()),
|
only_trait: only_trait.then_some(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.invalid_visibility(
|
self.visibility_not_permitted(
|
||||||
&item.vis,
|
&item.vis,
|
||||||
Some(errors::InvalidVisibilityNote::IndividualImplItems),
|
errors::VisibilityNotPermittedNote::IndividualImplItems,
|
||||||
);
|
);
|
||||||
if let &Unsafe::Yes(span) = unsafety {
|
if let &Unsafe::Yes(span) = unsafety {
|
||||||
self.err_handler().emit_err(errors::InherentImplCannotUnsafe {
|
self.err_handler().emit_err(errors::InherentImplCannotUnsafe {
|
||||||
|
@ -924,9 +923,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
ItemKind::ForeignMod(ForeignMod { abi, unsafety, .. }) => {
|
ItemKind::ForeignMod(ForeignMod { abi, unsafety, .. }) => {
|
||||||
let old_item = mem::replace(&mut self.extern_mod, Some(item));
|
let old_item = mem::replace(&mut self.extern_mod, Some(item));
|
||||||
self.invalid_visibility(
|
self.visibility_not_permitted(
|
||||||
&item.vis,
|
&item.vis,
|
||||||
Some(errors::InvalidVisibilityNote::IndividualForeignItems),
|
errors::VisibilityNotPermittedNote::IndividualForeignItems,
|
||||||
);
|
);
|
||||||
if let &Unsafe::Yes(span) = unsafety {
|
if let &Unsafe::Yes(span) = unsafety {
|
||||||
self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" });
|
self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" });
|
||||||
|
@ -940,9 +939,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
ItemKind::Enum(def, _) => {
|
ItemKind::Enum(def, _) => {
|
||||||
for variant in &def.variants {
|
for variant in &def.variants {
|
||||||
self.invalid_visibility(&variant.vis, None);
|
self.visibility_not_permitted(
|
||||||
|
&variant.vis,
|
||||||
|
errors::VisibilityNotPermittedNote::EnumVariant,
|
||||||
|
);
|
||||||
for field in variant.data.fields() {
|
for field in variant.data.fields() {
|
||||||
self.invalid_visibility(&field.vis, None);
|
self.visibility_not_permitted(
|
||||||
|
&field.vis,
|
||||||
|
errors::VisibilityNotPermittedNote::EnumVariant,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1303,7 +1308,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
|
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
|
||||||
self.invalid_visibility(&item.vis, None);
|
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
|
||||||
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
|
if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
|
||||||
self.check_trait_fn_not_const(sig.header.constness);
|
self.check_trait_fn_not_const(sig.header.constness);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,18 +42,20 @@ pub struct InvalidLabel {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_invalid_visibility, code = "E0449")]
|
#[diag(ast_passes_visibility_not_permitted, code = "E0449")]
|
||||||
pub struct InvalidVisibility {
|
pub struct VisibilityNotPermitted {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
#[label(ast_passes_implied)]
|
|
||||||
pub implied: Option<Span>,
|
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub note: Option<InvalidVisibilityNote>,
|
pub note: VisibilityNotPermittedNote,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub enum InvalidVisibilityNote {
|
pub enum VisibilityNotPermittedNote {
|
||||||
|
#[note(ast_passes_enum_variant)]
|
||||||
|
EnumVariant,
|
||||||
|
#[note(ast_passes_trait_impl)]
|
||||||
|
TraitImpl,
|
||||||
#[note(ast_passes_individual_impl_items)]
|
#[note(ast_passes_individual_impl_items)]
|
||||||
IndividualImplItems,
|
IndividualImplItems,
|
||||||
#[note(ast_passes_individual_foreign_items)]
|
#[note(ast_passes_individual_foreign_items)]
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
A visibility qualifier was used when it was unnecessary.
|
A visibility qualifier was used where one is not permitted. Visibility
|
||||||
|
qualifiers are not permitted on enum variants, trait items, impl blocks, and
|
||||||
|
extern blocks, as they already share the visibility of the parent item.
|
||||||
|
|
||||||
Erroneous code examples:
|
Erroneous code examples:
|
||||||
|
|
||||||
|
@ -9,15 +11,18 @@ trait Foo {
|
||||||
fn foo();
|
fn foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl Bar {} // error: unnecessary visibility qualifier
|
enum Baz {
|
||||||
|
pub Qux, // error: visibility qualifiers are not permitted here
|
||||||
|
}
|
||||||
|
|
||||||
pub impl Foo for Bar { // error: unnecessary visibility qualifier
|
pub impl Bar {} // error: visibility qualifiers are not permitted here
|
||||||
pub fn foo() {} // error: unnecessary visibility qualifier
|
|
||||||
|
pub impl Foo for Bar { // error: visibility qualifiers are not permitted here
|
||||||
|
pub fn foo() {} // error: visibility qualifiers are not permitted here
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
To fix this error, please remove the visibility qualifier when it is not
|
To fix this error, simply remove the visibility qualifier. Example:
|
||||||
required. Example:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
struct Bar;
|
struct Bar;
|
||||||
|
@ -26,12 +31,18 @@ trait Foo {
|
||||||
fn foo();
|
fn foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Baz {
|
||||||
|
// Enum variants share the visibility of the enum they are in, so
|
||||||
|
// `pub` is not allowed here
|
||||||
|
Qux,
|
||||||
|
}
|
||||||
|
|
||||||
// Directly implemented methods share the visibility of the type itself,
|
// Directly implemented methods share the visibility of the type itself,
|
||||||
// so `pub` is unnecessary here
|
// so `pub` is not allowed here
|
||||||
impl Bar {}
|
impl Bar {}
|
||||||
|
|
||||||
// Trait methods share the visibility of the trait, so `pub` is
|
// Trait methods share the visibility of the trait, so `pub` is not
|
||||||
// unnecessary in either case
|
// allowed in either case
|
||||||
impl Foo for Bar {
|
impl Foo for Bar {
|
||||||
fn foo() {}
|
fn foo() {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue