@@ -191,52 +191,7 @@ fn typeck_with_fallback<'tcx>(
191
191
192
192
check_fn ( & mut fcx, fn_sig, None , decl, def_id, body, tcx. features ( ) . unsized_fn_params ) ;
193
193
} else {
194
- let expected_type = if let Some ( & hir:: Ty { kind : hir:: TyKind :: Infer , span, .. } ) = body_ty {
195
- if let Some ( item) = tcx. opt_associated_item ( def_id. into ( ) )
196
- && let ty:: AssocKind :: Const = item. kind
197
- && let ty:: ImplContainer = item. container
198
- && let Some ( trait_item) = item. trait_item_def_id
199
- {
200
- let args =
201
- tcx. impl_trait_ref ( item. container_id ( tcx) ) . unwrap ( ) . instantiate_identity ( ) . args ;
202
- Some ( tcx. type_of ( trait_item) . instantiate ( tcx, args) )
203
- } else {
204
- Some ( fcx. next_ty_var ( TypeVariableOrigin {
205
- kind : TypeVariableOriginKind :: TypeInference ,
206
- span,
207
- } ) )
208
- }
209
- } else if let Node :: AnonConst ( _) = node {
210
- match tcx. parent_hir_node ( id) {
211
- Node :: Ty ( & hir:: Ty { kind : hir:: TyKind :: Typeof ( ref anon_const) , .. } )
212
- if anon_const. hir_id == id =>
213
- {
214
- Some ( fcx. next_ty_var ( TypeVariableOrigin {
215
- kind : TypeVariableOriginKind :: TypeInference ,
216
- span,
217
- } ) )
218
- }
219
- Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: InlineAsm ( asm) , .. } )
220
- | Node :: Item ( & hir:: Item { kind : hir:: ItemKind :: GlobalAsm ( asm) , .. } ) => {
221
- asm. operands . iter ( ) . find_map ( |( op, _op_sp) | match op {
222
- hir:: InlineAsmOperand :: Const { anon_const } if anon_const. hir_id == id => {
223
- // Inline assembly constants must be integers.
224
- Some ( fcx. next_int_var ( ) )
225
- }
226
- hir:: InlineAsmOperand :: SymFn { anon_const } if anon_const. hir_id == id => {
227
- Some ( fcx. next_ty_var ( TypeVariableOrigin {
228
- kind : TypeVariableOriginKind :: MiscVariable ,
229
- span,
230
- } ) )
231
- }
232
- _ => None ,
233
- } )
234
- }
235
- _ => None ,
236
- }
237
- } else {
238
- None
239
- } ;
194
+ let expected_type = infer_type_if_missing ( body_ty, & fcx, node) ;
240
195
let expected_type = expected_type. unwrap_or_else ( fallback) ;
241
196
242
197
let expected_type = fcx. normalize ( body. value . span , expected_type) ;
@@ -306,6 +261,63 @@ fn typeck_with_fallback<'tcx>(
306
261
typeck_results
307
262
}
308
263
264
+ fn infer_type_if_missing < ' tcx > (
265
+ body_ty : Option < & hir:: Ty < ' tcx > > ,
266
+ fcx : & FnCtxt < ' _ , ' tcx > ,
267
+ node : Node < ' tcx > ,
268
+ ) -> Option < Ty < ' tcx > > {
269
+ let tcx = fcx. tcx ;
270
+ let def_id = fcx. body_id ;
271
+ let expected_type = if let Some ( & hir:: Ty { kind : hir:: TyKind :: Infer , span, .. } ) = body_ty {
272
+ if let Some ( item) = tcx. opt_associated_item ( def_id. into ( ) )
273
+ && let ty:: AssocKind :: Const = item. kind
274
+ && let ty:: ImplContainer = item. container
275
+ && let Some ( trait_item) = item. trait_item_def_id
276
+ {
277
+ let args =
278
+ tcx. impl_trait_ref ( item. container_id ( tcx) ) . unwrap ( ) . instantiate_identity ( ) . args ;
279
+ Some ( tcx. type_of ( trait_item) . instantiate ( tcx, args) )
280
+ } else {
281
+ Some ( fcx. next_ty_var ( TypeVariableOrigin {
282
+ kind : TypeVariableOriginKind :: TypeInference ,
283
+ span,
284
+ } ) )
285
+ }
286
+ } else if let Node :: AnonConst ( _) = node {
287
+ let id = tcx. local_def_id_to_hir_id ( def_id) ;
288
+ match tcx. parent_hir_node ( id) {
289
+ Node :: Ty ( & hir:: Ty { kind : hir:: TyKind :: Typeof ( ref anon_const) , span, .. } )
290
+ if anon_const. hir_id == id =>
291
+ {
292
+ Some ( fcx. next_ty_var ( TypeVariableOrigin {
293
+ kind : TypeVariableOriginKind :: TypeInference ,
294
+ span,
295
+ } ) )
296
+ }
297
+ Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: InlineAsm ( asm) , span, .. } )
298
+ | Node :: Item ( & hir:: Item { kind : hir:: ItemKind :: GlobalAsm ( asm) , span, .. } ) => {
299
+ asm. operands . iter ( ) . find_map ( |( op, _op_sp) | match op {
300
+ hir:: InlineAsmOperand :: Const { anon_const } if anon_const. hir_id == id => {
301
+ // Inline assembly constants must be integers.
302
+ Some ( fcx. next_int_var ( ) )
303
+ }
304
+ hir:: InlineAsmOperand :: SymFn { anon_const } if anon_const. hir_id == id => {
305
+ Some ( fcx. next_ty_var ( TypeVariableOrigin {
306
+ kind : TypeVariableOriginKind :: MiscVariable ,
307
+ span,
308
+ } ) )
309
+ }
310
+ _ => None ,
311
+ } )
312
+ }
313
+ _ => None ,
314
+ }
315
+ } else {
316
+ None
317
+ } ;
318
+ expected_type
319
+ }
320
+
309
321
/// When `check_fn` is invoked on a coroutine (i.e., a body that
310
322
/// includes yield), it returns back some information about the yield
311
323
/// points.
0 commit comments