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
The following code should not be accepted:
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 typearguments.I was extremely surprised earlier today when I learned that this code is getting accepted.
There is no generic bound to distinguish
externtypes from other unsized types, so the options we have areexternTrying to actually build any such code will lead to ICEs such as
or