@@ -7,7 +7,7 @@ use rustc_hir::HirId;
77use rustc_middle:: query:: plumbing:: CyclePlaceholder ;
88use rustc_middle:: ty:: print:: with_forced_trimmed_paths;
99use 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 } ;
1111use rustc_middle:: { bug, span_bug} ;
1212use rustc_span:: symbol:: Ident ;
1313use 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,51 @@ 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:: 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+ }
55107 }
56108 Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => {
57109 tcx. adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
0 commit comments