@@ -3,7 +3,6 @@ use std::ops::ControlFlow;
3
3
4
4
use rustc_data_structures:: fx:: FxHashSet ;
5
5
use rustc_errors:: DiagMessage ;
6
- use rustc_hir:: def:: CtorKind ;
7
6
use rustc_hir:: { is_range_literal, Expr , ExprKind , Node } ;
8
7
use rustc_middle:: bug;
9
8
use rustc_middle:: ty:: layout:: { IntegerExt , LayoutOf , SizeSkeleton } ;
@@ -19,6 +18,8 @@ use rustc_target::spec::abi::Abi as SpecAbi;
19
18
use tracing:: debug;
20
19
use { rustc_ast as ast, rustc_attr as attr, rustc_hir as hir} ;
21
20
21
+ mod improper_ctypes;
22
+
22
23
use crate :: lints:: {
23
24
AmbiguousWidePointerComparisons , AmbiguousWidePointerComparisonsAddrMetadataSuggestion ,
24
25
AmbiguousWidePointerComparisonsAddrSuggestion , AtomicOrderingFence , AtomicOrderingLoad ,
@@ -1405,38 +1406,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1405
1406
} ;
1406
1407
}
1407
1408
1408
- // non_exhaustive suggests it is possible that someone might break ABI
1409
- // see: https://github.com/rust-lang/rust/issues/44109#issuecomment-537583344
1410
- // so warn on complex enums being used outside their crate
1411
- let nonexhaustive_nonlocal_ffi =
1412
- def. is_variant_list_non_exhaustive ( ) && !def. did ( ) . is_local ( ) ;
1409
+ use improper_ctypes:: {
1410
+ check_non_exhaustive_variant, non_local_and_non_exhaustive,
1411
+ } ;
1413
1412
1413
+ let non_local_def = non_local_and_non_exhaustive ( def) ;
1414
1414
// Check the contained variants.
1415
- for variant in def. variants ( ) {
1416
- // but only warn about really_tagged_union reprs,
1417
- // exempt enums with unit ctors like C's (like rust-bindgen)
1418
- if nonexhaustive_nonlocal_ffi
1419
- && !matches ! ( variant. ctor_kind( ) , Some ( CtorKind :: Const ) )
1420
- {
1421
- return FfiUnsafe {
1422
- ty,
1423
- reason : fluent:: lint_improper_ctypes_non_exhaustive,
1424
- help : None ,
1425
- } ;
1426
- } ;
1427
- let is_non_exhaustive = variant. is_field_list_non_exhaustive ( ) ;
1428
- if is_non_exhaustive && !variant. def_id . is_local ( ) {
1429
- return FfiUnsafe {
1430
- ty,
1431
- reason : fluent:: lint_improper_ctypes_non_exhaustive_variant,
1432
- help : None ,
1433
- } ;
1434
- }
1415
+ let ret = def. variants ( ) . iter ( ) . try_for_each ( |variant| {
1416
+ check_non_exhaustive_variant ( non_local_def, variant)
1417
+ . map_break ( |reason| FfiUnsafe { ty, reason, help : None } ) ?;
1435
1418
1436
1419
match self . check_variant_for_ffi ( acc, ty, def, variant, args) {
1437
- FfiSafe => ( ) ,
1438
- r => return r ,
1420
+ FfiSafe => ControlFlow :: Continue ( ( ) ) ,
1421
+ r => ControlFlow :: Break ( r ) ,
1439
1422
}
1423
+ } ) ;
1424
+ if let ControlFlow :: Break ( result) = ret {
1425
+ return result;
1440
1426
}
1441
1427
1442
1428
FfiSafe
0 commit comments