@@ -43,7 +43,7 @@ pub(crate) fn handle_nested_loops<'a>(
43
43
need_to_shadow. push ( iterable) ;
44
44
quote ! { & #iterable }
45
45
}
46
- Expr :: MethodCall ( _) => match crate :: is_iter ( iterable) {
46
+ Expr :: MethodCall ( _) => match is_iter ( iterable) {
47
47
true => quote ! { #iterable } ,
48
48
_ => panic ! (
49
49
"please ensure the first method call is iter(): \n {:#?}" ,
@@ -89,6 +89,46 @@ pub(crate) fn handle_nested_loops<'a>(
89
89
nested_code
90
90
}
91
91
92
+ struct IterMethodCallFinder {
93
+ is_iter : bool ,
94
+ }
95
+
96
+ use syn:: { ExprMethodCall , visit:: Visit } ;
97
+ impl < ' ast > Visit < ' ast > for IterMethodCallFinder {
98
+ fn visit_expr_method_call ( & mut self , node : & ' ast ExprMethodCall ) {
99
+ match * node. receiver {
100
+ syn:: Expr :: Path ( _) | syn:: Expr :: Field ( _) => {
101
+ if node. method == "iter" {
102
+ self . is_iter = true ;
103
+ }
104
+ }
105
+ _ => syn:: visit:: visit_expr ( & mut * self , & node. receiver ) ,
106
+ }
107
+ }
108
+ }
109
+
110
+ fn is_iter ( expr : & syn:: Expr ) -> bool {
111
+ let mut finder = IterMethodCallFinder { is_iter : false } ;
112
+ finder. visit_expr ( expr) ;
113
+
114
+ finder. is_iter
115
+ }
116
+
117
+ #[ test]
118
+ fn test_is_iter ( ) {
119
+ // 最右侧是iter方法
120
+ let expr = syn:: parse_quote!( some. method_1( ) . method_2( ) . iter( ) ) ;
121
+ assert ! ( !is_iter( & expr) ) ;
122
+ eprintln ! ( "--------------------------------" ) ;
123
+ // 最左侧是iter方法
124
+ let expr = syn:: parse_quote!( some. iter( ) . method_3( ) . method_4( ) ) ;
125
+ assert ! ( is_iter( & expr) ) ;
126
+ eprintln ! ( "--------------------------------" ) ;
127
+
128
+ let expr = syn:: parse_quote!( some. method_5( ) . iter( ) . method_6( ) ) ;
129
+ assert ! ( !is_iter( & expr) ) ;
130
+ }
131
+
92
132
#[ cfg( test) ]
93
133
mod tests {
94
134
use super :: * ;
0 commit comments