@@ -7,7 +7,7 @@ use rustc_hir::HirId;
7
7
use rustc_middle:: query:: plumbing:: CyclePlaceholder ;
8
8
use rustc_middle:: ty:: print:: with_forced_trimmed_paths;
9
9
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 } ;
11
11
use rustc_middle:: { bug, span_bug} ;
12
12
use rustc_span:: symbol:: Ident ;
13
13
use rustc_span:: { Span , DUMMY_SP } ;
@@ -34,6 +34,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
34
34
let parent_node_id = tcx. parent_hir_id ( hir_id) ;
35
35
let parent_node = tcx. hir_node ( parent_node_id) ;
36
36
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
+
37
51
match parent_node {
38
52
// Anon consts "inside" the type system.
39
53
Node :: ConstArg ( & ConstArg {
@@ -45,13 +59,51 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
45
59
// Anon consts outside the type system.
46
60
Node :: Expr ( & Expr { kind : ExprKind :: InlineAsm ( asm) , .. } )
47
61
| 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) =>
53
63
{
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:: Error ( _) => ty,
68
+ ty:: FnDef ( ..) => ty,
69
+ _ => {
70
+ let guar = tcx
71
+ . dcx ( )
72
+ . struct_span_err ( op_sp, "invalid `sym` operand" )
73
+ . with_span_label (
74
+ tcx. def_span ( anon_const. def_id ) ,
75
+ format ! ( "is {} `{}`" , ty. kind( ) . article( ) , ty) ,
76
+ )
77
+ . with_help ( "`sym` operands must refer to either a function or a static" )
78
+ . emit ( ) ;
79
+
80
+ Ty :: new_error ( tcx, guar)
81
+ }
82
+ }
83
+ }
84
+ Node :: Expr ( & Expr { kind : ExprKind :: InlineAsm ( asm) , .. } )
85
+ | Node :: Item ( & Item { kind : ItemKind :: GlobalAsm ( asm) , .. } )
86
+ if let Some ( ( anon_const, op_sp) ) = asm. operands . iter ( ) . find_map ( find_const) =>
87
+ {
88
+ let ty = tcx. typeck ( def_id) . node_type ( hir_id) ;
89
+
90
+ match ty. kind ( ) {
91
+ ty:: Error ( _) => ty,
92
+ ty:: Int ( _) | ty:: Uint ( _) => ty,
93
+ _ => {
94
+ let guar = tcx
95
+ . dcx ( )
96
+ . struct_span_err ( op_sp, "invalid type for `const` operand" )
97
+ . with_span_label (
98
+ tcx. def_span ( anon_const. def_id ) ,
99
+ format ! ( "is {} `{}`" , ty. kind( ) . article( ) , ty) ,
100
+ )
101
+ . with_help ( "`const` operands must be of an integer type" )
102
+ . emit ( ) ;
103
+
104
+ Ty :: new_error ( tcx, guar)
105
+ }
106
+ }
55
107
}
56
108
Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => {
57
109
tcx. adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
0 commit comments