diff --git a/src/librustc_platform_intrinsics/lib.rs b/src/librustc_platform_intrinsics/lib.rs index 134b4c66419..476b9ee31fe 100755 --- a/src/librustc_platform_intrinsics/lib.rs +++ b/src/librustc_platform_intrinsics/lib.rs @@ -30,7 +30,7 @@ pub struct Intrinsic { #[derive(Clone, Hash, Eq, PartialEq)] pub enum Type { - Integer(u8), + Integer(/* signed */ bool, u8), Float(u8), Pointer(Box), Vector(Box, u8), @@ -40,7 +40,8 @@ pub enum IntrinsicDef { Named(&'static str), } -fn i(width: u8) -> Type { Type::Integer(width) } +fn i(width: u8) -> Type { Type::Integer(true, width) } +fn u(width: u8) -> Type { Type::Integer(false, width) } fn f(width: u8) -> Type { Type::Float(width) } fn v(x: Type, length: u8) -> Type { Type::Vector(Box::new(x), length) } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index ded748e9894..d6275f2b9e8 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -927,7 +927,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, fn ty_to_type(ccx: &CrateContext, t: &intrinsics::Type) -> Type { use intrinsics::Type::*; match *t { - Integer(x) => Type::ix(ccx, x as u64), + Integer(_signed, x) => Type::ix(ccx, x as u64), Float(x) => { match x { 32 => Type::f32(ccx), diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 636f17db38c..24b63f5d4f4 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -456,13 +456,15 @@ fn match_intrinsic_type_to_type<'tcx, 'a>( }; match *expected { - Integer(bits) => match (bits, &t.sty) { - (8, &ty::TyInt(ast::TyI8)) | (8, &ty::TyUint(ast::TyU8)) | - (16, &ty::TyInt(ast::TyI16)) | (16, &ty::TyUint(ast::TyU16)) | - (32, &ty::TyInt(ast::TyI32)) | (32, &ty::TyUint(ast::TyU32)) | - (64, &ty::TyInt(ast::TyI64)) | (64, &ty::TyUint(ast::TyU64)) => {}, + Integer(signed, bits) => match (signed, bits, &t.sty) { + (true, 8, &ty::TyInt(ast::TyI8)) | (false, 8, &ty::TyUint(ast::TyU8)) | + (true, 16, &ty::TyInt(ast::TyI16)) | (false, 16, &ty::TyUint(ast::TyU16)) | + (true, 32, &ty::TyInt(ast::TyI32)) | (false, 32, &ty::TyUint(ast::TyU32)) | + (true, 64, &ty::TyInt(ast::TyI64)) | (false, 64, &ty::TyUint(ast::TyU64)) => {}, _ => simple_error(&format!("`{}`", t), - &format!("`i{n}` or `u{n}`", n = bits)), + &format!("`{}{n}`", + if signed {"i"} else {"u"}, + n = bits)), }, Float(bits) => match (bits, &t.sty) { (32, &ty::TyFloat(ast::TyF32)) | diff --git a/src/test/compile-fail/simd-intrinsic-declaration-type.rs b/src/test/compile-fail/simd-intrinsic-declaration-type.rs index effa1ed04d8..ef1f4d6f230 100644 --- a/src/test/compile-fail/simd-intrinsic-declaration-type.rs +++ b/src/test/compile-fail/simd-intrinsic-declaration-type.rs @@ -25,27 +25,38 @@ struct f32x4(f32, f32, f32, f32); #[repr(simd)] struct i64x2(i64, i64); -// signed vs. unsigned doesn't matter -mod i { - use i16x8; +// correct signatures work well +mod right { + use {i16x8, u16x8}; extern "platform-intrinsic" { fn x86_mm_adds_epi16(x: i16x8, y: i16x8) -> i16x8; + fn x86_mm_adds_epu16(x: u16x8, y: u16x8) -> u16x8; } } -mod u { - use u16x8; +// but incorrect ones don't. + +mod signedness { + use {i16x8, u16x8}; + // signedness matters extern "platform-intrinsic" { fn x86_mm_adds_epi16(x: u16x8, y: u16x8) -> u16x8; + //~^ ERROR intrinsic argument 1 has wrong type + //~^^ ERROR intrinsic argument 2 has wrong type + //~^^^ ERROR intrinsic return value has wrong type + fn x86_mm_adds_epu16(x: i16x8, y: i16x8) -> i16x8; + //~^ ERROR intrinsic argument 1 has wrong type + //~^^ ERROR intrinsic argument 2 has wrong type + //~^^^ ERROR intrinsic return value has wrong type } } -// but lengths do +// as do lengths extern "platform-intrinsic" { fn x86_mm_adds_epi16(x: i8x16, y: i32x4) -> i64x2; //~^ ERROR intrinsic argument 1 has wrong type //~^^ ERROR intrinsic argument 2 has wrong type //~^^^ ERROR intrinsic return value has wrong type } -// and so does int vs. float +// and so does int vs. float: extern "platform-intrinsic" { fn x86_mm_max_ps(x: i32x4, y: i32x4) -> i32x4; //~^ ERROR intrinsic argument 1 has wrong type