@@ -8,7 +8,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
88use rustc_hir as hir;
99use rustc_hir:: def:: { CtorOf , DefKind } ;
1010use rustc_hir:: lang_items:: LangItem ;
11- use rustc_hir:: { ExprKind , ItemKind , Node , StmtKind } ;
11+ use rustc_hir:: { Expr , ExprKind , ItemKind , Node , Stmt , StmtKind } ;
1212use rustc_infer:: infer;
1313use rustc_middle:: lint:: in_external_macro;
1414use rustc_middle:: ty:: { self , Binder , Ty } ;
@@ -489,18 +489,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
489489 }
490490 let found = self . resolve_vars_with_obligations ( found) ;
491491
492- if self . in_loop ( id) {
493- if self . in_local_statement ( id) {
494- err. multipart_suggestion (
495- "you might have meant to break the loop with this value" ,
496- vec ! [
497- ( expr. span. shrink_to_lo( ) , "break " . to_string( ) ) ,
498- ( expr. span. shrink_to_hi( ) , ";" . to_string( ) ) ,
499- ] ,
500- Applicability :: MaybeIncorrect ,
501- ) ;
502- return ;
503- }
492+ let in_loop = self . is_loop ( id)
493+ || self . tcx . hir ( ) . parent_iter ( id) . any ( |( parent_id, _) | self . is_loop ( parent_id) ) ;
494+
495+ let in_local_statement = self . is_local_statement ( id)
496+ || self
497+ . tcx
498+ . hir ( )
499+ . parent_iter ( id)
500+ . any ( |( parent_id, _) | self . is_local_statement ( parent_id) ) ;
501+
502+ if in_loop && in_local_statement {
503+ err. multipart_suggestion (
504+ "you might have meant to break the loop with this value" ,
505+ vec ! [
506+ ( expr. span. shrink_to_lo( ) , "break " . to_string( ) ) ,
507+ ( expr. span. shrink_to_hi( ) , ";" . to_string( ) ) ,
508+ ] ,
509+ Applicability :: MaybeIncorrect ,
510+ ) ;
511+ return ;
504512 }
505513
506514 if let hir:: FnRetTy :: Return ( ty) = fn_decl. output {
@@ -533,55 +541,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
533541 }
534542 }
535543
536- fn in_loop ( & self , id : hir:: HirId ) -> bool {
537- if self . is_loop ( id) {
538- return true ;
539- }
540-
541- for ( parent_id, _) in self . tcx . hir ( ) . parent_iter ( id) {
542- if self . is_loop ( parent_id) {
543- return true ;
544- }
545- }
546-
547- false
548- }
549-
550544 fn is_loop ( & self , id : hir:: HirId ) -> bool {
551545 let node = self . tcx . hir ( ) . get ( id) ;
552-
553- if let Node :: Expr ( expr) = node {
554- if let ExprKind :: Loop ( ..) = expr. kind {
555- return true ;
556- }
557- }
558-
559- false
560- }
561-
562- fn in_local_statement ( & self , id : hir:: HirId ) -> bool {
563- if self . is_local_statement ( id) {
564- return true ;
565- }
566-
567- for ( parent_id, _) in self . tcx . hir ( ) . parent_iter ( id) {
568- if self . is_local_statement ( parent_id) {
569- return true ;
570- }
571- }
572-
573- false
546+ matches ! ( node, Node :: Expr ( Expr { kind: ExprKind :: Loop ( ..) , .. } ) )
574547 }
575548
576549 fn is_local_statement ( & self , id : hir:: HirId ) -> bool {
577550 let node = self . tcx . hir ( ) . get ( id) ;
578-
579- if let Node :: Stmt ( stmt) = node {
580- if let StmtKind :: Local ( ..) = stmt. kind {
581- return true ;
582- }
583- }
584-
585- false
551+ matches ! ( node, Node :: Stmt ( Stmt { kind: StmtKind :: Local ( ..) , .. } ) )
586552 }
587553}
0 commit comments