@@ -33,7 +33,7 @@ use ast::{Stmt, StmtKind};
3333use ast:: { VariantData , StructField } ;
3434use ast:: StrStyle ;
3535use ast:: SelfKind ;
36- use ast:: { TraitItem , TraitRef } ;
36+ use ast:: { TraitItem , TraitRef , TraitObjectSyntax } ;
3737use ast:: { Ty , TyKind , TypeBinding , TyParam , TyParamBounds } ;
3838use ast:: { ViewPath , ViewPathGlob , ViewPathList , ViewPathSimple } ;
3939use ast:: { Visibility , WhereClause } ;
@@ -364,6 +364,13 @@ fn is_ident_or_underscore(t: &token::Token) -> bool {
364364 t. is_ident ( ) || * t == token:: Underscore
365365}
366366
367+ // Returns true if `IDENT t` can start a type - `IDENT::a::b`, `IDENT<u8, u8>`,
368+ // `IDENT<<u8 as Trait>::AssocTy>`, `IDENT(u8, u8) -> u8`.
369+ fn can_continue_type_after_ident ( t : & token:: Token ) -> bool {
370+ t == & token:: ModSep || t == & token:: Lt ||
371+ t == & token:: BinOp ( token:: Shl ) || t == & token:: OpenDelim ( token:: Paren )
372+ }
373+
367374/// Information about the path to a module.
368375pub struct ModulePath {
369376 pub name : String ,
@@ -1428,7 +1435,7 @@ impl<'a> Parser<'a> {
14281435 TyKind :: Path ( None , ref path) if maybe_bounds => {
14291436 self . parse_remaining_bounds ( Vec :: new ( ) , path. clone ( ) , lo, true ) ?
14301437 }
1431- TyKind :: TraitObject ( ref bounds)
1438+ TyKind :: TraitObject ( ref bounds, TraitObjectSyntax :: None )
14321439 if maybe_bounds && bounds. len ( ) == 1 && !trailing_plus => {
14331440 let path = match bounds[ 0 ] {
14341441 TraitTyParamBound ( ref pt, ..) => pt. trait_ref . path . clone ( ) ,
@@ -1472,27 +1479,6 @@ impl<'a> Parser<'a> {
14721479 } else if self . eat ( & token:: Underscore ) {
14731480 // A type to be inferred `_`
14741481 TyKind :: Infer
1475- } else if self . eat_lt ( ) {
1476- // Qualified path
1477- let ( qself, path) = self . parse_qpath ( PathStyle :: Type ) ?;
1478- TyKind :: Path ( Some ( qself) , path)
1479- } else if self . token . is_path_start ( ) {
1480- // Simple path
1481- let path = self . parse_path ( PathStyle :: Type ) ?;
1482- if self . eat ( & token:: Not ) {
1483- // Macro invocation in type position
1484- let ( _, tts) = self . expect_delimited_token_tree ( ) ?;
1485- TyKind :: Mac ( respan ( lo. to ( self . span ) , Mac_ { path : path, tts : tts } ) )
1486- } else {
1487- // Just a type path or bound list (trait object type) starting with a trait.
1488- // `Type`
1489- // `Trait1 + Trait2 + 'a`
1490- if allow_plus && self . check ( & token:: BinOp ( token:: Plus ) ) {
1491- self . parse_remaining_bounds ( Vec :: new ( ) , path, lo, true ) ?
1492- } else {
1493- TyKind :: Path ( None , path)
1494- }
1495- }
14961482 } else if self . token_is_bare_fn_keyword ( ) {
14971483 // Function pointer type
14981484 self . parse_ty_bare_fn ( Vec :: new ( ) ) ?
@@ -1512,10 +1498,37 @@ impl<'a> Parser<'a> {
15121498 } else if self . eat_keyword ( keywords:: Impl ) {
15131499 // FIXME: figure out priority of `+` in `impl Trait1 + Trait2` (#34511).
15141500 TyKind :: ImplTrait ( self . parse_ty_param_bounds ( ) ?)
1501+ } else if self . check_keyword ( keywords:: Dyn ) &&
1502+ self . look_ahead ( 1 , |t| t. can_begin_bound ( ) && !can_continue_type_after_ident ( t) ) {
1503+ // FIXME: figure out priority of `+` in `dyn Trait1 + Trait2` (#34511).
1504+ self . bump ( ) ; // `dyn`
1505+ TyKind :: TraitObject ( self . parse_ty_param_bounds ( ) ?, TraitObjectSyntax :: Dyn )
15151506 } else if self . check ( & token:: Question ) ||
1516- self . check_lifetime ( ) && self . look_ahead ( 1 , |t| t == & token:: BinOp ( token:: Plus ) ) {
1507+ self . check_lifetime ( ) && self . look_ahead ( 1 , |t| t == & token:: BinOp ( token:: Plus ) ) {
15171508 // Bound list (trait object type)
1518- TyKind :: TraitObject ( self . parse_ty_param_bounds_common ( allow_plus) ?)
1509+ TyKind :: TraitObject ( self . parse_ty_param_bounds_common ( allow_plus) ?,
1510+ TraitObjectSyntax :: None )
1511+ } else if self . eat_lt ( ) {
1512+ // Qualified path
1513+ let ( qself, path) = self . parse_qpath ( PathStyle :: Type ) ?;
1514+ TyKind :: Path ( Some ( qself) , path)
1515+ } else if self . token . is_path_start ( ) {
1516+ // Simple path
1517+ let path = self . parse_path ( PathStyle :: Type ) ?;
1518+ if self . eat ( & token:: Not ) {
1519+ // Macro invocation in type position
1520+ let ( _, tts) = self . expect_delimited_token_tree ( ) ?;
1521+ TyKind :: Mac ( respan ( lo. to ( self . span ) , Mac_ { path : path, tts : tts } ) )
1522+ } else {
1523+ // Just a type path or bound list (trait object type) starting with a trait.
1524+ // `Type`
1525+ // `Trait1 + Trait2 + 'a`
1526+ if allow_plus && self . check ( & token:: BinOp ( token:: Plus ) ) {
1527+ self . parse_remaining_bounds ( Vec :: new ( ) , path, lo, true ) ?
1528+ } else {
1529+ TyKind :: Path ( None , path)
1530+ }
1531+ }
15191532 } else {
15201533 let msg = format ! ( "expected type, found {}" , self . this_token_descr( ) ) ;
15211534 return Err ( self . fatal ( & msg) ) ;
@@ -1538,7 +1551,7 @@ impl<'a> Parser<'a> {
15381551 self . bump ( ) ; // `+`
15391552 bounds. append ( & mut self . parse_ty_param_bounds ( ) ?) ;
15401553 }
1541- Ok ( TyKind :: TraitObject ( bounds) )
1554+ Ok ( TyKind :: TraitObject ( bounds, TraitObjectSyntax :: None ) )
15421555 }
15431556
15441557 fn maybe_recover_from_bad_type_plus ( & mut self , allow_plus : bool , ty : & Ty ) -> PResult < ' a , ( ) > {
@@ -4256,6 +4269,7 @@ impl<'a> Parser<'a> {
42564269 fn parse_ty_param_bounds_common ( & mut self , allow_plus : bool ) -> PResult < ' a , TyParamBounds > {
42574270 let mut bounds = Vec :: new ( ) ;
42584271 loop {
4272+ // This needs to be syncronized with `Token::can_begin_bound`.
42594273 let is_bound_start = self . check_path ( ) || self . check_lifetime ( ) ||
42604274 self . check ( & token:: Question ) ||
42614275 self . check_keyword ( keywords:: For ) ||
0 commit comments