1
1
#![ allow( rustc:: diagnostic_outside_of_impl) ]
2
2
#![ allow( rustc:: untranslatable_diagnostic) ]
3
3
4
+ use core:: ops:: ControlFlow ;
4
5
use hir:: ExprKind ;
5
6
use rustc_errors:: { Applicability , Diag } ;
6
7
use rustc_hir as hir;
@@ -727,30 +728,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
727
728
_ => local_decl. source_info . span ,
728
729
} ;
729
730
730
- struct BindingFinder {
731
- span : Span ,
732
- hir_id : Option < hir:: HirId > ,
733
- }
734
-
735
- impl < ' tcx > Visitor < ' tcx > for BindingFinder {
736
- fn visit_stmt ( & mut self , s : & ' tcx hir:: Stmt < ' tcx > ) {
737
- if let hir:: StmtKind :: Local ( local) = s. kind {
738
- if local. pat . span == self . span {
739
- self . hir_id = Some ( local. hir_id ) ;
740
- }
741
- }
742
- hir:: intravisit:: walk_stmt ( self , s) ;
743
- }
744
- }
745
-
746
731
let def_id = self . body . source . def_id ( ) ;
747
732
let hir_id = if let Some ( local_def_id) = def_id. as_local ( )
748
733
&& let Some ( body_id) = self . infcx . tcx . hir ( ) . maybe_body_owned_by ( local_def_id)
749
734
{
750
735
let body = self . infcx . tcx . hir ( ) . body ( body_id) ;
751
- let mut v = BindingFinder { span : pat_span, hir_id : None } ;
752
- v. visit_body ( body) ;
753
- v. hir_id
736
+ BindingFinder { span : pat_span } . visit_body ( body) . break_value ( )
754
737
} else {
755
738
None
756
739
} ;
@@ -859,17 +842,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
859
842
} ;
860
843
861
844
let hir_map = self . infcx . tcx . hir ( ) ;
862
- struct Finder < ' tcx > {
845
+ struct Finder {
863
846
span : Span ,
864
- expr : Option < & ' tcx Expr < ' tcx > > ,
865
847
}
866
848
867
- impl < ' tcx > Visitor < ' tcx > for Finder < ' tcx > {
868
- fn visit_expr ( & mut self , e : & ' tcx hir:: Expr < ' tcx > ) {
869
- if e. span == self . span && self . expr . is_none ( ) {
870
- self . expr = Some ( e) ;
849
+ impl < ' tcx > Visitor < ' tcx > for Finder {
850
+ type Result = ControlFlow < & ' tcx Expr < ' tcx > > ;
851
+ fn visit_expr ( & mut self , e : & ' tcx hir:: Expr < ' tcx > ) -> Self :: Result {
852
+ if e. span == self . span {
853
+ ControlFlow :: Break ( e)
854
+ } else {
855
+ hir:: intravisit:: walk_expr ( self , e)
871
856
}
872
- hir:: intravisit:: walk_expr ( self , e) ;
873
857
}
874
858
}
875
859
if let Some ( body_id) = hir_map. maybe_body_owned_by ( self . mir_def_id ( ) )
@@ -878,9 +862,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
878
862
// `span` corresponds to the expression being iterated, find the `for`-loop desugared
879
863
// expression with that span in order to identify potential fixes when encountering a
880
864
// read-only iterator that should be mutable.
881
- let mut v = Finder { span, expr : None } ;
882
- v. visit_block ( block) ;
883
- if let Some ( expr) = v. expr
865
+ if let ControlFlow :: Break ( expr) = ( Finder { span } ) . visit_block ( block)
884
866
&& let Call ( _, [ expr] ) = expr. kind
885
867
{
886
868
match expr. kind {
@@ -1179,29 +1161,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
1179
1161
) ;
1180
1162
}
1181
1163
Some ( ( false , err_label_span, message) ) => {
1182
- struct BindingFinder {
1183
- span : Span ,
1184
- hir_id : Option < hir:: HirId > ,
1185
- }
1186
-
1187
- impl < ' tcx > Visitor < ' tcx > for BindingFinder {
1188
- fn visit_stmt ( & mut self , s : & ' tcx hir:: Stmt < ' tcx > ) {
1189
- if let hir:: StmtKind :: Local ( local) = s. kind {
1190
- if local. pat . span == self . span {
1191
- self . hir_id = Some ( local. hir_id ) ;
1192
- }
1193
- }
1194
- hir:: intravisit:: walk_stmt ( self , s) ;
1195
- }
1196
- }
1197
1164
let def_id = self . body . source . def_id ( ) ;
1198
1165
let hir_id = if let Some ( local_def_id) = def_id. as_local ( )
1199
1166
&& let Some ( body_id) = self . infcx . tcx . hir ( ) . maybe_body_owned_by ( local_def_id)
1200
1167
{
1201
1168
let body = self . infcx . tcx . hir ( ) . body ( body_id) ;
1202
- let mut v = BindingFinder { span : err_label_span, hir_id : None } ;
1203
- v. visit_body ( body) ;
1204
- v. hir_id
1169
+ BindingFinder { span : err_label_span } . visit_body ( body) . break_value ( )
1205
1170
} else {
1206
1171
None
1207
1172
} ;
@@ -1333,6 +1298,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
1333
1298
}
1334
1299
}
1335
1300
1301
+ struct BindingFinder {
1302
+ span : Span ,
1303
+ }
1304
+
1305
+ impl < ' tcx > Visitor < ' tcx > for BindingFinder {
1306
+ type Result = ControlFlow < hir:: HirId > ;
1307
+ fn visit_stmt ( & mut self , s : & ' tcx hir:: Stmt < ' tcx > ) -> Self :: Result {
1308
+ if let hir:: StmtKind :: Local ( local) = s. kind
1309
+ && local. pat . span == self . span
1310
+ {
1311
+ ControlFlow :: Break ( local. hir_id )
1312
+ } else {
1313
+ hir:: intravisit:: walk_stmt ( self , s)
1314
+ }
1315
+ }
1316
+ }
1317
+
1336
1318
pub fn mut_borrow_of_mutable_ref ( local_decl : & LocalDecl < ' _ > , local_name : Option < Symbol > ) -> bool {
1337
1319
debug ! ( "local_info: {:?}, ty.kind(): {:?}" , local_decl. local_info, local_decl. ty. kind( ) ) ;
1338
1320
0 commit comments