about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-11-22 19:57:41 +0100
committerGitHub <noreply@github.com>2019-11-22 19:57:41 +0100
commit8cba0a9073f740791c5d18148d649c61aaf7d6c7 (patch)
tree1906720783e10429ac031f9dab006757720840eb /src/libsyntax
parent083b5a0a1bb3b2ee0873697ebf37e88d85faa3e5 (diff)
parent9a88364525a4660dbd6f6a371b3b25199f5bbe4a (diff)
downloadrust-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.rs50
-rw-r--r--src/libsyntax/mut_visit.rs46
-rw-r--r--src/libsyntax/print/pprust/tests.rs1
-rw-r--r--src/libsyntax/visit.rs2
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);