@@ -151,7 +151,7 @@ pub trait InferCtxtExt<'tcx> {
151151 outer_generator : Option < DefId > ,
152152 trait_ref : ty:: TraitRef < ' tcx > ,
153153 target_ty : Ty < ' tcx > ,
154- typeck_results : & ty:: TypeckResults < ' tcx > ,
154+ typeck_results : Option < & ty:: TypeckResults < ' tcx > > ,
155155 obligation : & PredicateObligation < ' tcx > ,
156156 next_code : Option < & ObligationCauseCode < ' tcx > > ,
157157 ) ;
@@ -1463,11 +1463,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14631463 }
14641464
14651465 // Only continue if a generator was found.
1466- debug ! (
1467- "maybe_note_obligation_cause_for_async_await: generator={:?} trait_ref={:?} \
1468- target_ty={:?}",
1469- generator, trait_ref, target_ty
1470- ) ;
1466+ debug ! ( ?generator, ?trait_ref, ?target_ty, "maybe_note_obligation_cause_for_async_await" ) ;
14711467 let ( generator_did, trait_ref, target_ty) = match ( generator, trait_ref, target_ty) {
14721468 ( Some ( generator_did) , Some ( trait_ref) , Some ( target_ty) ) => {
14731469 ( generator_did, trait_ref, target_ty)
@@ -1477,14 +1473,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14771473
14781474 let span = self . tcx . def_span ( generator_did) ;
14791475
1480- // Do not ICE on closure typeck (#66868).
1481- if !generator_did. is_local ( ) {
1482- return false ;
1483- }
1484-
1485- // Get the typeck results from the infcx if the generator is the function we are
1486- // currently type-checking; otherwise, get them by performing a query.
1487- // This is needed to avoid cycles.
14881476 let in_progress_typeck_results = self . in_progress_typeck_results . map ( |t| t. borrow ( ) ) ;
14891477 let generator_did_root = self . tcx . closure_base_def_id ( generator_did) ;
14901478 debug ! (
@@ -1495,14 +1483,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14951483 in_progress_typeck_results. as_ref( ) . map( |t| t. hir_owner) ,
14961484 span
14971485 ) ;
1498- let query_typeck_results;
1499- let typeck_results: & TypeckResults < ' tcx > = match & in_progress_typeck_results {
1500- Some ( t) if t. hir_owner . to_def_id ( ) == generator_did_root => t,
1501- _ => {
1502- query_typeck_results = self . tcx . typeck ( generator_did. expect_local ( ) ) ;
1503- & query_typeck_results
1504- }
1505- } ;
15061486
15071487 let generator_body = generator_did
15081488 . as_local ( )
@@ -1545,51 +1525,59 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
15451525 let mut interior_or_upvar_span = None ;
15461526 let mut interior_extra_info = None ;
15471527
1548- if let Some ( upvars) = self . tcx . upvars_mentioned ( generator_did) {
1549- interior_or_upvar_span = upvars. iter ( ) . find_map ( |( upvar_id, upvar) | {
1550- let upvar_ty = typeck_results. node_type ( * upvar_id) ;
1551- let upvar_ty = self . resolve_vars_if_possible ( upvar_ty) ;
1552- if ty_matches ( ty:: Binder :: dummy ( upvar_ty) ) {
1553- Some ( GeneratorInteriorOrUpvar :: Upvar ( upvar. span ) )
1554- } else {
1555- None
1556- }
1557- } ) ;
1528+ // Get the typeck results from the infcx if the generator is the function we are currently
1529+ // type-checking; otherwise, get them by performing a query. This is needed to avoid
1530+ // cycles. If we can't use resolved types because the generator comes from another crate,
1531+ // we still provide a targeted error but without all the relevant spans.
1532+ let query_typeck_results;
1533+ let typeck_results: Option < & TypeckResults < ' tcx > > = match & in_progress_typeck_results {
1534+ Some ( t) if t. hir_owner . to_def_id ( ) == generator_did_root => Some ( & t) ,
1535+ _ if generator_did. is_local ( ) => {
1536+ query_typeck_results = self . tcx . typeck ( generator_did. expect_local ( ) ) ;
1537+ Some ( & query_typeck_results)
1538+ }
1539+ _ => None , // Do not ICE on closure typeck (#66868).
15581540 } ;
1541+ if let Some ( typeck_results) = typeck_results {
1542+ if let Some ( upvars) = self . tcx . upvars_mentioned ( generator_did) {
1543+ interior_or_upvar_span = upvars. iter ( ) . find_map ( |( upvar_id, upvar) | {
1544+ let upvar_ty = typeck_results. node_type ( * upvar_id) ;
1545+ let upvar_ty = self . resolve_vars_if_possible ( upvar_ty) ;
1546+ if ty_matches ( ty:: Binder :: dummy ( upvar_ty) ) {
1547+ Some ( GeneratorInteriorOrUpvar :: Upvar ( upvar. span ) )
1548+ } else {
1549+ None
1550+ }
1551+ } ) ;
1552+ } ;
15591553
1560- // The generator interior types share the same binders
1561- if let Some ( cause) =
1562- typeck_results. generator_interior_types . as_ref ( ) . skip_binder ( ) . iter ( ) . find (
1563- |ty:: GeneratorInteriorTypeCause { ty, .. } | {
1564- ty_matches ( typeck_results. generator_interior_types . rebind ( ty) )
1565- } ,
1566- )
1567- {
1568- // Check to see if any awaited expressions have the target type.
1569- let from_awaited_ty = visitor
1570- . awaits
1571- . into_iter ( )
1572- . map ( |id| hir. expect_expr ( id) )
1573- . find ( |await_expr| {
1574- let ty = typeck_results. expr_ty_adjusted ( & await_expr) ;
1575- debug ! (
1576- "maybe_note_obligation_cause_for_async_await: await_expr={:?}" ,
1577- await_expr
1578- ) ;
1579- ty_matches ( ty:: Binder :: dummy ( ty) )
1580- } )
1581- . map ( |expr| expr. span ) ;
1582- let ty:: GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
1554+ // The generator interior types share the same binders
1555+ if let Some ( cause) =
1556+ typeck_results. generator_interior_types . as_ref ( ) . skip_binder ( ) . iter ( ) . find (
1557+ |ty:: GeneratorInteriorTypeCause { ty, .. } | {
1558+ ty_matches ( typeck_results. generator_interior_types . rebind ( ty) )
1559+ } ,
1560+ )
1561+ {
1562+ // Check to see if any awaited expressions have the target type.
1563+ let from_awaited_ty = visitor
1564+ . awaits
1565+ . into_iter ( )
1566+ . map ( |id| hir. expect_expr ( id) )
1567+ . find ( |await_expr| {
1568+ ty_matches ( ty:: Binder :: dummy ( typeck_results. expr_ty_adjusted ( & await_expr) ) )
1569+ } )
1570+ . map ( |expr| expr. span ) ;
1571+ let ty:: GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } =
1572+ cause;
15831573
1584- interior_or_upvar_span = Some ( GeneratorInteriorOrUpvar :: Interior ( * span) ) ;
1585- interior_extra_info = Some ( ( * scope_span, * yield_span, * expr, from_awaited_ty) ) ;
1586- } ;
1574+ interior_or_upvar_span = Some ( GeneratorInteriorOrUpvar :: Interior ( * span) ) ;
1575+ interior_extra_info = Some ( ( * scope_span, * yield_span, * expr, from_awaited_ty) ) ;
1576+ } ;
1577+ } else {
1578+ interior_or_upvar_span = Some ( GeneratorInteriorOrUpvar :: Interior ( span) ) ;
1579+ }
15871580
1588- debug ! (
1589- "maybe_note_obligation_cause_for_async_await: interior_or_upvar={:?} \
1590- generator_interior_types={:?}",
1591- interior_or_upvar_span, typeck_results. generator_interior_types
1592- ) ;
15931581 if let Some ( interior_or_upvar_span) = interior_or_upvar_span {
15941582 self . note_obligation_cause_for_async_await (
15951583 err,
@@ -1620,7 +1608,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
16201608 outer_generator : Option < DefId > ,
16211609 trait_ref : ty:: TraitRef < ' tcx > ,
16221610 target_ty : Ty < ' tcx > ,
1623- typeck_results : & ty:: TypeckResults < ' tcx > ,
1611+ typeck_results : Option < & ty:: TypeckResults < ' tcx > > ,
16241612 obligation : & PredicateObligation < ' tcx > ,
16251613 next_code : Option < & ObligationCauseCode < ' tcx > > ,
16261614 ) {
@@ -1831,7 +1819,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18311819 // Look at the last interior type to get a span for the `.await`.
18321820 debug ! (
18331821 "note_obligation_cause_for_async_await generator_interior_types: {:#?}" ,
1834- typeck_results. generator_interior_types
1822+ typeck_results. as_ref ( ) . map ( |t| & t . generator_interior_types)
18351823 ) ;
18361824 explain_yield ( interior_span, yield_span, scope_span) ;
18371825 }
@@ -1852,10 +1840,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18521840 // ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
18531841 // ```
18541842 //
1855- let is_region_borrow = typeck_results
1856- . expr_adjustments ( expr)
1857- . iter ( )
1858- . any ( |adj| adj. is_region_borrow ( ) ) ;
1843+ let is_region_borrow = if let Some ( typeck_results) = typeck_results {
1844+ typeck_results
1845+ . expr_adjustments ( expr)
1846+ . iter ( )
1847+ . any ( |adj| adj. is_region_borrow ( ) )
1848+ } else {
1849+ false
1850+ } ;
18591851
18601852 // ```rust
18611853 // struct Foo(*const u8);
@@ -1868,15 +1860,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18681860 DefKind :: Fn | DefKind :: Ctor ( ..) => target_ty. is_unsafe_ptr ( ) ,
18691861 _ => false ,
18701862 } ;
1871-
1872- if ( typeck_results. is_method_call ( e) && is_region_borrow)
1873- || is_raw_borrow_inside_fn_like_call
1874- {
1875- err. span_help (
1876- parent_span,
1877- "consider moving this into a `let` \
1863+ if let Some ( typeck_results ) = typeck_results {
1864+ if ( typeck_results. is_method_call ( e) && is_region_borrow)
1865+ || is_raw_borrow_inside_fn_like_call
1866+ {
1867+ err. span_help (
1868+ parent_span,
1869+ "consider moving this into a `let` \
18781870 binding to create a shorter lived borrow",
1879- ) ;
1871+ ) ;
1872+ }
18801873 }
18811874 }
18821875 }
0 commit comments