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:
commit
c9687a95a6
13 changed files with 296 additions and 266 deletions
|
@ -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 { .. } => {}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
51
tests/ui/asm/invalid-const-operand.rs
Normal file
51
tests/ui/asm/invalid-const-operand.rs
Normal 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
|
||||
}
|
||||
}
|
86
tests/ui/asm/invalid-const-operand.stderr
Normal file
86
tests/ui/asm/invalid-const-operand.stderr
Normal 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`.
|
34
tests/ui/asm/invalid-sym-operand.rs
Normal file
34
tests/ui/asm/invalid-sym-operand.rs
Normal 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>);
|
||||
}
|
26
tests/ui/asm/invalid-sym-operand.stderr
Normal file
26
tests/ui/asm/invalid-sym-operand.stderr
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue