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 , DiagnosticBuilder } ;
6
7
use rustc_hir as hir;
@@ -732,30 +733,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
732
733
_ => local_decl. source_info . span ,
733
734
} ;
734
735
735
- struct BindingFinder {
736
- span : Span ,
737
- hir_id : Option < hir:: HirId > ,
738
- }
739
-
740
- impl < ' tcx > Visitor < ' tcx > for BindingFinder {
741
- fn visit_stmt ( & mut self , s : & ' tcx hir:: Stmt < ' tcx > ) {
742
- if let hir:: StmtKind :: Local ( local) = s. kind {
743
- if local. pat . span == self . span {
744
- self . hir_id = Some ( local. hir_id ) ;
745
- }
746
- }
747
- hir:: intravisit:: walk_stmt ( self , s) ;
748
- }
749
- }
750
-
751
736
let def_id = self . body . source . def_id ( ) ;
752
737
let hir_id = if let Some ( local_def_id) = def_id. as_local ( )
753
738
&& let Some ( body_id) = self . infcx . tcx . hir ( ) . maybe_body_owned_by ( local_def_id)
754
739
{
755
740
let body = self . infcx . tcx . hir ( ) . body ( body_id) ;
756
- let mut v = BindingFinder { span : pat_span, hir_id : None } ;
757
- v. visit_body ( body) ;
758
- v. hir_id
741
+ BindingFinder { span : pat_span } . visit_body ( body) . break_value ( )
759
742
} else {
760
743
None
761
744
} ;
@@ -864,17 +847,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
864
847
} ;
865
848
866
849
let hir_map = self . infcx . tcx . hir ( ) ;
867
- struct Finder < ' tcx > {
850
+ struct Finder {
868
851
span : Span ,
869
- expr : Option < & ' tcx Expr < ' tcx > > ,
870
852
}
871
853
872
- impl < ' tcx > Visitor < ' tcx > for Finder < ' tcx > {
873
- fn visit_expr ( & mut self , e : & ' tcx hir:: Expr < ' tcx > ) {
874
- if e. span == self . span && self . expr . is_none ( ) {
875
- self . expr = Some ( e) ;
854
+ impl < ' tcx > Visitor < ' tcx > for Finder {
855
+ type Result = ControlFlow < & ' tcx Expr < ' tcx > > ;
856
+ fn visit_expr ( & mut self , e : & ' tcx hir:: Expr < ' tcx > ) -> Self :: Result {
857
+ if e. span == self . span {
858
+ ControlFlow :: Break ( e)
859
+ } else {
860
+ hir:: intravisit:: walk_expr ( self , e)
876
861
}
877
- hir:: intravisit:: walk_expr ( self , e) ;
878
862
}
879
863
}
880
864
if let Some ( body_id) = hir_map. maybe_body_owned_by ( self . mir_def_id ( ) )
@@ -883,9 +867,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
883
867
// `span` corresponds to the expression being iterated, find the `for`-loop desugared
884
868
// expression with that span in order to identify potential fixes when encountering a
885
869
// read-only iterator that should be mutable.
886
- let mut v = Finder { span, expr : None } ;
887
- v. visit_block ( block) ;
888
- if let Some ( expr) = v. expr
870
+ if let ControlFlow :: Break ( expr) = ( Finder { span } ) . visit_block ( block)
889
871
&& let Call ( _, [ expr] ) = expr. kind
890
872
{
891
873
match expr. kind {
@@ -1184,29 +1166,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
1184
1166
) ;
1185
1167
}
1186
1168
Some ( ( false , err_label_span, message) ) => {
1187
- struct BindingFinder {
1188
- span : Span ,
1189
- hir_id : Option < hir:: HirId > ,
1190
- }
1191
-
1192
- impl < ' tcx > Visitor < ' tcx > for BindingFinder {
1193
- fn visit_stmt ( & mut self , s : & ' tcx hir:: Stmt < ' tcx > ) {
1194
- if let hir:: StmtKind :: Local ( local) = s. kind {
1195
- if local. pat . span == self . span {
1196
- self . hir_id = Some ( local. hir_id ) ;
1197
- }
1198
- }
1199
- hir:: intravisit:: walk_stmt ( self , s) ;
1200
- }
1201
- }
1202
1169
let def_id = self . body . source . def_id ( ) ;
1203
1170
let hir_id = if let Some ( local_def_id) = def_id. as_local ( )
1204
1171
&& let Some ( body_id) = self . infcx . tcx . hir ( ) . maybe_body_owned_by ( local_def_id)
1205
1172
{
1206
1173
let body = self . infcx . tcx . hir ( ) . body ( body_id) ;
1207
- let mut v = BindingFinder { span : err_label_span, hir_id : None } ;
1208
- v. visit_body ( body) ;
1209
- v. hir_id
1174
+ BindingFinder { span : err_label_span } . visit_body ( body) . break_value ( )
1210
1175
} else {
1211
1176
None
1212
1177
} ;
@@ -1338,6 +1303,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
1338
1303
}
1339
1304
}
1340
1305
1306
+ struct BindingFinder {
1307
+ span : Span ,
1308
+ }
1309
+
1310
+ impl < ' tcx > Visitor < ' tcx > for BindingFinder {
1311
+ type Result = ControlFlow < hir:: HirId > ;
1312
+ fn visit_stmt ( & mut self , s : & ' tcx hir:: Stmt < ' tcx > ) -> Self :: Result {
1313
+ if let hir:: StmtKind :: Local ( local) = s. kind
1314
+ && local. pat . span == self . span
1315
+ {
1316
+ ControlFlow :: Break ( local. hir_id )
1317
+ } else {
1318
+ hir:: intravisit:: walk_stmt ( self , s)
1319
+ }
1320
+ }
1321
+ }
1322
+
1341
1323
pub fn mut_borrow_of_mutable_ref ( local_decl : & LocalDecl < ' _ > , local_name : Option < Symbol > ) -> bool {
1342
1324
debug ! ( "local_info: {:?}, ty.kind(): {:?}" , local_decl. local_info, local_decl. ty. kind( ) ) ;
1343
1325
0 commit comments