@@ -1106,233 +1106,6 @@ impl TypleContext {
11061106 Ok ( ( ) )
11071107 }
11081108
1109- fn replace_typle_fold_expr (
1110- & self ,
1111- mac : & mut Macro ,
1112- attrs : Vec < Attribute > ,
1113- state : & mut BlockState ,
1114- default_span : Span ,
1115- ) -> syn:: Result < Expr > {
1116- let mut inner_state = BlockState :: default ( ) ;
1117- let token_stream = std:: mem:: take ( & mut mac. tokens ) ;
1118- let mut tokens = token_stream. into_iter ( ) ;
1119- let mut init_expr =
1120- syn:: parse2 :: < Expr > ( Self :: extract_to_semicolon ( & mut tokens, default_span) ?) ?;
1121- self . replace_expr ( & mut init_expr, & mut inner_state) ?;
1122- let ( pattern, range) = self . parse_pattern_range ( & mut tokens) ?;
1123- if range. is_empty ( ) {
1124- return Ok ( Expr :: Paren ( syn:: ExprParen {
1125- attrs,
1126- paren_token : token:: Paren :: default ( ) ,
1127- expr : Box :: new ( init_expr) ,
1128- } ) ) ;
1129- }
1130- let fold_ident = Self :: parse_fold_ident ( & mut tokens, default_span) ?;
1131- let fold_pat = Pat :: Ident ( syn:: PatIdent {
1132- attrs : Vec :: new ( ) ,
1133- by_ref : None ,
1134- mutability : None ,
1135- ident : fold_ident. clone ( ) ,
1136- subpat : None ,
1137- } ) ;
1138- let expr = syn:: parse2 :: < Expr > ( tokens. collect ( ) ) ?;
1139- let mut stmts = Vec :: with_capacity ( range. len ( ) + 2 ) ;
1140- stmts. push ( Stmt :: Local ( syn:: Local {
1141- attrs : Vec :: new ( ) ,
1142- let_token : token:: Let :: default ( ) ,
1143- pat : fold_pat. clone ( ) ,
1144- init : Some ( syn:: LocalInit {
1145- eq_token : token:: Eq :: default ( ) ,
1146- expr : Box :: new ( init_expr) ,
1147- diverge : None ,
1148- } ) ,
1149- semi_token : token:: Semi :: default ( ) ,
1150- } ) ) ;
1151- if !range. is_empty ( ) {
1152- let mut ctx = pattern. as_ref ( ) . map ( |ident| {
1153- let mut context = self . clone ( ) ;
1154- context. constants . insert ( ident. clone ( ) , 0 ) ;
1155- ( context, ident)
1156- } ) ;
1157- for ( index, mut expr) in range. zip_clone ( expr) {
1158- if let Some ( ( ref mut context, ident) ) = ctx {
1159- * context. constants . get_mut ( ident) . unwrap ( ) = index;
1160- }
1161- let context = ctx. as_ref ( ) . map_or ( self , |c| & c. 0 ) ;
1162- context. replace_expr ( & mut expr, & mut inner_state) ?;
1163- stmts. push ( Stmt :: Local ( syn:: Local {
1164- attrs : Vec :: new ( ) ,
1165- let_token : token:: Let :: default ( ) ,
1166- pat : fold_pat. clone ( ) ,
1167- init : Some ( syn:: LocalInit {
1168- eq_token : token:: Eq :: default ( ) ,
1169- expr : Box :: new ( expr) ,
1170- diverge : None ,
1171- } ) ,
1172- semi_token : token:: Semi :: default ( ) ,
1173- } ) ) ;
1174- }
1175- }
1176- if let Some ( span) = inner_state. unlabelled_continue {
1177- abort ! (
1178- span,
1179- "unlabelled `continue` not supported in `typle_fold!` macro"
1180- ) ;
1181- }
1182- state. propagate ( inner_state, None ) ;
1183- stmts. push ( Stmt :: Expr (
1184- Expr :: Break ( syn:: ExprBreak {
1185- attrs : Vec :: new ( ) ,
1186- break_token : token:: Break :: default ( ) ,
1187- label : None ,
1188- expr : Some ( Box :: new ( Expr :: Path ( syn:: PatPath {
1189- attrs : Vec :: new ( ) ,
1190- qself : None ,
1191- path : ident_to_path ( fold_ident) ,
1192- } ) ) ) ,
1193- } ) ,
1194- Some ( token:: Semi :: default ( ) ) ,
1195- ) ) ;
1196- // The fold may be used in an expression `typle_fold!() + ...`, in which
1197- // case the loop needs to be in parentheses.
1198- Ok ( Expr :: Paren ( syn:: ExprParen {
1199- attrs,
1200- paren_token : token:: Paren :: default ( ) ,
1201- expr : Box :: new ( Expr :: Loop ( syn:: ExprLoop {
1202- attrs : Vec :: new ( ) ,
1203- label : None ,
1204- loop_token : token:: Loop :: default ( ) ,
1205- body : Block {
1206- brace_token : token:: Brace :: default ( ) ,
1207- stmts,
1208- } ,
1209- } ) ) ,
1210- } ) )
1211- }
1212-
1213- fn replace_macro_expr (
1214- & self ,
1215- mac : & mut Macro ,
1216- attrs : & mut Vec < Attribute > ,
1217- state : & mut BlockState ,
1218- ) -> syn:: Result < Option < Expr > > {
1219- self . replace_attrs ( attrs) ?;
1220- if let Some ( macro_name) = mac. path . get_ident ( ) {
1221- let default_span = macro_name. span ( ) ;
1222- if macro_name == "typle" {
1223- // This is outside a comma-separated sequence so only no-range form is accepted
1224- // typle!(=> if T::LEN == 0 {} else {})
1225- let token_stream = std:: mem:: take ( & mut mac. tokens ) ;
1226- return self . expand_typle_macro_singleton ( token_stream, |context, token_stream| {
1227- let mut expr = syn:: parse2 :: < Expr > ( token_stream) ?;
1228- let mut state = BlockState :: default ( ) ;
1229- context. replace_expr ( & mut expr, & mut state) ?;
1230- Ok ( Some ( expr) )
1231- } ) ;
1232- } else if macro_name == "typle_fold" {
1233- let expr =
1234- self . replace_typle_fold_expr ( mac, std:: mem:: take ( attrs) , state, default_span) ?;
1235- return Ok ( Some ( expr) ) ;
1236- } else if macro_name == "typle_all" {
1237- let token_stream = std:: mem:: take ( & mut mac. tokens ) ;
1238- let expr = self . anyall (
1239- token_stream,
1240- state,
1241- BinOp :: And ( token:: AndAnd :: default ( ) ) ,
1242- true ,
1243- ) ?;
1244- return Ok ( Some ( expr) ) ;
1245- } else if macro_name == "typle_any" {
1246- let token_stream = std:: mem:: take ( & mut mac. tokens ) ;
1247- let expr = self . anyall (
1248- token_stream,
1249- state,
1250- BinOp :: Or ( token:: OrOr :: default ( ) ) ,
1251- false ,
1252- ) ?;
1253- return Ok ( Some ( expr) ) ;
1254- }
1255- }
1256- mac. tokens = self . replace_macro_token_stream ( std:: mem:: take ( & mut mac. tokens ) ) ?;
1257- Ok ( None )
1258- }
1259-
1260- fn anyall (
1261- & self ,
1262- token_stream : TokenStream ,
1263- state : & mut BlockState ,
1264- op : BinOp ,
1265- default : bool ,
1266- ) -> syn:: Result < Expr > {
1267- let mut tokens = token_stream. into_iter ( ) ;
1268- let ( pattern, mut range) = self . parse_pattern_range ( & mut tokens) ?;
1269- let expr = syn:: parse2 :: < Expr > ( tokens. collect ( ) ) ?;
1270- let all = match range. next ( ) {
1271- Some ( index) => {
1272- // Parenthesize low precedence expressions.
1273- let expr = match expr {
1274- expr @ Expr :: Lit ( syn:: PatLit {
1275- lit : Lit :: Bool ( _) , ..
1276- } ) => expr,
1277- expr @ Expr :: Block ( _) => expr,
1278- expr @ Expr :: Paren ( _) => expr,
1279- expr @ Expr :: Path ( _) => expr,
1280- expr @ Expr :: MethodCall ( _) => expr,
1281- expr @ Expr :: Field ( _) => expr,
1282- expr @ Expr :: Call ( _) => expr,
1283- expr @ Expr :: Index ( _) => expr,
1284- expr @ Expr :: Unary ( _) => expr,
1285- expr @ Expr :: Cast ( _) => expr,
1286- expr => Expr :: Paren ( syn:: ExprParen {
1287- attrs : Vec :: new ( ) ,
1288- paren_token : token:: Paren :: default ( ) ,
1289- expr : Box :: new ( expr) ,
1290- } ) ,
1291- } ;
1292-
1293- let mut context = self . clone ( ) ;
1294- if let Some ( ident) = & pattern {
1295- context. constants . insert ( ident. clone ( ) , index) ;
1296- }
1297- let mut all = expr. clone ( ) ;
1298- context. replace_expr ( & mut all, state) ?;
1299- for ( index, mut expr) in range. zip_clone ( expr) {
1300- if let Some ( ident) = & pattern {
1301- * context. constants . get_mut ( ident) . unwrap ( ) = index;
1302- }
1303- context. replace_expr ( & mut expr, state) ?;
1304- all = Expr :: Binary ( syn:: ExprBinary {
1305- attrs : Vec :: new ( ) ,
1306- left : Box :: new ( all) ,
1307- op,
1308- right : Box :: new ( expr) ,
1309- } ) ;
1310- }
1311- if let Expr :: Binary ( expr) = all {
1312- // Wrap entire expression in parentheses to:
1313- // 1. ensure that it is a single expression in a larger expression.
1314- // 2. handle ambiguity: `{ true } || { true }` is not a boolean expression.
1315- // It is a block followed by a closure that returns a boolean. Adding
1316- // parentheses `({ true } || { true })` makes it a boolean expression.
1317- all = Expr :: Paren ( syn:: ExprParen {
1318- attrs : Vec :: new ( ) ,
1319- paren_token : token:: Paren :: default ( ) ,
1320- expr : Box :: new ( Expr :: Binary ( expr) ) ,
1321- } ) ;
1322- }
1323- all
1324- }
1325- None => Expr :: Lit ( syn:: PatLit {
1326- attrs : Vec :: new ( ) ,
1327- lit : Lit :: Bool ( syn:: LitBool {
1328- value : default,
1329- span : expr. span ( ) ,
1330- } ) ,
1331- } ) ,
1332- } ;
1333- Ok ( all)
1334- }
1335-
13361109 // Look for `typle_ty!(...)` or `typle_expr!(...)` and evaluate body.
13371110 fn replace_macro_token_stream ( & self , input : TokenStream ) -> syn:: Result < TokenStream > {
13381111 enum TTState {
0 commit comments