apply fix suggested by lcnr
This commit is contained in:
parent
575fc72350
commit
97738e1b86
5 changed files with 127 additions and 85 deletions
|
@ -2,7 +2,7 @@ use rustc_ast::InlineAsmTemplatePiece;
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_hir::{self as hir, LangItem};
|
use rustc_hir::{self as hir, LangItem};
|
||||||
use rustc_middle::bug;
|
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_session::lint;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
|
@ -455,48 +455,22 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Typeck has checked that Const operands are integers.
|
||||||
hir::InlineAsmOperand::Const { anon_const } => {
|
hir::InlineAsmOperand::Const { anon_const } => {
|
||||||
let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity();
|
debug_assert!(matches!(
|
||||||
match ty.kind() {
|
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
|
||||||
ty::Error(_) => {}
|
ty::Error(_) | ty::Int(_) | ty::Uint(_)
|
||||||
ty::Int(_) | ty::Uint(_) => {}
|
));
|
||||||
_ => {
|
}
|
||||||
self.tcx
|
// Typeck has checked that SymFn refers to a function.
|
||||||
.dcx()
|
hir::InlineAsmOperand::SymFn { anon_const } => {
|
||||||
.struct_span_err(*op_sp, "invalid type for `const` operand")
|
debug_assert!(matches!(
|
||||||
.with_span_label(
|
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
|
||||||
self.tcx.def_span(anon_const.def_id),
|
ty::Error(_) | ty::Never | ty::FnDef(..)
|
||||||
format!("is {} `{}`", ty.kind().article(), ty),
|
));
|
||||||
)
|
|
||||||
.with_help("`const` operands must be of an integer type")
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
// AST lowering guarantees that SymStatic points to a static.
|
// AST lowering guarantees that SymStatic points to a static.
|
||||||
hir::InlineAsmOperand::SymStatic { .. } => {}
|
hir::InlineAsmOperand::SymStatic { .. } => {}
|
||||||
// Check that sym actually points to a function. Later passes
|
|
||||||
// depend on this.
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// No special checking is needed for labels.
|
// No special checking is needed for labels.
|
||||||
hir::InlineAsmOperand::Label { .. } => {}
|
hir::InlineAsmOperand::Label { .. } => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_hir::HirId;
|
||||||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||||
use rustc_middle::ty::util::IntTypeExt;
|
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_middle::{bug, span_bug};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
@ -35,6 +35,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_id = tcx.parent_hir_id(hir_id);
|
||||||
let parent_node = tcx.hir_node(parent_node_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 {
|
match parent_node {
|
||||||
// Anon consts "inside" the type system.
|
// Anon consts "inside" the type system.
|
||||||
Node::ConstArg(&ConstArg {
|
Node::ConstArg(&ConstArg {
|
||||||
|
@ -46,13 +60,57 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
// Anon consts outside the type system.
|
// Anon consts outside the type system.
|
||||||
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
||||||
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
|
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
|
||||||
if asm.operands.iter().any(|(op, _op_sp)| match op {
|
if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_sym_fn) =>
|
||||||
hir::InlineAsmOperand::Const { anon_const }
|
|
||||||
| hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
|
|
||||||
_ => false,
|
|
||||||
}) =>
|
|
||||||
{
|
{
|
||||||
tcx.typeck(def_id).node_type(hir_id)
|
let ty = tcx.typeck(def_id).node_type(hir_id);
|
||||||
|
|
||||||
|
match ty.kind() {
|
||||||
|
ty::Never | ty::Error(_) => ty,
|
||||||
|
ty::FnDef(..) => ty,
|
||||||
|
_ => {
|
||||||
|
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_with_message(
|
||||||
|
tcx,
|
||||||
|
span,
|
||||||
|
format!("invalid type for `const` operand"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
_ => {
|
||||||
|
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_with_message(
|
||||||
|
tcx,
|
||||||
|
span,
|
||||||
|
format!("invalid type for `const` operand"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
|
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)
|
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
|
||||||
|
|
|
@ -59,8 +59,8 @@ fn main() {
|
||||||
asm!("{}", const 0 as *mut u8);
|
asm!("{}", const 0 as *mut u8);
|
||||||
//~^ ERROR invalid type for `const` operand
|
//~^ ERROR invalid type for `const` operand
|
||||||
|
|
||||||
// FIXME: Currently ICEs due to #96304
|
asm!("{}", const &0);
|
||||||
//asm!("{}", const &0);
|
//~^ ERROR invalid type for `const` operand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,26 +39,6 @@ LL | asm!("{}", sym x);
|
||||||
|
|
|
|
||||||
= help: `sym` operands must refer to either a function or a static
|
= help: `sym` operands must refer to either a function or a static
|
||||||
|
|
||||||
error: invalid type for `const` operand
|
|
||||||
--> $DIR/type-check-1.rs:76: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/type-check-1.rs:78:19
|
|
||||||
|
|
|
||||||
LL | global_asm!("{}", const 0 as *mut u8);
|
|
||||||
| ^^^^^^------------
|
|
||||||
| |
|
|
||||||
| is a `*mut u8`
|
|
||||||
|
|
|
||||||
= help: `const` operands must be of an integer type
|
|
||||||
|
|
||||||
error: invalid asm output
|
error: invalid asm output
|
||||||
--> $DIR/type-check-1.rs:14:29
|
--> $DIR/type-check-1.rs:14:29
|
||||||
|
|
|
|
||||||
|
@ -142,7 +122,37 @@ LL | asm!("{}", const 0 as *mut u8);
|
||||||
|
|
|
|
||||||
= help: `const` operands must be of an integer type
|
= help: `const` operands must be of an integer type
|
||||||
|
|
||||||
error: aborting due to 16 previous errors
|
error: invalid type for `const` operand
|
||||||
|
--> $DIR/type-check-1.rs:62:20
|
||||||
|
|
|
||||||
|
LL | asm!("{}", const &0);
|
||||||
|
| ^^^^^^--
|
||||||
|
| |
|
||||||
|
| is a `&i32`
|
||||||
|
|
|
||||||
|
= help: `const` operands must be of an integer type
|
||||||
|
|
||||||
|
error: invalid type for `const` operand
|
||||||
|
--> $DIR/type-check-1.rs:76: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/type-check-1.rs:78:19
|
||||||
|
|
|
||||||
|
LL | global_asm!("{}", const 0 as *mut u8);
|
||||||
|
| ^^^^^^------------
|
||||||
|
| |
|
||||||
|
| is a `*mut u8`
|
||||||
|
|
|
||||||
|
= help: `const` operands must be of an integer type
|
||||||
|
|
||||||
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0435.
|
Some errors have detailed explanations: E0277, E0435.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -6,22 +6,6 @@ LL | asm!("{}", sym x);
|
||||||
|
|
|
|
||||||
= help: `sym` operands must refer to either a function or a static
|
= 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
|
error: arguments for inline assembly must be copyable
|
||||||
--> $DIR/type-check-2.rs:43:32
|
--> $DIR/type-check-2.rs:43:32
|
||||||
|
|
|
|
||||||
|
@ -79,6 +63,14 @@ LL | asm!("{}", inout(reg) r);
|
||||||
|
|
|
|
||||||
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
|
||||||
|
|
||||||
|
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[E0381]: used binding `x` isn't initialized
|
error[E0381]: used binding `x` isn't initialized
|
||||||
--> $DIR/type-check-2.rs:15:28
|
--> $DIR/type-check-2.rs:15:28
|
||||||
|
|
|
|
||||||
|
@ -121,6 +113,14 @@ help: consider changing this to be mutable
|
||||||
LL | let mut v: Vec<u64> = vec![0, 1, 2];
|
LL | let mut v: Vec<u64> = vec![0, 1, 2];
|
||||||
| +++
|
| +++
|
||||||
|
|
||||||
|
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: aborting due to 13 previous errors
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0381, E0596.
|
Some errors have detailed explanations: E0381, E0596.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue