about summary refs log tree commit diff
path: root/compiler/rustc_ty_utils/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-12-02 22:25:14 +0100
committerRalf Jung <post@ralfj.de>2023-12-03 08:11:15 +0100
commit5a20bac6b3ff61acc3cd68bed0eb3fa598181f17 (patch)
treed2fd3b80c9651b0630d3e6aee00c3d6cdacd2ffb /compiler/rustc_ty_utils/src
parent0908f173fd884ae90584e0b0bca83cb270c23936 (diff)
more targeted errors when extern types end up in places they should not
Diffstat (limited to 'compiler/rustc_ty_utils/src')
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs12
1 files changed, 12 insertions, 0 deletions
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index c6ff7e2a9ef..b28e3d5c412 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -424,11 +424,23 @@ fn fn_abi_sanity_check<'tcx>(
             }
             PassMode::Indirect { meta_attrs: None, .. } => {
                 // No metadata, must be sized.
+                // Conceptually, unsized arguments must be copied around, which requires dynamically
+                // determining their size, which we cannot do without metadata. Consult
+                // t-opsem before removing this check.
                 assert!(arg.layout.is_sized());
             }
             PassMode::Indirect { meta_attrs: Some(_), on_stack, .. } => {
                 // With metadata. Must be unsized and not on the stack.
                 assert!(arg.layout.is_unsized() && !on_stack);
+                // Also, must not be `extern` type.
+                let tail = cx.tcx.struct_tail_with_normalize(arg.layout.ty, |ty| ty, || {});
+                if matches!(tail.kind(), ty::Foreign(..)) {
+                    // These types do not have metadata, so having `meta_attrs` is bogus.
+                    // Conceptually, unsized arguments must be copied around, which requires dynamically
+                    // determining their size. Therefore, we cannot allow `extern` types here. Consult
+                    // t-opsem before removing this check.
+                    panic!("unsized arguments must not be `extern` types");
+                }
             }
         }
     }