Auto merge of #85290 - Amanieu:asm_const_int, r=nagisa

Remove support for floating-point constants in asm!

Floating-point constants aren't very useful anyways and this simplifies
the code since the type check can now be done in typeck.

cc `@rust-lang/wg-inline-asm`

r? `@nagisa`
This commit is contained in:
bors 2021-05-16 17:52:52 +00:00
commit 7dc9ff5c62
8 changed files with 70 additions and 91 deletions

View File

@ -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),
}
}

View File

@ -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> {

View File

@ -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(),
},

View File

@ -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 <expr>`
- `<expr>` must be an integer or floating-point constant expression.
- `<expr>` 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 <path>`
- `<path>` must refer to a `fn` or `static`.

View File

@ -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

View File

@ -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`
Some errors have detailed explanations: E0277, E0435.
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, E0308, E0435.
For more information about an error, try `rustc --explain E0277`.

View File

@ -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

View File

@ -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<i32>` 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<u64> = 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`.