about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKalita Alexey <kalita.alexey@outlook.com>2016-12-16 14:16:46 +0300
committerKalita Alexey <kalita.alexey@outlook.com>2016-12-16 14:16:46 +0300
commit12a6cf1123890fcc7ee4934422e4d344c5857923 (patch)
tree52a5af91d14170abd3d081c7c50a42231ca06657
parentd250169cb5a96481a3e7c8f9fe05de49f60e5ae5 (diff)
downloadrust-12a6cf1123890fcc7ee4934422e4d344c5857923.tar.gz
rust-12a6cf1123890fcc7ee4934422e4d344c5857923.zip
Allow path fragments to be parsed as type parameter bounds in macro expansion
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/test/run-pass/issue-8521.rs34
-rw-r--r--src/test/ui/macros/macro_path_as_generic_bound.rs19
-rw-r--r--src/test/ui/macros/macro_path_as_generic_bound.stderr11
4 files changed, 65 insertions, 1 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index bdd1606805f..8ea59a5cbab 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4173,7 +4173,7 @@ impl<'a> Parser<'a> {
                     }));
                     self.bump();
                 }
-                token::ModSep | token::Ident(..) => {
+                _ if self.token.is_path_start() || self.token.is_keyword(keywords::For) => {
                     let poly_trait_ref = self.parse_poly_trait_ref()?;
                     let modifier = if ate_question {
                         TraitBoundModifier::Maybe
diff --git a/src/test/run-pass/issue-8521.rs b/src/test/run-pass/issue-8521.rs
new file mode 100644
index 00000000000..ce362c4bcd1
--- /dev/null
+++ b/src/test/run-pass/issue-8521.rs
@@ -0,0 +1,34 @@
+// Copyright 2016 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.
+
+trait Foo1 {}
+
+trait A {}
+
+macro_rules! foo1(($t:path) => {
+    impl<T: $t> Foo1 for T {}
+});
+
+foo1!(A);
+
+trait Foo2 {}
+
+trait B<T> {}
+
+#[allow(unused)]
+struct C {}
+
+macro_rules! foo2(($t:path) => {
+    impl<T: $t> Foo2 for T {}
+});
+
+foo2!(B<C>);
+
+fn main() {}
diff --git a/src/test/ui/macros/macro_path_as_generic_bound.rs b/src/test/ui/macros/macro_path_as_generic_bound.rs
new file mode 100644
index 00000000000..781ea30ed8b
--- /dev/null
+++ b/src/test/ui/macros/macro_path_as_generic_bound.rs
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+trait Foo {}
+
+macro_rules! foo(($t:path) => {
+    impl<T: $t> Foo for T {}
+});
+
+foo!(m::m2::A);
+
+fn main() {}
diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr
new file mode 100644
index 00000000000..96635032105
--- /dev/null
+++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr
@@ -0,0 +1,11 @@
+error[E0433]: failed to resolve. Use of undeclared type or module `m`
+  --> $DIR/macro_path_as_generic_bound.rs:17:6
+   |
+17 | foo!(m::m2::A);
+   | -----^^^^^^^^--
+   | |    |
+   | |    Use of undeclared type or module `m`
+   | in this macro invocation
+
+error: cannot continue compilation due to previous error
+