1
Fork 0

Auto merge of #125558 - Amanieu:const-asm-type, r=lcnr

Tweak type inference for `const` operands in inline asm

Previously these would be treated like integer literals and default to `i32` if a type could not be determined. To allow for forward-compatibility with `str` constants in the future, this PR changes type inference to use an unbound type variable instead.

The actual type checking is deferred until after typeck where we still ensure that the final type for the `const` operand is an integer type.

<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.

This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using

    r​? <reviewer name>
-->
This commit is contained in:
bors 2024-08-06 01:20:43 +00:00
commit c9687a95a6
13 changed files with 296 additions and 266 deletions

View file

@ -2,7 +2,7 @@ use rustc_ast::InlineAsmTemplatePiece;
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir::{self as hir, LangItem};
use rustc_middle::bug;
use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
use rustc_session::lint;
use rustc_span::def_id::LocalDefId;
use rustc_span::Symbol;
@ -455,32 +455,22 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
);
}
}
// No special checking is needed for these:
// - Typeck has checked that Const operands are integers.
// - AST lowering guarantees that SymStatic points to a static.
hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymStatic { .. } => {}
// Check that sym actually points to a function. Later passes
// depend on this.
// Typeck has checked that Const operands are integers.
hir::InlineAsmOperand::Const { anon_const } => {
debug_assert!(matches!(
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
ty::Error(_) | ty::Int(_) | ty::Uint(_)
));
}
// Typeck has checked that SymFn refers to a function.
hir::InlineAsmOperand::SymFn { anon_const } => {
let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity();
match ty.kind() {
ty::Never | ty::Error(_) => {}
ty::FnDef(..) => {}
_ => {
self.tcx
.dcx()
.struct_span_err(*op_sp, "invalid `sym` operand")
.with_span_label(
self.tcx.def_span(anon_const.def_id),
format!("is {} `{}`", ty.kind().article(), ty),
)
.with_help(
"`sym` operands must refer to either a function or a static",
)
.emit();
}
};
debug_assert!(matches!(
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
ty::Error(_) | ty::FnDef(..)
));
}
// AST lowering guarantees that SymStatic points to a static.
hir::InlineAsmOperand::SymStatic { .. } => {}
// No special checking is needed for labels.
hir::InlineAsmOperand::Label { .. } => {}
}

View file

@ -7,7 +7,7 @@ use rustc_hir::HirId;
use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::Ident;
use rustc_span::{Span, DUMMY_SP};
@ -34,6 +34,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
let parent_node_id = tcx.parent_hir_id(hir_id);
let parent_node = tcx.hir_node(parent_node_id);
let find_sym_fn = |&(op, op_sp)| match op {
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == hir_id => {
Some((anon_const, op_sp))
}
_ => None,
};
let find_const = |&(op, op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => {
Some((anon_const, op_sp))
}
_ => None,
};
match parent_node {
// Anon consts "inside" the type system.
Node::ConstArg(&ConstArg {
@ -45,13 +59,51 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
// Anon consts outside the type system.
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
if asm.operands.iter().any(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const }
| hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
_ => false,
}) =>
if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_sym_fn) =>
{
tcx.typeck(def_id).node_type(hir_id)
let ty = tcx.typeck(def_id).node_type(hir_id);
match ty.kind() {
ty::Error(_) => ty,
ty::FnDef(..) => ty,
_ => {
let guar = tcx
.dcx()
.struct_span_err(op_sp, "invalid `sym` operand")
.with_span_label(
tcx.def_span(anon_const.def_id),
format!("is {} `{}`", ty.kind().article(), ty),
)
.with_help("`sym` operands must refer to either a function or a static")
.emit();
Ty::new_error(tcx, guar)
}
}
}
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) =>
{
let ty = tcx.typeck(def_id).node_type(hir_id);
match ty.kind() {
ty::Error(_) => ty,
ty::Int(_) | ty::Uint(_) => ty,
_ => {
let guar = tcx
.dcx()
.struct_span_err(op_sp, "invalid type for `const` operand")
.with_span_label(
tcx.def_span(anon_const.def_id),
format!("is {} `{}`", ty.kind().article(), ty),
)
.with_help("`const` operands must be of an integer type")
.emit();
Ty::new_error(tcx, guar)
}
}
}
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)

View file

@ -265,11 +265,10 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. })
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => {
asm.operands.iter().find_map(|(op, _op_sp)| match op {
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
// Inline assembly constants must be integers.
Some(fcx.next_int_var())
}
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
hir::InlineAsmOperand::Const { anon_const }
| hir::InlineAsmOperand::SymFn { anon_const }
if anon_const.hir_id == id =>
{
Some(fcx.next_ty_var(span))
}
_ => None,

View file

@ -15,15 +15,6 @@ fn main() {
unsafe {
// Inputs must be initialized
// Sym operands must point to a function or static
const C: i32 = 0;
static S: i32 = 0;
asm!("{}", sym S);
asm!("{}", sym main);
asm!("{}", sym C);
//~^ ERROR invalid `sym` operand
// Register operands must be Copy
asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
@ -65,12 +56,3 @@ fn main() {
asm!("{}", in(reg) u);
}
}
// Sym operands must point to a function or static
const C: i32 = 0;
static S: i32 = 0;
global_asm!("{}", sym S);
global_asm!("{}", sym main);
global_asm!("{}", sym C);
//~^ ERROR invalid `sym` operand

View file

@ -1,29 +1,13 @@
error: invalid `sym` operand
--> $DIR/type-check-2.rs:75:19
|
LL | global_asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:24:20
|
LL | asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: arguments for inline assembly must be copyable
--> $DIR/type-check-2.rs:29:31
--> $DIR/type-check-2.rs:20:31
|
LL | asm!("{:v}", in(vreg) 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:41:28: 41:36}` for inline assembly
--> $DIR/type-check-2.rs:41:28
error: cannot use value of type `{closure@$DIR/type-check-2.rs:32:28: 32:36}` for inline assembly
--> $DIR/type-check-2.rs:32:28
|
LL | asm!("{}", in(reg) |x: i32| x);
| ^^^^^^^^^^
@ -31,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:43:28
--> $DIR/type-check-2.rs:34:28
|
LL | asm!("{}", in(reg) vec![0]);
| ^^^^^^^
@ -40,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:45:28
--> $DIR/type-check-2.rs:36:28
|
LL | asm!("{}", in(reg) (1, 2, 3));
| ^^^^^^^^^
@ -48,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:47:28
--> $DIR/type-check-2.rs:38:28
|
LL | asm!("{}", in(reg) [1, 2, 3]);
| ^^^^^^^^^
@ -56,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:55:31
--> $DIR/type-check-2.rs:46:31
|
LL | asm!("{}", inout(reg) f);
| ^
@ -64,12 +48,12 @@ 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:58:31
--> $DIR/type-check-2.rs:49: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: aborting due to 9 previous errors
error: aborting due to 7 previous errors

View file

@ -0,0 +1,51 @@
//@ needs-asm-support
//@ ignore-nvptx64
//@ ignore-spirv
#![feature(asm_const)]
use std::arch::{asm, global_asm};
// 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 invalid type for `const` operand
global_asm!("{}", const 0 as *mut u8);
//~^ ERROR invalid type for `const` operand
fn main() {
unsafe {
// Const operands must be integers and must be constants.
asm!("{}", const 0);
asm!("{}", const 0i32);
asm!("{}", const 0i128);
asm!("{}", const 0f32);
//~^ ERROR invalid type for `const` operand
asm!("{}", const 0 as *mut u8);
//~^ ERROR invalid type for `const` operand
asm!("{}", const &0);
//~^ ERROR invalid type for `const` operand
// Constants must be... constant
let x = 0;
const fn const_foo(x: i32) -> i32 {
x
}
const fn const_bar<T>(x: T) -> T {
x
}
asm!("{}", const x);
//~^ ERROR attempt to use a non-constant value in a constant
asm!("{}", const const_foo(0));
asm!("{}", const const_foo(x));
//~^ ERROR attempt to use a non-constant value in a constant
asm!("{}", const const_bar(0));
asm!("{}", const const_bar(x));
//~^ ERROR attempt to use a non-constant value in a constant
}
}

View file

@ -0,0 +1,86 @@
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/invalid-const-operand.rs:42:26
|
LL | asm!("{}", const x);
| ^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const x: /* Type */ = 0;
| ~~~~~ ++++++++++++
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/invalid-const-operand.rs:45:36
|
LL | asm!("{}", const const_foo(x));
| ^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const x: /* Type */ = 0;
| ~~~~~ ++++++++++++
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/invalid-const-operand.rs:48:36
|
LL | asm!("{}", const const_bar(x));
| ^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const x: /* Type */ = 0;
| ~~~~~ ++++++++++++
error: invalid type for `const` operand
--> $DIR/invalid-const-operand.rs:14:19
|
LL | global_asm!("{}", const 0f32);
| ^^^^^^----
| |
| is an `f32`
|
= help: `const` operands must be of an integer type
error: invalid type for `const` operand
--> $DIR/invalid-const-operand.rs:16:19
|
LL | global_asm!("{}", const 0 as *mut u8);
| ^^^^^^------------
| |
| is a `*mut u8`
|
= help: `const` operands must be of an integer type
error: invalid type for `const` operand
--> $DIR/invalid-const-operand.rs:26:20
|
LL | asm!("{}", const 0f32);
| ^^^^^^----
| |
| is an `f32`
|
= help: `const` operands must be of an integer type
error: invalid type for `const` operand
--> $DIR/invalid-const-operand.rs:28:20
|
LL | asm!("{}", const 0 as *mut u8);
| ^^^^^^------------
| |
| is a `*mut u8`
|
= help: `const` operands must be of an integer type
error: invalid type for `const` operand
--> $DIR/invalid-const-operand.rs:30:20
|
LL | asm!("{}", const &0);
| ^^^^^^--
| |
| is a `&i32`
|
= help: `const` operands must be of an integer type
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0435`.

View file

@ -0,0 +1,34 @@
//@ needs-asm-support
//@ ignore-nvptx64
//@ ignore-spirv
use std::arch::{asm, global_asm};
// Sym operands must point to a function or static
const C: i32 = 0;
static S: i32 = 0;
global_asm!("{}", sym S);
global_asm!("{}", sym main);
global_asm!("{}", sym C);
//~^ ERROR invalid `sym` operand
fn main() {
unsafe {
// Sym operands must point to a function or static
let x: u64 = 0;
const C: i32 = 0;
static S: i32 = 0;
asm!("{}", sym S);
asm!("{}", sym main);
asm!("{}", sym C);
//~^ ERROR invalid `sym` operand
asm!("{}", sym x);
//~^ ERROR invalid `sym` operand
}
}
unsafe fn generic<T>() {
asm!("{}", sym generic::<T>);
}

View file

@ -0,0 +1,26 @@
error: invalid `sym` operand
--> $DIR/invalid-sym-operand.rs:27:24
|
LL | asm!("{}", sym x);
| ^ is a local variable
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/invalid-sym-operand.rs:13:19
|
LL | global_asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/invalid-sym-operand.rs:25:20
|
LL | asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: aborting due to 3 previous errors

View file

@ -28,51 +28,5 @@ fn main() {
asm!("{}", inout(reg) v[..]);
//~^ ERROR the size for values of type `[u64]` cannot be known at compilation time
//~| ERROR cannot use value of type `[u64]` for inline assembly
// Constants must be... constant
let x = 0;
const fn const_foo(x: i32) -> i32 {
x
}
const fn const_bar<T>(x: T) -> T {
x
}
asm!("{}", const x);
//~^ ERROR attempt to use a non-constant value in a constant
asm!("{}", const const_foo(0));
asm!("{}", const const_foo(x));
//~^ ERROR attempt to use a non-constant value in a constant
asm!("{}", const const_bar(0));
asm!("{}", const const_bar(x));
//~^ ERROR attempt to use a non-constant value in a constant
asm!("{}", sym x);
//~^ ERROR invalid `sym` operand
// 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
asm!("{}", const &0);
//~^ ERROR mismatched types
}
}
unsafe fn generic<T>() {
asm!("{}", sym generic::<T>);
}
// 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

@ -1,44 +1,3 @@
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/type-check-1.rs:41:26
|
LL | asm!("{}", const x);
| ^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const x: /* Type */ = 0;
| ~~~~~ ++++++++++++
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/type-check-1.rs:44:36
|
LL | asm!("{}", const const_foo(x));
| ^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const x: /* Type */ = 0;
| ~~~~~ ++++++++++++
error[E0435]: attempt to use a non-constant value in a constant
--> $DIR/type-check-1.rs:47:36
|
LL | asm!("{}", const const_bar(x));
| ^ non-constant value
|
help: consider using `const` instead of `let`
|
LL | const x: /* Type */ = 0;
| ~~~~~ ++++++++++++
error: invalid `sym` operand
--> $DIR/type-check-1.rs:49:24
|
LL | asm!("{}", sym x);
| ^ is a local variable
|
= help: `sym` operands must refer to either a function or a static
error: invalid asm output
--> $DIR/type-check-1.rs:14:29
|
@ -102,49 +61,6 @@ LL | asm!("{}", inout(reg) v[..]);
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
error[E0308]: mismatched types
--> $DIR/type-check-1.rs:57:26
|
LL | asm!("{}", const 0f32);
| ^^^^ expected integer, found `f32`
error: aborting due to 8 previous errors
error[E0308]: mismatched types
--> $DIR/type-check-1.rs:59:26
|
LL | asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^ expected integer, found `*mut u8`
|
= note: expected type `{integer}`
found raw pointer `*mut u8`
error[E0308]: mismatched types
--> $DIR/type-check-1.rs:61:26
|
LL | asm!("{}", const &0);
| ^^ expected integer, found `&{integer}`
|
help: consider removing the borrow
|
LL - asm!("{}", const &0);
LL + asm!("{}", const 0);
|
error[E0308]: mismatched types
--> $DIR/type-check-1.rs:75:25
|
LL | global_asm!("{}", const 0f32);
| ^^^^ expected integer, found `f32`
error[E0308]: mismatched types
--> $DIR/type-check-1.rs:77:25
|
LL | global_asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^ expected integer, found `*mut u8`
|
= note: expected type `{integer}`
found raw pointer `*mut u8`
error: aborting due to 17 previous errors
Some errors have detailed explanations: E0277, E0308, E0435.
For more information about an error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0277`.

View file

@ -27,17 +27,6 @@ fn main() {
asm!("{}", out(reg) v[0]);
asm!("{}", inout(reg) v[0]);
// Sym operands must point to a function or static
const C: i32 = 0;
static S: i32 = 0;
asm!("{}", sym S);
asm!("{}", sym main);
asm!("{}", sym C);
//~^ ERROR invalid `sym` operand
asm!("{}", sym x);
//~^ ERROR invalid `sym` operand
// Register operands must be Copy
asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
@ -79,12 +68,3 @@ fn main() {
asm!("{}", in(reg) u);
}
}
// Sym operands must point to a function or static
const C: i32 = 0;
static S: i32 = 0;
global_asm!("{}", sym S);
global_asm!("{}", sym main);
global_asm!("{}", sym C);
//~^ ERROR invalid `sym` operand

View file

@ -1,37 +1,13 @@
error: invalid `sym` operand
--> $DIR/type-check-2.rs:38:24
|
LL | asm!("{}", sym x);
| ^ is a local variable
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:89:19
|
LL | global_asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: invalid `sym` operand
--> $DIR/type-check-2.rs:36:20
|
LL | asm!("{}", sym C);
| ^^^^^ is an `i32`
|
= help: `sym` operands must refer to either a function or a static
error: arguments for inline assembly must be copyable
--> $DIR/type-check-2.rs:43:32
--> $DIR/type-check-2.rs:32: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:55:28: 55:36}` for inline assembly
--> $DIR/type-check-2.rs:55:28
error: cannot use value of type `{closure@$DIR/type-check-2.rs:44:28: 44:36}` for inline assembly
--> $DIR/type-check-2.rs:44:28
|
LL | asm!("{}", in(reg) |x: i32| x);
| ^^^^^^^^^^
@ -39,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:57:28
--> $DIR/type-check-2.rs:46:28
|
LL | asm!("{}", in(reg) vec![0]);
| ^^^^^^^
@ -48,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:59:28
--> $DIR/type-check-2.rs:48:28
|
LL | asm!("{}", in(reg) (1, 2, 3));
| ^^^^^^^^^
@ -56,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:61:28
--> $DIR/type-check-2.rs:50:28
|
LL | asm!("{}", in(reg) [1, 2, 3]);
| ^^^^^^^^^
@ -64,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:69:31
--> $DIR/type-check-2.rs:58:31
|
LL | asm!("{}", inout(reg) f);
| ^
@ -72,7 +48,7 @@ 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:72:31
--> $DIR/type-check-2.rs:61:31
|
LL | asm!("{}", inout(reg) r);
| ^
@ -121,7 +97,7 @@ help: consider changing this to be mutable
LL | let mut v: Vec<u64> = vec![0, 1, 2];
| +++
error: aborting due to 13 previous errors
error: aborting due to 10 previous errors
Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.