@@ -6,7 +6,7 @@ use rustc_hir::HirId;
6
6
use rustc_middle:: query:: plumbing:: CyclePlaceholder ;
7
7
use rustc_middle:: ty:: print:: with_forced_trimmed_paths;
8
8
use rustc_middle:: ty:: util:: IntTypeExt ;
9
- use rustc_middle:: ty:: { self , IsSuggestable , Ty , TyCtxt , TypeVisitableExt } ;
9
+ use rustc_middle:: ty:: { self , Article , IsSuggestable , Ty , TyCtxt , TypeVisitableExt } ;
10
10
use rustc_middle:: { bug, span_bug} ;
11
11
use rustc_span:: symbol:: Ident ;
12
12
use rustc_span:: { Span , DUMMY_SP } ;
@@ -35,6 +35,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
35
35
let parent_node_id = tcx. parent_hir_id ( hir_id) ;
36
36
let parent_node = tcx. hir_node ( parent_node_id) ;
37
37
38
+ let find_sym_fn = |& ( op, op_sp) | match op {
39
+ hir:: InlineAsmOperand :: SymFn { anon_const } if anon_const. hir_id == hir_id => {
40
+ Some ( ( anon_const, op_sp) )
41
+ }
42
+ _ => None ,
43
+ } ;
44
+
45
+ let find_const = |& ( op, op_sp) | match op {
46
+ hir:: InlineAsmOperand :: Const { anon_const } if anon_const. hir_id == hir_id => {
47
+ Some ( ( anon_const, op_sp) )
48
+ }
49
+ _ => None ,
50
+ } ;
51
+
38
52
match parent_node {
39
53
// Anon consts "inside" the type system.
40
54
Node :: ConstArg ( & ConstArg {
@@ -46,13 +60,57 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
46
60
// Anon consts outside the type system.
47
61
Node :: Expr ( & Expr { kind : ExprKind :: InlineAsm ( asm) , .. } )
48
62
| Node :: Item ( & Item { kind : ItemKind :: GlobalAsm ( asm) , .. } )
49
- if asm. operands . iter ( ) . any ( |( op, _op_sp) | match op {
50
- hir:: InlineAsmOperand :: Const { anon_const }
51
- | hir:: InlineAsmOperand :: SymFn { anon_const } => anon_const. hir_id == hir_id,
52
- _ => false ,
53
- } ) =>
63
+ if let Some ( ( anon_const, op_sp) ) = asm. operands . iter ( ) . find_map ( find_sym_fn) =>
54
64
{
55
- tcx. typeck ( def_id) . node_type ( hir_id)
65
+ let ty = tcx. typeck ( def_id) . node_type ( hir_id) ;
66
+
67
+ match ty. kind ( ) {
68
+ ty:: Never | ty:: Error ( _) => ty,
69
+ ty:: FnDef ( ..) => ty,
70
+ _ => {
71
+ tcx. 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_with_message (
81
+ tcx,
82
+ span,
83
+ format ! ( "invalid type for `const` operand" ) ,
84
+ )
85
+ }
86
+ }
87
+ }
88
+ Node :: Expr ( & Expr { kind : ExprKind :: InlineAsm ( asm) , .. } )
89
+ | Node :: Item ( & Item { kind : ItemKind :: GlobalAsm ( asm) , .. } )
90
+ if let Some ( ( anon_const, op_sp) ) = asm. operands . iter ( ) . find_map ( find_const) =>
91
+ {
92
+ let ty = tcx. typeck ( def_id) . node_type ( hir_id) ;
93
+
94
+ match ty. kind ( ) {
95
+ ty:: Error ( _) => ty,
96
+ ty:: Int ( _) | ty:: Uint ( _) => ty,
97
+ _ => {
98
+ tcx. dcx ( )
99
+ . struct_span_err ( op_sp, "invalid type for `const` operand" )
100
+ . with_span_label (
101
+ tcx. def_span ( anon_const. def_id ) ,
102
+ format ! ( "is {} `{}`" , ty. kind( ) . article( ) , ty) ,
103
+ )
104
+ . with_help ( "`const` operands must be of an integer type" )
105
+ . emit ( ) ;
106
+
107
+ Ty :: new_error_with_message (
108
+ tcx,
109
+ span,
110
+ format ! ( "invalid type for `const` operand" ) ,
111
+ )
112
+ }
113
+ }
56
114
}
57
115
Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => {
58
116
tcx. adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
0 commit comments