Skip to content

Commit 222a054

Browse files
committed
apply fix suggested by lcnr
1 parent 0116cb3 commit 222a054

File tree

5 files changed

+127
-85
lines changed

5 files changed

+127
-85
lines changed

compiler/rustc_hir_analysis/src/check/intrinsicck.rs

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_ast::InlineAsmTemplatePiece;
22
use rustc_data_structures::fx::FxIndexSet;
33
use rustc_hir::{self as hir, LangItem};
44
use rustc_middle::bug;
5-
use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
5+
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
66
use rustc_session::lint;
77
use rustc_span::def_id::LocalDefId;
88
use rustc_span::Symbol;
@@ -455,48 +455,22 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
455455
);
456456
}
457457
}
458+
// Typeck has checked that Const operands are integers.
458459
hir::InlineAsmOperand::Const { anon_const } => {
459-
let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity();
460-
match ty.kind() {
461-
ty::Error(_) => {}
462-
ty::Int(_) | ty::Uint(_) => {}
463-
_ => {
464-
self.tcx
465-
.dcx()
466-
.struct_span_err(*op_sp, "invalid type for `const` operand")
467-
.with_span_label(
468-
self.tcx.def_span(anon_const.def_id),
469-
format!("is {} `{}`", ty.kind().article(), ty),
470-
)
471-
.with_help("`const` operands must be of an integer type")
472-
.emit();
473-
}
474-
};
460+
debug_assert!(matches!(
461+
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
462+
ty::Error(_) | ty::Int(_) | ty::Uint(_)
463+
));
475464
}
476-
// AST lowering guarantees that SymStatic points to a static.
477-
hir::InlineAsmOperand::SymStatic { .. } => {}
478-
// Check that sym actually points to a function. Later passes
479-
// depend on this.
465+
// Typeck has checked that SymFn refers to a function.
480466
hir::InlineAsmOperand::SymFn { anon_const } => {
481-
let ty = self.tcx.type_of(anon_const.def_id).instantiate_identity();
482-
match ty.kind() {
483-
ty::Never | ty::Error(_) => {}
484-
ty::FnDef(..) => {}
485-
_ => {
486-
self.tcx
487-
.dcx()
488-
.struct_span_err(*op_sp, "invalid `sym` operand")
489-
.with_span_label(
490-
self.tcx.def_span(anon_const.def_id),
491-
format!("is {} `{}`", ty.kind().article(), ty),
492-
)
493-
.with_help(
494-
"`sym` operands must refer to either a function or a static",
495-
)
496-
.emit();
497-
}
498-
};
467+
debug_assert!(matches!(
468+
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
469+
ty::Error(_) | ty::Never | ty::FnDef(..)
470+
));
499471
}
472+
// AST lowering guarantees that SymStatic points to a static.
473+
hir::InlineAsmOperand::SymStatic { .. } => {}
500474
// No special checking is needed for labels.
501475
hir::InlineAsmOperand::Label { .. } => {}
502476
}

compiler/rustc_hir_analysis/src/collect/type_of.rs

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_hir::HirId;
77
use rustc_middle::query::plumbing::CyclePlaceholder;
88
use rustc_middle::ty::print::with_forced_trimmed_paths;
99
use rustc_middle::ty::util::IntTypeExt;
10-
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
10+
use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
1111
use rustc_middle::{bug, span_bug};
1212
use rustc_span::symbol::Ident;
1313
use rustc_span::{Span, DUMMY_SP};
@@ -34,6 +34,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
3434
let parent_node_id = tcx.parent_hir_id(hir_id);
3535
let parent_node = tcx.hir_node(parent_node_id);
3636

37+
let find_sym_fn = |&(op, op_sp)| match op {
38+
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == hir_id => {
39+
Some((anon_const, op_sp))
40+
}
41+
_ => None,
42+
};
43+
44+
let find_const = |&(op, op_sp)| match op {
45+
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == hir_id => {
46+
Some((anon_const, op_sp))
47+
}
48+
_ => None,
49+
};
50+
3751
match parent_node {
3852
// Anon consts "inside" the type system.
3953
Node::ConstArg(&ConstArg {
@@ -45,13 +59,57 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
4559
// Anon consts outside the type system.
4660
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
4761
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
48-
if asm.operands.iter().any(|(op, _op_sp)| match op {
49-
hir::InlineAsmOperand::Const { anon_const }
50-
| hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
51-
_ => false,
52-
}) =>
62+
if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_sym_fn) =>
5363
{
54-
tcx.typeck(def_id).node_type(hir_id)
64+
let ty = tcx.typeck(def_id).node_type(hir_id);
65+
66+
match ty.kind() {
67+
ty::Never | ty::Error(_) => ty,
68+
ty::FnDef(..) => ty,
69+
_ => {
70+
tcx.dcx()
71+
.struct_span_err(op_sp, "invalid `sym` operand")
72+
.with_span_label(
73+
tcx.def_span(anon_const.def_id),
74+
format!("is {} `{}`", ty.kind().article(), ty),
75+
)
76+
.with_help("`sym` operands must refer to either a function or a static")
77+
.emit();
78+
79+
Ty::new_error_with_message(
80+
tcx,
81+
span,
82+
format!("invalid type for `const` operand"),
83+
)
84+
}
85+
}
86+
}
87+
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
88+
| Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
89+
if let Some((anon_const, op_sp)) = asm.operands.iter().find_map(find_const) =>
90+
{
91+
let ty = tcx.typeck(def_id).node_type(hir_id);
92+
93+
match ty.kind() {
94+
ty::Error(_) => ty,
95+
ty::Int(_) | ty::Uint(_) => ty,
96+
_ => {
97+
tcx.dcx()
98+
.struct_span_err(op_sp, "invalid type for `const` operand")
99+
.with_span_label(
100+
tcx.def_span(anon_const.def_id),
101+
format!("is {} `{}`", ty.kind().article(), ty),
102+
)
103+
.with_help("`const` operands must be of an integer type")
104+
.emit();
105+
106+
Ty::new_error_with_message(
107+
tcx,
108+
span,
109+
format!("invalid type for `const` operand"),
110+
)
111+
}
112+
}
55113
}
56114
Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
57115
tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)

tests/ui/asm/type-check-1.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ fn main() {
5959
asm!("{}", const 0 as *mut u8);
6060
//~^ ERROR invalid type for `const` operand
6161

62-
// FIXME: Currently ICEs due to #96304
63-
//asm!("{}", const &0);
62+
asm!("{}", const &0);
63+
//~^ ERROR invalid type for `const` operand
6464
}
6565
}
6666

tests/ui/asm/type-check-1.stderr

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,6 @@ LL | asm!("{}", sym x);
3939
|
4040
= help: `sym` operands must refer to either a function or a static
4141

42-
error: invalid type for `const` operand
43-
--> $DIR/type-check-1.rs:76:19
44-
|
45-
LL | global_asm!("{}", const 0f32);
46-
| ^^^^^^----
47-
| |
48-
| is an `f32`
49-
|
50-
= help: `const` operands must be of an integer type
51-
52-
error: invalid type for `const` operand
53-
--> $DIR/type-check-1.rs:78:19
54-
|
55-
LL | global_asm!("{}", const 0 as *mut u8);
56-
| ^^^^^^------------
57-
| |
58-
| is a `*mut u8`
59-
|
60-
= help: `const` operands must be of an integer type
61-
6242
error: invalid asm output
6343
--> $DIR/type-check-1.rs:14:29
6444
|
@@ -142,7 +122,37 @@ LL | asm!("{}", const 0 as *mut u8);
142122
|
143123
= help: `const` operands must be of an integer type
144124

145-
error: aborting due to 16 previous errors
125+
error: invalid type for `const` operand
126+
--> $DIR/type-check-1.rs:62:20
127+
|
128+
LL | asm!("{}", const &0);
129+
| ^^^^^^--
130+
| |
131+
| is a `&i32`
132+
|
133+
= help: `const` operands must be of an integer type
134+
135+
error: invalid type for `const` operand
136+
--> $DIR/type-check-1.rs:76:19
137+
|
138+
LL | global_asm!("{}", const 0f32);
139+
| ^^^^^^----
140+
| |
141+
| is an `f32`
142+
|
143+
= help: `const` operands must be of an integer type
144+
145+
error: invalid type for `const` operand
146+
--> $DIR/type-check-1.rs:78:19
147+
|
148+
LL | global_asm!("{}", const 0 as *mut u8);
149+
| ^^^^^^------------
150+
| |
151+
| is a `*mut u8`
152+
|
153+
= help: `const` operands must be of an integer type
154+
155+
error: aborting due to 17 previous errors
146156

147157
Some errors have detailed explanations: E0277, E0435.
148158
For more information about an error, try `rustc --explain E0277`.

tests/ui/asm/x86_64/type-check-2.stderr

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,6 @@ LL | asm!("{}", sym x);
66
|
77
= help: `sym` operands must refer to either a function or a static
88

9-
error: invalid `sym` operand
10-
--> $DIR/type-check-2.rs:89:19
11-
|
12-
LL | global_asm!("{}", sym C);
13-
| ^^^^^ is an `i32`
14-
|
15-
= help: `sym` operands must refer to either a function or a static
16-
17-
error: invalid `sym` operand
18-
--> $DIR/type-check-2.rs:36:20
19-
|
20-
LL | asm!("{}", sym C);
21-
| ^^^^^ is an `i32`
22-
|
23-
= help: `sym` operands must refer to either a function or a static
24-
259
error: arguments for inline assembly must be copyable
2610
--> $DIR/type-check-2.rs:43:32
2711
|
@@ -79,6 +63,14 @@ LL | asm!("{}", inout(reg) r);
7963
|
8064
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
8165

66+
error: invalid `sym` operand
67+
--> $DIR/type-check-2.rs:36:20
68+
|
69+
LL | asm!("{}", sym C);
70+
| ^^^^^ is an `i32`
71+
|
72+
= help: `sym` operands must refer to either a function or a static
73+
8274
error[E0381]: used binding `x` isn't initialized
8375
--> $DIR/type-check-2.rs:15:28
8476
|
@@ -121,6 +113,14 @@ help: consider changing this to be mutable
121113
LL | let mut v: Vec<u64> = vec![0, 1, 2];
122114
| +++
123115

116+
error: invalid `sym` operand
117+
--> $DIR/type-check-2.rs:89:19
118+
|
119+
LL | global_asm!("{}", sym C);
120+
| ^^^^^ is an `i32`
121+
|
122+
= help: `sym` operands must refer to either a function or a static
123+
124124
error: aborting due to 13 previous errors
125125

126126
Some errors have detailed explanations: E0381, E0596.

0 commit comments

Comments
 (0)