@@ -31,26 +31,20 @@ pub(super) fn lint(cx: &LateContext<'_>, expr: &'tcx Expr<'_>, args: &[&[Expr<'_
3131 let body = cx. tcx. hir( ) . body( body_id) ;
3232 if let ExprKind :: Block ( ..) = body. value. kind;
3333 then {
34- let mut ret_span_collector = RetSpanCollector :: new( ) ;
35- ret_span_collector. visit_expr( & body. value) ;
36-
37- let label = "'outer" ;
38- let loop_label = if ret_span_collector. need_label {
39- format!( "{}: " , label)
40- } else {
41- "" . to_string( )
42- } ;
34+ let mut ret_collector = RetCollector :: new( ) ;
35+ ret_collector. visit_expr( & body. value) ;
36+
37+ // Skip the lint if `return` is used in `Loop` to avoid a suggest using `'label`.
38+ if ret_collector. ret_in_loop {
39+ return ;
40+ }
41+
4342 let sugg =
44- format!( "{} for {} in {} {{ .. }}" , loop_label , snippet( cx, body. params[ 0 ] . pat. span, "" ) , snippet( cx, for_each_receiver. span, "" ) ) ;
43+ format!( "for {} in {} {{ .. }}" , snippet( cx, body. params[ 0 ] . pat. span, "" ) , snippet( cx, for_each_receiver. span, "" ) ) ;
4544
4645 let mut notes = vec![ ] ;
47- for ( span, need_label) in ret_span_collector. spans {
48- let cont_label = if need_label {
49- format!( " {}" , label)
50- } else {
51- "" . to_string( )
52- } ;
53- let note = format!( "change `return` to `continue{}` in the loop body" , cont_label) ;
46+ for span in ret_collector. spans {
47+ let note = format!( "change `return` to `continue` in the loop body" ) ;
5448 notes. push( ( span, note) ) ;
5549 }
5650
@@ -100,34 +94,37 @@ fn is_target_ty(cx: &LateContext<'_>, expr_ty: Ty<'_>) -> bool {
10094 false
10195}
10296
103- /// Collect spans of `return` in the closure body.
104- struct RetSpanCollector {
105- spans : Vec < ( Span , bool ) > ,
97+ /// This type plays two roles.
98+ /// 1. Collect spans of `return` in the closure body.
99+ /// 2. Detect use of `return` in `Loop` in the closure body.
100+ struct RetCollector {
101+ spans : Vec < Span > ,
102+ ret_in_loop : bool ,
103+
106104 loop_depth : u16 ,
107- need_label : bool ,
108105}
109106
110- impl RetSpanCollector {
107+ impl RetCollector {
111108 fn new ( ) -> Self {
112109 Self {
113110 spans : Vec :: new ( ) ,
111+ ret_in_loop : false ,
114112 loop_depth : 0 ,
115- need_label : false ,
116113 }
117114 }
118115}
119116
120- impl < ' tcx > Visitor < ' tcx > for RetSpanCollector {
117+ impl < ' tcx > Visitor < ' tcx > for RetCollector {
121118 type Map = Map < ' tcx > ;
122119
123120 fn visit_expr ( & mut self , expr : & Expr < ' _ > ) {
124121 match expr. kind {
125122 ExprKind :: Ret ( ..) => {
126- if self . loop_depth > 0 && !self . need_label {
127- self . need_label = true
123+ if self . loop_depth > 0 && !self . ret_in_loop {
124+ self . ret_in_loop = true
128125 }
129126
130- self . spans . push ( ( expr. span , self . loop_depth > 0 ) )
127+ self . spans . push ( expr. span )
131128 } ,
132129
133130 ExprKind :: Loop ( ..) => {
0 commit comments