@@ -463,43 +463,64 @@ fn fn_abi_sanity_check<'tcx>(
463
463
arg : & ArgAbi < ' tcx , Ty < ' tcx > > ,
464
464
) {
465
465
let tcx = cx. tcx ( ) ;
466
+
467
+ if spec_abi == ExternAbi :: Rust
468
+ || spec_abi == ExternAbi :: RustCall
469
+ || spec_abi == ExternAbi :: RustCold
470
+ {
471
+ if arg. layout . is_zst ( ) {
472
+ // Casting closures to function pointers depends on ZST closure types being
473
+ // omitted entirely in the calling convention.
474
+ assert ! ( arg. is_ignore( ) ) ;
475
+ }
476
+ if let PassMode :: Indirect { on_stack, .. } = arg. mode {
477
+ assert ! ( !on_stack, "rust abi shouldn't use on_stack" ) ;
478
+ }
479
+ }
480
+
466
481
match & arg. mode {
467
- PassMode :: Ignore => { }
482
+ PassMode :: Ignore => {
483
+ assert ! ( arg. layout. is_zst( ) || arg. layout. is_uninhabited( ) ) ;
484
+ }
468
485
PassMode :: Direct ( _) => {
469
486
// Here the Rust type is used to determine the actual ABI, so we have to be very
470
- // careful. Scalar/ScalarPair is fine, since backends will generally use
471
- // `layout.abi` and ignore everything else. We should just reject `Aggregate`
472
- // entirely here, but some targets need to be fixed first.
473
- if matches ! ( arg. layout. backend_repr, BackendRepr :: Memory { .. } ) {
474
- // For an unsized type we'd only pass the sized prefix, so there is no universe
475
- // in which we ever want to allow this.
476
- assert ! (
477
- arg. layout. is_sized( ) ,
478
- "`PassMode::Direct` for unsized type in ABI: {:#?}" ,
479
- fn_abi
480
- ) ;
481
- // This really shouldn't happen even for sized aggregates, since
482
- // `immediate_llvm_type` will use `layout.fields` to turn this Rust type into an
483
- // LLVM type. This means all sorts of Rust type details leak into the ABI.
484
- // However wasm sadly *does* currently use this mode so we have to allow it --
485
- // but we absolutely shouldn't let any more targets do that.
486
- // (Also see <https://github.com/rust-lang/rust/issues/115666>.)
487
- //
488
- // The unstable abi `PtxKernel` also uses Direct for now.
489
- // It needs to switch to something else before stabilization can happen.
490
- // (See issue: https://github.com/rust-lang/rust/issues/117271)
491
- assert ! (
492
- matches!( & * tcx. sess. target. arch, "wasm32" | "wasm64" )
493
- || matches!( spec_abi, ExternAbi :: PtxKernel | ExternAbi :: Unadjusted ) ,
494
- "`PassMode::Direct` for aggregates only allowed for \" unadjusted\" and \" ptx-kernel\" functions and on wasm\n \
487
+ // careful. Scalar/Vector is fine, since backends will generally use
488
+ // `layout.backend_repr` and ignore everything else. We should just reject
489
+ //`Aggregate` entirely here, but some targets need to be fixed first.
490
+ match arg. layout . backend_repr {
491
+ BackendRepr :: Uninhabited
492
+ | BackendRepr :: Scalar ( _)
493
+ | BackendRepr :: Vector { .. } => { }
494
+ BackendRepr :: ScalarPair ( ..) => {
495
+ panic ! ( "`PassMode::Direct` used for ScalarPair type {}" , arg. layout. ty)
496
+ }
497
+ BackendRepr :: Memory { sized } => {
498
+ // For an unsized type we'd only pass the sized prefix, so there is no universe
499
+ // in which we ever want to allow this.
500
+ assert ! ( sized, "`PassMode::Direct` for unsized type in ABI: {:#?}" , fn_abi) ;
501
+ // This really shouldn't happen even for sized aggregates, since
502
+ // `immediate_llvm_type` will use `layout.fields` to turn this Rust type into an
503
+ // LLVM type. This means all sorts of Rust type details leak into the ABI.
504
+ // However wasm sadly *does* currently use this mode so we have to allow it --
505
+ // but we absolutely shouldn't let any more targets do that.
506
+ // (Also see <https://github.com/rust-lang/rust/issues/115666>.)
507
+ //
508
+ // The unstable abi `PtxKernel` also uses Direct for now.
509
+ // It needs to switch to something else before stabilization can happen.
510
+ // (See issue: https://github.com/rust-lang/rust/issues/117271)
511
+ assert ! (
512
+ matches!( & * tcx. sess. target. arch, "wasm32" | "wasm64" )
513
+ || matches!( spec_abi, ExternAbi :: PtxKernel | ExternAbi :: Unadjusted ) ,
514
+ "`PassMode::Direct` for aggregates only allowed for \" unadjusted\" and \" ptx-kernel\" functions and on wasm\n \
495
515
Problematic type: {:#?}",
496
- arg. layout,
497
- ) ;
516
+ arg. layout,
517
+ ) ;
518
+ }
498
519
}
499
520
}
500
521
PassMode :: Pair ( _, _) => {
501
- // Similar to `Direct`, we need to make sure that backends use `layout.abi` and
502
- // ignore the rest of the layout.
522
+ // Similar to `Direct`, we need to make sure that backends use `layout.backend_repr`
523
+ // and ignore the rest of the layout.
503
524
assert ! (
504
525
matches!( arg. layout. backend_repr, BackendRepr :: ScalarPair ( ..) ) ,
505
526
"PassMode::Pair for type {}" ,
0 commit comments