diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-11-22 19:57:41 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-22 19:57:41 +0100 |
| commit | 8cba0a9073f740791c5d18148d649c61aaf7d6c7 (patch) | |
| tree | 1906720783e10429ac031f9dab006757720840eb /src/libsyntax | |
| parent | 083b5a0a1bb3b2ee0873697ebf37e88d85faa3e5 (diff) | |
| parent | 9a88364525a4660dbd6f6a371b3b25199f5bbe4a (diff) | |
| download | rust-8cba0a9073f740791c5d18148d649c61aaf7d6c7.tar.gz rust-8cba0a9073f740791c5d18148d649c61aaf7d6c7.zip | |
Rollup merge of #66183 - Centril:empty-vis-trait-decl, r=petrochenkov
*Syntactically* permit visibilities on trait items & enum variants
Fixes #65041
Suppose we have `$vis trait_item` or `$vis enum_variant` and `$vis` is a `:vis` macro fragment. Before this PR, this would fail to parse. This is now instead allowed as per language team consensus in https://github.com/rust-lang/rust/issues/65041#issuecomment-538105286. (See added tests for elaboration.)
Moreover, we now also permit visibility modifiers on trait items & enum variants *syntactically* but reject them with semantic checks (in `ast_validation`):
```rust
#[cfg(FALSE)]
trait Foo { pub fn bar(); } // OK
#[cfg(FALSE)]
enum E { pub U } // OK
```
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 50 | ||||
| -rw-r--r-- | src/libsyntax/mut_visit.rs | 46 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust/tests.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
4 files changed, 56 insertions, 43 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a9f03e4af5b..14243076941 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -982,12 +982,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 attrs: ThinVec<Attribute>, + pub id: NodeId, + pub span: Span, pub ident: Ident, pub expr: P<Expr>, - pub span: Span, pub is_shorthand: bool, - pub attrs: ThinVec<Attribute>, - pub id: NodeId, pub is_placeholder: bool, } @@ -1567,12 +1567,14 @@ pub struct FnSig { /// signature) or provided (meaning it has a default implementation). #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct TraitItem { + pub attrs: Vec<Attribute>, pub id: NodeId, + pub span: Span, + pub vis: Visibility, pub ident: Ident, - pub attrs: Vec<Attribute>, + pub generics: Generics, pub kind: TraitItemKind, - pub span: Span, /// See `Item::tokens` for what this is. pub tokens: Option<TokenStream>, } @@ -1588,14 +1590,15 @@ pub enum TraitItemKind { /// Represents anything within an `impl` block. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct ImplItem { + pub attrs: Vec<Attribute>, pub id: NodeId, - pub ident: Ident, + pub span: Span, pub vis: Visibility, + pub ident: Ident, + pub defaultness: Defaultness, - pub attrs: Vec<Attribute>, pub generics: Generics, pub kind: ImplItemKind, - pub span: Span, /// See `Item::tokens` for what this is. pub tokens: Option<TokenStream>, } @@ -2174,22 +2177,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, } @@ -2368,12 +2373,13 @@ impl VisibilityKind { /// E.g., `bar: usize` as in `struct Foo { bar: usize }`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct StructField { + pub attrs: Vec<Attribute>, + pub id: NodeId, pub span: Span, - pub ident: Option<Ident>, pub vis: Visibility, - pub id: NodeId, + pub ident: Option<Ident>, + pub ty: P<Ty>, - pub attrs: Vec<Attribute>, pub is_placeholder: bool, } @@ -2417,12 +2423,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 @@ -2579,12 +2586,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. diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index da3c885b860..a7bd587ac9b 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -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] } @@ -916,32 +917,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] } diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs index 2c6dd0fb1c6..d7725acb5d4 100644 --- a/src/libsyntax/print/pprust/tests.rs +++ b/src/libsyntax/print/pprust/tests.rs @@ -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), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 2597ffd750d..f7b06c55a3a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -310,6 +310,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); @@ -581,6 +582,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); |
