about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2018-02-24 15:52:16 -0800
committerGitHub <noreply@github.com>2018-02-24 15:52:16 -0800
commit7e6829938c198afe033119f1927459c64d2ea4d7 (patch)
treefefcaeee946e7ce0413d75d304a8db0da1e63aa8 /src
parent2dba874d57257949ef203eec6ec7be34ff39955b (diff)
parent4c73f82614ad846d41be3c0dd1e7e179c493ff8a (diff)
downloadrust-7e6829938c198afe033119f1927459c64d2ea4d7.tar.gz
rust-7e6829938c198afe033119f1927459c64d2ea4d7.zip
Rollup merge of #48481 - Manishearth:dyn-paren, r=petrochenkov
Allow parentheses in `dyn (Trait)`

r? @eddyb @nikomatsakis
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/parser.rs14
-rw-r--r--src/test/compile-fail/dyn-trait-compatibility.rs5
-rw-r--r--src/test/run-pass/dyn-trait.rs2
3 files changed, 11 insertions, 10 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 26b18213f27..62233f97e75 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -405,11 +405,14 @@ impl TokenType {
     }
 }
 
-// Returns true if `IDENT t` can start a type - `IDENT::a::b`, `IDENT<u8, u8>`,
-// `IDENT<<u8 as Trait>::AssocTy>`, `IDENT(u8, u8) -> u8`.
-fn can_continue_type_after_ident(t: &token::Token) -> bool {
+/// Returns true if `IDENT t` can start a type - `IDENT::a::b`, `IDENT<u8, u8>`,
+/// `IDENT<<u8 as Trait>::AssocTy>`.
+///
+/// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
+/// that IDENT is not the ident of a fn trait
+fn can_continue_type_after_non_fn_ident(t: &token::Token) -> bool {
     t == &token::ModSep || t == &token::Lt ||
-    t == &token::BinOp(token::Shl) || t == &token::OpenDelim(token::Paren)
+    t == &token::BinOp(token::Shl)
 }
 
 /// Information about the path to a module.
@@ -1619,7 +1622,8 @@ impl<'a> Parser<'a> {
             impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
             TyKind::ImplTrait(bounds)
         } else if self.check_keyword(keywords::Dyn) &&
-                  self.look_ahead(1, |t| t.can_begin_bound() && !can_continue_type_after_ident(t)) {
+                  self.look_ahead(1, |t| t.can_begin_bound() &&
+                                         !can_continue_type_after_non_fn_ident(t)) {
             self.bump(); // `dyn`
             // Always parse bounds greedily for better error recovery.
             let bounds = self.parse_ty_param_bounds()?;
diff --git a/src/test/compile-fail/dyn-trait-compatibility.rs b/src/test/compile-fail/dyn-trait-compatibility.rs
index a7cfda504c7..454b6d2f566 100644
--- a/src/test/compile-fail/dyn-trait-compatibility.rs
+++ b/src/test/compile-fail/dyn-trait-compatibility.rs
@@ -20,10 +20,5 @@ type A3 = dyn<<dyn as dyn>::dyn>;
 //~^ ERROR cannot find type `dyn` in this scope
 //~| ERROR cannot find type `dyn` in this scope
 //~| ERROR Use of undeclared type or module `dyn`
-type A4 = dyn(dyn, dyn) -> dyn;
-//~^ ERROR cannot find type `dyn` in this scope
-//~| ERROR cannot find type `dyn` in this scope
-//~| ERROR cannot find type `dyn` in this scope
-//~| ERROR cannot find type `dyn` in this scope
 
 fn main() {}
diff --git a/src/test/run-pass/dyn-trait.rs b/src/test/run-pass/dyn-trait.rs
index 91930852a57..d6ddb9b6008 100644
--- a/src/test/run-pass/dyn-trait.rs
+++ b/src/test/run-pass/dyn-trait.rs
@@ -17,6 +17,8 @@ static BYTE: u8 = 33;
 fn main() {
     let x: &(dyn 'static + Display) = &BYTE;
     let y: Box<dyn Display + 'static> = Box::new(BYTE);
+    let _: &dyn (Display) = &BYTE;
+    let _: &dyn (::std::fmt::Display) = &BYTE;
     let xstr = format!("{}", x);
     let ystr = format!("{}", y);
     assert_eq!(xstr, "33");