@@ -35,16 +35,59 @@ 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
+ match parent_node {
39
+ // Anon consts "inside" the type system.
40
+ Node :: ConstArg ( & ConstArg {
41
+ hir_id : arg_hir_id,
42
+ kind : ConstArgKind :: Anon ( & AnonConst { hir_id : anon_hir_id, .. } ) ,
43
+ ..
44
+ } ) if anon_hir_id == hir_id => const_arg_anon_type_of ( tcx, arg_hir_id, def_id, span) ,
45
+
46
+ // Anon consts outside the type system.
47
+ Node :: Expr ( & Expr { kind : ExprKind :: InlineAsm ( asm) , .. } )
48
+ | 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
+ } ) =>
54
+ {
55
+ tcx. typeck ( def_id) . node_type ( hir_id)
56
+ }
57
+ Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => {
58
+ tcx. adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx)
59
+ }
60
+
61
+ _ => Ty :: new_error_with_message (
62
+ tcx,
63
+ span,
64
+ format ! ( "unexpected anon const parent in type_of(): {parent_node:?}" ) ,
65
+ ) ,
66
+ }
67
+ }
68
+
69
+ fn const_arg_anon_type_of < ' tcx > (
70
+ tcx : TyCtxt < ' tcx > ,
71
+ arg_hir_id : HirId ,
72
+ anon_def_id : LocalDefId ,
73
+ span : Span ,
74
+ ) -> Ty < ' tcx > {
75
+ use hir:: * ;
76
+ use rustc_middle:: ty:: Ty ;
77
+
78
+ let parent_node_id = tcx. parent_hir_id ( arg_hir_id) ;
79
+ let parent_node = tcx. hir_node ( parent_node_id) ;
80
+
38
81
let ( generics, arg_idx) = match parent_node {
39
82
// Easy case: arrays repeat expressions.
40
83
Node :: Ty ( & hir:: Ty { kind : TyKind :: Array ( _, ref constant) , .. } )
41
84
| Node :: Expr ( & Expr { kind : ExprKind :: Repeat ( _, ref constant) , .. } )
42
- if constant. hir_id ( ) == hir_id =>
85
+ if constant. hir_id ( ) == arg_hir_id =>
43
86
{
44
87
return tcx. types . usize ;
45
88
}
46
- Node :: Ty ( & hir:: Ty { kind : TyKind :: Typeof ( ref e) , span, .. } ) if e. hir_id == hir_id => {
47
- let ty = tcx. typeck ( def_id ) . node_type ( e . hir_id ) ;
89
+ Node :: Ty ( & hir:: Ty { kind : TyKind :: Typeof ( ref e) , span, .. } ) if e. hir_id == arg_hir_id => {
90
+ let ty = tcx. typeck ( anon_def_id ) . node_type ( tcx . local_def_id_to_hir_id ( anon_def_id ) ) ;
48
91
let ty = tcx. fold_regions ( ty, |r, _| {
49
92
if r. is_erased ( ) { ty:: Region :: new_error_misc ( tcx) } else { r }
50
93
} ) ;
@@ -56,24 +99,11 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
56
99
tcx. dcx ( ) . emit_err ( TypeofReservedKeywordUsed { span, ty, opt_sugg } ) ;
57
100
return ty;
58
101
}
59
- Node :: Expr ( & Expr { kind : ExprKind :: InlineAsm ( asm) , .. } )
60
- | Node :: Item ( & Item { kind : ItemKind :: GlobalAsm ( asm) , .. } )
61
- if asm. operands . iter ( ) . any ( |( op, _op_sp) | match op {
62
- hir:: InlineAsmOperand :: Const { anon_const }
63
- | hir:: InlineAsmOperand :: SymFn { anon_const } => anon_const. hir_id == hir_id,
64
- _ => false ,
65
- } ) =>
66
- {
67
- return tcx. typeck ( def_id) . node_type ( hir_id) ;
68
- }
69
- Node :: Variant ( Variant { disr_expr : Some ( ref e) , .. } ) if e. hir_id == hir_id => {
70
- return tcx. adt_def ( tcx. hir ( ) . get_parent_item ( hir_id) ) . repr ( ) . discr_type ( ) . to_ty ( tcx) ;
71
- }
72
102
Node :: GenericParam ( & GenericParam {
73
103
def_id : param_def_id,
74
104
kind : GenericParamKind :: Const { default : Some ( ct) , .. } ,
75
105
..
76
- } ) if ct. hir_id == hir_id => {
106
+ } ) if ct. hir_id == arg_hir_id => {
77
107
return tcx
78
108
. type_of ( param_def_id)
79
109
. no_bound_vars ( )
@@ -104,7 +134,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
104
134
// to a ty::Alias(ty::Projection, `<Self as Foo>::Assoc<3>`).
105
135
let item_def_id = tcx
106
136
. hir ( )
107
- . parent_owner_iter ( hir_id )
137
+ . parent_owner_iter ( arg_hir_id )
108
138
. find ( |( _, node) | matches ! ( node, OwnerNode :: Item ( _) ) )
109
139
. unwrap ( )
110
140
. 0
@@ -124,7 +154,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
124
154
args. args
125
155
. iter ( )
126
156
. filter ( |arg| arg. is_ty_or_const ( ) )
127
- . position ( |arg| arg. hir_id ( ) == hir_id )
157
+ . position ( |arg| arg. hir_id ( ) == arg_hir_id )
128
158
} )
129
159
. unwrap_or_else ( || {
130
160
bug ! ( "no arg matching AnonConst in segment" ) ;
@@ -145,7 +175,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
145
175
ExprKind :: MethodCall ( segment, ..) | ExprKind :: Path ( QPath :: TypeRelative ( _, segment) ) ,
146
176
..
147
177
} ) => {
148
- let body_owner = tcx. hir ( ) . enclosing_body_owner ( hir_id ) ;
178
+ let body_owner = tcx. hir ( ) . enclosing_body_owner ( arg_hir_id ) ;
149
179
let tables = tcx. typeck ( body_owner) ;
150
180
// This may fail in case the method/path does not actually exist.
151
181
// As there is no relevant param for `def_id`, we simply return
@@ -163,10 +193,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
163
193
args. args
164
194
. iter ( )
165
195
. filter ( |arg| arg. is_ty_or_const ( ) )
166
- . position ( |arg| arg. hir_id ( ) == hir_id )
196
+ . position ( |arg| arg. hir_id ( ) == arg_hir_id )
167
197
} )
168
198
. unwrap_or_else ( || {
169
- bug ! ( "no arg matching AnonConst in segment" ) ;
199
+ bug ! ( "no arg matching ConstArg in segment" ) ;
170
200
} ) ;
171
201
172
202
( tcx. generics_of ( type_dependent_def) , idx)
@@ -185,18 +215,18 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
185
215
| ExprKind :: Struct ( & QPath :: Resolved ( _, path) , ..) ,
186
216
..
187
217
} ) => {
188
- let body_owner = tcx. hir ( ) . enclosing_body_owner ( hir_id ) ;
218
+ let body_owner = tcx. hir ( ) . enclosing_body_owner ( arg_hir_id ) ;
189
219
let _tables = tcx. typeck ( body_owner) ;
190
220
& * path
191
221
}
192
222
Node :: Pat ( pat) => {
193
- if let Some ( path) = get_path_containing_arg_in_pat ( pat, hir_id ) {
223
+ if let Some ( path) = get_path_containing_arg_in_pat ( pat, arg_hir_id ) {
194
224
path
195
225
} else {
196
226
return Ty :: new_error_with_message (
197
227
tcx,
198
228
span,
199
- format ! ( "unable to find const parent for {hir_id } in pat {pat:?}" ) ,
229
+ format ! ( "unable to find const parent for {arg_hir_id } in pat {pat:?}" ) ,
200
230
) ;
201
231
}
202
232
}
@@ -217,14 +247,14 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
217
247
args. args
218
248
. iter ( )
219
249
. filter ( |arg| arg. is_ty_or_const ( ) )
220
- . position ( |arg| arg. hir_id ( ) == hir_id )
250
+ . position ( |arg| arg. hir_id ( ) == arg_hir_id )
221
251
. map ( |index| ( index, seg) )
222
252
. or_else ( || {
223
253
args. constraints
224
254
. iter ( )
225
255
. copied ( )
226
256
. filter_map ( AssocItemConstraint :: ct)
227
- . position ( |ct| ct. hir_id == hir_id )
257
+ . position ( |ct| ct. hir_id == arg_hir_id )
228
258
. map ( |idx| ( idx, seg) )
229
259
} )
230
260
} ) else {
@@ -249,7 +279,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
249
279
return Ty :: new_error_with_message (
250
280
tcx,
251
281
span,
252
- format ! ( "unexpected const parent in type_of(): {parent_node:?}" ) ,
282
+ format ! ( "unexpected const arg parent in type_of(): {parent_node:?}" ) ,
253
283
) ;
254
284
}
255
285
} ;
0 commit comments