@@ -83,20 +83,6 @@ macro_rules! type_error_struct {
83
83
} )
84
84
}
85
85
86
- /// If this `DefId` is a "primary tables entry", returns
87
- /// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`.
88
- ///
89
- /// If this function returns `Some`, then `typeck_results(def_id)` will
90
- /// succeed; if it returns `None`, then `typeck_results(def_id)` may or
91
- /// may not succeed. In some cases where this function returns `None`
92
- /// (notably closures), `typeck_results(def_id)` would wind up
93
- /// redirecting to the owning function.
94
- fn primary_body_of (
95
- node : Node < ' _ > ,
96
- ) -> Option < ( hir:: BodyId , Option < & hir:: Ty < ' _ > > , Option < & hir:: FnSig < ' _ > > ) > {
97
- Some ( ( node. body_id ( ) ?, node. ty ( ) , node. fn_sig ( ) ) )
98
- }
99
-
100
86
fn has_typeck_results ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
101
87
// Closures' typeck results come from their outermost function,
102
88
// as they are part of the same "inference environment".
@@ -106,7 +92,7 @@ fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
106
92
}
107
93
108
94
if let Some ( def_id) = def_id. as_local ( ) {
109
- primary_body_of ( tcx. hir_node_by_def_id ( def_id) ) . is_some ( )
95
+ tcx. hir_node_by_def_id ( def_id) . body_id ( ) . is_some ( )
110
96
} else {
111
97
false
112
98
}
@@ -163,7 +149,7 @@ fn typeck_with_fallback<'tcx>(
163
149
let span = tcx. hir ( ) . span ( id) ;
164
150
165
151
// Figure out what primary body this item has.
166
- let ( body_id, body_ty , fn_sig ) = primary_body_of ( node) . unwrap_or_else ( || {
152
+ let body_id = node. body_id ( ) . unwrap_or_else ( || {
167
153
span_bug ! ( span, "can't type-check body of {:?}" , def_id) ;
168
154
} ) ;
169
155
let body = tcx. hir ( ) . body ( body_id) ;
@@ -176,7 +162,7 @@ fn typeck_with_fallback<'tcx>(
176
162
}
177
163
let mut fcx = FnCtxt :: new ( & root_ctxt, param_env, def_id) ;
178
164
179
- if let Some ( hir:: FnSig { header, decl, .. } ) = fn_sig {
165
+ if let Some ( hir:: FnSig { header, decl, .. } ) = node . fn_sig ( ) {
180
166
let fn_sig = if decl. output . get_infer_ret_ty ( ) . is_some ( ) {
181
167
fcx. lowerer ( ) . lower_fn_ty ( id, header. unsafety , header. abi , decl, None , None )
182
168
} else {
@@ -191,42 +177,7 @@ fn typeck_with_fallback<'tcx>(
191
177
192
178
check_fn ( & mut fcx, fn_sig, None , decl, def_id, body, tcx. features ( ) . unsized_fn_params ) ;
193
179
} else {
194
- let expected_type = if let Some ( & hir:: Ty { kind : hir:: TyKind :: Infer , span, .. } ) = body_ty {
195
- Some ( fcx. next_ty_var ( TypeVariableOrigin {
196
- kind : TypeVariableOriginKind :: TypeInference ,
197
- span,
198
- } ) )
199
- } else if let Node :: AnonConst ( _) = node {
200
- match tcx. parent_hir_node ( id) {
201
- Node :: Ty ( & hir:: Ty { kind : hir:: TyKind :: Typeof ( ref anon_const) , .. } )
202
- if anon_const. hir_id == id =>
203
- {
204
- Some ( fcx. next_ty_var ( TypeVariableOrigin {
205
- kind : TypeVariableOriginKind :: TypeInference ,
206
- span,
207
- } ) )
208
- }
209
- Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: InlineAsm ( asm) , .. } )
210
- | Node :: Item ( & hir:: Item { kind : hir:: ItemKind :: GlobalAsm ( asm) , .. } ) => {
211
- asm. operands . iter ( ) . find_map ( |( op, _op_sp) | match op {
212
- hir:: InlineAsmOperand :: Const { anon_const } if anon_const. hir_id == id => {
213
- // Inline assembly constants must be integers.
214
- Some ( fcx. next_int_var ( ) )
215
- }
216
- hir:: InlineAsmOperand :: SymFn { anon_const } if anon_const. hir_id == id => {
217
- Some ( fcx. next_ty_var ( TypeVariableOrigin {
218
- kind : TypeVariableOriginKind :: MiscVariable ,
219
- span,
220
- } ) )
221
- }
222
- _ => None ,
223
- } )
224
- }
225
- _ => None ,
226
- }
227
- } else {
228
- None
229
- } ;
180
+ let expected_type = infer_type_if_missing ( & fcx, node) ;
230
181
let expected_type = expected_type. unwrap_or_else ( fallback) ;
231
182
232
183
let expected_type = fcx. normalize ( body. value . span , expected_type) ;
@@ -296,6 +247,59 @@ fn typeck_with_fallback<'tcx>(
296
247
typeck_results
297
248
}
298
249
250
+ fn infer_type_if_missing < ' tcx > ( fcx : & FnCtxt < ' _ , ' tcx > , node : Node < ' tcx > ) -> Option < Ty < ' tcx > > {
251
+ let tcx = fcx. tcx ;
252
+ let def_id = fcx. body_id ;
253
+ let expected_type = if let Some ( & hir:: Ty { kind : hir:: TyKind :: Infer , span, .. } ) = node. ty ( ) {
254
+ if let Some ( item) = tcx. opt_associated_item ( def_id. into ( ) )
255
+ && let ty:: AssocKind :: Const = item. kind
256
+ && let ty:: ImplContainer = item. container
257
+ && let Some ( trait_item) = item. trait_item_def_id
258
+ {
259
+ let args =
260
+ tcx. impl_trait_ref ( item. container_id ( tcx) ) . unwrap ( ) . instantiate_identity ( ) . args ;
261
+ Some ( tcx. type_of ( trait_item) . instantiate ( tcx, args) )
262
+ } else {
263
+ Some ( fcx. next_ty_var ( TypeVariableOrigin {
264
+ kind : TypeVariableOriginKind :: TypeInference ,
265
+ span,
266
+ } ) )
267
+ }
268
+ } else if let Node :: AnonConst ( _) = node {
269
+ let id = tcx. local_def_id_to_hir_id ( def_id) ;
270
+ match tcx. parent_hir_node ( id) {
271
+ Node :: Ty ( & hir:: Ty { kind : hir:: TyKind :: Typeof ( ref anon_const) , span, .. } )
272
+ if anon_const. hir_id == id =>
273
+ {
274
+ Some ( fcx. next_ty_var ( TypeVariableOrigin {
275
+ kind : TypeVariableOriginKind :: TypeInference ,
276
+ span,
277
+ } ) )
278
+ }
279
+ Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: InlineAsm ( asm) , span, .. } )
280
+ | Node :: Item ( & hir:: Item { kind : hir:: ItemKind :: GlobalAsm ( asm) , span, .. } ) => {
281
+ asm. operands . iter ( ) . find_map ( |( op, _op_sp) | match op {
282
+ hir:: InlineAsmOperand :: Const { anon_const } if anon_const. hir_id == id => {
283
+ // Inline assembly constants must be integers.
284
+ Some ( fcx. next_int_var ( ) )
285
+ }
286
+ hir:: InlineAsmOperand :: SymFn { anon_const } if anon_const. hir_id == id => {
287
+ Some ( fcx. next_ty_var ( TypeVariableOrigin {
288
+ kind : TypeVariableOriginKind :: MiscVariable ,
289
+ span,
290
+ } ) )
291
+ }
292
+ _ => None ,
293
+ } )
294
+ }
295
+ _ => None ,
296
+ }
297
+ } else {
298
+ None
299
+ } ;
300
+ expected_type
301
+ }
302
+
299
303
/// When `check_fn` is invoked on a coroutine (i.e., a body that
300
304
/// includes yield), it returns back some information about the yield
301
305
/// points.
0 commit comments