@@ -6,7 +6,7 @@ use rustc_hir::HirId;
66use rustc_middle:: query:: plumbing:: CyclePlaceholder ;
77use rustc_middle:: ty:: print:: with_forced_trimmed_paths;
88use 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 } ;
1010use rustc_middle:: { bug, span_bug} ;
1111use rustc_span:: symbol:: Ident ;
1212use rustc_span:: { Span , DUMMY_SP } ;
@@ -35,6 +35,20 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
3535 let parent_node_id = tcx. parent_hir_id ( hir_id) ;
3636 let parent_node = tcx. hir_node ( parent_node_id) ;
3737
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+
3852 match parent_node {
3953 // Anon consts "inside" the type system.
4054 Node :: ConstArg ( & ConstArg {
@@ -46,13 +60,57 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
4660 // Anon consts outside the type system.
4761 Node :: Expr ( & Expr { kind : ExprKind :: InlineAsm ( asm) , .. } )
4862 | 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) =>
5464 {
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+ }
56114 }
57115 Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => {
58116 tcx. adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
0 commit comments