@@ -191,52 +191,7 @@ fn typeck_with_fallback<'tcx>(
191191
192192 check_fn ( & mut fcx, fn_sig, None , decl, def_id, body, tcx. features ( ) . unsized_fn_params ) ;
193193 } 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) ;
240195 let expected_type = expected_type. unwrap_or_else ( fallback) ;
241196
242197 let expected_type = fcx. normalize ( body. value . span , expected_type) ;
@@ -306,6 +261,63 @@ fn typeck_with_fallback<'tcx>(
306261 typeck_results
307262}
308263
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+
309321/// When `check_fn` is invoked on a coroutine (i.e., a body that
310322/// includes yield), it returns back some information about the yield
311323/// points.
0 commit comments