Open
Description
The following code should not be accepted:
#![feature(extern_types)]
#![feature(unsized_fn_params)]
extern {
type E;
}
fn test(e: E) {}
fn calltest(e: Box<E>) {
test(*e)
}
In terms of MIR semantics I think we want to view a function call as making copies of its arguments. This requires at least dynamically determining the size of the argument, and therefore we shouldn't accept extern type
arguments.
I was extremely surprised earlier today when I learned that this code is getting accepted.
There is no generic bound to distinguish extern
types from other unsized types, so the options we have are
- require the unsized type to be concrete enough that we can determine its tail, and ensure it is not
extern
- raise the error during monomorphization / codegen
Trying to actually build any such code will lead to ICEs such as
error: internal compiler error: compiler/rustc_codegen_llvm/src/type_of.rs:306:13: TyAndLayout::scalar_pair_element_llty(TyAndLayout { ty: *mut E, layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 0..=18446744073709551615 }), fields: Primitive, largest_niche: None, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes) } }): not applicable
or
thread 'rustc' panicked at compiler/rustc_codegen_llvm/src/builder.rs:491:9:
assertion `left == right` failed
left: false
right: true