@@ -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,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)
0 commit comments