@@ -1570,36 +1570,130 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
15701570 format ! ( "does not implement `{}`" , trait_ref. print_only_trait_path( ) )
15711571 } ;
15721572
1573- let mut explain_yield = |interior_span : Span ,
1574- yield_span : Span ,
1575- scope_span : Option < Span > | {
1576- let mut span = MultiSpan :: from_span ( yield_span) ;
1577- if let Ok ( snippet) = source_map. span_to_snippet ( interior_span) {
1578- span. push_span_label (
1579- yield_span,
1580- format ! ( "{} occurs here, with `{}` maybe used later" , await_or_yield, snippet) ,
1581- ) ;
1582- // If available, use the scope span to annotate the drop location.
1583- if let Some ( scope_span) = scope_span {
1584- span. push_span_label (
1585- source_map. end_point ( scope_span) ,
1586- format ! ( "`{}` is later dropped here" , snippet) ,
1587- ) ;
1573+ let mut explain_yield =
1574+ |interior_span : Span , yield_span : Span , scope_span : Option < Span > | {
1575+ let mut span = MultiSpan :: from_span ( yield_span) ;
1576+ if let Ok ( snippet) = source_map. span_to_snippet ( interior_span) {
1577+ // #70935: If snippet contains newlines, display "the value" instead
1578+ // so that we do not emit complex diagnostics.
1579+ let snippet = & format ! ( "`{}`" , snippet) ;
1580+ let snippet = if snippet. contains ( '\n' ) { "the value" } else { snippet } ;
1581+ // The multispan can be complex here, like:
1582+ // note: future is not `Send` as this value is used across an await
1583+ // --> $DIR/issue-70935-complex-spans.rs:13:9
1584+ // |
1585+ // LL | baz(|| async{
1586+ // | __________^___-
1587+ // | | _________|
1588+ // | ||
1589+ // LL | || foo(tx.clone());
1590+ // LL | || }).await;
1591+ // | || - ^- value is later dropped here
1592+ // | ||_________|______|
1593+ // | |__________| await occurs here, with value maybe used later
1594+ // | has type `closure` which is not `Send`
1595+ //
1596+ // So, detect it and separate into some notes, like:
1597+ //
1598+ // note: future is not `Send` as this value is used across an await
1599+ // --> $DIR/issue-70935-complex-spans.rs:13:9
1600+ // |
1601+ // LL | / baz(|| async{
1602+ // LL | | foo(tx.clone());
1603+ // LL | | }).await;
1604+ // | |________________^ first, await occurs here, with the value maybe used later...
1605+ // note: the value is later dropped here
1606+ // --> $DIR/issue-70935-complex-spans.rs:15:17
1607+ // |
1608+ // LL | }).await;
1609+ // | ^
1610+ //
1611+ // If available, use the scope span to annotate the drop location.
1612+ if let Some ( scope_span) = scope_span {
1613+ let scope_span = source_map. end_point ( scope_span) ;
1614+ let is_overlapped =
1615+ yield_span. overlaps ( scope_span) || yield_span. overlaps ( interior_span) ;
1616+ if is_overlapped {
1617+ span. push_span_label (
1618+ yield_span,
1619+ format ! (
1620+ "first, {} occurs here, with {} maybe used later..." ,
1621+ await_or_yield, snippet
1622+ ) ,
1623+ ) ;
1624+ err. span_note (
1625+ span,
1626+ & format ! (
1627+ "{} {} as this value is used across {}" ,
1628+ future_or_generator, trait_explanation, an_await_or_yield
1629+ ) ,
1630+ ) ;
1631+ if source_map. is_multiline ( interior_span) {
1632+ err. span_note (
1633+ scope_span,
1634+ & format ! ( "{} is later dropped here" , snippet) ,
1635+ ) ;
1636+ err. span_note (
1637+ interior_span,
1638+ & format ! (
1639+ "this has type `{}` which {}" ,
1640+ target_ty, trait_explanation
1641+ ) ,
1642+ ) ;
1643+ } else {
1644+ let mut span = MultiSpan :: from_span ( scope_span) ;
1645+ span. push_span_label (
1646+ interior_span,
1647+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1648+ ) ;
1649+ err. span_note ( span, & format ! ( "{} is later dropped here" , snippet) ) ;
1650+ }
1651+ } else {
1652+ span. push_span_label (
1653+ yield_span,
1654+ format ! (
1655+ "{} occurs here, with {} maybe used later" ,
1656+ await_or_yield, snippet
1657+ ) ,
1658+ ) ;
1659+ span. push_span_label (
1660+ scope_span,
1661+ format ! ( "{} is later dropped here" , snippet) ,
1662+ ) ;
1663+ span. push_span_label (
1664+ interior_span,
1665+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1666+ ) ;
1667+ err. span_note (
1668+ span,
1669+ & format ! (
1670+ "{} {} as this value is used across {}" ,
1671+ future_or_generator, trait_explanation, an_await_or_yield
1672+ ) ,
1673+ ) ;
1674+ }
1675+ } else {
1676+ span. push_span_label (
1677+ yield_span,
1678+ format ! (
1679+ "{} occurs here, with {} maybe used later" ,
1680+ await_or_yield, snippet
1681+ ) ,
1682+ ) ;
1683+ span. push_span_label (
1684+ interior_span,
1685+ format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1686+ ) ;
1687+ err. span_note (
1688+ span,
1689+ & format ! (
1690+ "{} {} as this value is used across {}" ,
1691+ future_or_generator, trait_explanation, an_await_or_yield
1692+ ) ,
1693+ ) ;
1694+ }
15881695 }
1589- }
1590- span. push_span_label (
1591- interior_span,
1592- format ! ( "has type `{}` which {}" , target_ty, trait_explanation) ,
1593- ) ;
1594-
1595- err. span_note (
1596- span,
1597- & format ! (
1598- "{} {} as this value is used across {}" ,
1599- future_or_generator, trait_explanation, an_await_or_yield
1600- ) ,
1601- ) ;
1602- } ;
1696+ } ;
16031697 match interior_or_upvar_span {
16041698 GeneratorInteriorOrUpvar :: Interior ( interior_span) => {
16051699 if let Some ( ( scope_span, yield_span, expr, from_awaited_ty) ) = interior_extra_info {
0 commit comments