mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 09:44:08 +00:00
syntactically allow visibility on trait item & enum variant
This commit is contained in:
parent
e2fa9527d4
commit
9a88364525
@ -1187,26 +1187,6 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Recovers from `pub` keyword in places where it seems _reasonable_ but isn't valid.
|
||||
pub(super) fn eat_bad_pub(&mut self) {
|
||||
// When `unclosed_delims` is populated, it means that the code being parsed is already
|
||||
// quite malformed, which might mean that, for example, a pub struct definition could be
|
||||
// parsed as being a trait item, which is invalid and this error would trigger
|
||||
// unconditionally, resulting in misleading diagnostics. Because of this, we only attempt
|
||||
// this nice to have recovery for code that is otherwise well formed.
|
||||
if self.token.is_keyword(kw::Pub) && self.unclosed_delims.is_empty() {
|
||||
match self.parse_visibility(false) {
|
||||
Ok(vis) => {
|
||||
self.diagnostic()
|
||||
.struct_span_err(vis.span, "unnecessary visibility qualifier")
|
||||
.span_label(vis.span, "`pub` not permitted here")
|
||||
.emit();
|
||||
}
|
||||
Err(mut err) => err.emit(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Eats tokens until we can be relatively sure we reached the end of the
|
||||
/// statement. This is something of a best-effort heuristic.
|
||||
///
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{Parser, PathStyle};
|
||||
use super::{Parser, PathStyle, FollowedByType};
|
||||
use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim};
|
||||
|
||||
use crate::maybe_whole;
|
||||
@ -93,7 +93,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let lo = self.token.span;
|
||||
|
||||
let vis = self.parse_visibility(false)?;
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
|
||||
if self.eat_keyword(kw::Use) {
|
||||
// USE ITEM
|
||||
@ -706,7 +706,7 @@ impl<'a> Parser<'a> {
|
||||
mut attrs: Vec<Attribute>,
|
||||
) -> PResult<'a, ImplItem> {
|
||||
let lo = self.token.span;
|
||||
let vis = self.parse_visibility(false)?;
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
let defaultness = self.parse_defaultness();
|
||||
let (name, kind, generics) = if let Some(type_) = self.eat_type() {
|
||||
let (name, alias, generics) = type_?;
|
||||
@ -896,7 +896,7 @@ impl<'a> Parser<'a> {
|
||||
mut attrs: Vec<Attribute>,
|
||||
) -> PResult<'a, TraitItem> {
|
||||
let lo = self.token.span;
|
||||
self.eat_bad_pub();
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
let (name, kind, generics) = if self.eat_keyword(kw::Type) {
|
||||
self.parse_trait_item_assoc_ty()?
|
||||
} else if self.is_const_item() {
|
||||
@ -912,6 +912,7 @@ impl<'a> Parser<'a> {
|
||||
id: DUMMY_NODE_ID,
|
||||
ident: name,
|
||||
attrs,
|
||||
vis,
|
||||
generics,
|
||||
kind,
|
||||
span: lo.to(self.prev_span),
|
||||
@ -1142,7 +1143,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let lo = self.token.span;
|
||||
let visibility = self.parse_visibility(false)?;
|
||||
let visibility = self.parse_visibility(FollowedByType::No)?;
|
||||
|
||||
// FOREIGN STATIC ITEM
|
||||
// Treat `const` as `static` for error recovery, but don't add it to expected tokens.
|
||||
@ -1370,7 +1371,7 @@ impl<'a> Parser<'a> {
|
||||
let variant_attrs = self.parse_outer_attributes()?;
|
||||
let vlo = self.token.span;
|
||||
|
||||
self.eat_bad_pub();
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
let ident = self.parse_ident()?;
|
||||
|
||||
let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
|
||||
@ -1397,6 +1398,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let vr = ast::Variant {
|
||||
ident,
|
||||
vis,
|
||||
id: DUMMY_NODE_ID,
|
||||
attrs: variant_attrs,
|
||||
data: struct_def,
|
||||
@ -1550,7 +1552,7 @@ impl<'a> Parser<'a> {
|
||||
self.parse_paren_comma_seq(|p| {
|
||||
let attrs = p.parse_outer_attributes()?;
|
||||
let lo = p.token.span;
|
||||
let vis = p.parse_visibility(true)?;
|
||||
let vis = p.parse_visibility(FollowedByType::Yes)?;
|
||||
let ty = p.parse_ty()?;
|
||||
Ok(StructField {
|
||||
span: lo.to(ty.span),
|
||||
@ -1568,7 +1570,7 @@ impl<'a> Parser<'a> {
|
||||
fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
let lo = self.token.span;
|
||||
let vis = self.parse_visibility(false)?;
|
||||
let vis = self.parse_visibility(FollowedByType::No)?;
|
||||
self.parse_single_struct_field(lo, vis, attrs)
|
||||
}
|
||||
|
||||
|
@ -346,6 +346,8 @@ impl SeqSep {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum FollowedByType { Yes, No }
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
pub fn new(
|
||||
sess: &'a ParseSess,
|
||||
@ -1116,7 +1118,7 @@ impl<'a> Parser<'a> {
|
||||
/// If the following element can't be a tuple (i.e., it's a function definition), then
|
||||
/// it's not a tuple struct field), and the contents within the parentheses isn't valid,
|
||||
/// so emit a proper diagnostic.
|
||||
pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> {
|
||||
pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
|
||||
maybe_whole!(self, NtVis, |x| x);
|
||||
|
||||
self.expected_tokens.push(TokenType::Keyword(kw::Crate));
|
||||
@ -1171,7 +1173,9 @@ impl<'a> Parser<'a> {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
};
|
||||
return Ok(respan(lo.to(self.prev_span), vis));
|
||||
} else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct.
|
||||
} else if let FollowedByType::No = fbt {
|
||||
// Provide this diagnostic if a type cannot follow;
|
||||
// in particular, if this is not a tuple struct.
|
||||
self.recover_incorrect_vis_restriction()?;
|
||||
// Emit diagnostic, but continue with public visibility.
|
||||
}
|
||||
|
@ -524,6 +524,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
ItemKind::Enum(ref def, _) => {
|
||||
for variant in &def.variants {
|
||||
self.invalid_visibility(&variant.vis, None);
|
||||
for field in variant.data.fields() {
|
||||
self.invalid_visibility(&field.vis, None);
|
||||
}
|
||||
@ -754,6 +755,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
visit::walk_impl_item(self, ii);
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &'a TraitItem) {
|
||||
self.invalid_visibility(&ti.vis, None);
|
||||
visit::walk_trait_item(self, ti);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffer) -> bool {
|
||||
|
@ -961,12 +961,12 @@ pub struct Arm {
|
||||
/// Access of a named (e.g., `obj.foo`) or unnamed (e.g., `obj.0`) struct field.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Field {
|
||||
pub ident: Ident,
|
||||
pub expr: P<Expr>,
|
||||
pub span: Span,
|
||||
pub is_shorthand: bool,
|
||||
pub attrs: ThinVec<Attribute>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub ident: Ident,
|
||||
pub expr: P<Expr>,
|
||||
pub is_shorthand: bool,
|
||||
pub is_placeholder: bool,
|
||||
}
|
||||
|
||||
@ -1515,12 +1515,14 @@ pub struct FnSig {
|
||||
/// signature) or provided (meaning it has a default implementation).
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct TraitItem {
|
||||
pub id: NodeId,
|
||||
pub ident: Ident,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub ident: Ident,
|
||||
|
||||
pub generics: Generics,
|
||||
pub kind: TraitItemKind,
|
||||
pub span: Span,
|
||||
/// See `Item::tokens` for what this is.
|
||||
pub tokens: Option<TokenStream>,
|
||||
}
|
||||
@ -1536,14 +1538,15 @@ pub enum TraitItemKind {
|
||||
/// Represents anything within an `impl` block.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct ImplItem {
|
||||
pub id: NodeId,
|
||||
pub ident: Ident,
|
||||
pub vis: Visibility,
|
||||
pub defaultness: Defaultness,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub ident: Ident,
|
||||
|
||||
pub defaultness: Defaultness,
|
||||
pub generics: Generics,
|
||||
pub kind: ImplItemKind,
|
||||
pub span: Span,
|
||||
/// See `Item::tokens` for what this is.
|
||||
pub tokens: Option<TokenStream>,
|
||||
}
|
||||
@ -2101,22 +2104,24 @@ pub struct GlobalAsm {
|
||||
pub struct EnumDef {
|
||||
pub variants: Vec<Variant>,
|
||||
}
|
||||
|
||||
/// Enum variant.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Variant {
|
||||
/// Name of the variant.
|
||||
pub ident: Ident,
|
||||
/// Attributes of the variant.
|
||||
pub attrs: Vec<Attribute>,
|
||||
/// Id of the variant (not the constructor, see `VariantData::ctor_id()`).
|
||||
pub id: NodeId,
|
||||
/// Span
|
||||
pub span: Span,
|
||||
/// The visibility of the variant. Syntactically accepted but not semantically.
|
||||
pub vis: Visibility,
|
||||
/// Name of the variant.
|
||||
pub ident: Ident,
|
||||
|
||||
/// Fields and constructor id of the variant.
|
||||
pub data: VariantData,
|
||||
/// Explicit discriminant, e.g., `Foo = 1`.
|
||||
pub disr_expr: Option<AnonConst>,
|
||||
/// Span
|
||||
pub span: Span,
|
||||
/// Is a macro placeholder
|
||||
pub is_placeholder: bool,
|
||||
}
|
||||
@ -2295,12 +2300,13 @@ impl VisibilityKind {
|
||||
/// E.g., `bar: usize` as in `struct Foo { bar: usize }`.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct StructField {
|
||||
pub span: Span,
|
||||
pub ident: Option<Ident>,
|
||||
pub vis: Visibility,
|
||||
pub id: NodeId,
|
||||
pub ty: P<Ty>,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub ident: Option<Ident>,
|
||||
|
||||
pub ty: P<Ty>,
|
||||
pub is_placeholder: bool,
|
||||
}
|
||||
|
||||
@ -2344,12 +2350,13 @@ impl VariantData {
|
||||
/// The name might be a dummy name in case of anonymous items.
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Item {
|
||||
pub ident: Ident,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub id: NodeId,
|
||||
pub kind: ItemKind,
|
||||
pub vis: Visibility,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub ident: Ident,
|
||||
|
||||
pub kind: ItemKind,
|
||||
|
||||
/// Original tokens this item was parsed from. This isn't necessarily
|
||||
/// available for all items, although over time more and more items should
|
||||
@ -2518,12 +2525,13 @@ impl ItemKind {
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct ForeignItem {
|
||||
pub ident: Ident,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub kind: ForeignItemKind,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
pub ident: Ident,
|
||||
|
||||
pub kind: ForeignItemKind,
|
||||
}
|
||||
|
||||
/// An item within an `extern` block.
|
||||
|
@ -472,16 +472,17 @@ pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis:
|
||||
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
|
||||
}
|
||||
|
||||
pub fn noop_flat_map_variant<T: MutVisitor>(mut variant: Variant, vis: &mut T)
|
||||
pub fn noop_flat_map_variant<T: MutVisitor>(mut variant: Variant, visitor: &mut T)
|
||||
-> SmallVec<[Variant; 1]>
|
||||
{
|
||||
let Variant { ident, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
|
||||
vis.visit_ident(ident);
|
||||
visit_attrs(attrs, vis);
|
||||
vis.visit_id(id);
|
||||
vis.visit_variant_data(data);
|
||||
visit_opt(disr_expr, |disr_expr| vis.visit_anon_const(disr_expr));
|
||||
vis.visit_span(span);
|
||||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
|
||||
visitor.visit_ident(ident);
|
||||
visitor.visit_vis(vis);
|
||||
visit_attrs(attrs, visitor);
|
||||
visitor.visit_id(id);
|
||||
visitor.visit_variant_data(data);
|
||||
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
|
||||
visitor.visit_span(span);
|
||||
smallvec![variant]
|
||||
}
|
||||
|
||||
@ -920,32 +921,33 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_flat_map_trait_item<T: MutVisitor>(mut item: TraitItem, vis: &mut T)
|
||||
pub fn noop_flat_map_trait_item<T: MutVisitor>(mut item: TraitItem, visitor: &mut T)
|
||||
-> SmallVec<[TraitItem; 1]>
|
||||
{
|
||||
let TraitItem { id, ident, attrs, generics, kind, span, tokens: _ } = &mut item;
|
||||
vis.visit_id(id);
|
||||
vis.visit_ident(ident);
|
||||
visit_attrs(attrs, vis);
|
||||
vis.visit_generics(generics);
|
||||
let TraitItem { id, ident, vis, attrs, generics, kind, span, tokens: _ } = &mut item;
|
||||
visitor.visit_id(id);
|
||||
visitor.visit_ident(ident);
|
||||
visitor.visit_vis(vis);
|
||||
visit_attrs(attrs, visitor);
|
||||
visitor.visit_generics(generics);
|
||||
match kind {
|
||||
TraitItemKind::Const(ty, default) => {
|
||||
vis.visit_ty(ty);
|
||||
visit_opt(default, |default| vis.visit_expr(default));
|
||||
visitor.visit_ty(ty);
|
||||
visit_opt(default, |default| visitor.visit_expr(default));
|
||||
}
|
||||
TraitItemKind::Method(sig, body) => {
|
||||
visit_fn_sig(sig, vis);
|
||||
visit_opt(body, |body| vis.visit_block(body));
|
||||
visit_fn_sig(sig, visitor);
|
||||
visit_opt(body, |body| visitor.visit_block(body));
|
||||
}
|
||||
TraitItemKind::Type(bounds, default) => {
|
||||
visit_bounds(bounds, vis);
|
||||
visit_opt(default, |default| vis.visit_ty(default));
|
||||
visit_bounds(bounds, visitor);
|
||||
visit_opt(default, |default| visitor.visit_ty(default));
|
||||
}
|
||||
TraitItemKind::Macro(mac) => {
|
||||
vis.visit_mac(mac);
|
||||
visitor.visit_mac(mac);
|
||||
}
|
||||
}
|
||||
vis.visit_span(span);
|
||||
visitor.visit_span(span);
|
||||
|
||||
smallvec![item]
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ fn test_variant_to_string() {
|
||||
|
||||
let var = ast::Variant {
|
||||
ident,
|
||||
vis: source_map::respan(syntax_pos::DUMMY_SP, ast::VisibilityKind::Inherited),
|
||||
attrs: Vec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
data: ast::VariantData::Unit(ast::DUMMY_NODE_ID),
|
||||
|
@ -314,6 +314,7 @@ pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant)
|
||||
where V: Visitor<'a>,
|
||||
{
|
||||
visitor.visit_ident(variant.ident);
|
||||
visitor.visit_vis(&variant.vis);
|
||||
visitor.visit_variant_data(&variant.data);
|
||||
walk_list!(visitor, visit_anon_const, &variant.disr_expr);
|
||||
walk_list!(visitor, visit_attribute, &variant.attrs);
|
||||
@ -585,6 +586,7 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl
|
||||
}
|
||||
|
||||
pub fn walk_trait_item<'a, V: Visitor<'a>>(visitor: &mut V, trait_item: &'a TraitItem) {
|
||||
visitor.visit_vis(&trait_item.vis);
|
||||
visitor.visit_ident(trait_item.ident);
|
||||
walk_list!(visitor, visit_attribute, &trait_item.attrs);
|
||||
visitor.visit_generics(&trait_item.generics);
|
||||
|
@ -582,12 +582,13 @@ impl<'a> ExtCtxt<'a> {
|
||||
}
|
||||
|
||||
pub fn variant(&self, span: Span, ident: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
|
||||
let vis_span = span.shrink_to_lo();
|
||||
let fields: Vec<_> = tys.into_iter().map(|ty| {
|
||||
ast::StructField {
|
||||
span: ty.span,
|
||||
ty,
|
||||
ident: None,
|
||||
vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
|
||||
vis: respan(vis_span, ast::VisibilityKind::Inherited),
|
||||
attrs: Vec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
is_placeholder: false,
|
||||
@ -606,6 +607,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
disr_expr: None,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident,
|
||||
vis: respan(vis_span, ast::VisibilityKind::Inherited),
|
||||
span,
|
||||
is_placeholder: false,
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ use TokenTreeOrTokenTreeSlice::*;
|
||||
use crate::mbe::{self, TokenTree};
|
||||
|
||||
use rustc_parse::Directory;
|
||||
use rustc_parse::parser::{Parser, PathStyle};
|
||||
use rustc_parse::parser::{Parser, PathStyle, FollowedByType};
|
||||
use syntax::ast::{Ident, Name};
|
||||
use syntax::print::pprust;
|
||||
use syntax::sess::ParseSess;
|
||||
@ -933,7 +933,7 @@ fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a,
|
||||
}
|
||||
sym::path => token::NtPath(p.parse_path(PathStyle::Type)?),
|
||||
sym::meta => token::NtMeta(p.parse_attr_item()?),
|
||||
sym::vis => token::NtVis(p.parse_visibility(true)?),
|
||||
sym::vis => token::NtVis(p.parse_visibility(FollowedByType::Yes)?),
|
||||
sym::lifetime => if p.check_lifetime() {
|
||||
token::NtLifetime(p.expect_lifetime().ident)
|
||||
} else {
|
||||
|
@ -53,7 +53,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment {
|
||||
tokens: None,
|
||||
})]),
|
||||
AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![ast::TraitItem {
|
||||
id, span, ident, attrs, generics,
|
||||
id, span, ident, vis, attrs, generics,
|
||||
kind: ast::TraitItemKind::Macro(mac_placeholder()),
|
||||
tokens: None,
|
||||
}]),
|
||||
@ -150,6 +150,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment {
|
||||
id,
|
||||
ident,
|
||||
span,
|
||||
vis,
|
||||
is_placeholder: true,
|
||||
}
|
||||
])
|
||||
|
@ -1 +1 @@
|
||||
{"module":{"inner":{"lo":0,"hi":0},"items":[{"ident":{"name":"core","span":{"lo":0,"hi":0}},"attrs":[],"id":0,"kind":{"variant":"ExternCrate","fields":[null]},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"span":{"lo":0,"hi":0},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}}
|
||||
{"module":{"inner":{"lo":0,"hi":0},"items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}}
|
||||
|
@ -1,14 +1,15 @@
|
||||
error: unnecessary visibility qualifier
|
||||
error[E0449]: unnecessary visibility qualifier
|
||||
--> $DIR/issue-28433.rs:2:5
|
||||
|
|
||||
LL | pub Duck,
|
||||
| ^^^ `pub` not permitted here
|
||||
| ^^^ `pub` not permitted here because it's implied
|
||||
|
||||
error: unnecessary visibility qualifier
|
||||
error[E0449]: unnecessary visibility qualifier
|
||||
--> $DIR/issue-28433.rs:5:5
|
||||
|
|
||||
LL | pub(crate) Dove
|
||||
| ^^^^^^^^^^ `pub` not permitted here
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0449`.
|
||||
|
@ -4,7 +4,7 @@ trait T {
|
||||
fn qux() -> Option<usize> {
|
||||
let _ = if true {
|
||||
});
|
||||
//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
|
||||
//~^ ERROR expected one of `async`
|
||||
//~| ERROR expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
|
||||
//~| ERROR expected identifier, found `;`
|
||||
Some(4)
|
||||
|
@ -4,7 +4,7 @@ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
|
||||
LL | });
|
||||
| ^ expected one of `.`, `;`, `?`, `else`, or an operator
|
||||
|
||||
error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
|
||||
error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `;`
|
||||
--> $DIR/issue-60075.rs:6:11
|
||||
|
|
||||
LL | fn qux() -> Option<usize> {
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `...`
|
||||
error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `...`
|
||||
--> $DIR/issue-32446.rs:4:11
|
||||
|
|
||||
LL | trait T { ... }
|
||||
| ^^^ expected one of 7 possible tokens
|
||||
| ^^^ expected one of 9 possible tokens
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
28
src/test/ui/parser/issue-65041-empty-vis-matcher-in-enum.rs
Normal file
28
src/test/ui/parser/issue-65041-empty-vis-matcher-in-enum.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// check-pass
|
||||
|
||||
// Here we check that a `:vis` macro matcher subsititued for the empty visibility
|
||||
// (`VisibilityKind::Inherited`) is accepted when used before an enum variant.
|
||||
|
||||
fn main() {}
|
||||
|
||||
macro_rules! mac_variant {
|
||||
($vis:vis MARKER) => {
|
||||
enum Enum {
|
||||
$vis Unit,
|
||||
|
||||
$vis Tuple(u8, u16),
|
||||
|
||||
$vis Struct { f: u8 },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mac_variant!(MARKER);
|
||||
|
||||
// We also accept visibilities on variants syntactically but not semantically.
|
||||
#[cfg(FALSE)]
|
||||
enum E {
|
||||
pub U,
|
||||
pub(crate) T(u8),
|
||||
pub(super) T { f: String }
|
||||
}
|
28
src/test/ui/parser/issue-65041-empty-vis-matcher-in-trait.rs
Normal file
28
src/test/ui/parser/issue-65041-empty-vis-matcher-in-trait.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// check-pass
|
||||
|
||||
// Here we check that a `:vis` macro matcher subsititued for the empty visibility
|
||||
// (`VisibilityKind::Inherited`) is accepted when used before an item in a trait.
|
||||
|
||||
fn main() {}
|
||||
|
||||
macro_rules! mac_in_trait {
|
||||
($vis:vis MARKER) => {
|
||||
$vis fn beta() {}
|
||||
|
||||
$vis const GAMMA: u8;
|
||||
|
||||
$vis type Delta;
|
||||
}
|
||||
}
|
||||
|
||||
trait Alpha {
|
||||
mac_in_trait!(MARKER);
|
||||
}
|
||||
|
||||
// We also accept visibilities on items in traits syntactically but not semantically.
|
||||
#[cfg(FALSE)]
|
||||
trait Foo {
|
||||
pub fn bar();
|
||||
pub(crate) type baz;
|
||||
pub(super) const QUUX: u8;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
macro_rules! bah {
|
||||
($a:expr) => ($a)
|
||||
//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found `2`
|
||||
//~^ ERROR expected one of `async`
|
||||
}
|
||||
|
||||
trait bar {
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found `2`
|
||||
error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `2`
|
||||
--> $DIR/trait-non-item-macros.rs:2:19
|
||||
|
|
||||
LL | ($a:expr) => ($a)
|
||||
| ^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`
|
||||
| ^^ expected one of 8 possible tokens
|
||||
...
|
||||
LL | bah!(2);
|
||||
| -------- in this macro invocation
|
||||
|
@ -1,7 +1,9 @@
|
||||
trait T {
|
||||
//~^ ERROR `main` function not found in crate `missing_close_brace_in_trait`
|
||||
fn foo(&self);
|
||||
|
||||
pub(crate) struct Bar<T>(); //~ ERROR expected one of
|
||||
pub(crate) struct Bar<T>();
|
||||
//~^ ERROR expected one of
|
||||
|
||||
impl T for Bar<usize> {
|
||||
fn foo(&self) {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: this file contains an un-closed delimiter
|
||||
--> $DIR/missing-close-brace-in-trait.rs:10:66
|
||||
--> $DIR/missing-close-brace-in-trait.rs:12:66
|
||||
|
|
||||
LL | trait T {
|
||||
| - un-closed delimiter
|
||||
@ -7,19 +7,24 @@ LL | trait T {
|
||||
LL | fn main() {}
|
||||
| ^
|
||||
|
||||
error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found keyword `pub`
|
||||
--> $DIR/missing-close-brace-in-trait.rs:4:1
|
||||
error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found keyword `struct`
|
||||
--> $DIR/missing-close-brace-in-trait.rs:5:12
|
||||
|
|
||||
LL | trait T {
|
||||
| - unclosed delimiter
|
||||
LL | fn foo(&self);
|
||||
| -
|
||||
| |
|
||||
| expected one of 7 possible tokens
|
||||
| help: `}` may belong here
|
||||
LL |
|
||||
LL | pub(crate) struct Bar<T>();
|
||||
| ^^^ unexpected token
|
||||
| ^^^^^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0601]: `main` function not found in crate `missing_close_brace_in_trait`
|
||||
--> $DIR/missing-close-brace-in-trait.rs:1:1
|
||||
|
|
||||
LL | / trait T {
|
||||
LL | |
|
||||
LL | | fn foo(&self);
|
||||
LL | |
|
||||
... |
|
||||
LL | |
|
||||
LL | | fn main() {}
|
||||
| |_________________________________________________________________^ consider adding a `main` function to `$DIR/missing-close-brace-in-trait.rs`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0601`.
|
||||
|
@ -1,8 +1,9 @@
|
||||
error: unnecessary visibility qualifier
|
||||
error[E0449]: unnecessary visibility qualifier
|
||||
--> $DIR/trait-pub-assoc-const.rs:2:5
|
||||
|
|
||||
LL | pub const Foo: u32;
|
||||
| ^^^ `pub` not permitted here
|
||||
| ^^^ `pub` not permitted here because it's implied
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0449`.
|
||||
|
@ -1,8 +1,9 @@
|
||||
error: unnecessary visibility qualifier
|
||||
error[E0449]: unnecessary visibility qualifier
|
||||
--> $DIR/trait-pub-assoc-ty.rs:2:5
|
||||
|
|
||||
LL | pub type Foo;
|
||||
| ^^^ `pub` not permitted here
|
||||
| ^^^ `pub` not permitted here because it's implied
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0449`.
|
||||
|
@ -1,8 +1,9 @@
|
||||
error: unnecessary visibility qualifier
|
||||
error[E0449]: unnecessary visibility qualifier
|
||||
--> $DIR/trait-pub-method.rs:2:5
|
||||
|
|
||||
LL | pub fn foo();
|
||||
| ^^^ `pub` not permitted here
|
||||
| ^^^ `pub` not permitted here because it's implied
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0449`.
|
||||
|
Loading…
Reference in New Issue
Block a user