@@ -232,6 +232,24 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
232
232
}
233
233
}
234
234
235
+ fn check_unwind_edge ( & mut self , location : Location , unwind : UnwindAction ) {
236
+ let is_cleanup = self . body . basic_blocks [ location. block ] . is_cleanup ;
237
+ match unwind {
238
+ UnwindAction :: Cleanup ( unwind) => {
239
+ if is_cleanup {
240
+ self . fail ( location, "unwind on cleanup block" ) ;
241
+ }
242
+ self . check_edge ( location, unwind, EdgeKind :: Unwind ) ;
243
+ }
244
+ UnwindAction :: Continue => {
245
+ if is_cleanup {
246
+ self . fail ( location, "unwind on cleanup block" ) ;
247
+ }
248
+ }
249
+ UnwindAction :: Unreachable | UnwindAction :: Terminate => ( ) ,
250
+ }
251
+ }
252
+
235
253
/// Check if src can be assigned into dest.
236
254
/// This is not precise, it will accept some incorrect assignments.
237
255
fn mir_assign_valid_types ( & self , src : Ty < ' tcx > , dest : Ty < ' tcx > ) -> bool {
@@ -902,9 +920,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
902
920
}
903
921
TerminatorKind :: Drop { target, unwind, .. } => {
904
922
self . check_edge ( location, * target, EdgeKind :: Normal ) ;
905
- if let UnwindAction :: Cleanup ( unwind) = unwind {
906
- self . check_edge ( location, * unwind, EdgeKind :: Unwind ) ;
907
- }
923
+ self . check_unwind_edge ( location, * unwind) ;
908
924
}
909
925
TerminatorKind :: Call { func, args, destination, target, unwind, .. } => {
910
926
let func_ty = func. ty ( & self . body . local_decls , self . tcx ) ;
@@ -918,9 +934,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
918
934
if let Some ( target) = target {
919
935
self . check_edge ( location, * target, EdgeKind :: Normal ) ;
920
936
}
921
- if let UnwindAction :: Cleanup ( cleanup) = unwind {
922
- self . check_edge ( location, * cleanup, EdgeKind :: Unwind ) ;
923
- }
937
+ self . check_unwind_edge ( location, * unwind) ;
924
938
925
939
// The call destination place and Operand::Move place used as an argument might be
926
940
// passed by a reference to the callee. Consequently they must be non-overlapping.
@@ -958,9 +972,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
958
972
) ;
959
973
}
960
974
self . check_edge ( location, * target, EdgeKind :: Normal ) ;
961
- if let UnwindAction :: Cleanup ( cleanup) = unwind {
962
- self . check_edge ( location, * cleanup, EdgeKind :: Unwind ) ;
963
- }
975
+ self . check_unwind_edge ( location, * unwind) ;
964
976
}
965
977
TerminatorKind :: Yield { resume, drop, .. } => {
966
978
if self . body . generator . is_none ( ) {
@@ -992,17 +1004,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
992
1004
) ;
993
1005
}
994
1006
self . check_edge ( location, * real_target, EdgeKind :: Normal ) ;
995
- if let UnwindAction :: Cleanup ( unwind) = unwind {
996
- self . check_edge ( location, * unwind, EdgeKind :: Unwind ) ;
997
- }
1007
+ self . check_unwind_edge ( location, * unwind) ;
998
1008
}
999
1009
TerminatorKind :: InlineAsm { destination, unwind, .. } => {
1000
1010
if let Some ( destination) = destination {
1001
1011
self . check_edge ( location, * destination, EdgeKind :: Normal ) ;
1002
1012
}
1003
- if let UnwindAction :: Cleanup ( cleanup) = unwind {
1004
- self . check_edge ( location, * cleanup, EdgeKind :: Unwind ) ;
1005
- }
1013
+ self . check_unwind_edge ( location, * unwind) ;
1006
1014
}
1007
1015
TerminatorKind :: GeneratorDrop => {
1008
1016
if self . body . generator . is_none ( ) {
0 commit comments