From bdccbcf41bd881806d5370b8c7fe05e90143a076 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 12:39:51 -0800 Subject: [PATCH 1/3] parse `dyn (Foo)` as a trait object --- src/libsyntax/parse/parser.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 74daa5179d381..f798855d0e0f8 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`, -// `IDENT<::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`, +/// `IDENT<::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()?; From 4c73f82614ad846d41be3c0dd1e7e179c493ff8a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 23 Feb 2018 12:45:10 -0800 Subject: [PATCH 2/3] Add test --- src/test/compile-fail/dyn-trait-compatibility.rs | 5 ----- src/test/run-pass/dyn-trait.rs | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/test/compile-fail/dyn-trait-compatibility.rs b/src/test/compile-fail/dyn-trait-compatibility.rs index a7cfda504c753..454b6d2f566eb 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>; //~^ 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 91930852a57f6..d6ddb9b6008d7 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 = 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"); From 9ae431cf5dde5ab7b0fd7f83d1654e5a9b154cc1 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 24 Feb 2018 18:02:33 -0800 Subject: [PATCH 3/3] ignore-pretty on dyn trait test --- src/test/run-pass/dyn-trait.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-pass/dyn-trait.rs b/src/test/run-pass/dyn-trait.rs index d6ddb9b6008d7..fdec6a26ac945 100644 --- a/src/test/run-pass/dyn-trait.rs +++ b/src/test/run-pass/dyn-trait.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-pretty `dyn ::foo` parses differently in the current epoch + #![feature(dyn_trait)] use std::fmt::Display;