about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-11 09:19:23 +0000
committerbors <bors@rust-lang.org>2018-10-11 09:19:23 +0000
commita534216fa6d518088ae4468f1cdc519cd79e6247 (patch)
treef5aa2d027d7d74fc41cf54153c015d144c167d47 /src
parentcb6eeddd4dcefa4b71bb4b6bb087d05ad8e82145 (diff)
parent344747330c5f88d204ee99507aa0bd6358d0fbec (diff)
downloadrust-a534216fa6d518088ae4468f1cdc519cd79e6247.tar.gz
rust-a534216fa6d518088ae4468f1cdc519cd79e6247.zip
Auto merge of #54850 - mcr431:fix-54707-trait-function-from-macro, r=nikomatsakis
Fix #54707 - parse_trait_item_ now handles interpolated blocks as function body decls

Fix #54707 - parse_trait_item_ now handles interpolated blocks as function body decls

Previously parsing trait items only handled opening brace token and semicolon, I added a branch to the match statement that will also handle interpolated blocks.
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/parser.rs17
-rw-r--r--src/test/run-pass/macros/macro-as-fn-body.rs42
2 files changed, 59 insertions, 0 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 3099b2a3e8e..6c375799c38 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1430,6 +1430,23 @@ impl<'a> Parser<'a> {
                     attrs.extend(inner_attrs.iter().cloned());
                     Some(body)
                 }
+                token::Interpolated(ref nt) => {
+                    match &nt.0 {
+                        token::NtBlock(..) => {
+                            *at_end = true;
+                            let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+                            attrs.extend(inner_attrs.iter().cloned());
+                            Some(body)
+                        }
+                        _ => {
+                            let token_str = self.this_token_to_string();
+                            let mut err = self.fatal(&format!("expected `;` or `{{`, found `{}`",
+                                                              token_str));
+                            err.span_label(self.span, "expected `;` or `{`");
+                            return Err(err);
+                        }
+                    }
+                }
                 _ => {
                     let token_str = self.this_token_to_string();
                     let mut err = self.fatal(&format!("expected `;` or `{{`, found `{}`",
diff --git a/src/test/run-pass/macros/macro-as-fn-body.rs b/src/test/run-pass/macros/macro-as-fn-body.rs
new file mode 100644
index 00000000000..8c3c9fdc66d
--- /dev/null
+++ b/src/test/run-pass/macros/macro-as-fn-body.rs
@@ -0,0 +1,42 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// run-pass
+//
+// Description - ensure Interpolated blocks can act as valid function bodies
+// Covered cases: free functions, struct methods, and default trait functions
+
+macro_rules! def_fn {
+    ($body:block) => {
+        fn bar() $body
+    }
+}
+
+trait Foo {
+    def_fn!({ println!("foo"); });
+}
+
+struct Baz {}
+
+impl Foo for Baz {}
+
+struct Qux {}
+
+impl Qux {
+    def_fn!({ println!("qux"); });
+}
+
+def_fn!({ println!("quux"); });
+
+pub fn main() {
+    Baz::bar();
+    Qux::bar();
+    bar();
+}