Skip to content

Commit

Permalink
Rollup merge of rust-lang#48481 - Manishearth:dyn-paren, r=petrochenkov
Browse files Browse the repository at this point in the history
Allow parentheses in `dyn (Trait)`

r? @eddyb @nikomatsakis
  • Loading branch information
Manishearth authored Feb 24, 2018
2 parents 2dba874 + 4c73f82 commit 7e68299
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 10 deletions.
14 changes: 9 additions & 5 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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()?;
Expand Down
5 changes: 0 additions & 5 deletions src/test/compile-fail/dyn-trait-compatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
2 changes: 2 additions & 0 deletions src/test/run-pass/dyn-trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 7e68299

Please sign in to comment.