@@ -8,10 +8,10 @@ mod ty;
88mod path;
99pub use path:: PathStyle ;
1010mod stmt;
11+ mod generics;
1112
1213use crate :: ast:: { self , AttrStyle , Attribute , Arg , BindingMode , StrStyle , SelfKind } ;
13- use crate :: ast:: { FnDecl , Ident , IsAsync , Lifetime , MacDelimiter , Mutability } ;
14- use crate :: ast:: { GenericParam , GenericParamKind , WhereClause , TyKind , GenericBounds } ;
14+ use crate :: ast:: { FnDecl , Ident , IsAsync , Lifetime , MacDelimiter , Mutability , TyKind } ;
1515use crate :: ast:: { Visibility , VisibilityKind , Unsafety , CrateSugar } ;
1616use crate :: ext:: hygiene:: SyntaxContext ;
1717use crate :: source_map:: { self , respan} ;
@@ -1205,249 +1205,6 @@ impl<'a> Parser<'a> {
12051205
12061206 }
12071207
1208- /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
1209- ///
1210- /// ```
1211- /// BOUND = LT_BOUND (e.g., `'a`)
1212- /// ```
1213- fn parse_lt_param_bounds ( & mut self ) -> GenericBounds {
1214- let mut lifetimes = Vec :: new ( ) ;
1215- while self . check_lifetime ( ) {
1216- lifetimes. push ( ast:: GenericBound :: Outlives ( self . expect_lifetime ( ) ) ) ;
1217-
1218- if !self . eat_plus ( ) {
1219- break
1220- }
1221- }
1222- lifetimes
1223- }
1224-
1225- /// Matches `typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?`.
1226- fn parse_ty_param ( & mut self ,
1227- preceding_attrs : Vec < Attribute > )
1228- -> PResult < ' a , GenericParam > {
1229- let ident = self . parse_ident ( ) ?;
1230-
1231- // Parse optional colon and param bounds.
1232- let bounds = if self . eat ( & token:: Colon ) {
1233- self . parse_generic_bounds ( Some ( self . prev_span ) ) ?
1234- } else {
1235- Vec :: new ( )
1236- } ;
1237-
1238- let default = if self . eat ( & token:: Eq ) {
1239- Some ( self . parse_ty ( ) ?)
1240- } else {
1241- None
1242- } ;
1243-
1244- Ok ( GenericParam {
1245- ident,
1246- id : ast:: DUMMY_NODE_ID ,
1247- attrs : preceding_attrs. into ( ) ,
1248- bounds,
1249- kind : GenericParamKind :: Type {
1250- default,
1251- }
1252- } )
1253- }
1254-
1255- fn parse_const_param ( & mut self , preceding_attrs : Vec < Attribute > ) -> PResult < ' a , GenericParam > {
1256- self . expect_keyword ( kw:: Const ) ?;
1257- let ident = self . parse_ident ( ) ?;
1258- self . expect ( & token:: Colon ) ?;
1259- let ty = self . parse_ty ( ) ?;
1260-
1261- Ok ( GenericParam {
1262- ident,
1263- id : ast:: DUMMY_NODE_ID ,
1264- attrs : preceding_attrs. into ( ) ,
1265- bounds : Vec :: new ( ) ,
1266- kind : GenericParamKind :: Const {
1267- ty,
1268- }
1269- } )
1270- }
1271-
1272- /// Parses a (possibly empty) list of lifetime and type parameters, possibly including
1273- /// a trailing comma and erroneous trailing attributes.
1274- crate fn parse_generic_params ( & mut self ) -> PResult < ' a , Vec < ast:: GenericParam > > {
1275- let mut params = Vec :: new ( ) ;
1276- loop {
1277- let attrs = self . parse_outer_attributes ( ) ?;
1278- if self . check_lifetime ( ) {
1279- let lifetime = self . expect_lifetime ( ) ;
1280- // Parse lifetime parameter.
1281- let bounds = if self . eat ( & token:: Colon ) {
1282- self . parse_lt_param_bounds ( )
1283- } else {
1284- Vec :: new ( )
1285- } ;
1286- params. push ( ast:: GenericParam {
1287- ident : lifetime. ident ,
1288- id : lifetime. id ,
1289- attrs : attrs. into ( ) ,
1290- bounds,
1291- kind : ast:: GenericParamKind :: Lifetime ,
1292- } ) ;
1293- } else if self . check_keyword ( kw:: Const ) {
1294- // Parse const parameter.
1295- params. push ( self . parse_const_param ( attrs) ?) ;
1296- } else if self . check_ident ( ) {
1297- // Parse type parameter.
1298- params. push ( self . parse_ty_param ( attrs) ?) ;
1299- } else {
1300- // Check for trailing attributes and stop parsing.
1301- if !attrs. is_empty ( ) {
1302- if !params. is_empty ( ) {
1303- self . struct_span_err (
1304- attrs[ 0 ] . span ,
1305- & format ! ( "trailing attribute after generic parameter" ) ,
1306- )
1307- . span_label ( attrs[ 0 ] . span , "attributes must go before parameters" )
1308- . emit ( ) ;
1309- } else {
1310- self . struct_span_err (
1311- attrs[ 0 ] . span ,
1312- & format ! ( "attribute without generic parameters" ) ,
1313- )
1314- . span_label (
1315- attrs[ 0 ] . span ,
1316- "attributes are only permitted when preceding parameters" ,
1317- )
1318- . emit ( ) ;
1319- }
1320- }
1321- break
1322- }
1323-
1324- if !self . eat ( & token:: Comma ) {
1325- break
1326- }
1327- }
1328- Ok ( params)
1329- }
1330-
1331- /// Parses a set of optional generic type parameter declarations. Where
1332- /// clauses are not parsed here, and must be added later via
1333- /// `parse_where_clause()`.
1334- ///
1335- /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
1336- /// | ( < lifetimes , typaramseq ( , )? > )
1337- /// where typaramseq = ( typaram ) | ( typaram , typaramseq )
1338- fn parse_generics ( & mut self ) -> PResult < ' a , ast:: Generics > {
1339- let span_lo = self . token . span ;
1340- let ( params, span) = if self . eat_lt ( ) {
1341- let params = self . parse_generic_params ( ) ?;
1342- self . expect_gt ( ) ?;
1343- ( params, span_lo. to ( self . prev_span ) )
1344- } else {
1345- ( vec ! [ ] , self . prev_span . between ( self . token . span ) )
1346- } ;
1347- Ok ( ast:: Generics {
1348- params,
1349- where_clause : WhereClause {
1350- predicates : Vec :: new ( ) ,
1351- span : DUMMY_SP ,
1352- } ,
1353- span,
1354- } )
1355- }
1356-
1357- /// Parses an optional where-clause and places it in `generics`.
1358- ///
1359- /// ```ignore (only-for-syntax-highlight)
1360- /// where T : Trait<U, V> + 'b, 'a : 'b
1361- /// ```
1362- fn parse_where_clause ( & mut self ) -> PResult < ' a , WhereClause > {
1363- let mut where_clause = WhereClause {
1364- predicates : Vec :: new ( ) ,
1365- span : self . prev_span . to ( self . prev_span ) ,
1366- } ;
1367-
1368- if !self . eat_keyword ( kw:: Where ) {
1369- return Ok ( where_clause) ;
1370- }
1371- let lo = self . prev_span ;
1372-
1373- // We are considering adding generics to the `where` keyword as an alternative higher-rank
1374- // parameter syntax (as in `where<'a>` or `where<T>`. To avoid that being a breaking
1375- // change we parse those generics now, but report an error.
1376- if self . choose_generics_over_qpath ( ) {
1377- let generics = self . parse_generics ( ) ?;
1378- self . struct_span_err (
1379- generics. span ,
1380- "generic parameters on `where` clauses are reserved for future use" ,
1381- )
1382- . span_label ( generics. span , "currently unsupported" )
1383- . emit ( ) ;
1384- }
1385-
1386- loop {
1387- let lo = self . token . span ;
1388- if self . check_lifetime ( ) && self . look_ahead ( 1 , |t| !t. is_like_plus ( ) ) {
1389- let lifetime = self . expect_lifetime ( ) ;
1390- // Bounds starting with a colon are mandatory, but possibly empty.
1391- self . expect ( & token:: Colon ) ?;
1392- let bounds = self . parse_lt_param_bounds ( ) ;
1393- where_clause. predicates . push ( ast:: WherePredicate :: RegionPredicate (
1394- ast:: WhereRegionPredicate {
1395- span : lo. to ( self . prev_span ) ,
1396- lifetime,
1397- bounds,
1398- }
1399- ) ) ;
1400- } else if self . check_type ( ) {
1401- // Parse optional `for<'a, 'b>`.
1402- // This `for` is parsed greedily and applies to the whole predicate,
1403- // the bounded type can have its own `for` applying only to it.
1404- // Examples:
1405- // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>`
1406- // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>`
1407- // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>`
1408- let lifetime_defs = self . parse_late_bound_lifetime_defs ( ) ?;
1409-
1410- // Parse type with mandatory colon and (possibly empty) bounds,
1411- // or with mandatory equality sign and the second type.
1412- let ty = self . parse_ty ( ) ?;
1413- if self . eat ( & token:: Colon ) {
1414- let bounds = self . parse_generic_bounds ( Some ( self . prev_span ) ) ?;
1415- where_clause. predicates . push ( ast:: WherePredicate :: BoundPredicate (
1416- ast:: WhereBoundPredicate {
1417- span : lo. to ( self . prev_span ) ,
1418- bound_generic_params : lifetime_defs,
1419- bounded_ty : ty,
1420- bounds,
1421- }
1422- ) ) ;
1423- // FIXME: Decide what should be used here, `=` or `==`.
1424- // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
1425- } else if self . eat ( & token:: Eq ) || self . eat ( & token:: EqEq ) {
1426- let rhs_ty = self . parse_ty ( ) ?;
1427- where_clause. predicates . push ( ast:: WherePredicate :: EqPredicate (
1428- ast:: WhereEqPredicate {
1429- span : lo. to ( self . prev_span ) ,
1430- lhs_ty : ty,
1431- rhs_ty,
1432- id : ast:: DUMMY_NODE_ID ,
1433- }
1434- ) ) ;
1435- } else {
1436- return self . unexpected ( ) ;
1437- }
1438- } else {
1439- break
1440- }
1441-
1442- if !self . eat ( & token:: Comma ) {
1443- break
1444- }
1445- }
1446-
1447- where_clause. span = lo. to ( self . prev_span ) ;
1448- Ok ( where_clause)
1449- }
1450-
14511208 fn parse_fn_args ( & mut self , named_args : bool , allow_c_variadic : bool )
14521209 -> PResult < ' a , ( Vec < Arg > , bool ) > {
14531210 let sp = self . token . span ;
@@ -1671,31 +1428,6 @@ impl<'a> Parser<'a> {
16711428 } ) )
16721429 }
16731430
1674- fn choose_generics_over_qpath ( & self ) -> bool {
1675- // There's an ambiguity between generic parameters and qualified paths in impls.
1676- // If we see `<` it may start both, so we have to inspect some following tokens.
1677- // The following combinations can only start generics,
1678- // but not qualified paths (with one exception):
1679- // `<` `>` - empty generic parameters
1680- // `<` `#` - generic parameters with attributes
1681- // `<` (LIFETIME|IDENT) `>` - single generic parameter
1682- // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
1683- // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
1684- // `<` (LIFETIME|IDENT) `=` - generic parameter with a default
1685- // `<` const - generic const parameter
1686- // The only truly ambiguous case is
1687- // `<` IDENT `>` `::` IDENT ...
1688- // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
1689- // because this is what almost always expected in practice, qualified paths in impls
1690- // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
1691- self . token == token:: Lt &&
1692- ( self . look_ahead ( 1 , |t| t == & token:: Pound || t == & token:: Gt ) ||
1693- self . look_ahead ( 1 , |t| t. is_lifetime ( ) || t. is_ident ( ) ) &&
1694- self . look_ahead ( 2 , |t| t == & token:: Gt || t == & token:: Comma ||
1695- t == & token:: Colon || t == & token:: Eq ) ||
1696- self . is_keyword_ahead ( 1 , & [ kw:: Const ] ) )
1697- }
1698-
16991431 fn is_crate_vis ( & self ) -> bool {
17001432 self . token . is_keyword ( kw:: Crate ) && self . look_ahead ( 1 , |t| t != & token:: ModSep )
17011433 }
0 commit comments