@@ -833,6 +833,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
833
833
llret_ty : & ' ll Type ,
834
834
span : Span ,
835
835
) -> Result < & ' ll Value , ( ) > {
836
+ // Existing macros:
837
+
836
838
// macros for error handling:
837
839
#[ allow( unused_macro_rules) ]
838
840
macro_rules! emit_error {
@@ -870,13 +872,50 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
870
872
} ;
871
873
}
872
874
875
+ // [Experimental] macros for localized error handling:
876
+
877
+ macro_rules! return_localized_error {
878
+ ( $diag: tt) => { {
879
+ bx. sess( ) . emit_err( $diag) ;
880
+ return Err ( ( ) ) ;
881
+ } } ;
882
+ }
883
+
884
+ macro_rules! require_localized {
885
+ ( $cond: expr, $diag: tt) => {
886
+ if !$cond {
887
+ return_localized_error!( $diag) ;
888
+ }
889
+ } ;
890
+ }
891
+
892
+ macro_rules! require_simd_localized {
893
+ ( $ty: expr, $diag: tt) => {
894
+ require_localized!( $ty. is_simd( ) , $diag)
895
+ } ;
896
+ }
897
+
873
898
let tcx = bx. tcx ( ) ;
874
899
let sig =
875
900
tcx. normalize_erasing_late_bound_regions ( ty:: ParamEnv :: reveal_all ( ) , callee_ty. fn_sig ( tcx) ) ;
876
901
let arg_tys = sig. inputs ( ) ;
877
902
878
903
if name == sym:: simd_select_bitmask {
904
+ // Example of the two options presented above:
905
+
906
+ // 1. Existing code: macro passing non-translatable strings.
879
907
require_simd ! ( arg_tys[ 1 ] , "argument" ) ;
908
+
909
+ // 2. Macro accepting diagnostics.
910
+ let diag = InvalidMonomorphization :: SimdArgument { span, name, ty : arg_tys[ 1 ] } ;
911
+ require_simd_localized ! ( arg_tys[ 1 ] , diag) ;
912
+
913
+ // 3. No macros: evaluating condition, emitting diagnostic and returning error.
914
+ if !arg_tys[ 1 ] . is_simd ( ) {
915
+ tcx. sess . emit_err ( InvalidMonomorphization :: SimdArgument { span, name, ty : arg_tys[ 1 ] } ) ;
916
+ return Err ( ( ) ) ;
917
+ }
918
+
880
919
let ( len, _) = arg_tys[ 1 ] . simd_size_and_type ( bx. tcx ( ) ) ;
881
920
882
921
let expected_int_bits = ( len. max ( 8 ) - 1 ) . next_power_of_two ( ) ;
@@ -1298,12 +1337,55 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
1298
1337
// * T: type of the element to load
1299
1338
// * M: any integer width is supported, will be truncated to i1
1300
1339
1340
+ // Example of the two options presented above:
1341
+
1342
+ // 1. Existing code: macro passing non-translatable strings.
1301
1343
// All types must be simd vector types
1302
1344
require_simd ! ( in_ty, "first" ) ;
1303
1345
require_simd ! ( arg_tys[ 1 ] , "second" ) ;
1304
1346
require_simd ! ( arg_tys[ 2 ] , "third" ) ;
1305
1347
require_simd ! ( ret_ty, "return" ) ;
1306
1348
1349
+ // 2. Macro accepting diagnostics.
1350
+ let diag = InvalidMonomorphization :: SimdFirstType { span, name, in_ty } ;
1351
+ require_simd ! ( in_ty, diag) ;
1352
+ let diag = InvalidMonomorphization :: SimdSecondType { span, name, in_ty : arg_tys[ 1 ] } ;
1353
+ require_simd ! ( arg_tys[ 1 ] , diag) ;
1354
+ let diag = InvalidMonomorphization :: SimdThirdType { span, name, in_ty : arg_tys[ 2 ] } ;
1355
+ require_simd ! ( arg_tys[ 2 ] , diag) ;
1356
+ let diag = InvalidMonomorphization :: SimdReturnType { span, name, in_ty : ret_ty } ;
1357
+ require_simd ! ( ret_ty, diag) ;
1358
+
1359
+ // 3. No macros: evaluating condition, emitting diagnostic and returning error.
1360
+ if !in_ty. is_simd ( ) {
1361
+ tcx. sess . emit_err ( InvalidMonomorphization :: SimdFirstType { span, name, in_ty } ) ;
1362
+ return Err ( ( ) ) ;
1363
+ }
1364
+ if !arg_tys[ 1 ] . is_simd ( ) {
1365
+ tcx. sess . emit_err ( InvalidMonomorphization :: SimdSecondType {
1366
+ span,
1367
+ name,
1368
+ in_ty : arg_tys[ 1 ] ,
1369
+ } ) ;
1370
+ return Err ( ( ) ) ;
1371
+ }
1372
+ if !arg_tys[ 2 ] . is_simd ( ) {
1373
+ tcx. sess . emit_err ( InvalidMonomorphization :: SimdThirdType {
1374
+ span,
1375
+ name,
1376
+ in_ty : arg_tys[ 2 ] ,
1377
+ } ) ;
1378
+ return Err ( ( ) ) ;
1379
+ }
1380
+ if !ret_ty. is_simd ( ) {
1381
+ tcx. sess . emit_err ( InvalidMonomorphization :: SimdReturnType {
1382
+ span,
1383
+ name,
1384
+ in_ty : ret_ty,
1385
+ } ) ;
1386
+ return Err ( ( ) ) ;
1387
+ }
1388
+
1307
1389
// Of the same length:
1308
1390
let ( out_len, _) = arg_tys[ 1 ] . simd_size_and_type ( bx. tcx ( ) ) ;
1309
1391
let ( out_len2, _) = arg_tys[ 2 ] . simd_size_and_type ( bx. tcx ( ) ) ;
0 commit comments