@@ -113,6 +113,260 @@ fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
113113 tcx. calculate_dtor ( def_id, dropck:: check_drop_impl)
114114}
115115
116+ /// If this `DefId` is a "primary tables entry", returns
117+ /// `Some((body_id, body_ty, fn_sig))`. Otherwise, returns `None`.
118+ ///
119+ /// If this function returns `Some`, then `typeck_results(def_id)` will
120+ /// succeed; if it returns `None`, then `typeck_results(def_id)` may or
121+ /// may not succeed. In some cases where this function returns `None`
122+ /// (notably closures), `typeck_results(def_id)` would wind up
123+ /// redirecting to the owning function.
124+ fn primary_body_of (
125+ tcx : TyCtxt < ' _ > ,
126+ id : hir:: HirId ,
127+ ) -> Option < ( hir:: BodyId , Option < & hir:: Ty < ' _ > > , Option < & hir:: FnSig < ' _ > > ) > {
128+ match tcx. hir ( ) . get ( id) {
129+ Node :: Item ( item) => match item. kind {
130+ hir:: ItemKind :: Const ( ty, body) | hir:: ItemKind :: Static ( ty, _, body) => {
131+ Some ( ( body, Some ( ty) , None ) )
132+ }
133+ hir:: ItemKind :: Fn ( ref sig, .., body) => Some ( ( body, None , Some ( sig) ) ) ,
134+ _ => None ,
135+ } ,
136+ Node :: TraitItem ( item) => match item. kind {
137+ hir:: TraitItemKind :: Const ( ty, Some ( body) ) => Some ( ( body, Some ( ty) , None ) ) ,
138+ hir:: TraitItemKind :: Fn ( ref sig, hir:: TraitFn :: Provided ( body) ) => {
139+ Some ( ( body, None , Some ( sig) ) )
140+ }
141+ _ => None ,
142+ } ,
143+ Node :: ImplItem ( item) => match item. kind {
144+ hir:: ImplItemKind :: Const ( ty, body) => Some ( ( body, Some ( ty) , None ) ) ,
145+ hir:: ImplItemKind :: Fn ( ref sig, body) => Some ( ( body, None , Some ( sig) ) ) ,
146+ _ => None ,
147+ } ,
148+ Node :: AnonConst ( constant) => Some ( ( constant. body , None , None ) ) ,
149+ _ => None ,
150+ }
151+ }
152+
153+ fn has_typeck_results ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
154+ // Closures' typeck results come from their outermost function,
155+ // as they are part of the same "inference environment".
156+ let typeck_root_def_id = tcx. typeck_root_def_id ( def_id) ;
157+ if typeck_root_def_id != def_id {
158+ return tcx. has_typeck_results ( typeck_root_def_id) ;
159+ }
160+
161+ if let Some ( def_id) = def_id. as_local ( ) {
162+ let id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
163+ primary_body_of ( tcx, id) . is_some ( )
164+ } else {
165+ false
166+ }
167+ }
168+
169+ fn used_trait_imports ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> & FxHashSet < LocalDefId > {
170+ & * tcx. typeck ( def_id) . used_trait_imports
171+ }
172+
173+ fn typeck_const_arg < ' tcx > (
174+ tcx : TyCtxt < ' tcx > ,
175+ ( did, param_did) : ( LocalDefId , DefId ) ,
176+ ) -> & ty:: TypeckResults < ' tcx > {
177+ let fallback = move || tcx. type_of ( param_did) ;
178+ typeck_with_fallback ( tcx, did, fallback)
179+ }
180+
181+ fn typeck < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) -> & ty:: TypeckResults < ' tcx > {
182+ if let Some ( param_did) = tcx. opt_const_param_of ( def_id) {
183+ tcx. typeck_const_arg ( ( def_id, param_did) )
184+ } else {
185+ let fallback = move || tcx. type_of ( def_id. to_def_id ( ) ) ;
186+ typeck_with_fallback ( tcx, def_id, fallback)
187+ }
188+ }
189+
190+ /// Used only to get `TypeckResults` for type inference during error recovery.
191+ /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
192+ fn diagnostic_only_typeck < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) -> & ty:: TypeckResults < ' tcx > {
193+ let fallback = move || {
194+ let span = tcx. hir ( ) . span ( tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ) ;
195+ tcx. ty_error_with_message ( span, "diagnostic only typeck table used" )
196+ } ;
197+ typeck_with_fallback ( tcx, def_id, fallback)
198+ }
199+
200+ fn typeck_with_fallback < ' tcx > (
201+ tcx : TyCtxt < ' tcx > ,
202+ def_id : LocalDefId ,
203+ fallback : impl Fn ( ) -> Ty < ' tcx > + ' tcx ,
204+ ) -> & ' tcx ty:: TypeckResults < ' tcx > {
205+ // Closures' typeck results come from their outermost function,
206+ // as they are part of the same "inference environment".
207+ let typeck_root_def_id = tcx. typeck_root_def_id ( def_id. to_def_id ( ) ) . expect_local ( ) ;
208+ if typeck_root_def_id != def_id {
209+ return tcx. typeck ( typeck_root_def_id) ;
210+ }
211+
212+ let id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ;
213+ let span = tcx. hir ( ) . span ( id) ;
214+
215+ // Figure out what primary body this item has.
216+ let ( body_id, body_ty, fn_sig) = primary_body_of ( tcx, id) . unwrap_or_else ( || {
217+ span_bug ! ( span, "can't type-check body of {:?}" , def_id) ;
218+ } ) ;
219+ let body = tcx. hir ( ) . body ( body_id) ;
220+
221+ let typeck_results = Inherited :: build ( tcx, def_id) . enter ( |inh| {
222+ let param_env = tcx. param_env ( def_id) ;
223+ let mut fcx = if let Some ( hir:: FnSig { header, decl, .. } ) = fn_sig {
224+ let fn_sig = if crate :: collect:: get_infer_ret_ty ( & decl. output ) . is_some ( ) {
225+ let fcx = FnCtxt :: new ( & inh, param_env, body. value . hir_id ) ;
226+ <dyn AstConv < ' _ > >:: ty_of_fn ( & fcx, id, header. unsafety , header. abi , decl, None , None )
227+ } else {
228+ tcx. fn_sig ( def_id)
229+ } ;
230+
231+ check_abi ( tcx, id, span, fn_sig. abi ( ) ) ;
232+
233+ // Compute the function signature from point of view of inside the fn.
234+ let fn_sig = tcx. liberate_late_bound_regions ( def_id. to_def_id ( ) , fn_sig) ;
235+ let fn_sig = inh. normalize_associated_types_in (
236+ body. value . span ,
237+ body_id. hir_id ,
238+ param_env,
239+ fn_sig,
240+ ) ;
241+ check_fn ( & inh, param_env, fn_sig, decl, id, body, None , true ) . 0
242+ } else {
243+ let fcx = FnCtxt :: new ( & inh, param_env, body. value . hir_id ) ;
244+ let expected_type = body_ty
245+ . and_then ( |ty| match ty. kind {
246+ hir:: TyKind :: Infer => Some ( <dyn AstConv < ' _ > >:: ast_ty_to_ty ( & fcx, ty) ) ,
247+ _ => None ,
248+ } )
249+ . unwrap_or_else ( || match tcx. hir ( ) . get ( id) {
250+ Node :: AnonConst ( _) => match tcx. hir ( ) . get ( tcx. hir ( ) . get_parent_node ( id) ) {
251+ Node :: Expr ( & hir:: Expr {
252+ kind : hir:: ExprKind :: ConstBlock ( ref anon_const) ,
253+ ..
254+ } ) if anon_const. hir_id == id => fcx. next_ty_var ( TypeVariableOrigin {
255+ kind : TypeVariableOriginKind :: TypeInference ,
256+ span,
257+ } ) ,
258+ Node :: Ty ( & hir:: Ty {
259+ kind : hir:: TyKind :: Typeof ( ref anon_const) , ..
260+ } ) if anon_const. hir_id == id => fcx. next_ty_var ( TypeVariableOrigin {
261+ kind : TypeVariableOriginKind :: TypeInference ,
262+ span,
263+ } ) ,
264+ Node :: Expr ( & hir:: Expr { kind : hir:: ExprKind :: InlineAsm ( asm) , .. } )
265+ | Node :: Item ( & hir:: Item { kind : hir:: ItemKind :: GlobalAsm ( asm) , .. } ) => {
266+ let operand_ty = asm
267+ . operands
268+ . iter ( )
269+ . filter_map ( |( op, _op_sp) | match op {
270+ hir:: InlineAsmOperand :: Const { anon_const }
271+ if anon_const. hir_id == id =>
272+ {
273+ // Inline assembly constants must be integers.
274+ Some ( fcx. next_int_var ( ) )
275+ }
276+ hir:: InlineAsmOperand :: SymFn { anon_const }
277+ if anon_const. hir_id == id =>
278+ {
279+ Some ( fcx. next_ty_var ( TypeVariableOrigin {
280+ kind : TypeVariableOriginKind :: MiscVariable ,
281+ span,
282+ } ) )
283+ }
284+ _ => None ,
285+ } )
286+ . next ( ) ;
287+ operand_ty. unwrap_or_else ( fallback)
288+ }
289+ _ => fallback ( ) ,
290+ } ,
291+ _ => fallback ( ) ,
292+ } ) ;
293+
294+ let expected_type = fcx. normalize_associated_types_in ( body. value . span , expected_type) ;
295+ fcx. require_type_is_sized ( expected_type, body. value . span , traits:: ConstSized ) ;
296+
297+ // Gather locals in statics (because of block expressions).
298+ GatherLocalsVisitor :: new ( & fcx) . visit_body ( body) ;
299+
300+ fcx. check_expr_coercable_to_type ( & body. value , expected_type, None ) ;
301+
302+ fcx. write_ty ( id, expected_type) ;
303+
304+ fcx
305+ } ;
306+
307+ let fallback_has_occurred = fcx. type_inference_fallback ( ) ;
308+
309+ // Even though coercion casts provide type hints, we check casts after fallback for
310+ // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
311+ fcx. check_casts ( ) ;
312+ fcx. select_obligations_where_possible ( fallback_has_occurred, |_| { } ) ;
313+
314+ // Closure and generator analysis may run after fallback
315+ // because they don't constrain other type variables.
316+ // Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
317+ let prev_constness = fcx. param_env . constness ( ) ;
318+ fcx. param_env = fcx. param_env . without_const ( ) ;
319+ fcx. closure_analyze ( body) ;
320+ fcx. param_env = fcx. param_env . with_constness ( prev_constness) ;
321+ assert ! ( fcx. deferred_call_resolutions. borrow( ) . is_empty( ) ) ;
322+ // Before the generator analysis, temporary scopes shall be marked to provide more
323+ // precise information on types to be captured.
324+ fcx. resolve_rvalue_scopes ( def_id. to_def_id ( ) ) ;
325+ fcx. resolve_generator_interiors ( def_id. to_def_id ( ) ) ;
326+
327+ for ( ty, span, code) in fcx. deferred_sized_obligations . borrow_mut ( ) . drain ( ..) {
328+ let ty = fcx. normalize_ty ( span, ty) ;
329+ fcx. require_type_is_sized ( ty, span, code) ;
330+ }
331+
332+ fcx. resolve_base_expr ( ) ;
333+
334+ fcx. select_all_obligations_or_error ( ) ;
335+
336+ if !fcx. infcx . is_tainted_by_errors ( ) {
337+ fcx. check_transmutes ( ) ;
338+ }
339+
340+ fcx. check_asms ( ) ;
341+
342+ fcx. infcx . skip_region_resolution ( ) ;
343+
344+ fcx. resolve_type_vars_in_body ( body)
345+ } ) ;
346+
347+ // Consistency check our TypeckResults instance can hold all ItemLocalIds
348+ // it will need to hold.
349+ assert_eq ! ( typeck_results. hir_owner, id. owner) ;
350+
351+ typeck_results
352+ }
353+
354+ /// When `check_fn` is invoked on a generator (i.e., a body that
355+ /// includes yield), it returns back some information about the yield
356+ /// points.
357+ struct GeneratorTypes < ' tcx > {
358+ /// Type of generator argument / values returned by `yield`.
359+ resume_ty : Ty < ' tcx > ,
360+
361+ /// Type of value that is yielded.
362+ yield_ty : Ty < ' tcx > ,
363+
364+ /// Types that are captured (see `GeneratorInterior` for more).
365+ interior : Ty < ' tcx > ,
366+
367+ /// Indicates if the generator is movable or static (immovable).
368+ movability : hir:: Movability ,
369+ }
116370/// Given a `DefId` for an opaque type in return position, find its parent item's return
117371/// expressions.
118372fn get_owner_return_paths < ' tcx > (
0 commit comments