1
Fork 0

DELETE - fn span_invalid_monomorphization_error and localize intrinsics macros

This commit is contained in:
Jhonny Bill Mena 2022-11-26 20:28:01 -05:00
parent 27744460e2
commit 29d8c87fe8
4 changed files with 670 additions and 253 deletions

View file

@ -8,9 +8,8 @@ use crate::va_arg::emit_va_arg;
use crate::value::Value; use crate::value::Value;
use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh}; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh};
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_codegen_ssa::errors::InvalidMonomorphization; use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization};
use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::operand::OperandRef;
use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::traits::*;
@ -835,40 +834,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
llret_ty: &'ll Type, llret_ty: &'ll Type,
span: Span, span: Span,
) -> Result<&'ll Value, ()> { ) -> Result<&'ll Value, ()> {
// macros for error handling:
#[allow(unused_macro_rules)]
macro_rules! emit_error {
($msg: tt) => {
emit_error!($msg, )
};
($msg: tt, $($fmt: tt)*) => {
span_invalid_monomorphization_error(
bx.sess(), span,
&format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
name, $($fmt)*));
}
}
macro_rules! return_error { macro_rules! return_error {
($($fmt: tt)*) => { ($diag: expr) => {{
{ bx.sess().emit_err($diag);
emit_error!($($fmt)*); return Err(());
return Err(()); }};
}
}
} }
macro_rules! require { macro_rules! require {
($cond: expr, $($fmt: tt)*) => { ($cond: expr, $diag: expr) => {
if !$cond { if !$cond {
return_error!($($fmt)*); return_error!($diag);
} }
}; };
} }
macro_rules! require_simd { macro_rules! require_simd {
($ty: expr, $position: expr) => { ($ty: expr, $diag: expr) => {
require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty) require!($ty.is_simd(), $diag)
}; };
} }
@ -878,7 +861,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
let arg_tys = sig.inputs(); let arg_tys = sig.inputs();
if name == sym::simd_select_bitmask { if name == sym::simd_select_bitmask {
require_simd!(arg_tys[1], "argument"); require_simd!(
arg_tys[1],
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
);
let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
let expected_int_bits = (len.max(8) - 1).next_power_of_two(); let expected_int_bits = (len.max(8) - 1).next_power_of_two();
@ -899,12 +886,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty)); let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty));
bx.load(int_ty, ptr, Align::ONE) bx.load(int_ty, ptr, Align::ONE)
} }
_ => return_error!( _ => return_error!(InvalidMonomorphization::InvalidBitmask {
"invalid bitmask `{}`, expected `u{}` or `[u8; {}]`", span,
name,
mask_ty, mask_ty,
expected_int_bits, expected_int_bits,
expected_bytes expected_bytes
), }),
}; };
let i1 = bx.type_i1(); let i1 = bx.type_i1();
@ -916,7 +904,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
} }
// every intrinsic below takes a SIMD vector as its first argument // every intrinsic below takes a SIMD vector as its first argument
require_simd!(arg_tys[0], "input"); require_simd!(arg_tys[0], InvalidMonomorphization::SimdInput { span, name, ty: arg_tys[0] });
let in_ty = arg_tys[0]; let in_ty = arg_tys[0];
let comparison = match name { let comparison = match name {
@ -931,23 +919,24 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
let (in_len, in_elem) = arg_tys[0].simd_size_and_type(bx.tcx()); let (in_len, in_elem) = arg_tys[0].simd_size_and_type(bx.tcx());
if let Some(cmp_op) = comparison { if let Some(cmp_op) = comparison {
require_simd!(ret_ty, "return"); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
require!( require!(
in_len == out_len, in_len == out_len,
"expected return type with length {} (same as input type `{}`), \ InvalidMonomorphization::ReturnLengthInputType {
found `{}` with length {}", span,
in_len, name,
in_ty, in_len,
ret_ty, in_ty,
out_len ret_ty,
out_len
}
); );
require!( require!(
bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
"expected return type with integer elements, found `{}` with non-integer `{}`", InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
ret_ty,
out_ty
); );
return Ok(compare_simd_types( return Ok(compare_simd_types(
@ -972,10 +961,11 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
span_bug!(span, "could not evaluate shuffle index array length") span_bug!(span, "could not evaluate shuffle index array length")
}) })
} }
_ => return_error!( _ => return_error!(InvalidMonomorphization::SimdShuffle {
"simd_shuffle index must be an array of `u32`, got `{}`", span,
args[2].layout.ty name,
), ty: args[2].layout.ty
}),
} }
} else { } else {
stripped.parse().unwrap_or_else(|_| { stripped.parse().unwrap_or_else(|_| {
@ -983,23 +973,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
}) })
}; };
require_simd!(ret_ty, "return"); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
require!( require!(
out_len == n, out_len == n,
"expected return type of length {}, found `{}` with length {}", InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
n,
ret_ty,
out_len
); );
require!( require!(
in_elem == out_ty, in_elem == out_ty,
"expected return element type `{}` (element of input `{}`), \ InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
found `{}` with element type `{}`",
in_elem,
in_ty,
ret_ty,
out_ty
); );
let total_len = u128::from(in_len) * 2; let total_len = u128::from(in_len) * 2;
@ -1012,15 +994,20 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
let val = bx.const_get_elt(vector, i as u64); let val = bx.const_get_elt(vector, i as u64);
match bx.const_to_opt_u128(val, true) { match bx.const_to_opt_u128(val, true) {
None => { None => {
emit_error!("shuffle index #{} is not a constant", arg_idx); bx.sess().emit_err(InvalidMonomorphization::ShuffleIndexNotConstant {
span,
name,
arg_idx,
});
None None
} }
Some(idx) if idx >= total_len => { Some(idx) if idx >= total_len => {
emit_error!( bx.sess().emit_err(InvalidMonomorphization::ShuffleIndexOutOfBounds {
"shuffle index #{} is out of bounds (limit {})", span,
name,
arg_idx, arg_idx,
total_len total_len,
); });
None None
} }
Some(idx) => Some(bx.const_i32(idx as i32)), Some(idx) => Some(bx.const_i32(idx as i32)),
@ -1041,10 +1028,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
if name == sym::simd_insert { if name == sym::simd_insert {
require!( require!(
in_elem == arg_tys[2], in_elem == arg_tys[2],
"expected inserted type `{}` (element of input `{}`), found `{}`", InvalidMonomorphization::InsertedType {
in_elem, span,
in_ty, name,
arg_tys[2] in_elem,
in_ty,
out_ty: arg_tys[2]
}
); );
return Ok(bx.insert_element( return Ok(bx.insert_element(
args[0].immediate(), args[0].immediate(),
@ -1055,10 +1045,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
if name == sym::simd_extract { if name == sym::simd_extract {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`", InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
in_elem,
in_ty,
ret_ty
); );
return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())); return Ok(bx.extract_element(args[0].immediate(), args[1].immediate()));
} }
@ -1066,17 +1053,18 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
if name == sym::simd_select { if name == sym::simd_select {
let m_elem_ty = in_elem; let m_elem_ty = in_elem;
let m_len = in_len; let m_len = in_len;
require_simd!(arg_tys[1], "argument"); require_simd!(
arg_tys[1],
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
);
let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
require!( require!(
m_len == v_len, m_len == v_len,
"mismatched lengths: mask length `{}` != other vector length `{}`", InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
m_len,
v_len
); );
match m_elem_ty.kind() { match m_elem_ty.kind() {
ty::Int(_) => {} ty::Int(_) => {}
_ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty), _ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }),
} }
// truncate the mask to a vector of i1s // truncate the mask to a vector of i1s
let i1 = bx.type_i1(); let i1 = bx.type_i1();
@ -1108,11 +1096,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
args[0].immediate(), args[0].immediate(),
i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()), i.bit_width().unwrap_or_else(|| bx.data_layout().pointer_size.bits()),
), ),
_ => return_error!( _ => return_error!(InvalidMonomorphization::VectorArgument {
"vector argument `{}`'s element type `{}`, expected integer element type", span,
name,
in_ty, in_ty,
in_elem in_elem
), }),
}; };
// Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position. // Shift the MSB to the right by "in_elem_bitwidth - 1" into the first bit position.
@ -1147,12 +1136,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
let ptr = bx.pointercast(ptr, bx.cx.type_ptr_to(array_ty)); let ptr = bx.pointercast(ptr, bx.cx.type_ptr_to(array_ty));
return Ok(bx.load(array_ty, ptr, Align::ONE)); return Ok(bx.load(array_ty, ptr, Align::ONE));
} }
_ => return_error!( _ => return_error!(InvalidMonomorphization::CannotReturn {
"cannot return `{}`, expected `u{}` or `[u8; {}]`", span,
name,
ret_ty, ret_ty,
expected_int_bits, expected_int_bits,
expected_bytes expected_bytes
), }),
} }
} }
@ -1165,24 +1155,27 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
span: Span, span: Span,
args: &[OperandRef<'tcx, &'ll Value>], args: &[OperandRef<'tcx, &'ll Value>],
) -> Result<&'ll Value, ()> { ) -> Result<&'ll Value, ()> {
macro_rules! return_error {
($diag: expr) => {{
bx.sess().emit_err($diag);
return Err(());
}};
}
let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() {
let elem_ty = bx.cx.type_float_from_ty(*f); let elem_ty = bx.cx.type_float_from_ty(*f);
match f.bit_width() { match f.bit_width() {
32 => ("f32", elem_ty), 32 => ("f32", elem_ty),
64 => ("f64", elem_ty), 64 => ("f64", elem_ty),
_ => { _ => return_error!(InvalidMonomorphization::FloatingPointVector {
bx.sess().emit_err(InvalidMonomorphization::FloatingPointVector { span,
span, name,
name, f_ty: *f,
f_ty: *f, in_ty,
in_ty, }),
});
return Err(());
}
} }
} else { } else {
bx.sess().emit_err(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty });
return Err(());
}; };
let vec_ty = bx.type_vector(elem_ty, in_len); let vec_ty = bx.type_vector(elem_ty, in_len);
@ -1204,10 +1197,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)),
_ => { _ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }),
bx.sess().emit_err(InvalidMonomorphization::UnrecognizedIntrinsic { span, name });
return Err(());
}
}; };
let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty); let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty);
@ -1301,37 +1291,48 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
// * M: any integer width is supported, will be truncated to i1 // * M: any integer width is supported, will be truncated to i1
// All types must be simd vector types // All types must be simd vector types
require_simd!(in_ty, "first"); require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
require_simd!(arg_tys[1], "second"); require_simd!(
require_simd!(arg_tys[2], "third"); arg_tys[1],
require_simd!(ret_ty, "return"); InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
);
require_simd!(
arg_tys[2],
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
);
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
// Of the same length: // Of the same length:
let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
require!( require!(
in_len == out_len, in_len == out_len,
"expected {} argument with length {} (same as input type `{}`), \ InvalidMonomorphization::SecondArgumentLength {
found `{}` with length {}", span,
"second", name,
in_len, in_len,
in_ty, in_ty,
arg_tys[1], arg_ty: arg_tys[1],
out_len out_len
}
); );
require!( require!(
in_len == out_len2, in_len == out_len2,
"expected {} argument with length {} (same as input type `{}`), \ InvalidMonomorphization::ThirdArgumentLength {
found `{}` with length {}", span,
"third", name,
in_len, in_len,
in_ty, in_ty,
arg_tys[2], arg_ty: arg_tys[2],
out_len2 out_len: out_len2
}
); );
// The return type must match the first argument type // The return type must match the first argument type
require!(ret_ty == in_ty, "expected return type `{}`, found `{}`", in_ty, ret_ty); require!(
ret_ty == in_ty,
InvalidMonomorphization::ExpectedReturnType { span, name, in_ty, ret_ty }
);
// This counts how many pointers // This counts how many pointers
fn ptr_count(t: Ty<'_>) -> usize { fn ptr_count(t: Ty<'_>) -> usize {
@ -1358,15 +1359,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
_ => { _ => {
require!( require!(
false, false,
"expected element type `{}` of second argument `{}` \ InvalidMonomorphization::ExpectedElementType {
to be a pointer to the element type `{}` of the first \ span,
argument `{}`, found `{}` != `*_ {}`", name,
element_ty1, expected_element: element_ty1,
arg_tys[1], second_arg: arg_tys[1],
in_elem, in_elem,
in_ty, in_ty,
element_ty1, mutability: ExpectedPointerMutability::Not,
in_elem }
); );
unreachable!(); unreachable!();
} }
@ -1382,10 +1383,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
_ => { _ => {
require!( require!(
false, false,
"expected element type `{}` of third argument `{}` \ InvalidMonomorphization::ThirdArgElementType {
to be a signed integer type", span,
element_ty2, name,
arg_tys[2] expected_element: element_ty2,
third_arg: arg_tys[2]
}
); );
} }
} }
@ -1434,32 +1437,40 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
// * M: any integer width is supported, will be truncated to i1 // * M: any integer width is supported, will be truncated to i1
// All types must be simd vector types // All types must be simd vector types
require_simd!(in_ty, "first"); require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
require_simd!(arg_tys[1], "second"); require_simd!(
require_simd!(arg_tys[2], "third"); arg_tys[1],
InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
);
require_simd!(
arg_tys[2],
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
);
// Of the same length: // Of the same length:
let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx()); let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx());
let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx()); let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
require!( require!(
in_len == element_len1, in_len == element_len1,
"expected {} argument with length {} (same as input type `{}`), \ InvalidMonomorphization::SecondArgumentLength {
found `{}` with length {}", span,
"second", name,
in_len, in_len,
in_ty, in_ty,
arg_tys[1], arg_ty: arg_tys[1],
element_len1 out_len: element_len1
}
); );
require!( require!(
in_len == element_len2, in_len == element_len2,
"expected {} argument with length {} (same as input type `{}`), \ InvalidMonomorphization::ThirdArgumentLength {
found `{}` with length {}", span,
"third", name,
in_len, in_len,
in_ty, in_ty,
arg_tys[2], arg_ty: arg_tys[2],
element_len2 out_len: element_len2
}
); );
// This counts how many pointers // This counts how many pointers
@ -1490,15 +1501,15 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
_ => { _ => {
require!( require!(
false, false,
"expected element type `{}` of second argument `{}` \ InvalidMonomorphization::ExpectedElementType {
to be a pointer to the element type `{}` of the first \ span,
argument `{}`, found `{}` != `*mut {}`", name,
element_ty1, expected_element: element_ty1,
arg_tys[1], second_arg: arg_tys[1],
in_elem, in_elem,
in_ty, in_ty,
element_ty1, mutability: ExpectedPointerMutability::Mut,
in_elem }
); );
unreachable!(); unreachable!();
} }
@ -1513,10 +1524,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
_ => { _ => {
require!( require!(
false, false,
"expected element type `{}` of third argument `{}` \ InvalidMonomorphization::ThirdArgElementType {
be a signed integer type", span,
element_ty2, name,
arg_tys[2] expected_element: element_ty2,
third_arg: arg_tys[2]
}
); );
} }
} }
@ -1563,10 +1576,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
if name == sym::$name { if name == sym::$name {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`", InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
in_elem,
in_ty,
ret_ty
); );
return match in_elem.kind() { return match in_elem.kind() {
ty::Int(_) | ty::Uint(_) => { ty::Int(_) | ty::Uint(_) => {
@ -1589,25 +1599,28 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
32 => bx.const_real(bx.type_f32(), $identity), 32 => bx.const_real(bx.type_f32(), $identity),
64 => bx.const_real(bx.type_f64(), $identity), 64 => bx.const_real(bx.type_f64(), $identity),
v => return_error!( v => return_error!(
r#" InvalidMonomorphization::UnsupportedSymbolOfSize {
unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, span,
sym::$name, name,
in_ty, symbol: sym::$name,
in_elem, in_ty,
v, in_elem,
ret_ty size: v,
ret_ty
}
), ),
} }
}; };
Ok(bx.$float_reduce(acc, args[0].immediate())) Ok(bx.$float_reduce(acc, args[0].immediate()))
} }
_ => return_error!( _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
"unsupported {} from `{}` with element `{}` to `{}`", span,
sym::$name, name,
symbol: sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
), }),
}; };
} }
}; };
@ -1635,22 +1648,20 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
if name == sym::$name { if name == sym::$name {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`", InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
in_elem,
in_ty,
ret_ty
); );
return match in_elem.kind() { return match in_elem.kind() {
ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)), ty::Int(_i) => Ok(bx.$int_red(args[0].immediate(), true)),
ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)), ty::Uint(_u) => Ok(bx.$int_red(args[0].immediate(), false)),
ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())), ty::Float(_f) => Ok(bx.$float_red(args[0].immediate())),
_ => return_error!( _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
"unsupported {} from `{}` with element `{}` to `{}`", span,
sym::$name, name,
symbol: sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
), }),
}; };
} }
}; };
@ -1668,22 +1679,20 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
let input = if !$boolean { let input = if !$boolean {
require!( require!(
ret_ty == in_elem, ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`", InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
in_elem,
in_ty,
ret_ty
); );
args[0].immediate() args[0].immediate()
} else { } else {
match in_elem.kind() { match in_elem.kind() {
ty::Int(_) | ty::Uint(_) => {} ty::Int(_) | ty::Uint(_) => {}
_ => return_error!( _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
"unsupported {} from `{}` with element `{}` to `{}`", span,
sym::$name, name,
symbol: sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
), }),
} }
// boolean reductions operate on vectors of i1s: // boolean reductions operate on vectors of i1s:
@ -1696,13 +1705,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
let r = bx.$red(input); let r = bx.$red(input);
Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) }) Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) })
} }
_ => return_error!( _ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
"unsupported {} from `{}` with element `{}` to `{}`", span,
sym::$name, name,
symbol: sym::$name,
in_ty, in_ty,
in_elem, in_elem,
ret_ty ret_ty
), }),
}; };
} }
}; };
@ -1715,16 +1725,18 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
bitwise_red!(simd_reduce_any: vector_reduce_or, true); bitwise_red!(simd_reduce_any: vector_reduce_or, true);
if name == sym::simd_cast_ptr { if name == sym::simd_cast_ptr {
require_simd!(ret_ty, "return"); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
require!( require!(
in_len == out_len, in_len == out_len,
"expected return type with length {} (same as input type `{}`), \ InvalidMonomorphization::ReturnLengthInputType {
found `{}` with length {}", span,
in_len, name,
in_ty, in_len,
ret_ty, in_ty,
out_len ret_ty,
out_len
}
); );
match in_elem.kind() { match in_elem.kind() {
@ -1733,9 +1745,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
}); });
assert!(!check_sized); // we are in codegen, so we shouldn't see these types assert!(!check_sized); // we are in codegen, so we shouldn't see these types
require!(metadata.is_unit(), "cannot cast fat pointer `{}`", in_elem) require!(
metadata.is_unit(),
InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem }
);
}
_ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
} }
_ => return_error!("expected pointer, got `{}`", in_elem),
} }
match out_elem.kind() { match out_elem.kind() {
ty::RawPtr(p) => { ty::RawPtr(p) => {
@ -1743,9 +1760,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty) bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
}); });
assert!(!check_sized); // we are in codegen, so we shouldn't see these types assert!(!check_sized); // we are in codegen, so we shouldn't see these types
require!(metadata.is_unit(), "cannot cast to fat pointer `{}`", out_elem) require!(
metadata.is_unit(),
InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem }
);
}
_ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
} }
_ => return_error!("expected pointer, got `{}`", out_elem),
} }
if in_elem == out_elem { if in_elem == out_elem {
@ -1756,66 +1778,76 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
} }
if name == sym::simd_expose_addr { if name == sym::simd_expose_addr {
require_simd!(ret_ty, "return"); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
require!( require!(
in_len == out_len, in_len == out_len,
"expected return type with length {} (same as input type `{}`), \ InvalidMonomorphization::ReturnLengthInputType {
found `{}` with length {}", span,
in_len, name,
in_ty, in_len,
ret_ty, in_ty,
out_len ret_ty,
out_len
}
); );
match in_elem.kind() { match in_elem.kind() {
ty::RawPtr(_) => {} ty::RawPtr(_) => {}
_ => return_error!("expected pointer, got `{}`", in_elem), _ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: in_elem })
}
} }
match out_elem.kind() { match out_elem.kind() {
ty::Uint(ty::UintTy::Usize) => {} ty::Uint(ty::UintTy::Usize) => {}
_ => return_error!("expected `usize`, got `{}`", out_elem), _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: out_elem }),
} }
return Ok(bx.ptrtoint(args[0].immediate(), llret_ty)); return Ok(bx.ptrtoint(args[0].immediate(), llret_ty));
} }
if name == sym::simd_from_exposed_addr { if name == sym::simd_from_exposed_addr {
require_simd!(ret_ty, "return"); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
require!( require!(
in_len == out_len, in_len == out_len,
"expected return type with length {} (same as input type `{}`), \ InvalidMonomorphization::ReturnLengthInputType {
found `{}` with length {}", span,
in_len, name,
in_ty, in_len,
ret_ty, in_ty,
out_len ret_ty,
out_len
}
); );
match in_elem.kind() { match in_elem.kind() {
ty::Uint(ty::UintTy::Usize) => {} ty::Uint(ty::UintTy::Usize) => {}
_ => return_error!("expected `usize`, got `{}`", in_elem), _ => return_error!(InvalidMonomorphization::ExpectedUsize { span, name, ty: in_elem }),
} }
match out_elem.kind() { match out_elem.kind() {
ty::RawPtr(_) => {} ty::RawPtr(_) => {}
_ => return_error!("expected pointer, got `{}`", out_elem), _ => {
return_error!(InvalidMonomorphization::ExpectedPointer { span, name, ty: out_elem })
}
} }
return Ok(bx.inttoptr(args[0].immediate(), llret_ty)); return Ok(bx.inttoptr(args[0].immediate(), llret_ty));
} }
if name == sym::simd_cast || name == sym::simd_as { if name == sym::simd_cast || name == sym::simd_as {
require_simd!(ret_ty, "return"); require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
require!( require!(
in_len == out_len, in_len == out_len,
"expected return type with length {} (same as input type `{}`), \ InvalidMonomorphization::ReturnLengthInputType {
found `{}` with length {}", span,
in_len, name,
in_ty, in_len,
ret_ty, in_ty,
out_len ret_ty,
out_len
}
); );
// casting cares about nominal type, not just structural type // casting cares about nominal type, not just structural type
if in_elem == out_elem { if in_elem == out_elem {
@ -1894,11 +1926,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
} }
require!( require!(
false, false,
"unsupported cast from `{}` with element `{}` to `{}` with element `{}`", InvalidMonomorphization::UnsupportedCast {
in_ty, span,
in_elem, name,
ret_ty, in_ty,
out_elem in_elem,
ret_ty,
out_elem
}
); );
} }
macro_rules! arith_binary { macro_rules! arith_binary {
@ -1910,10 +1945,10 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
})* })*
_ => {}, _ => {},
} }
require!(false, require!(
"unsupported operation on `{}` with element `{}`", false,
in_ty, InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem }
in_elem) );
})* })*
} }
} }
@ -1941,10 +1976,10 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
})* })*
_ => {}, _ => {},
} }
require!(false, require!(
"unsupported operation on `{}` with element `{}`", false,
in_ty, InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem }
in_elem) );
})* })*
} }
} }
@ -1982,12 +2017,12 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)), ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)),
ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)), ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)),
_ => { _ => {
return_error!( return_error!(InvalidMonomorphization::ExpectedVectorElementType {
"expected element type `{}` of vector type `{}` \ span,
to be a signed or unsigned integer type", name,
arg_tys[0].simd_size_and_type(bx.tcx()).1, expected_element: arg_tys[0].simd_size_and_type(bx.tcx()).1,
arg_tys[0] vector_type: arg_tys[0]
); });
} }
}; };
let llvm_intrinsic = &format!( let llvm_intrinsic = &format!(

View file

@ -1,10 +1,8 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use rustc_errors::struct_span_err;
use rustc_hir::LangItem; use rustc_hir::LangItem;
use rustc_middle::mir::interpret::ConstValue; use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt}; use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::Span; use rustc_span::Span;
use crate::base; use crate::base;
@ -193,10 +191,6 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
} }
} }
pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
struct_span_err!(a, b, E0511, "{}", c).emit();
}
pub fn asm_const_to_str<'tcx>( pub fn asm_const_to_str<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
sp: Span, sp: Span,

View file

@ -663,4 +663,326 @@ pub enum InvalidMonomorphization<'tcx> {
span: Span, span: Span,
name: Symbol, name: Symbol,
}, },
#[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = "E0511")]
SimdArgument {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_simd_input, code = "E0511")]
SimdInput {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_simd_first, code = "E0511")]
SimdFirst {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_simd_second, code = "E0511")]
SimdSecond {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_simd_third, code = "E0511")]
SimdThird {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_simd_return, code = "E0511")]
SimdReturn {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = "E0511")]
InvalidBitmask {
#[primary_span]
span: Span,
name: Symbol,
mask_ty: Ty<'tcx>,
expected_int_bits: u64,
expected_bytes: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = "E0511")]
ReturnLengthInputType {
#[primary_span]
span: Span,
name: Symbol,
in_len: u64,
in_ty: Ty<'tcx>,
ret_ty: Ty<'tcx>,
out_len: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = "E0511")]
SecondArgumentLength {
#[primary_span]
span: Span,
name: Symbol,
in_len: u64,
in_ty: Ty<'tcx>,
arg_ty: Ty<'tcx>,
out_len: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = "E0511")]
ThirdArgumentLength {
#[primary_span]
span: Span,
name: Symbol,
in_len: u64,
in_ty: Ty<'tcx>,
arg_ty: Ty<'tcx>,
out_len: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = "E0511")]
ReturnIntegerType {
#[primary_span]
span: Span,
name: Symbol,
ret_ty: Ty<'tcx>,
out_ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = "E0511")]
SimdShuffle {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_return_length, code = "E0511")]
ReturnLength {
#[primary_span]
span: Span,
name: Symbol,
in_len: u64,
ret_ty: Ty<'tcx>,
out_len: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_return_element, code = "E0511")]
ReturnElement {
#[primary_span]
span: Span,
name: Symbol,
in_elem: Ty<'tcx>,
in_ty: Ty<'tcx>,
ret_ty: Ty<'tcx>,
out_ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = "E0511")]
ShuffleIndexNotConstant {
#[primary_span]
span: Span,
name: Symbol,
arg_idx: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = "E0511")]
ShuffleIndexOutOfBounds {
#[primary_span]
span: Span,
name: Symbol,
arg_idx: u64,
total_len: u128,
},
#[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = "E0511")]
InsertedType {
#[primary_span]
span: Span,
name: Symbol,
in_elem: Ty<'tcx>,
in_ty: Ty<'tcx>,
out_ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_return_type, code = "E0511")]
ReturnType {
#[primary_span]
span: Span,
name: Symbol,
in_elem: Ty<'tcx>,
in_ty: Ty<'tcx>,
ret_ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = "E0511")]
ExpectedReturnType {
#[primary_span]
span: Span,
name: Symbol,
in_ty: Ty<'tcx>,
ret_ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = "E0511")]
MismatchedLengths {
#[primary_span]
span: Span,
name: Symbol,
m_len: u64,
v_len: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_mask_type, code = "E0511")]
MaskType {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_vector_argument, code = "E0511")]
VectorArgument {
#[primary_span]
span: Span,
name: Symbol,
in_ty: Ty<'tcx>,
in_elem: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = "E0511")]
CannotReturn {
#[primary_span]
span: Span,
name: Symbol,
ret_ty: Ty<'tcx>,
expected_int_bits: u64,
expected_bytes: u64,
},
#[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = "E0511")]
ExpectedElementType {
#[primary_span]
span: Span,
name: Symbol,
expected_element: Ty<'tcx>,
second_arg: Ty<'tcx>,
in_elem: Ty<'tcx>,
in_ty: Ty<'tcx>,
mutability: ExpectedPointerMutability,
},
#[diag(codegen_ssa_invalid_monomorphization_third_arg_element_type, code = "E0511")]
ThirdArgElementType {
#[primary_span]
span: Span,
name: Symbol,
expected_element: Ty<'tcx>,
third_arg: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = "E0511")]
UnsupportedSymbolOfSize {
#[primary_span]
span: Span,
name: Symbol,
symbol: Symbol,
in_ty: Ty<'tcx>,
in_elem: Ty<'tcx>,
size: u64,
ret_ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = "E0511")]
UnsupportedSymbol {
#[primary_span]
span: Span,
name: Symbol,
symbol: Symbol,
in_ty: Ty<'tcx>,
in_elem: Ty<'tcx>,
ret_ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = "E0511")]
CastFatPointer {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = "E0511")]
ExpectedPointer {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = "E0511")]
ExpectedUsize {
#[primary_span]
span: Span,
name: Symbol,
ty: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = "E0511")]
UnsupportedCast {
#[primary_span]
span: Span,
name: Symbol,
in_ty: Ty<'tcx>,
in_elem: Ty<'tcx>,
ret_ty: Ty<'tcx>,
out_elem: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = "E0511")]
UnsupportedOperation {
#[primary_span]
span: Span,
name: Symbol,
in_ty: Ty<'tcx>,
in_elem: Ty<'tcx>,
},
#[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = "E0511")]
ExpectedVectorElementType {
#[primary_span]
span: Span,
name: Symbol,
expected_element: Ty<'tcx>,
vector_type: Ty<'tcx>,
},
}
pub enum ExpectedPointerMutability {
Mut,
Not,
}
impl IntoDiagnosticArg for ExpectedPointerMutability {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
match self {
ExpectedPointerMutability::Mut => DiagnosticArgValue::Str(Cow::Borrowed("*mut")),
ExpectedPointerMutability::Not => DiagnosticArgValue::Str(Cow::Borrowed("*_")),
}
}
} }

View file

@ -226,4 +226,70 @@ codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphizat
codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}` codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`
codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric codegen_ssa_polymorphic_constant_too_generic = codegen encountered polymorphic constant: TooGeneric
codegen_ssa_invalid_monomorphization_return_length_input_type = invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_third_argument_length = invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`
codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
codegen_ssa_invalid_monomorphization_return_length = invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`
codegen_ssa_invalid_monomorphization_shuffle_index_not_constant = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is not a constant
codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: shuffle index #{$arg_idx} is out of bounds (limit {$total_len})
codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`
codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`
codegen_ssa_invalid_monomorphization_expected_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}`
codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`
codegen_ssa_invalid_monomorphization_mask_type = invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_`
codegen_ssa_invalid_monomorphization_vector_argument = invalid monomorphization of `{$name}` intrinsic: vector argument `{$in_ty}`'s element type `{$in_elem}`, expected integer element type
codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
codegen_ssa_invalid_monomorphization_expected_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}`
codegen_ssa_invalid_monomorphization_third_arg_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of third argument `{$third_arg}` to be a signed integer type
codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`
codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}`
codegen_ssa_invalid_monomorphization_cast_fat_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast fat pointer `{$ty}`
codegen_ssa_invalid_monomorphization_expected_pointer = invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}`
codegen_ssa_invalid_monomorphization_expected_usize = invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}`
codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`
codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`
codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type