@@ -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
) ;
@@ -1463,11 +1463,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1463
1463
}
1464
1464
1465
1465
// 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" ) ;
1471
1467
let ( generator_did, trait_ref, target_ty) = match ( generator, trait_ref, target_ty) {
1472
1468
( Some ( generator_did) , Some ( trait_ref) , Some ( target_ty) ) => {
1473
1469
( generator_did, trait_ref, target_ty)
@@ -1477,14 +1473,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1477
1473
1478
1474
let span = self . tcx . def_span ( generator_did) ;
1479
1475
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.
1488
1476
let in_progress_typeck_results = self . in_progress_typeck_results . map ( |t| t. borrow ( ) ) ;
1489
1477
let generator_did_root = self . tcx . closure_base_def_id ( generator_did) ;
1490
1478
debug ! (
@@ -1495,14 +1483,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1495
1483
in_progress_typeck_results. as_ref( ) . map( |t| t. hir_owner) ,
1496
1484
span
1497
1485
) ;
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
- } ;
1506
1486
1507
1487
let generator_body = generator_did
1508
1488
. as_local ( )
@@ -1545,51 +1525,59 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1545
1525
let mut interior_or_upvar_span = None ;
1546
1526
let mut interior_extra_info = None ;
1547
1527
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).
1558
1540
} ;
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
+ } ;
1559
1553
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;
1583
1573
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
+ }
1587
1580
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
- ) ;
1593
1581
if let Some ( interior_or_upvar_span) = interior_or_upvar_span {
1594
1582
self . note_obligation_cause_for_async_await (
1595
1583
err,
@@ -1620,7 +1608,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1620
1608
outer_generator : Option < DefId > ,
1621
1609
trait_ref : ty:: TraitRef < ' tcx > ,
1622
1610
target_ty : Ty < ' tcx > ,
1623
- typeck_results : & ty:: TypeckResults < ' tcx > ,
1611
+ typeck_results : Option < & ty:: TypeckResults < ' tcx > > ,
1624
1612
obligation : & PredicateObligation < ' tcx > ,
1625
1613
next_code : Option < & ObligationCauseCode < ' tcx > > ,
1626
1614
) {
@@ -1831,7 +1819,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1831
1819
// Look at the last interior type to get a span for the `.await`.
1832
1820
debug ! (
1833
1821
"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)
1835
1823
) ;
1836
1824
explain_yield ( interior_span, yield_span, scope_span) ;
1837
1825
}
@@ -1852,10 +1840,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1852
1840
// ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
1853
1841
// ```
1854
1842
//
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
+ } ;
1859
1851
1860
1852
// ```rust
1861
1853
// struct Foo(*const u8);
@@ -1868,15 +1860,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1868
1860
DefKind :: Fn | DefKind :: Ctor ( ..) => target_ty. is_unsafe_ptr ( ) ,
1869
1861
_ => false ,
1870
1862
} ;
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` \
1878
1870
binding to create a shorter lived borrow",
1879
- ) ;
1871
+ ) ;
1872
+ }
1880
1873
}
1881
1874
}
1882
1875
}
0 commit comments