Skip to content

Commit 272188e

Browse files
authored
Rollup merge of #90939 - estebank:wg-af-polish, r=tmandry
Tweak errors coming from `for`-loop, `?` and `.await` desugaring * Suggest removal of `.await` on non-`Future` expression * Keep track of obligations introduced by desugaring * Remove span pointing at method for obligation errors coming from desugaring * Point at called local sync `fn` and suggest making it `async` ``` error[E0277]: `()` is not a future --> $DIR/unnecessary-await.rs:9:10 | LL | boo().await; | -----^^^^^^ `()` is not a future | | | this call returns `()` | = help: the trait `Future` is not implemented for `()` help: do not `.await` the expression | LL - boo().await; LL + boo(); | help: alternatively, consider making `fn boo` asynchronous | LL | async fn boo () {} | +++++ ``` Fix #66731.
2 parents 2f4da62 + f2fc84f commit 272188e

File tree

60 files changed

+446
-366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+446
-366
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+55-15
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
130130
hir::AsyncGeneratorKind::Block,
131131
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
132132
),
133-
ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
133+
ExprKind::Await(ref expr) => {
134+
let span = if expr.span.hi() < e.span.hi() {
135+
expr.span.shrink_to_hi().with_hi(e.span.hi())
136+
} else {
137+
// this is a recovered `await expr`
138+
e.span
139+
};
140+
self.lower_expr_await(span, expr)
141+
}
134142
ExprKind::Closure(
135143
capture_clause,
136144
asyncness,
@@ -479,8 +487,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
479487
expr: &'hir hir::Expr<'hir>,
480488
overall_span: Span,
481489
) -> &'hir hir::Expr<'hir> {
482-
let constructor =
483-
self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, ThinVec::new()));
490+
let constructor = self.arena.alloc(self.expr_lang_item_path(
491+
method_span,
492+
lang_item,
493+
ThinVec::new(),
494+
None,
495+
));
484496
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
485497
}
486498

@@ -584,8 +596,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
584596
// `future::from_generator`:
585597
let unstable_span =
586598
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
587-
let gen_future =
588-
self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator, ThinVec::new());
599+
let gen_future = self.expr_lang_item_path(
600+
unstable_span,
601+
hir::LangItem::FromGenerator,
602+
ThinVec::new(),
603+
None,
604+
);
589605

590606
// `future::from_generator(generator)`:
591607
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
@@ -607,6 +623,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
607623
/// }
608624
/// ```
609625
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
626+
let dot_await_span = expr.span.shrink_to_hi().to(await_span);
610627
match self.generator_kind {
611628
Some(hir::GeneratorKind::Async(_)) => {}
612629
Some(hir::GeneratorKind::Gen) | None => {
@@ -623,13 +640,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
623640
err.emit();
624641
}
625642
}
626-
let span = self.mark_span_with_reason(DesugaringKind::Await, await_span, None);
643+
let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
627644
let gen_future_span = self.mark_span_with_reason(
628645
DesugaringKind::Await,
629646
await_span,
630647
self.allow_gen_future.clone(),
631648
);
632649
let expr = self.lower_expr_mut(expr);
650+
let expr_hir_id = expr.hir_id;
633651

634652
let pinned_ident = Ident::with_dummy_span(sym::pinned);
635653
let (pinned_pat, pinned_pat_hid) =
@@ -656,16 +674,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
656674
span,
657675
hir::LangItem::PinNewUnchecked,
658676
arena_vec![self; ref_mut_pinned],
677+
Some(expr_hir_id),
659678
);
660679
let get_context = self.expr_call_lang_item_fn_mut(
661680
gen_future_span,
662681
hir::LangItem::GetContext,
663682
arena_vec![self; task_context],
683+
Some(expr_hir_id),
664684
);
665685
let call = self.expr_call_lang_item_fn(
666686
span,
667687
hir::LangItem::FuturePoll,
668688
arena_vec![self; new_unchecked, get_context],
689+
Some(expr_hir_id),
669690
);
670691
self.arena.alloc(self.expr_unsafe(call))
671692
};
@@ -678,18 +699,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
678699
let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
679700
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
680701
let ready_field = self.single_pat_field(span, x_pat);
681-
let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field);
702+
let ready_pat = self.pat_lang_item_variant(
703+
span,
704+
hir::LangItem::PollReady,
705+
ready_field,
706+
Some(expr_hir_id),
707+
);
682708
let break_x = self.with_loop_scope(loop_node_id, move |this| {
683709
let expr_break =
684710
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
685-
this.arena.alloc(this.expr(await_span, expr_break, ThinVec::new()))
711+
this.arena.alloc(this.expr(span, expr_break, ThinVec::new()))
686712
});
687713
self.arm(ready_pat, break_x)
688714
};
689715

690716
// `::std::task::Poll::Pending => {}`
691717
let pending_arm = {
692-
let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
718+
let pending_pat = self.pat_lang_item_variant(
719+
span,
720+
hir::LangItem::PollPending,
721+
&[],
722+
Some(expr_hir_id),
723+
);
693724
let empty_block = self.expr_block_empty(span);
694725
self.arm(pending_pat, empty_block)
695726
};
@@ -709,7 +740,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
709740
let unit = self.expr_unit(span);
710741
let yield_expr = self.expr(
711742
span,
712-
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr.hir_id) }),
743+
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
713744
ThinVec::new(),
714745
);
715746
let yield_expr = self.arena.alloc(yield_expr);
@@ -756,6 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
756787
into_future_span,
757788
hir::LangItem::IntoFutureIntoFuture,
758789
arena_vec![self; expr],
790+
Some(expr_hir_id),
759791
);
760792

761793
// match <into_future_expr> {
@@ -1160,7 +1192,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
11601192
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
11611193
let e1 = self.lower_expr_mut(e1);
11621194
let e2 = self.lower_expr_mut(e2);
1163-
let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span));
1195+
let fn_path =
1196+
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
11641197
let fn_expr =
11651198
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
11661199
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
@@ -1194,7 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11941227
);
11951228

11961229
hir::ExprKind::Struct(
1197-
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span))),
1230+
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span), None)),
11981231
fields,
11991232
None,
12001233
)
@@ -1389,6 +1422,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13891422
head_span,
13901423
hir::LangItem::IteratorNext,
13911424
arena_vec![self; ref_mut_iter],
1425+
None,
13921426
);
13931427
let arms = arena_vec![self; none_arm, some_arm];
13941428

@@ -1417,6 +1451,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14171451
head_span,
14181452
hir::LangItem::IntoIterIntoIter,
14191453
arena_vec![self; head],
1454+
None,
14201455
)
14211456
};
14221457

@@ -1472,6 +1507,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14721507
unstable_span,
14731508
hir::LangItem::TryTraitBranch,
14741509
arena_vec![self; sub_expr],
1510+
None,
14751511
)
14761512
};
14771513

@@ -1628,8 +1664,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
16281664
span: Span,
16291665
lang_item: hir::LangItem,
16301666
args: &'hir [hir::Expr<'hir>],
1667+
hir_id: Option<hir::HirId>,
16311668
) -> hir::Expr<'hir> {
1632-
let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new()));
1669+
let path =
1670+
self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id));
16331671
self.expr_call_mut(span, path, args)
16341672
}
16351673

@@ -1638,19 +1676,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
16381676
span: Span,
16391677
lang_item: hir::LangItem,
16401678
args: &'hir [hir::Expr<'hir>],
1679+
hir_id: Option<hir::HirId>,
16411680
) -> &'hir hir::Expr<'hir> {
1642-
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args))
1681+
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args, hir_id))
16431682
}
16441683

16451684
fn expr_lang_item_path(
16461685
&mut self,
16471686
span: Span,
16481687
lang_item: hir::LangItem,
16491688
attrs: AttrVec,
1689+
hir_id: Option<hir::HirId>,
16501690
) -> hir::Expr<'hir> {
16511691
self.expr(
16521692
span,
1653-
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span))),
1693+
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
16541694
attrs,
16551695
)
16561696
}

compiler/rustc_ast_lowering/src/lib.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -2127,21 +2127,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21272127

21282128
fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
21292129
let field = self.single_pat_field(span, pat);
2130-
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2130+
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field, None)
21312131
}
21322132

21332133
fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
21342134
let field = self.single_pat_field(span, pat);
2135-
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2135+
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field, None)
21362136
}
21372137

21382138
fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
21392139
let field = self.single_pat_field(span, pat);
2140-
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2140+
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field, None)
21412141
}
21422142

21432143
fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2144-
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2144+
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[], None)
21452145
}
21462146

21472147
fn single_pat_field(
@@ -2164,8 +2164,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21642164
span: Span,
21652165
lang_item: hir::LangItem,
21662166
fields: &'hir [hir::PatField<'hir>],
2167+
hir_id: Option<hir::HirId>,
21672168
) -> &'hir hir::Pat<'hir> {
2168-
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2169+
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id);
21692170
self.pat(span, hir::PatKind::Struct(qpath, fields, false))
21702171
}
21712172

compiler/rustc_hir/src/hir.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1627,13 +1627,13 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
16271627
| LangItem::RangeFrom
16281628
| LangItem::RangeFull
16291629
| LangItem::RangeToInclusive,
1630-
_,
1630+
..
16311631
)
16321632
),
16331633

16341634
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
16351635
ExprKind::Call(ref func, _) => {
1636-
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, _)))
1636+
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
16371637
}
16381638

16391639
_ => false,
@@ -1788,8 +1788,8 @@ pub enum QPath<'hir> {
17881788
/// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
17891789
TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
17901790

1791-
/// Reference to a `#[lang = "foo"]` item.
1792-
LangItem(LangItem, Span),
1791+
/// Reference to a `#[lang = "foo"]` item. `HirId` of the inner expr.
1792+
LangItem(LangItem, Span, Option<HirId>),
17931793
}
17941794

17951795
impl<'hir> QPath<'hir> {
@@ -1798,7 +1798,7 @@ impl<'hir> QPath<'hir> {
17981798
match *self {
17991799
QPath::Resolved(_, path) => path.span,
18001800
QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
1801-
QPath::LangItem(_, span) => span,
1801+
QPath::LangItem(_, span, _) => span,
18021802
}
18031803
}
18041804

@@ -1808,7 +1808,7 @@ impl<'hir> QPath<'hir> {
18081808
match *self {
18091809
QPath::Resolved(_, path) => path.span,
18101810
QPath::TypeRelative(qself, _) => qself.span,
1811-
QPath::LangItem(_, span) => span,
1811+
QPath::LangItem(_, span, _) => span,
18121812
}
18131813
}
18141814

@@ -1818,7 +1818,7 @@ impl<'hir> QPath<'hir> {
18181818
match *self {
18191819
QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
18201820
QPath::TypeRelative(_, segment) => segment.ident.span,
1821-
QPath::LangItem(_, span) => span,
1821+
QPath::LangItem(_, span, _) => span,
18221822
}
18231823
}
18241824
}

compiler/rustc_hir_pretty/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1731,7 +1731,7 @@ impl<'a> State<'a> {
17311731
colons_before_params,
17321732
)
17331733
}
1734-
hir::QPath::LangItem(lang_item, span) => {
1734+
hir::QPath::LangItem(lang_item, span, _) => {
17351735
self.word("#[lang = \"");
17361736
self.print_ident(Ident::new(lang_item.name(), span));
17371737
self.word("\"]");

compiler/rustc_lint/src/array_into_iter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
5252
if let hir::ExprKind::Call(path, [arg]) = &arg.kind {
5353
if let hir::ExprKind::Path(hir::QPath::LangItem(
5454
hir::LangItem::IntoIterIntoIter,
55-
_,
55+
..,
5656
)) = &path.kind
5757
{
5858
self.for_expr_span = arg.span;

compiler/rustc_middle/src/traits/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,12 @@ pub enum ObligationCauseCode<'tcx> {
348348
/// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
349349
OpaqueType,
350350

351+
AwaitableExpr(Option<hir::HirId>),
352+
353+
ForLoopIterator,
354+
355+
QuestionMark,
356+
351357
/// Well-formed checking. If a `WellFormedLoc` is provided,
352358
/// then it will be used to eprform HIR-based wf checking
353359
/// after an error occurs, in order to generate a more precise error span.

compiler/rustc_passes/src/region.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -421,11 +421,14 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
421421
// Mark this expr's scope and all parent scopes as containing `yield`.
422422
let mut scope = Scope { id: expr.hir_id.local_id, data: ScopeData::Node };
423423
loop {
424-
let data = YieldData {
425-
span: expr.span,
426-
expr_and_pat_count: visitor.expr_and_pat_count,
427-
source: *source,
424+
let span = match expr.kind {
425+
hir::ExprKind::Yield(expr, hir::YieldSource::Await { .. }) => {
426+
expr.span.shrink_to_hi().to(expr.span)
427+
}
428+
_ => expr.span,
428429
};
430+
let data =
431+
YieldData { span, expr_and_pat_count: visitor.expr_and_pat_count, source: *source };
429432
visitor.scope_tree.yield_in_scope.insert(scope, data);
430433
if visitor.pessimistic_yield {
431434
debug!("resolve_expr in pessimistic_yield - marking scope {:?} for fixup", scope);

compiler/rustc_save_analysis/src/sig.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
286286
refs: vec![SigElement { id, start, end }],
287287
})
288288
}
289-
hir::TyKind::Path(hir::QPath::LangItem(lang_item, _)) => {
289+
hir::TyKind::Path(hir::QPath::LangItem(lang_item, _, _)) => {
290290
Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name())))
291291
}
292292
hir::TyKind::TraitObject(bounds, ..) => {

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
439439
self.suggest_remove_reference(&obligation, &mut err, trait_ref);
440440
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
441441
self.note_version_mismatch(&mut err, &trait_ref);
442+
self.suggest_remove_await(&obligation, &mut err);
442443

443444
if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
444445
self.suggest_await_before_try(&mut err, &obligation, trait_ref, span);

0 commit comments

Comments
 (0)