]> git.lizzy.rs Git - rust.git/commitdiff
Alias `TraitItem` & `ImplItem`.
authorMazdak Farrokhzad <twingoow@gmail.com>
Sat, 30 Nov 2019 17:25:44 +0000 (18:25 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Thu, 12 Dec 2019 16:54:48 +0000 (17:54 +0100)
Allow defaultness on trait items syntactically.

13 files changed:
src/librustc_parse/parser/item.rs
src/librustc_passes/ast_validation.rs
src/libsyntax/ast.rs
src/libsyntax/mut_visit.rs
src/libsyntax/print/pprust.rs
src/libsyntax_expand/placeholders.rs
src/test/ui/issues/issue-60075.stderr
src/test/ui/parser/issue-32446.stderr
src/test/ui/parser/macro/trait-non-item-macros.stderr
src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs [new file with mode: 0644]
src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr [new file with mode: 0644]
src/test/ui/parser/trait-item-with-defaultness-pass.rs [new file with mode: 0644]

index 34ef12e818c57386ca40853551b4ba819b8aa8a9..c159fb66d50701afce375194a3340a4cf9da2cad 100644 (file)
@@ -714,9 +714,9 @@ fn parse_impl_item_(
             id: DUMMY_NODE_ID,
             span: lo.to(self.prev_span),
             ident: name,
+            attrs,
             vis,
             defaultness,
-            attrs,
             generics,
             kind,
             tokens: None,
@@ -882,6 +882,7 @@ fn parse_trait_item_(
     ) -> PResult<'a, TraitItem> {
         let lo = self.token.span;
         let vis = self.parse_visibility(FollowedByType::No)?;
+        let defaultness = self.parse_defaultness();
         let (name, kind, generics) = if self.eat_keyword(kw::Type) {
             self.parse_trait_item_assoc_ty()?
         } else if self.is_const_item() {
@@ -895,12 +896,13 @@ fn parse_trait_item_(
 
         Ok(TraitItem {
             id: DUMMY_NODE_ID,
+            span: lo.to(self.prev_span),
             ident: name,
             attrs,
             vis,
+            defaultness,
             generics,
             kind,
-            span: lo.to(self.prev_span),
             tokens: None,
         })
     }
index 202b6ae2f94c470a8903fd2ceba820a2fe053d9a..a078a36db7ac4b533212909862253995fc8aadf1 100644 (file)
@@ -271,6 +271,14 @@ fn check_fn_decl(&self, fn_decl: &FnDecl) {
                 forbid, and warn are the only allowed built-in attributes in function parameters")
             });
     }
+
+    fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
+        if let Defaultness::Default = defaultness {
+            self.err_handler()
+                .struct_span_err(span, "`default` is only allowed on items in `impl` definitions")
+                .emit();
+        }
+    }
 }
 
 enum GenericPosition {
@@ -746,6 +754,7 @@ fn visit_impl_item(&mut self, ii: &'a ImplItem) {
 
     fn visit_trait_item(&mut self, ti: &'a TraitItem) {
         self.invalid_visibility(&ti.vis, None);
+        self.check_defaultness(ti.span, ti.defaultness);
         visit::walk_trait_item(self, ti);
     }
 }
index 92ba071a03d684da82d9f7916ec1d21e905485d4..964acfa92b9bb5fe851c4d260b2e8b655cad0e2f 100644 (file)
@@ -1603,24 +1603,12 @@ pub struct FnSig {
     pub decl: P<FnDecl>,
 }
 
-/// Represents an item declaration within a trait declaration,
+pub type TraitItem = ImplItem<TraitItemKind>;
+
+/// Represents the kind of an item declaration within a trait declaration,
 /// possibly including a default implementation. A trait item is
 /// either required (meaning it doesn't have an implementation, just a
 /// 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 generics: Generics,
-    pub kind: TraitItemKind,
-    /// See `Item::tokens` for what this is.
-    pub tokens: Option<TokenStream>,
-}
-
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum TraitItemKind {
     Const(P<Ty>, Option<P<Expr>>),
@@ -1631,7 +1619,7 @@ pub enum TraitItemKind {
 
 /// Represents anything within an `impl` block.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct ImplItem {
+pub struct ImplItem<K = ImplItemKind> {
     pub attrs: Vec<Attribute>,
     pub id: NodeId,
     pub span: Span,
@@ -1640,7 +1628,7 @@ pub struct ImplItem {
 
     pub defaultness: Defaultness,
     pub generics: Generics,
-    pub kind: ImplItemKind,
+    pub kind: K,
     /// See `Item::tokens` for what this is.
     pub tokens: Option<TokenStream>,
 }
index f8795d885d2164c784b69cb1c5125f4b2de53964..9d0a29f29511d1b62da8177fdb7e992b43b1983e 100644 (file)
@@ -939,7 +939,8 @@ 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, visitor: &mut T)
     -> SmallVec<[TraitItem; 1]>
 {
-    let TraitItem { id, ident, vis, attrs, generics, kind, span, tokens: _ } = &mut item;
+    let TraitItem { id, ident, vis, defaultness: _, attrs, generics, kind, span, tokens: _ } =
+        &mut item;
     visitor.visit_id(id);
     visitor.visit_ident(ident);
     visitor.visit_vis(vis);
index f0c5fb32fb16dbddc1dd733e5cc9e1b23dad323d..2e3ea5e24440fdab4ad1b48876c06ac09108b918 100644 (file)
@@ -1550,6 +1550,7 @@ fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(ti.span.lo());
         self.print_outer_attributes(&ti.attrs);
+        self.print_defaultness(ti.defaultness);
         match ti.kind {
             ast::TraitItemKind::Const(ref ty, ref default) => {
                 self.print_associated_const(
index faea04e691be51c3142525d7f546bb816eca05be..6057be9826a5125ac585bda993a952101be7aed4 100644 (file)
@@ -53,6 +53,7 @@ fn mac_placeholder() -> ast::Mac {
         AstFragmentKind::TraitItems => AstFragment::TraitItems(smallvec![ast::TraitItem {
             id, span, ident, vis, attrs, generics,
             kind: ast::TraitItemKind::Macro(mac_placeholder()),
+            defaultness: ast::Defaultness::Final,
             tokens: None,
         }]),
         AstFragmentKind::ImplItems => AstFragment::ImplItems(smallvec![ast::ImplItem {
index e0b15130c337d5401a23fcc95847b2b0207d3472..e8ef981f515fc669305ba0d3d778a3bc972556c4 100644 (file)
@@ -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`, `crate`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `;`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `;`
   --> $DIR/issue-60075.rs:6:11
    |
 LL |     fn qux() -> Option<usize> {
index 70256a59231fb799b0fa6bd87146a9029875caad..1a97f54160b24bfed843ac35de5402f6d66965eb 100644 (file)
@@ -1,8 +1,8 @@
-error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `...`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `...`
   --> $DIR/issue-32446.rs:4:11
    |
 LL | trait T { ... }
-   |           ^^^ expected one of 9 possible tokens
+   |           ^^^ expected one of 10 possible tokens
 
 error: aborting due to previous error
 
index 0a433ab278e43b327de3daff1732efdabc31a856..7647ba500e03a9e99d345d14f38f6a0006c9aa90 100644 (file)
@@ -1,8 +1,8 @@
-error: expected one of `async`, `const`, `crate`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `2`
+error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, or `unsafe`, found `2`
   --> $DIR/trait-non-item-macros.rs:2:19
    |
 LL |     ($a:expr) => ($a)
-   |                   ^^ expected one of 8 possible tokens
+   |                   ^^ expected one of 9 possible tokens
 ...
 LL |     bah!(2);
    |     -------- in this macro invocation
index cbaf9315e8540847a06d98b33fe2a4384938314e..7e8abf22d55ab4b535950c88ea83ef9ba0cb6557 100644 (file)
@@ -7,11 +7,11 @@ LL | trait T {
 LL | fn main() {}
    |                                                                  ^
 
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found keyword `struct`
+error: expected one of `async`, `const`, `default`, `extern`, `fn`, `type`, or `unsafe`, found keyword `struct`
   --> $DIR/missing-close-brace-in-trait.rs:5:12
    |
 LL | pub(crate) struct Bar<T>();
-   |            ^^^^^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`
+   |            ^^^^^^ expected one of 7 possible tokens
 
 error[E0601]: `main` function not found in crate `missing_close_brace_in_trait`
   --> $DIR/missing-close-brace-in-trait.rs:1:1
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.rs
new file mode 100644 (file)
index 0000000..b67e306
--- /dev/null
@@ -0,0 +1,10 @@
+fn main() {}
+
+trait X {
+    default const A: u8; //~ ERROR `default` is only allowed on items in `impl` definitions
+    default const B: u8 = 0;  //~ ERROR `default` is only allowed on items in `impl` definitions
+    default type D; //~ ERROR `default` is only allowed on items in `impl` definitions
+    default type C: Ord; //~ ERROR `default` is only allowed on items in `impl` definitions
+    default fn f1(); //~ ERROR `default` is only allowed on items in `impl` definitions
+    default fn f2() {} //~ ERROR `default` is only allowed on items in `impl` definitions
+}
diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr
new file mode 100644 (file)
index 0000000..48b502a
--- /dev/null
@@ -0,0 +1,38 @@
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:4:5
+   |
+LL |     default const A: u8;
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:5:5
+   |
+LL |     default const B: u8 = 0;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:6:5
+   |
+LL |     default type D;
+   |     ^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:7:5
+   |
+LL |     default type C: Ord;
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:8:5
+   |
+LL |     default fn f1();
+   |     ^^^^^^^^^^^^^^^^
+
+error: `default` is only allowed on items in `impl` definitions
+  --> $DIR/trait-item-with-defaultness-fail-semantic.rs:9:5
+   |
+LL |     default fn f2() {}
+   |     ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/parser/trait-item-with-defaultness-pass.rs b/src/test/ui/parser/trait-item-with-defaultness-pass.rs
new file mode 100644 (file)
index 0000000..a6318bd
--- /dev/null
@@ -0,0 +1,13 @@
+// check-pass
+
+fn main() {}
+
+#[cfg(FALSE)]
+trait X {
+    default const A: u8;
+    default const B: u8 = 0;
+    default type D;
+    default type C: Ord;
+    default fn f1();
+    default fn f2() {}
+}