@@ -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 ) ;
@@ -1460,11 +1460,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14601460 }
14611461
14621462 // Only continue if a generator was found.
1463- debug ! (
1464- "maybe_note_obligation_cause_for_async_await: generator={:?} trait_ref={:?} \
1465- target_ty={:?}",
1466- generator, trait_ref, target_ty
1467- ) ;
1463+ debug ! ( ?generator, ?trait_ref, ?target_ty, "maybe_note_obligation_cause_for_async_await" ) ;
14681464 let ( generator_did, trait_ref, target_ty) = match ( generator, trait_ref, target_ty) {
14691465 ( Some ( generator_did) , Some ( trait_ref) , Some ( target_ty) ) => {
14701466 ( generator_did, trait_ref, target_ty)
@@ -1474,14 +1470,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14741470
14751471 let span = self . tcx . def_span ( generator_did) ;
14761472
1477- // Do not ICE on closure typeck (#66868).
1478- if !generator_did. is_local ( ) {
1479- return false ;
1480- }
1481-
1482- // Get the typeck results from the infcx if the generator is the function we are
1483- // currently type-checking; otherwise, get them by performing a query.
1484- // This is needed to avoid cycles.
14851473 let in_progress_typeck_results = self . in_progress_typeck_results . map ( |t| t. borrow ( ) ) ;
14861474 let generator_did_root = self . tcx . closure_base_def_id ( generator_did) ;
14871475 debug ! (
@@ -1492,14 +1480,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14921480 in_progress_typeck_results. as_ref( ) . map( |t| t. hir_owner) ,
14931481 span
14941482 ) ;
1495- let query_typeck_results;
1496- let typeck_results: & TypeckResults < ' tcx > = match & in_progress_typeck_results {
1497- Some ( t) if t. hir_owner . to_def_id ( ) == generator_did_root => t,
1498- _ => {
1499- query_typeck_results = self . tcx . typeck ( generator_did. expect_local ( ) ) ;
1500- & query_typeck_results
1501- }
1502- } ;
15031483
15041484 let generator_body = generator_did
15051485 . as_local ( )
@@ -1542,51 +1522,59 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
15421522 let mut interior_or_upvar_span = None ;
15431523 let mut interior_extra_info = None ;
15441524
1545- if let Some ( upvars) = self . tcx . upvars_mentioned ( generator_did) {
1546- interior_or_upvar_span = upvars. iter ( ) . find_map ( |( upvar_id, upvar) | {
1547- let upvar_ty = typeck_results. node_type ( * upvar_id) ;
1548- let upvar_ty = self . resolve_vars_if_possible ( upvar_ty) ;
1549- if ty_matches ( ty:: Binder :: dummy ( upvar_ty) ) {
1550- Some ( GeneratorInteriorOrUpvar :: Upvar ( upvar. span ) )
1551- } else {
1552- None
1553- }
1554- } ) ;
1525+ // Get the typeck results from the infcx if the generator is the function we are currently
1526+ // type-checking; otherwise, get them by performing a query. This is needed to avoid
1527+ // cycles. If we can't use resolved types because the generator comes from another crate,
1528+ // we still provide a targeted error but without all the relevant spans.
1529+ let query_typeck_results;
1530+ let typeck_results: Option < & TypeckResults < ' tcx > > = match & in_progress_typeck_results {
1531+ Some ( t) if t. hir_owner . to_def_id ( ) == generator_did_root => Some ( & t) ,
1532+ _ if generator_did. is_local ( ) => {
1533+ query_typeck_results = self . tcx . typeck ( generator_did. expect_local ( ) ) ;
1534+ Some ( & query_typeck_results)
1535+ }
1536+ _ => None , // Do not ICE on closure typeck (#66868).
15551537 } ;
1538+ if let Some ( typeck_results) = typeck_results {
1539+ if let Some ( upvars) = self . tcx . upvars_mentioned ( generator_did) {
1540+ interior_or_upvar_span = upvars. iter ( ) . find_map ( |( upvar_id, upvar) | {
1541+ let upvar_ty = typeck_results. node_type ( * upvar_id) ;
1542+ let upvar_ty = self . resolve_vars_if_possible ( upvar_ty) ;
1543+ if ty_matches ( ty:: Binder :: dummy ( upvar_ty) ) {
1544+ Some ( GeneratorInteriorOrUpvar :: Upvar ( upvar. span ) )
1545+ } else {
1546+ None
1547+ }
1548+ } ) ;
1549+ } ;
15561550
1557- // The generator interior types share the same binders
1558- if let Some ( cause) =
1559- typeck_results. generator_interior_types . as_ref ( ) . skip_binder ( ) . iter ( ) . find (
1560- |ty:: GeneratorInteriorTypeCause { ty, .. } | {
1561- ty_matches ( typeck_results. generator_interior_types . rebind ( ty) )
1562- } ,
1563- )
1564- {
1565- // Check to see if any awaited expressions have the target type.
1566- let from_awaited_ty = visitor
1567- . awaits
1568- . into_iter ( )
1569- . map ( |id| hir. expect_expr ( id) )
1570- . find ( |await_expr| {
1571- let ty = typeck_results. expr_ty_adjusted ( & await_expr) ;
1572- debug ! (
1573- "maybe_note_obligation_cause_for_async_await: await_expr={:?}" ,
1574- await_expr
1575- ) ;
1576- ty_matches ( ty:: Binder :: dummy ( ty) )
1577- } )
1578- . map ( |expr| expr. span ) ;
1579- let ty:: GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
1551+ // The generator interior types share the same binders
1552+ if let Some ( cause) =
1553+ typeck_results. generator_interior_types . as_ref ( ) . skip_binder ( ) . iter ( ) . find (
1554+ |ty:: GeneratorInteriorTypeCause { ty, .. } | {
1555+ ty_matches ( typeck_results. generator_interior_types . rebind ( ty) )
1556+ } ,
1557+ )
1558+ {
1559+ // Check to see if any awaited expressions have the target type.
1560+ let from_awaited_ty = visitor
1561+ . awaits
1562+ . into_iter ( )
1563+ . map ( |id| hir. expect_expr ( id) )
1564+ . find ( |await_expr| {
1565+ ty_matches ( ty:: Binder :: dummy ( typeck_results. expr_ty_adjusted ( & await_expr) ) )
1566+ } )
1567+ . map ( |expr| expr. span ) ;
1568+ let ty:: GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } =
1569+ cause;
15801570
1581- interior_or_upvar_span = Some ( GeneratorInteriorOrUpvar :: Interior ( * span) ) ;
1582- interior_extra_info = Some ( ( * scope_span, * yield_span, * expr, from_awaited_ty) ) ;
1583- } ;
1571+ interior_or_upvar_span = Some ( GeneratorInteriorOrUpvar :: Interior ( * span) ) ;
1572+ interior_extra_info = Some ( ( * scope_span, * yield_span, * expr, from_awaited_ty) ) ;
1573+ } ;
1574+ } else {
1575+ interior_or_upvar_span = Some ( GeneratorInteriorOrUpvar :: Interior ( span) ) ;
1576+ }
15841577
1585- debug ! (
1586- "maybe_note_obligation_cause_for_async_await: interior_or_upvar={:?} \
1587- generator_interior_types={:?}",
1588- interior_or_upvar_span, typeck_results. generator_interior_types
1589- ) ;
15901578 if let Some ( interior_or_upvar_span) = interior_or_upvar_span {
15911579 self . note_obligation_cause_for_async_await (
15921580 err,
@@ -1617,7 +1605,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
16171605 outer_generator : Option < DefId > ,
16181606 trait_ref : ty:: TraitRef < ' tcx > ,
16191607 target_ty : Ty < ' tcx > ,
1620- typeck_results : & ty:: TypeckResults < ' tcx > ,
1608+ typeck_results : Option < & ty:: TypeckResults < ' tcx > > ,
16211609 obligation : & PredicateObligation < ' tcx > ,
16221610 next_code : Option < & ObligationCauseCode < ' tcx > > ,
16231611 ) {
@@ -1828,7 +1816,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18281816 // Look at the last interior type to get a span for the `.await`.
18291817 debug ! (
18301818 "note_obligation_cause_for_async_await generator_interior_types: {:#?}" ,
1831- typeck_results. generator_interior_types
1819+ typeck_results. as_ref ( ) . map ( |t| & t . generator_interior_types)
18321820 ) ;
18331821 explain_yield ( interior_span, yield_span, scope_span) ;
18341822 }
@@ -1849,10 +1837,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18491837 // ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
18501838 // ```
18511839 //
1852- let is_region_borrow = typeck_results
1853- . expr_adjustments ( expr)
1854- . iter ( )
1855- . any ( |adj| adj. is_region_borrow ( ) ) ;
1840+ let is_region_borrow = if let Some ( typeck_results) = typeck_results {
1841+ typeck_results
1842+ . expr_adjustments ( expr)
1843+ . iter ( )
1844+ . any ( |adj| adj. is_region_borrow ( ) )
1845+ } else {
1846+ false
1847+ } ;
18561848
18571849 // ```rust
18581850 // struct Foo(*const u8);
@@ -1865,15 +1857,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
18651857 DefKind :: Fn | DefKind :: Ctor ( ..) => target_ty. is_unsafe_ptr ( ) ,
18661858 _ => false ,
18671859 } ;
1868-
1869- if ( typeck_results. is_method_call ( e) && is_region_borrow)
1870- || is_raw_borrow_inside_fn_like_call
1871- {
1872- err. span_help (
1873- parent_span,
1874- "consider moving this into a `let` \
1860+ if let Some ( typeck_results ) = typeck_results {
1861+ if ( typeck_results. is_method_call ( e) && is_region_borrow)
1862+ || is_raw_borrow_inside_fn_like_call
1863+ {
1864+ err. span_help (
1865+ parent_span,
1866+ "consider moving this into a `let` \
18751867 binding to create a shorter lived borrow",
1876- ) ;
1868+ ) ;
1869+ }
18771870 }
18781871 }
18791872 }
0 commit comments