diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 955f658eb1c7e..1fa60612d26a3 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -219,8 +219,6 @@ pub fn asm_const_to_str<'tcx>( ty::IntTy::I128 => (value as i128).to_string(), ty::IntTy::Isize => unreachable!(), }, - ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(), - ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(), _ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty), } } diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs index 4532a0a350cef..012d97ef106c7 100644 --- a/compiler/rustc_passes/src/intrinsicck.rs +++ b/compiler/rustc_passes/src/intrinsicck.rs @@ -347,7 +347,7 @@ impl ExprVisitor<'tcx> { } fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) { - for (idx, (op, op_sp)) in asm.operands.iter().enumerate() { + for (idx, (op, _)) in asm.operands.iter().enumerate() { match *op { hir::InlineAsmOperand::In { reg, ref expr } => { self.check_asm_operand_type(idx, reg, expr, asm.template, None); @@ -372,19 +372,7 @@ impl ExprVisitor<'tcx> { ); } } - hir::InlineAsmOperand::Const { ref anon_const } => { - let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); - let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id); - match value.ty.kind() { - ty::Int(_) | ty::Uint(_) | ty::Float(_) => {} - _ => { - let msg = - "asm `const` arguments must be integer or floating-point values"; - self.tcx.sess.span_err(*op_sp, msg); - } - } - } - hir::InlineAsmOperand::Sym { .. } => {} + hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => {} } } } @@ -405,33 +393,6 @@ impl Visitor<'tcx> for ItemVisitor<'tcx> { ExprVisitor { tcx: self.tcx, param_env, typeck_results }.visit_body(body); self.visit_body(body); } - - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - if let hir::ItemKind::GlobalAsm(asm) = item.kind { - for (op, op_sp) in asm.operands { - match *op { - hir::InlineAsmOperand::Const { ref anon_const } => { - let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id); - let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id); - match value.ty.kind() { - ty::Int(_) | ty::Uint(_) | ty::Float(_) => {} - _ => { - let msg = "asm `const` arguments must be integer or floating-point values"; - self.tcx.sess.span_err(*op_sp, msg); - } - } - } - hir::InlineAsmOperand::In { .. } - | hir::InlineAsmOperand::Out { .. } - | hir::InlineAsmOperand::InOut { .. } - | hir::InlineAsmOperand::SplitInOut { .. } - | hir::InlineAsmOperand::Sym { .. } => unreachable!(), - } - } - } - - intravisit::walk_item(self, item); - } } impl Visitor<'tcx> for ExprVisitor<'tcx> { diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs index 994206bd41934..62db535f835fe 100644 --- a/compiler/rustc_typeck/src/check/mod.rs +++ b/compiler/rustc_typeck/src/check/mod.rs @@ -554,10 +554,8 @@ fn typeck_with_fallback<'tcx>( _ => false, }) => { - fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }) + // Inline assembly constants must be integers. + fcx.next_int_var() } _ => fallback(), }, diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index 107fc6d42cf8e..5503b3b4b32fb 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -509,7 +509,7 @@ Several types of operands are supported: - Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`). - You should only write to the register after all inputs are read, otherwise you may clobber an input. * `const ` - - `` must be an integer or floating-point constant expression. + - `` must be an integer constant expression. - The value of the expression is formatted as a string and substituted directly into the asm template string. * `sym ` - `` must refer to a `fn` or `static`. diff --git a/src/test/ui/asm/type-check-1.rs b/src/test/ui/asm/type-check-1.rs index 57a91aaa934e9..5e38fb70a4adf 100644 --- a/src/test/ui/asm/type-check-1.rs +++ b/src/test/ui/asm/type-check-1.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm)] +#![feature(asm, global_asm)] fn main() { unsafe { @@ -39,5 +39,25 @@ fn main() { asm!("{}", const const_bar(0)); asm!("{}", const const_bar(x)); //~^ ERROR attempt to use a non-constant value in a constant + + // Const operands must be integers and must be constants. + + asm!("{}", const 0); + asm!("{}", const 0i32); + asm!("{}", const 0i128); + asm!("{}", const 0f32); + //~^ ERROR mismatched types + asm!("{}", const 0 as *mut u8); + //~^ ERROR mismatched types } } + +// Const operands must be integers and must be constants. + +global_asm!("{}", const 0); +global_asm!("{}", const 0i32); +global_asm!("{}", const 0i128); +global_asm!("{}", const 0f32); +//~^ ERROR mismatched types +global_asm!("{}", const 0 as *mut u8); +//~^ ERROR mismatched types diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr index eefab6d397788..ad981d93d514e 100644 --- a/src/test/ui/asm/type-check-1.stderr +++ b/src/test/ui/asm/type-check-1.stderr @@ -64,7 +64,37 @@ LL | asm!("{}", inout(reg) v[..]); = help: the trait `Sized` is not implemented for `[u64]` = note: all inline asm arguments must have a statically known size -error: aborting due to 8 previous errors +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:48:26 + | +LL | asm!("{}", const 0f32); + | ^^^^ expected integer, found `f32` + +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:50:26 + | +LL | asm!("{}", const 0 as *mut u8); + | ^^^^^^^^^^^^ expected integer, found *-ptr + | + = note: expected type `{integer}` + found raw pointer `*mut u8` + +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:60:25 + | +LL | global_asm!("{}", const 0f32); + | ^^^^ expected integer, found `f32` + +error[E0308]: mismatched types + --> $DIR/type-check-1.rs:62:25 + | +LL | global_asm!("{}", const 0 as *mut u8); + | ^^^^^^^^^^^^ expected integer, found *-ptr + | + = note: expected type `{integer}` + found raw pointer `*mut u8` + +error: aborting due to 12 previous errors -Some errors have detailed explanations: E0277, E0435. +Some errors have detailed explanations: E0277, E0308, E0435. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/asm/type-check-2.rs b/src/test/ui/asm/type-check-2.rs index 060a88fc93713..c70a8802814f7 100644 --- a/src/test/ui/asm/type-check-2.rs +++ b/src/test/ui/asm/type-check-2.rs @@ -1,6 +1,6 @@ // only-x86_64 -#![feature(asm, global_asm, repr_simd, never_type)] +#![feature(asm, repr_simd, never_type)] #[repr(simd)] struct SimdNonCopy(f32, f32, f32, f32); @@ -26,14 +26,6 @@ fn main() { asm!("{}", inout(reg) v[0]); //~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable - // Const operands must be integer or floats, and must be constants. - - asm!("{}", const 0); - asm!("{}", const 0i32); - asm!("{}", const 0f32); - asm!("{}", const 0 as *mut u8); - //~^ ERROR asm `const` arguments must be integer or floating-point values - // This currently causes an ICE: https://github.com/rust-lang/rust/issues/81857 // asm!("{}", const &0); // ERROR asm `const` arguments must be integer or floating-point values @@ -90,11 +82,3 @@ fn main() { asm!("{}", in(reg) u); } } - -// Const operands must be integer or floats, and must be constants. - -global_asm!("{}", const 0); -global_asm!("{}", const 0i32); -global_asm!("{}", const 0f32); -global_asm!("{}", const 0 as *mut u8); -//~^ ERROR asm `const` arguments must be integer or floating-point values diff --git a/src/test/ui/asm/type-check-2.stderr b/src/test/ui/asm/type-check-2.stderr index f61f690bdb4dd..1354a9dd849b3 100644 --- a/src/test/ui/asm/type-check-2.stderr +++ b/src/test/ui/asm/type-check-2.stderr @@ -1,19 +1,13 @@ -error: asm `const` arguments must be integer or floating-point values - --> $DIR/type-check-2.rs:34:20 - | -LL | asm!("{}", const 0 as *mut u8); - | ^^^^^^^^^^^^^^^^^^ - error: arguments for inline assembly must be copyable - --> $DIR/type-check-2.rs:54:32 + --> $DIR/type-check-2.rs:46:32 | LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `SimdNonCopy` does not implement the Copy trait -error: cannot use value of type `[closure@$DIR/type-check-2.rs:66:28: 66:38]` for inline assembly - --> $DIR/type-check-2.rs:66:28 +error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly + --> $DIR/type-check-2.rs:58:28 | LL | asm!("{}", in(reg) |x: i32| x); | ^^^^^^^^^^ @@ -21,7 +15,7 @@ LL | asm!("{}", in(reg) |x: i32| x); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `Vec` for inline assembly - --> $DIR/type-check-2.rs:68:28 + --> $DIR/type-check-2.rs:60:28 | LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ @@ -30,7 +24,7 @@ LL | asm!("{}", in(reg) vec![0]); = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly - --> $DIR/type-check-2.rs:70:28 + --> $DIR/type-check-2.rs:62:28 | LL | asm!("{}", in(reg) (1, 2, 3)); | ^^^^^^^^^ @@ -38,7 +32,7 @@ LL | asm!("{}", in(reg) (1, 2, 3)); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `[i32; 3]` for inline assembly - --> $DIR/type-check-2.rs:72:28 + --> $DIR/type-check-2.rs:64:28 | LL | asm!("{}", in(reg) [1, 2, 3]); | ^^^^^^^^^ @@ -46,7 +40,7 @@ LL | asm!("{}", in(reg) [1, 2, 3]); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `fn() {main}` for inline assembly - --> $DIR/type-check-2.rs:80:31 + --> $DIR/type-check-2.rs:72:31 | LL | asm!("{}", inout(reg) f); | ^ @@ -54,27 +48,21 @@ LL | asm!("{}", inout(reg) f); = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly error: cannot use value of type `&mut i32` for inline assembly - --> $DIR/type-check-2.rs:83:31 + --> $DIR/type-check-2.rs:75:31 | LL | asm!("{}", inout(reg) r); | ^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly -error: asm `const` arguments must be integer or floating-point values - --> $DIR/type-check-2.rs:99:19 - | -LL | global_asm!("{}", const 0 as *mut u8); - | ^^^^^^^^^^^^^^^^^^ - error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:47:24 + --> $DIR/type-check-2.rs:39:24 | LL | asm!("{}", sym C); | ^ error: asm `sym` operand must point to a fn or static - --> $DIR/type-check-2.rs:49:24 + --> $DIR/type-check-2.rs:41:24 | LL | asm!("{}", sym x); | ^ @@ -109,7 +97,7 @@ LL | let v: Vec = vec![0, 1, 2]; LL | asm!("{}", inout(reg) v[0]); | ^ cannot borrow as mutable -error: aborting due to 15 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0381, E0596. For more information about an error, try `rustc --explain E0381`.