@@ -39,6 +39,7 @@ use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
39
39
use rustc_trait_selection:: traits:: error_reporting:: FindExprBySpan ;
40
40
use rustc_trait_selection:: traits:: { Obligation , ObligationCause , ObligationCtxt } ;
41
41
use std:: iter;
42
+ use std:: ops:: ControlFlow ;
42
43
43
44
use crate :: borrow_set:: TwoPhaseActivation ;
44
45
use crate :: borrowck_errors;
@@ -784,20 +785,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
784
785
/// binding declaration within every scope we inspect.
785
786
struct Finder {
786
787
hir_id : hir:: HirId ,
787
- found : bool ,
788
788
}
789
789
impl < ' hir > Visitor < ' hir > for Finder {
790
- fn visit_pat ( & mut self , pat : & ' hir hir:: Pat < ' hir > ) {
790
+ type Result = ControlFlow < ( ) > ;
791
+ fn visit_pat ( & mut self , pat : & ' hir hir:: Pat < ' hir > ) -> Self :: Result {
791
792
if pat. hir_id == self . hir_id {
792
- self . found = true ;
793
+ return ControlFlow :: Break ( ( ) ) ;
793
794
}
794
- hir:: intravisit:: walk_pat ( self , pat) ;
795
+ hir:: intravisit:: walk_pat ( self , pat)
795
796
}
796
- fn visit_expr ( & mut self , ex : & ' hir hir:: Expr < ' hir > ) {
797
+ fn visit_expr ( & mut self , ex : & ' hir hir:: Expr < ' hir > ) -> Self :: Result {
797
798
if ex. hir_id == self . hir_id {
798
- self . found = true ;
799
+ return ControlFlow :: Break ( ( ) ) ;
799
800
}
800
- hir:: intravisit:: walk_expr ( self , ex) ;
801
+ hir:: intravisit:: walk_expr ( self , ex)
801
802
}
802
803
}
803
804
// The immediate HIR parent of the moved expression. We'll look for it to be a call.
@@ -822,9 +823,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
822
823
_ => continue ,
823
824
} ;
824
825
if let Some ( & hir_id) = local_hir_id {
825
- let mut finder = Finder { hir_id, found : false } ;
826
- finder. visit_expr ( e) ;
827
- if finder. found {
826
+ if ( Finder { hir_id } ) . visit_expr ( e) . is_break ( ) {
828
827
// The current scope includes the declaration of the binding we're accessing, we
829
828
// can't look up any further for loops.
830
829
break ;
@@ -839,9 +838,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
839
838
hir:: Node :: Expr ( hir:: Expr {
840
839
kind : hir:: ExprKind :: If ( cond, ..) , ..
841
840
} ) => {
842
- let mut finder = Finder { hir_id : expr. hir_id , found : false } ;
843
- finder. visit_expr ( cond) ;
844
- if finder. found {
841
+ if ( Finder { hir_id : expr. hir_id } ) . visit_expr ( cond) . is_break ( ) {
845
842
// The expression where the move error happened is in a `while let`
846
843
// condition Don't suggest clone as it will likely end in an
847
844
// infinite loop.
@@ -1837,15 +1834,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
1837
1834
1838
1835
pub struct Holds < ' tcx > {
1839
1836
ty : Ty < ' tcx > ,
1840
- holds : bool ,
1841
1837
}
1842
1838
1843
1839
impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for Holds < ' tcx > {
1844
1840
type Result = std:: ops:: ControlFlow < ( ) > ;
1845
1841
1846
1842
fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> Self :: Result {
1847
1843
if t == self . ty {
1848
- self . holds = true ;
1844
+ return ControlFlow :: Break ( ( ) ) ;
1849
1845
}
1850
1846
t. super_visit_with ( self )
1851
1847
}
@@ -1863,9 +1859,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
1863
1859
&& rcvr_ty == ty
1864
1860
&& let ty:: Ref ( _, inner, _) = rcvr_ty. kind ( )
1865
1861
&& let inner = inner. peel_refs ( )
1866
- && let mut v = ( Holds { ty : inner, holds : false } )
1867
- && let _ = v. visit_ty ( local_ty)
1868
- && v. holds
1862
+ && ( Holds { ty : inner } ) . visit_ty ( local_ty) . is_break ( )
1869
1863
&& let None = self . infcx . type_implements_trait_shallow ( clone, inner, self . param_env )
1870
1864
{
1871
1865
err. span_label (
@@ -4325,15 +4319,14 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
4325
4319
}
4326
4320
4327
4321
/// Detect whether one of the provided spans is a statement nested within the top-most visited expr
4328
- struct ReferencedStatementsVisitor < ' a > ( & ' a [ Span ] , bool ) ;
4322
+ struct ReferencedStatementsVisitor < ' a > ( & ' a [ Span ] ) ;
4329
4323
4330
- impl < ' a , ' v > Visitor < ' v > for ReferencedStatementsVisitor < ' a > {
4331
- fn visit_stmt ( & mut self , s : & ' v hir:: Stmt < ' v > ) {
4324
+ impl < ' v > Visitor < ' v > for ReferencedStatementsVisitor < ' _ > {
4325
+ type Result = ControlFlow < ( ) > ;
4326
+ fn visit_stmt ( & mut self , s : & ' v hir:: Stmt < ' v > ) -> Self :: Result {
4332
4327
match s. kind {
4333
- hir:: StmtKind :: Semi ( expr) if self . 0 . contains ( & expr. span ) => {
4334
- self . 1 = true ;
4335
- }
4336
- _ => { }
4328
+ hir:: StmtKind :: Semi ( expr) if self . 0 . contains ( & expr. span ) => ControlFlow :: Break ( ( ) ) ,
4329
+ _ => ControlFlow :: Continue ( ( ) ) ,
4337
4330
}
4338
4331
}
4339
4332
}
@@ -4375,9 +4368,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
4375
4368
hir:: ExprKind :: If ( cond, body, None ) => {
4376
4369
// `if` expressions with no `else` that initialize the binding might be missing an
4377
4370
// `else` arm.
4378
- let mut v = ReferencedStatementsVisitor ( self . spans , false ) ;
4379
- v. visit_expr ( body) ;
4380
- if v. 1 {
4371
+ if ReferencedStatementsVisitor ( self . spans ) . visit_expr ( body) . is_break ( ) {
4381
4372
self . errors . push ( (
4382
4373
cond. span ,
4383
4374
format ! (
@@ -4394,11 +4385,9 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
4394
4385
hir:: ExprKind :: If ( cond, body, Some ( other) ) => {
4395
4386
// `if` expressions where the binding is only initialized in one of the two arms
4396
4387
// might be missing a binding initialization.
4397
- let mut a = ReferencedStatementsVisitor ( self . spans , false ) ;
4398
- a. visit_expr ( body) ;
4399
- let mut b = ReferencedStatementsVisitor ( self . spans , false ) ;
4400
- b. visit_expr ( other) ;
4401
- match ( a. 1 , b. 1 ) {
4388
+ let a = ReferencedStatementsVisitor ( self . spans ) . visit_expr ( body) . is_break ( ) ;
4389
+ let b = ReferencedStatementsVisitor ( self . spans ) . visit_expr ( other) . is_break ( ) ;
4390
+ match ( a, b) {
4402
4391
( true , true ) | ( false , false ) => { }
4403
4392
( true , false ) => {
4404
4393
if other. span . is_desugaring ( DesugaringKind :: WhileLoop ) {
@@ -4437,11 +4426,7 @@ impl<'b, 'v, 'tcx> Visitor<'v> for ConditionVisitor<'b, 'tcx> {
4437
4426
// arms might be missing an initialization.
4438
4427
let results: Vec < bool > = arms
4439
4428
. iter ( )
4440
- . map ( |arm| {
4441
- let mut v = ReferencedStatementsVisitor ( self . spans , false ) ;
4442
- v. visit_arm ( arm) ;
4443
- v. 1
4444
- } )
4429
+ . map ( |arm| ReferencedStatementsVisitor ( self . spans ) . visit_arm ( arm) . is_break ( ) )
4445
4430
. collect ( ) ;
4446
4431
if results. iter ( ) . any ( |x| * x) && !results. iter ( ) . all ( |x| * x) {
4447
4432
for ( arm, seen) in arms. iter ( ) . zip ( results) {
0 commit comments