@@ -151,7 +151,7 @@ pub trait InferCtxtExt<'tcx> {
151
151
outer_generator : Option < DefId > ,
152
152
trait_ref : ty:: TraitRef < ' tcx > ,
153
153
target_ty : Ty < ' tcx > ,
154
- typeck_results : & ty:: TypeckResults < ' tcx > ,
154
+ typeck_results : Option < & ty:: TypeckResults < ' tcx > > ,
155
155
obligation : & PredicateObligation < ' tcx > ,
156
156
next_code : Option < & ObligationCauseCode < ' tcx > > ,
157
157
) ;
@@ -1460,11 +1460,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1460
1460
}
1461
1461
1462
1462
// 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" ) ;
1468
1464
let ( generator_did, trait_ref, target_ty) = match ( generator, trait_ref, target_ty) {
1469
1465
( Some ( generator_did) , Some ( trait_ref) , Some ( target_ty) ) => {
1470
1466
( generator_did, trait_ref, target_ty)
@@ -1474,14 +1470,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1474
1470
1475
1471
let span = self . tcx . def_span ( generator_did) ;
1476
1472
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.
1485
1473
let in_progress_typeck_results = self . in_progress_typeck_results . map ( |t| t. borrow ( ) ) ;
1486
1474
let generator_did_root = self . tcx . closure_base_def_id ( generator_did) ;
1487
1475
debug ! (
@@ -1492,14 +1480,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1492
1480
in_progress_typeck_results. as_ref( ) . map( |t| t. hir_owner) ,
1493
1481
span
1494
1482
) ;
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
- } ;
1503
1483
1504
1484
let generator_body = generator_did
1505
1485
. as_local ( )
@@ -1542,51 +1522,59 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1542
1522
let mut interior_or_upvar_span = None ;
1543
1523
let mut interior_extra_info = None ;
1544
1524
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).
1555
1537
} ;
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
+ } ;
1556
1550
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;
1580
1570
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
+ }
1584
1577
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
- ) ;
1590
1578
if let Some ( interior_or_upvar_span) = interior_or_upvar_span {
1591
1579
self . note_obligation_cause_for_async_await (
1592
1580
err,
@@ -1617,7 +1605,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1617
1605
outer_generator : Option < DefId > ,
1618
1606
trait_ref : ty:: TraitRef < ' tcx > ,
1619
1607
target_ty : Ty < ' tcx > ,
1620
- typeck_results : & ty:: TypeckResults < ' tcx > ,
1608
+ typeck_results : Option < & ty:: TypeckResults < ' tcx > > ,
1621
1609
obligation : & PredicateObligation < ' tcx > ,
1622
1610
next_code : Option < & ObligationCauseCode < ' tcx > > ,
1623
1611
) {
@@ -1828,7 +1816,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1828
1816
// Look at the last interior type to get a span for the `.await`.
1829
1817
debug ! (
1830
1818
"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)
1832
1820
) ;
1833
1821
explain_yield ( interior_span, yield_span, scope_span) ;
1834
1822
}
@@ -1849,10 +1837,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1849
1837
// ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
1850
1838
// ```
1851
1839
//
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
+ } ;
1856
1848
1857
1849
// ```rust
1858
1850
// struct Foo(*const u8);
@@ -1865,15 +1857,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1865
1857
DefKind :: Fn | DefKind :: Ctor ( ..) => target_ty. is_unsafe_ptr ( ) ,
1866
1858
_ => false ,
1867
1859
} ;
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` \
1875
1867
binding to create a shorter lived borrow",
1876
- ) ;
1868
+ ) ;
1869
+ }
1877
1870
}
1878
1871
}
1879
1872
}
0 commit comments