1
Fork 0

Auto merge of #115699 - RalfJung:interpret-abi-compat, r=oli-obk

interpret: change ABI-compat test to be type-based

This makes the test consistent across targets. Otherwise the chances are very high that ABI mismatches get accepted on x86_64 but still fail on many other targets with more complicated ABIs.

This implements (most of) the rules described in https://github.com/rust-lang/rust/pull/115476.
This commit is contained in:
bors 2023-09-12 03:34:55 +00:00
commit 366dab13f7
13 changed files with 270 additions and 116 deletions

View file

@ -255,9 +255,16 @@ impl_into_diagnostic_arg_through_debug! {
/// Error information for when the program caused Undefined Behavior.
#[derive(Debug)]
pub enum UndefinedBehaviorInfo<'a> {
pub enum UndefinedBehaviorInfo<'tcx> {
/// Free-form case. Only for errors that are never caught! Used by miri
Ub(String),
// FIXME(fee1-dead) these should all be actual variants of the enum instead of dynamically
// dispatched
/// A custom (free-form) fluent-translated error, created by `err_ub_custom!`.
Custom(crate::error::CustomSubdiagnostic<'tcx>),
/// Validation error.
ValidationError(ValidationErrorInfo<'tcx>),
/// Unreachable code was executed.
Unreachable,
/// A slice/array index projection went out-of-bounds.
@ -319,12 +326,10 @@ pub enum UndefinedBehaviorInfo<'a> {
UninhabitedEnumVariantWritten(VariantIdx),
/// An uninhabited enum variant is projected.
UninhabitedEnumVariantRead(VariantIdx),
/// Validation error.
ValidationError(ValidationErrorInfo<'a>),
// FIXME(fee1-dead) these should all be actual variants of the enum instead of dynamically
// dispatched
/// A custom (free-form) error, created by `err_ub_custom!`.
Custom(crate::error::CustomSubdiagnostic<'a>),
/// ABI-incompatible argument types.
AbiMismatchArgument { caller_ty: Ty<'tcx>, callee_ty: Ty<'tcx> },
/// ABI-incompatible return types.
AbiMismatchReturn { caller_ty: Ty<'tcx>, callee_ty: Ty<'tcx> },
}
#[derive(Debug, Clone, Copy)]

View file

@ -2749,6 +2749,8 @@ impl<'tcx> Ty<'tcx> {
| ty::Error(_)
// Extern types have metadata = ().
| ty::Foreign(..)
// `dyn*` has no metadata
| ty::Dynamic(_, _, DynKind::DynStar)
// If returned by `struct_tail_without_normalization` this is a unit struct
// without any fields, or not a struct, and therefore is Sized.
| ty::Adt(..)
@ -2757,7 +2759,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Tuple(..) => (tcx.types.unit, false),
ty::Str | ty::Slice(_) => (tcx.types.usize, false),
ty::Dynamic(..) => {
ty::Dynamic(_, _, DynKind::Dyn) => {
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]), false)
},