@@ -43,7 +43,7 @@ pub(crate) fn handle_nested_loops<'a>(
4343 need_to_shadow. push ( iterable) ;
4444 quote ! { & #iterable }
4545 }
46- Expr :: MethodCall ( _) => match crate :: is_iter ( iterable) {
46+ Expr :: MethodCall ( _) => match is_iter ( iterable) {
4747 true => quote ! { #iterable } ,
4848 _ => panic ! (
4949 "please ensure the first method call is iter(): \n {:#?}" ,
@@ -89,6 +89,46 @@ pub(crate) fn handle_nested_loops<'a>(
8989 nested_code
9090}
9191
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+
92132#[ cfg( test) ]
93133mod tests {
94134 use super :: * ;
0 commit comments