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.
This commit is contained in:
commit
272188eecd
60 changed files with 446 additions and 366 deletions
|
@ -130,7 +130,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::AsyncGeneratorKind::Block,
|
hir::AsyncGeneratorKind::Block,
|
||||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||||
),
|
),
|
||||||
ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
|
ExprKind::Await(ref expr) => {
|
||||||
|
let span = if expr.span.hi() < e.span.hi() {
|
||||||
|
expr.span.shrink_to_hi().with_hi(e.span.hi())
|
||||||
|
} else {
|
||||||
|
// this is a recovered `await expr`
|
||||||
|
e.span
|
||||||
|
};
|
||||||
|
self.lower_expr_await(span, expr)
|
||||||
|
}
|
||||||
ExprKind::Closure(
|
ExprKind::Closure(
|
||||||
capture_clause,
|
capture_clause,
|
||||||
asyncness,
|
asyncness,
|
||||||
|
@ -479,8 +487,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
expr: &'hir hir::Expr<'hir>,
|
expr: &'hir hir::Expr<'hir>,
|
||||||
overall_span: Span,
|
overall_span: Span,
|
||||||
) -> &'hir hir::Expr<'hir> {
|
) -> &'hir hir::Expr<'hir> {
|
||||||
let constructor =
|
let constructor = self.arena.alloc(self.expr_lang_item_path(
|
||||||
self.arena.alloc(self.expr_lang_item_path(method_span, lang_item, ThinVec::new()));
|
method_span,
|
||||||
|
lang_item,
|
||||||
|
ThinVec::new(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,8 +596,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
// `future::from_generator`:
|
// `future::from_generator`:
|
||||||
let unstable_span =
|
let unstable_span =
|
||||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
||||||
let gen_future =
|
let gen_future = self.expr_lang_item_path(
|
||||||
self.expr_lang_item_path(unstable_span, hir::LangItem::FromGenerator, ThinVec::new());
|
unstable_span,
|
||||||
|
hir::LangItem::FromGenerator,
|
||||||
|
ThinVec::new(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
// `future::from_generator(generator)`:
|
// `future::from_generator(generator)`:
|
||||||
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
|
hir::ExprKind::Call(self.arena.alloc(gen_future), arena_vec![self; generator])
|
||||||
|
@ -607,6 +623,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
|
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
|
||||||
|
let dot_await_span = expr.span.shrink_to_hi().to(await_span);
|
||||||
match self.generator_kind {
|
match self.generator_kind {
|
||||||
Some(hir::GeneratorKind::Async(_)) => {}
|
Some(hir::GeneratorKind::Async(_)) => {}
|
||||||
Some(hir::GeneratorKind::Gen) | None => {
|
Some(hir::GeneratorKind::Gen) | None => {
|
||||||
|
@ -623,13 +640,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let span = self.mark_span_with_reason(DesugaringKind::Await, await_span, None);
|
let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
|
||||||
let gen_future_span = self.mark_span_with_reason(
|
let gen_future_span = self.mark_span_with_reason(
|
||||||
DesugaringKind::Await,
|
DesugaringKind::Await,
|
||||||
await_span,
|
await_span,
|
||||||
self.allow_gen_future.clone(),
|
self.allow_gen_future.clone(),
|
||||||
);
|
);
|
||||||
let expr = self.lower_expr_mut(expr);
|
let expr = self.lower_expr_mut(expr);
|
||||||
|
let expr_hir_id = expr.hir_id;
|
||||||
|
|
||||||
let pinned_ident = Ident::with_dummy_span(sym::pinned);
|
let pinned_ident = Ident::with_dummy_span(sym::pinned);
|
||||||
let (pinned_pat, pinned_pat_hid) =
|
let (pinned_pat, pinned_pat_hid) =
|
||||||
|
@ -656,16 +674,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
span,
|
span,
|
||||||
hir::LangItem::PinNewUnchecked,
|
hir::LangItem::PinNewUnchecked,
|
||||||
arena_vec![self; ref_mut_pinned],
|
arena_vec![self; ref_mut_pinned],
|
||||||
|
Some(expr_hir_id),
|
||||||
);
|
);
|
||||||
let get_context = self.expr_call_lang_item_fn_mut(
|
let get_context = self.expr_call_lang_item_fn_mut(
|
||||||
gen_future_span,
|
gen_future_span,
|
||||||
hir::LangItem::GetContext,
|
hir::LangItem::GetContext,
|
||||||
arena_vec![self; task_context],
|
arena_vec![self; task_context],
|
||||||
|
Some(expr_hir_id),
|
||||||
);
|
);
|
||||||
let call = self.expr_call_lang_item_fn(
|
let call = self.expr_call_lang_item_fn(
|
||||||
span,
|
span,
|
||||||
hir::LangItem::FuturePoll,
|
hir::LangItem::FuturePoll,
|
||||||
arena_vec![self; new_unchecked, get_context],
|
arena_vec![self; new_unchecked, get_context],
|
||||||
|
Some(expr_hir_id),
|
||||||
);
|
);
|
||||||
self.arena.alloc(self.expr_unsafe(call))
|
self.arena.alloc(self.expr_unsafe(call))
|
||||||
};
|
};
|
||||||
|
@ -678,18 +699,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
|
let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
|
||||||
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
|
let x_expr = self.expr_ident(span, x_ident, x_pat_hid);
|
||||||
let ready_field = self.single_pat_field(span, x_pat);
|
let ready_field = self.single_pat_field(span, x_pat);
|
||||||
let ready_pat = self.pat_lang_item_variant(span, hir::LangItem::PollReady, ready_field);
|
let ready_pat = self.pat_lang_item_variant(
|
||||||
|
span,
|
||||||
|
hir::LangItem::PollReady,
|
||||||
|
ready_field,
|
||||||
|
Some(expr_hir_id),
|
||||||
|
);
|
||||||
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
||||||
let expr_break =
|
let expr_break =
|
||||||
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
||||||
this.arena.alloc(this.expr(await_span, expr_break, ThinVec::new()))
|
this.arena.alloc(this.expr(span, expr_break, ThinVec::new()))
|
||||||
});
|
});
|
||||||
self.arm(ready_pat, break_x)
|
self.arm(ready_pat, break_x)
|
||||||
};
|
};
|
||||||
|
|
||||||
// `::std::task::Poll::Pending => {}`
|
// `::std::task::Poll::Pending => {}`
|
||||||
let pending_arm = {
|
let pending_arm = {
|
||||||
let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
|
let pending_pat = self.pat_lang_item_variant(
|
||||||
|
span,
|
||||||
|
hir::LangItem::PollPending,
|
||||||
|
&[],
|
||||||
|
Some(expr_hir_id),
|
||||||
|
);
|
||||||
let empty_block = self.expr_block_empty(span);
|
let empty_block = self.expr_block_empty(span);
|
||||||
self.arm(pending_pat, empty_block)
|
self.arm(pending_pat, empty_block)
|
||||||
};
|
};
|
||||||
|
@ -709,7 +740,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
let unit = self.expr_unit(span);
|
let unit = self.expr_unit(span);
|
||||||
let yield_expr = self.expr(
|
let yield_expr = self.expr(
|
||||||
span,
|
span,
|
||||||
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr.hir_id) }),
|
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
|
||||||
ThinVec::new(),
|
ThinVec::new(),
|
||||||
);
|
);
|
||||||
let yield_expr = self.arena.alloc(yield_expr);
|
let yield_expr = self.arena.alloc(yield_expr);
|
||||||
|
@ -756,6 +787,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
into_future_span,
|
into_future_span,
|
||||||
hir::LangItem::IntoFutureIntoFuture,
|
hir::LangItem::IntoFutureIntoFuture,
|
||||||
arena_vec![self; expr],
|
arena_vec![self; expr],
|
||||||
|
Some(expr_hir_id),
|
||||||
);
|
);
|
||||||
|
|
||||||
// match <into_future_expr> {
|
// match <into_future_expr> {
|
||||||
|
@ -1160,7 +1192,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
|
fn lower_expr_range_closed(&mut self, span: Span, e1: &Expr, e2: &Expr) -> hir::ExprKind<'hir> {
|
||||||
let e1 = self.lower_expr_mut(e1);
|
let e1 = self.lower_expr_mut(e1);
|
||||||
let e2 = self.lower_expr_mut(e2);
|
let e2 = self.lower_expr_mut(e2);
|
||||||
let fn_path = hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span));
|
let fn_path =
|
||||||
|
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
|
||||||
let fn_expr =
|
let fn_expr =
|
||||||
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
|
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
|
||||||
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
||||||
|
@ -1194,7 +1227,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
);
|
);
|
||||||
|
|
||||||
hir::ExprKind::Struct(
|
hir::ExprKind::Struct(
|
||||||
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span))),
|
self.arena.alloc(hir::QPath::LangItem(lang_item, self.lower_span(span), None)),
|
||||||
fields,
|
fields,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
@ -1389,6 +1422,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
head_span,
|
head_span,
|
||||||
hir::LangItem::IteratorNext,
|
hir::LangItem::IteratorNext,
|
||||||
arena_vec![self; ref_mut_iter],
|
arena_vec![self; ref_mut_iter],
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
let arms = arena_vec![self; none_arm, some_arm];
|
let arms = arena_vec![self; none_arm, some_arm];
|
||||||
|
|
||||||
|
@ -1417,6 +1451,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
head_span,
|
head_span,
|
||||||
hir::LangItem::IntoIterIntoIter,
|
hir::LangItem::IntoIterIntoIter,
|
||||||
arena_vec![self; head],
|
arena_vec![self; head],
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1472,6 +1507,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
unstable_span,
|
unstable_span,
|
||||||
hir::LangItem::TryTraitBranch,
|
hir::LangItem::TryTraitBranch,
|
||||||
arena_vec![self; sub_expr],
|
arena_vec![self; sub_expr],
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1628,8 +1664,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
args: &'hir [hir::Expr<'hir>],
|
args: &'hir [hir::Expr<'hir>],
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
let path = self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new()));
|
let path =
|
||||||
|
self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id));
|
||||||
self.expr_call_mut(span, path, args)
|
self.expr_call_mut(span, path, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1638,8 +1676,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
args: &'hir [hir::Expr<'hir>],
|
args: &'hir [hir::Expr<'hir>],
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> &'hir hir::Expr<'hir> {
|
) -> &'hir hir::Expr<'hir> {
|
||||||
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args))
|
self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args, hir_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_lang_item_path(
|
fn expr_lang_item_path(
|
||||||
|
@ -1647,10 +1686,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
attrs: AttrVec,
|
attrs: AttrVec,
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> hir::Expr<'hir> {
|
) -> hir::Expr<'hir> {
|
||||||
self.expr(
|
self.expr(
|
||||||
span,
|
span,
|
||||||
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span))),
|
hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id)),
|
||||||
attrs,
|
attrs,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2127,21 +2127,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
||||||
let field = self.single_pat_field(span, pat);
|
let field = self.single_pat_field(span, pat);
|
||||||
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
|
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
||||||
let field = self.single_pat_field(span, pat);
|
let field = self.single_pat_field(span, pat);
|
||||||
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
|
self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
|
||||||
let field = self.single_pat_field(span, pat);
|
let field = self.single_pat_field(span, pat);
|
||||||
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
|
self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
|
fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
|
||||||
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
|
self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[], None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_pat_field(
|
fn single_pat_field(
|
||||||
|
@ -2164,8 +2164,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span: Span,
|
span: Span,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
fields: &'hir [hir::PatField<'hir>],
|
fields: &'hir [hir::PatField<'hir>],
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> &'hir hir::Pat<'hir> {
|
) -> &'hir hir::Pat<'hir> {
|
||||||
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
|
let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id);
|
||||||
self.pat(span, hir::PatKind::Struct(qpath, fields, false))
|
self.pat(span, hir::PatKind::Struct(qpath, fields, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1627,13 +1627,13 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
|
||||||
| LangItem::RangeFrom
|
| LangItem::RangeFrom
|
||||||
| LangItem::RangeFull
|
| LangItem::RangeFull
|
||||||
| LangItem::RangeToInclusive,
|
| LangItem::RangeToInclusive,
|
||||||
_,
|
..
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
|
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
|
||||||
ExprKind::Call(ref func, _) => {
|
ExprKind::Call(ref func, _) => {
|
||||||
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, _)))
|
matches!(func.kind, ExprKind::Path(QPath::LangItem(LangItem::RangeInclusiveNew, ..)))
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -1788,8 +1788,8 @@ pub enum QPath<'hir> {
|
||||||
/// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
|
/// the `X` and `Y` nodes each being a `TyKind::Path(QPath::TypeRelative(..))`.
|
||||||
TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
|
TypeRelative(&'hir Ty<'hir>, &'hir PathSegment<'hir>),
|
||||||
|
|
||||||
/// Reference to a `#[lang = "foo"]` item.
|
/// Reference to a `#[lang = "foo"]` item. `HirId` of the inner expr.
|
||||||
LangItem(LangItem, Span),
|
LangItem(LangItem, Span, Option<HirId>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'hir> QPath<'hir> {
|
impl<'hir> QPath<'hir> {
|
||||||
|
@ -1798,7 +1798,7 @@ impl<'hir> QPath<'hir> {
|
||||||
match *self {
|
match *self {
|
||||||
QPath::Resolved(_, path) => path.span,
|
QPath::Resolved(_, path) => path.span,
|
||||||
QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
|
QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
|
||||||
QPath::LangItem(_, span) => span,
|
QPath::LangItem(_, span, _) => span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1808,7 +1808,7 @@ impl<'hir> QPath<'hir> {
|
||||||
match *self {
|
match *self {
|
||||||
QPath::Resolved(_, path) => path.span,
|
QPath::Resolved(_, path) => path.span,
|
||||||
QPath::TypeRelative(qself, _) => qself.span,
|
QPath::TypeRelative(qself, _) => qself.span,
|
||||||
QPath::LangItem(_, span) => span,
|
QPath::LangItem(_, span, _) => span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1818,7 +1818,7 @@ impl<'hir> QPath<'hir> {
|
||||||
match *self {
|
match *self {
|
||||||
QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
|
QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
|
||||||
QPath::TypeRelative(_, segment) => segment.ident.span,
|
QPath::TypeRelative(_, segment) => segment.ident.span,
|
||||||
QPath::LangItem(_, span) => span,
|
QPath::LangItem(_, span, _) => span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1731,7 +1731,7 @@ impl<'a> State<'a> {
|
||||||
colons_before_params,
|
colons_before_params,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
hir::QPath::LangItem(lang_item, span) => {
|
hir::QPath::LangItem(lang_item, span, _) => {
|
||||||
self.word("#[lang = \"");
|
self.word("#[lang = \"");
|
||||||
self.print_ident(Ident::new(lang_item.name(), span));
|
self.print_ident(Ident::new(lang_item.name(), span));
|
||||||
self.word("\"]");
|
self.word("\"]");
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter {
|
||||||
if let hir::ExprKind::Call(path, [arg]) = &arg.kind {
|
if let hir::ExprKind::Call(path, [arg]) = &arg.kind {
|
||||||
if let hir::ExprKind::Path(hir::QPath::LangItem(
|
if let hir::ExprKind::Path(hir::QPath::LangItem(
|
||||||
hir::LangItem::IntoIterIntoIter,
|
hir::LangItem::IntoIterIntoIter,
|
||||||
_,
|
..,
|
||||||
)) = &path.kind
|
)) = &path.kind
|
||||||
{
|
{
|
||||||
self.for_expr_span = arg.span;
|
self.for_expr_span = arg.span;
|
||||||
|
|
|
@ -348,6 +348,12 @@ pub enum ObligationCauseCode<'tcx> {
|
||||||
/// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
|
/// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
|
||||||
OpaqueType,
|
OpaqueType,
|
||||||
|
|
||||||
|
AwaitableExpr(Option<hir::HirId>),
|
||||||
|
|
||||||
|
ForLoopIterator,
|
||||||
|
|
||||||
|
QuestionMark,
|
||||||
|
|
||||||
/// Well-formed checking. If a `WellFormedLoc` is provided,
|
/// Well-formed checking. If a `WellFormedLoc` is provided,
|
||||||
/// then it will be used to eprform HIR-based wf checking
|
/// then it will be used to eprform HIR-based wf checking
|
||||||
/// after an error occurs, in order to generate a more precise error span.
|
/// after an error occurs, in order to generate a more precise error span.
|
||||||
|
|
|
@ -421,11 +421,14 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
|
||||||
// Mark this expr's scope and all parent scopes as containing `yield`.
|
// Mark this expr's scope and all parent scopes as containing `yield`.
|
||||||
let mut scope = Scope { id: expr.hir_id.local_id, data: ScopeData::Node };
|
let mut scope = Scope { id: expr.hir_id.local_id, data: ScopeData::Node };
|
||||||
loop {
|
loop {
|
||||||
let data = YieldData {
|
let span = match expr.kind {
|
||||||
span: expr.span,
|
hir::ExprKind::Yield(expr, hir::YieldSource::Await { .. }) => {
|
||||||
expr_and_pat_count: visitor.expr_and_pat_count,
|
expr.span.shrink_to_hi().to(expr.span)
|
||||||
source: *source,
|
}
|
||||||
|
_ => expr.span,
|
||||||
};
|
};
|
||||||
|
let data =
|
||||||
|
YieldData { span, expr_and_pat_count: visitor.expr_and_pat_count, source: *source };
|
||||||
visitor.scope_tree.yield_in_scope.insert(scope, data);
|
visitor.scope_tree.yield_in_scope.insert(scope, data);
|
||||||
if visitor.pessimistic_yield {
|
if visitor.pessimistic_yield {
|
||||||
debug!("resolve_expr in pessimistic_yield - marking scope {:?} for fixup", scope);
|
debug!("resolve_expr in pessimistic_yield - marking scope {:?} for fixup", scope);
|
||||||
|
|
|
@ -286,7 +286,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
|
||||||
refs: vec![SigElement { id, start, end }],
|
refs: vec![SigElement { id, start, end }],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
hir::TyKind::Path(hir::QPath::LangItem(lang_item, _)) => {
|
hir::TyKind::Path(hir::QPath::LangItem(lang_item, _, _)) => {
|
||||||
Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name())))
|
Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name())))
|
||||||
}
|
}
|
||||||
hir::TyKind::TraitObject(bounds, ..) => {
|
hir::TyKind::TraitObject(bounds, ..) => {
|
||||||
|
|
|
@ -439,6 +439,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
self.suggest_remove_reference(&obligation, &mut err, trait_ref);
|
self.suggest_remove_reference(&obligation, &mut err, trait_ref);
|
||||||
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
|
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
|
||||||
self.note_version_mismatch(&mut err, &trait_ref);
|
self.note_version_mismatch(&mut err, &trait_ref);
|
||||||
|
self.suggest_remove_await(&obligation, &mut err);
|
||||||
|
|
||||||
if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
|
if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
|
||||||
self.suggest_await_before_try(&mut err, &obligation, trait_ref, span);
|
self.suggest_await_before_try(&mut err, &obligation, trait_ref, span);
|
||||||
|
|
|
@ -89,6 +89,12 @@ pub trait InferCtxtExt<'tcx> {
|
||||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
fn suggest_remove_await(
|
||||||
|
&self,
|
||||||
|
obligation: &PredicateObligation<'tcx>,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
);
|
||||||
|
|
||||||
fn suggest_change_mut(
|
fn suggest_change_mut(
|
||||||
&self,
|
&self,
|
||||||
obligation: &PredicateObligation<'tcx>,
|
obligation: &PredicateObligation<'tcx>,
|
||||||
|
@ -873,6 +879,63 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suggest_remove_await(
|
||||||
|
&self,
|
||||||
|
obligation: &PredicateObligation<'tcx>,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
) {
|
||||||
|
let span = obligation.cause.span;
|
||||||
|
|
||||||
|
if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code.peel_derives() {
|
||||||
|
let hir = self.tcx.hir();
|
||||||
|
if let Some(node) = hir_id.and_then(|hir_id| hir.find(hir_id)) {
|
||||||
|
if let hir::Node::Expr(expr) = node {
|
||||||
|
// FIXME: use `obligation.predicate.kind()...trait_ref.self_ty()` to see if we have `()`
|
||||||
|
// and if not maybe suggest doing something else? If we kept the expression around we
|
||||||
|
// could also check if it is an fn call (very likely) and suggest changing *that*, if
|
||||||
|
// it is from the local crate.
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
expr.span.shrink_to_hi().with_hi(span.hi()),
|
||||||
|
"remove the `.await`",
|
||||||
|
String::new(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
// FIXME: account for associated `async fn`s.
|
||||||
|
if let hir::Expr { span, kind: hir::ExprKind::Call(base, _), .. } = expr {
|
||||||
|
if let ty::PredicateKind::Trait(pred) =
|
||||||
|
obligation.predicate.kind().skip_binder()
|
||||||
|
{
|
||||||
|
err.span_label(
|
||||||
|
*span,
|
||||||
|
&format!("this call returns `{}`", pred.self_ty()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(typeck_results) =
|
||||||
|
self.in_progress_typeck_results.map(|t| t.borrow())
|
||||||
|
{
|
||||||
|
let ty = typeck_results.expr_ty_adjusted(base);
|
||||||
|
if let ty::FnDef(def_id, _substs) = ty.kind() {
|
||||||
|
if let Some(hir::Node::Item(hir::Item { span, ident, .. })) =
|
||||||
|
hir.get_if_local(*def_id)
|
||||||
|
{
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
span.shrink_to_lo(),
|
||||||
|
&format!(
|
||||||
|
"alternatively, consider making `fn {}` asynchronous",
|
||||||
|
ident
|
||||||
|
),
|
||||||
|
"async ".to_string(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Check if the trait bound is implemented for a different mutability and note it in the
|
/// Check if the trait bound is implemented for a different mutability and note it in the
|
||||||
/// final error.
|
/// final error.
|
||||||
fn suggest_change_mut(
|
fn suggest_change_mut(
|
||||||
|
@ -1654,120 +1717,51 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
format!("does not implement `{}`", trait_ref.print_only_trait_path())
|
format!("does not implement `{}`", trait_ref.print_only_trait_path())
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut explain_yield =
|
let mut explain_yield = |interior_span: Span,
|
||||||
|interior_span: Span, yield_span: Span, scope_span: Option<Span>| {
|
yield_span: Span,
|
||||||
|
scope_span: Option<Span>| {
|
||||||
let mut span = MultiSpan::from_span(yield_span);
|
let mut span = MultiSpan::from_span(yield_span);
|
||||||
if let Ok(snippet) = source_map.span_to_snippet(interior_span) {
|
if let Ok(snippet) = source_map.span_to_snippet(interior_span) {
|
||||||
// #70935: If snippet contains newlines, display "the value" instead
|
// #70935: If snippet contains newlines, display "the value" instead
|
||||||
// so that we do not emit complex diagnostics.
|
// so that we do not emit complex diagnostics.
|
||||||
let snippet = &format!("`{}`", snippet);
|
let snippet = &format!("`{}`", snippet);
|
||||||
let snippet = if snippet.contains('\n') { "the value" } else { snippet };
|
let snippet = if snippet.contains('\n') { "the value" } else { snippet };
|
||||||
// The multispan can be complex here, like:
|
|
||||||
// note: future is not `Send` as this value is used across an await
|
// note: future is not `Send` as this value is used across an await
|
||||||
// --> $DIR/issue-70935-complex-spans.rs:13:9
|
// --> $DIR/issue-70935-complex-spans.rs:13:9
|
||||||
// |
|
// |
|
||||||
// LL | baz(|| async{
|
// LL | baz(|| async {
|
||||||
// | __________^___-
|
// | ______________-
|
||||||
// | | _________|
|
// | |
|
||||||
// | ||
|
// | |
|
||||||
// LL | || foo(tx.clone());
|
|
||||||
// LL | || }).await;
|
|
||||||
// | || - ^- value is later dropped here
|
|
||||||
// | ||_________|______|
|
|
||||||
// | |__________| await occurs here, with value maybe used later
|
|
||||||
// | has type `closure` which is not `Send`
|
|
||||||
//
|
|
||||||
// So, detect it and separate into some notes, like:
|
|
||||||
//
|
|
||||||
// note: future is not `Send` as this value is used across an await
|
|
||||||
// --> $DIR/issue-70935-complex-spans.rs:13:9
|
|
||||||
// |
|
|
||||||
// LL | / baz(|| async{
|
|
||||||
// LL | | foo(tx.clone());
|
// LL | | foo(tx.clone());
|
||||||
// LL | | }).await;
|
// LL | | }).await;
|
||||||
// | |________________^ first, await occurs here, with the value maybe used later...
|
// | | - ^^^^^^ await occurs here, with value maybe used later
|
||||||
// note: the value is later dropped here
|
// | |__________|
|
||||||
// --> $DIR/issue-70935-complex-spans.rs:15:17
|
// | has type `closure` which is not `Send`
|
||||||
// |
|
// note: value is later dropped here
|
||||||
// LL | }).await;
|
// LL | | }).await;
|
||||||
// | ^
|
// | | ^
|
||||||
//
|
//
|
||||||
|
span.push_span_label(
|
||||||
|
yield_span,
|
||||||
|
format!("{} occurs here, with {} maybe used later", await_or_yield, snippet),
|
||||||
|
);
|
||||||
|
span.push_span_label(
|
||||||
|
interior_span,
|
||||||
|
format!("has type `{}` which {}", target_ty, trait_explanation),
|
||||||
|
);
|
||||||
// If available, use the scope span to annotate the drop location.
|
// If available, use the scope span to annotate the drop location.
|
||||||
|
let mut scope_note = None;
|
||||||
if let Some(scope_span) = scope_span {
|
if let Some(scope_span) = scope_span {
|
||||||
let scope_span = source_map.end_point(scope_span);
|
let scope_span = source_map.end_point(scope_span);
|
||||||
let is_overlapped =
|
|
||||||
yield_span.overlaps(scope_span) || yield_span.overlaps(interior_span);
|
let msg = format!("{} is later dropped here", snippet);
|
||||||
if is_overlapped {
|
if source_map.is_multiline(yield_span.between(scope_span)) {
|
||||||
span.push_span_label(
|
span.push_span_label(scope_span, msg);
|
||||||
yield_span,
|
|
||||||
format!(
|
|
||||||
"first, {} occurs here, with {} maybe used later...",
|
|
||||||
await_or_yield, snippet
|
|
||||||
),
|
|
||||||
);
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!(
|
|
||||||
"{} {} as this value is used across {}",
|
|
||||||
future_or_generator, trait_explanation, an_await_or_yield
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if source_map.is_multiline(interior_span) {
|
|
||||||
err.span_note(
|
|
||||||
scope_span,
|
|
||||||
&format!("{} is later dropped here", snippet),
|
|
||||||
);
|
|
||||||
err.span_note(
|
|
||||||
interior_span,
|
|
||||||
&format!(
|
|
||||||
"this has type `{}` which {}",
|
|
||||||
target_ty, trait_explanation
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
let mut span = MultiSpan::from_span(scope_span);
|
scope_note = Some((scope_span, msg));
|
||||||
span.push_span_label(
|
|
||||||
interior_span,
|
|
||||||
format!("has type `{}` which {}", target_ty, trait_explanation),
|
|
||||||
);
|
|
||||||
err.span_note(span, &format!("{} is later dropped here", snippet));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
span.push_span_label(
|
|
||||||
yield_span,
|
|
||||||
format!(
|
|
||||||
"{} occurs here, with {} maybe used later",
|
|
||||||
await_or_yield, snippet
|
|
||||||
),
|
|
||||||
);
|
|
||||||
span.push_span_label(
|
|
||||||
scope_span,
|
|
||||||
format!("{} is later dropped here", snippet),
|
|
||||||
);
|
|
||||||
span.push_span_label(
|
|
||||||
interior_span,
|
|
||||||
format!("has type `{}` which {}", target_ty, trait_explanation),
|
|
||||||
);
|
|
||||||
err.span_note(
|
|
||||||
span,
|
|
||||||
&format!(
|
|
||||||
"{} {} as this value is used across {}",
|
|
||||||
future_or_generator, trait_explanation, an_await_or_yield
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
span.push_span_label(
|
|
||||||
yield_span,
|
|
||||||
format!(
|
|
||||||
"{} occurs here, with {} maybe used later",
|
|
||||||
await_or_yield, snippet
|
|
||||||
),
|
|
||||||
);
|
|
||||||
span.push_span_label(
|
|
||||||
interior_span,
|
|
||||||
format!("has type `{}` which {}", target_ty, trait_explanation),
|
|
||||||
);
|
|
||||||
err.span_note(
|
err.span_note(
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
|
@ -1775,6 +1769,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
future_or_generator, trait_explanation, an_await_or_yield
|
future_or_generator, trait_explanation, an_await_or_yield
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
if let Some((span, msg)) = scope_note {
|
||||||
|
err.span_note(span, &msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1935,6 +1931,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
| ObligationCauseCode::ReturnType
|
| ObligationCauseCode::ReturnType
|
||||||
| ObligationCauseCode::ReturnValue(_)
|
| ObligationCauseCode::ReturnValue(_)
|
||||||
| ObligationCauseCode::BlockTailExpression(_)
|
| ObligationCauseCode::BlockTailExpression(_)
|
||||||
|
| ObligationCauseCode::AwaitableExpr(_)
|
||||||
|
| ObligationCauseCode::ForLoopIterator
|
||||||
|
| ObligationCauseCode::QuestionMark
|
||||||
| ObligationCauseCode::LetElse => {}
|
| ObligationCauseCode::LetElse => {}
|
||||||
ObligationCauseCode::SliceOrArrayElem => {
|
ObligationCauseCode::SliceOrArrayElem => {
|
||||||
err.note("slice and array elements must have `Sized` type");
|
err.note("slice and array elements must have `Sized` type");
|
||||||
|
|
|
@ -2340,7 +2340,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.map(|(ty, _, _)| ty)
|
.map(|(ty, _, _)| ty)
|
||||||
.unwrap_or_else(|_| tcx.ty_error())
|
.unwrap_or_else(|_| tcx.ty_error())
|
||||||
}
|
}
|
||||||
hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
|
hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
|
||||||
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
||||||
let (substs, _) = self.create_substs_for_ast_path(
|
let (substs, _) = self.create_substs_for_ast_path(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -277,8 +277,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
ExprKind::AddrOf(kind, mutbl, oprnd) => {
|
ExprKind::AddrOf(kind, mutbl, oprnd) => {
|
||||||
self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
|
self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
|
||||||
}
|
}
|
||||||
ExprKind::Path(QPath::LangItem(lang_item, _)) => {
|
ExprKind::Path(QPath::LangItem(lang_item, _, hir_id)) => {
|
||||||
self.check_lang_item_path(lang_item, expr)
|
self.check_lang_item_path(lang_item, expr, hir_id)
|
||||||
}
|
}
|
||||||
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]),
|
ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr, &[]),
|
||||||
ExprKind::InlineAsm(asm) => self.check_expr_asm(asm),
|
ExprKind::InlineAsm(asm) => self.check_expr_asm(asm),
|
||||||
|
@ -498,8 +498,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
hir_id: Option<hir::HirId>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id).1
|
self.resolve_lang_item_path(lang_item, expr.span, expr.hir_id, hir_id).1
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn check_expr_path(
|
pub(crate) fn check_expr_path(
|
||||||
|
|
|
@ -791,6 +791,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
lang_item: hir::LangItem,
|
lang_item: hir::LangItem,
|
||||||
span: Span,
|
span: Span,
|
||||||
hir_id: hir::HirId,
|
hir_id: hir::HirId,
|
||||||
|
expr_hir_id: Option<hir::HirId>,
|
||||||
) -> (Res, Ty<'tcx>) {
|
) -> (Res, Ty<'tcx>) {
|
||||||
let def_id = self.tcx.require_lang_item(lang_item, Some(span));
|
let def_id = self.tcx.require_lang_item(lang_item, Some(span));
|
||||||
let def_kind = self.tcx.def_kind(def_id);
|
let def_kind = self.tcx.def_kind(def_id);
|
||||||
|
@ -804,7 +805,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let ty = item_ty.subst(self.tcx, substs);
|
let ty = item_ty.subst(self.tcx, substs);
|
||||||
|
|
||||||
self.write_resolution(hir_id, Ok((def_kind, def_id)));
|
self.write_resolution(hir_id, Ok((def_kind, def_id)));
|
||||||
self.add_required_obligations(span, def_id, &substs);
|
self.add_required_obligations_with_code(
|
||||||
|
span,
|
||||||
|
def_id,
|
||||||
|
&substs,
|
||||||
|
match lang_item {
|
||||||
|
hir::LangItem::IntoFutureIntoFuture => {
|
||||||
|
ObligationCauseCode::AwaitableExpr(expr_hir_id)
|
||||||
|
}
|
||||||
|
hir::LangItem::IteratorNext | hir::LangItem::IntoIterIntoIter => {
|
||||||
|
ObligationCauseCode::ForLoopIterator
|
||||||
|
}
|
||||||
|
hir::LangItem::TryTraitFromOutput
|
||||||
|
| hir::LangItem::TryTraitFromResidual
|
||||||
|
| hir::LangItem::TryTraitBranch => ObligationCauseCode::QuestionMark,
|
||||||
|
_ => traits::ItemObligation(def_id),
|
||||||
|
},
|
||||||
|
);
|
||||||
(Res::Def(def_kind, def_id), ty)
|
(Res::Def(def_kind, def_id), ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1486,12 +1503,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add all the obligations that are required, substituting and normalized appropriately.
|
/// Add all the obligations that are required, substituting and normalized appropriately.
|
||||||
#[tracing::instrument(level = "debug", skip(self, span, def_id, substs))]
|
|
||||||
crate fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
|
crate fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
|
||||||
|
self.add_required_obligations_with_code(
|
||||||
|
span,
|
||||||
|
def_id,
|
||||||
|
substs,
|
||||||
|
traits::ItemObligation(def_id),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(self, span, def_id, substs))]
|
||||||
|
fn add_required_obligations_with_code(
|
||||||
|
&self,
|
||||||
|
span: Span,
|
||||||
|
def_id: DefId,
|
||||||
|
substs: &SubstsRef<'tcx>,
|
||||||
|
code: ObligationCauseCode<'tcx>,
|
||||||
|
) {
|
||||||
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
|
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
|
||||||
|
|
||||||
for obligation in traits::predicates_for_generics(
|
for obligation in traits::predicates_for_generics(
|
||||||
traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
|
traits::ObligationCause::new(span, self.body_id, code),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
bounds,
|
bounds,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -938,8 +938,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
(result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
|
(result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
|
||||||
}
|
}
|
||||||
QPath::LangItem(lang_item, span) => {
|
QPath::LangItem(lang_item, span, id) => {
|
||||||
self.resolve_lang_item_path(lang_item, span, hir_id)
|
self.resolve_lang_item_path(lang_item, span, hir_id, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,15 +115,14 @@ use crate::ops::ControlFlow;
|
||||||
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
on(
|
on(
|
||||||
all(from_method = "from_output", from_desugaring = "TryBlock"),
|
all(from_desugaring = "TryBlock"),
|
||||||
message = "a `try` block must return `Result` or `Option` \
|
message = "a `try` block must return `Result` or `Option` \
|
||||||
(or another type that implements `{Try}`)",
|
(or another type that implements `{Try}`)",
|
||||||
label = "could not wrap the final value of the block as `{Self}` doesn't implement `Try`",
|
label = "could not wrap the final value of the block as `{Self}` doesn't implement `Try`",
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
all(from_method = "branch", from_desugaring = "QuestionMark"),
|
all(from_desugaring = "QuestionMark"),
|
||||||
message = "the `?` operator can only be applied to values \
|
message = "the `?` operator can only be applied to values that implement `{Try}`",
|
||||||
that implement `{Try}`",
|
|
||||||
label = "the `?` operator cannot be applied to type `{Self}`"
|
label = "the `?` operator cannot be applied to type `{Self}`"
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
|
@ -226,7 +225,6 @@ pub trait Try: FromResidual {
|
||||||
#[rustc_on_unimplemented(
|
#[rustc_on_unimplemented(
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
_Self = "std::result::Result<T, E>",
|
_Self = "std::result::Result<T, E>",
|
||||||
R = "std::option::Option<std::convert::Infallible>"
|
R = "std::option::Option<std::convert::Infallible>"
|
||||||
|
@ -238,7 +236,6 @@ pub trait Try: FromResidual {
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
_Self = "std::result::Result<T, E>",
|
_Self = "std::result::Result<T, E>",
|
||||||
),
|
),
|
||||||
|
@ -252,7 +249,6 @@ pub trait Try: FromResidual {
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
_Self = "std::option::Option<T>",
|
_Self = "std::option::Option<T>",
|
||||||
R = "std::result::Result<T, E>",
|
R = "std::result::Result<T, E>",
|
||||||
|
@ -264,7 +260,6 @@ pub trait Try: FromResidual {
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
_Self = "std::option::Option<T>",
|
_Self = "std::option::Option<T>",
|
||||||
),
|
),
|
||||||
|
@ -277,7 +272,6 @@ pub trait Try: FromResidual {
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
_Self = "std::ops::ControlFlow<B, C>",
|
_Self = "std::ops::ControlFlow<B, C>",
|
||||||
R = "std::ops::ControlFlow<B, C>",
|
R = "std::ops::ControlFlow<B, C>",
|
||||||
|
@ -290,7 +284,6 @@ pub trait Try: FromResidual {
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
all(
|
all(
|
||||||
from_method = "from_residual",
|
|
||||||
from_desugaring = "QuestionMark",
|
from_desugaring = "QuestionMark",
|
||||||
_Self = "std::ops::ControlFlow<B, C>",
|
_Self = "std::ops::ControlFlow<B, C>",
|
||||||
// `R` is not a `ControlFlow`, as that case was matched previously
|
// `R` is not a `ControlFlow`, as that case was matched previously
|
||||||
|
@ -301,10 +294,7 @@ pub trait Try: FromResidual {
|
||||||
enclosing_scope = "this function returns a `ControlFlow`",
|
enclosing_scope = "this function returns a `ControlFlow`",
|
||||||
),
|
),
|
||||||
on(
|
on(
|
||||||
all(
|
all(from_desugaring = "QuestionMark"),
|
||||||
from_method = "from_residual",
|
|
||||||
from_desugaring = "QuestionMark"
|
|
||||||
),
|
|
||||||
message = "the `?` operator can only be used in {ItemContext} \
|
message = "the `?` operator can only be used in {ItemContext} \
|
||||||
that returns `Result` or `Option` \
|
that returns `Result` or `Option` \
|
||||||
(or another type that implements `{FromResidual}`)",
|
(or another type that implements `{FromResidual}`)",
|
||||||
|
|
|
@ -41,9 +41,9 @@
|
||||||
41| 1| // executed asynchronously.
|
41| 1| // executed asynchronously.
|
||||||
42| 1| match x {
|
42| 1| match x {
|
||||||
43| 1| y if c(x).await == y + 1 => { d().await; }
|
43| 1| y if c(x).await == y + 1 => { d().await; }
|
||||||
^0 ^0
|
^0 ^0 ^0 ^0
|
||||||
44| 1| y if f().await == y + 1 => (),
|
44| 1| y if f().await == y + 1 => (),
|
||||||
^0 ^0
|
^0 ^0 ^0
|
||||||
45| 1| _ => (),
|
45| 1| _ => (),
|
||||||
46| | }
|
46| | }
|
||||||
47| 1|}
|
47| 1|}
|
||||||
|
|
|
@ -14,10 +14,10 @@ LL | let a;
|
||||||
| ^ cannot infer type
|
| ^ cannot infer type
|
||||||
|
|
|
|
||||||
note: the type is part of the `async fn` body because of this `await`
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
--> $DIR/async-error-span.rs:14:5
|
--> $DIR/async-error-span.rs:14:17
|
||||||
|
|
|
|
||||||
LL | get_future().await;
|
LL | get_future().await;
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,13 @@ LL | assert_send(local_dropped_before_await());
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/async-fn-nonsend.rs:24:5
|
--> $DIR/async-fn-nonsend.rs:24:10
|
||||||
|
|
|
|
||||||
LL | let x = non_send();
|
LL | let x = non_send();
|
||||||
| - has type `impl Debug` which is not `Send`
|
| - has type `impl Debug` which is not `Send`
|
||||||
LL | drop(x);
|
LL | drop(x);
|
||||||
LL | fut().await;
|
LL | fut().await;
|
||||||
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later
|
| ^^^^^^ await occurs here, with `x` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` is later dropped here
|
| - `x` is later dropped here
|
||||||
note: required by a bound in `assert_send`
|
note: required by a bound in `assert_send`
|
||||||
|
@ -29,12 +29,12 @@ LL | assert_send(non_send_temporary_in_match());
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/async-fn-nonsend.rs:33:20
|
--> $DIR/async-fn-nonsend.rs:33:25
|
||||||
|
|
|
|
||||||
LL | match Some(non_send()) {
|
LL | match Some(non_send()) {
|
||||||
| ---------- has type `impl Debug` which is not `Send`
|
| ---------- has type `impl Debug` which is not `Send`
|
||||||
LL | Some(_) => fut().await,
|
LL | Some(_) => fut().await,
|
||||||
| ^^^^^^^^^^^ await occurs here, with `non_send()` maybe used later
|
| ^^^^^^ await occurs here, with `non_send()` maybe used later
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `non_send()` is later dropped here
|
| - `non_send()` is later dropped here
|
||||||
|
@ -52,13 +52,13 @@ LL | assert_send(non_sync_with_method_call());
|
||||||
|
|
|
|
||||||
= help: the trait `Send` is not implemented for `dyn std::fmt::Write`
|
= help: the trait `Send` is not implemented for `dyn std::fmt::Write`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/async-fn-nonsend.rs:42:9
|
--> $DIR/async-fn-nonsend.rs:42:14
|
||||||
|
|
|
|
||||||
LL | let f: &mut std::fmt::Formatter = panic!();
|
LL | let f: &mut std::fmt::Formatter = panic!();
|
||||||
| - has type `&mut Formatter<'_>` which is not `Send`
|
| - has type `&mut Formatter<'_>` which is not `Send`
|
||||||
LL | if non_sync().fmt(f).unwrap() == () {
|
LL | if non_sync().fmt(f).unwrap() == () {
|
||||||
LL | fut().await;
|
LL | fut().await;
|
||||||
| ^^^^^^^^^^^ await occurs here, with `f` maybe used later
|
| ^^^^^^ await occurs here, with `f` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
LL | }
|
LL | }
|
||||||
| - `f` is later dropped here
|
| - `f` is later dropped here
|
||||||
|
|
|
@ -162,68 +162,68 @@ LL | let _ = (await bar())?;
|
||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:71:13
|
--> $DIR/incorrect-syntax-suggestions.rs:71:18
|
||||||
|
|
|
|
||||||
LL | fn foo13() -> Result<(), ()> {
|
LL | fn foo13() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
LL | let _ = bar().await();
|
LL | let _ = bar().await();
|
||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:76:13
|
--> $DIR/incorrect-syntax-suggestions.rs:76:18
|
||||||
|
|
|
|
||||||
LL | fn foo14() -> Result<(), ()> {
|
LL | fn foo14() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
LL | let _ = bar().await()?;
|
LL | let _ = bar().await()?;
|
||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:81:13
|
--> $DIR/incorrect-syntax-suggestions.rs:81:18
|
||||||
|
|
|
|
||||||
LL | fn foo15() -> Result<(), ()> {
|
LL | fn foo15() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
LL | let _ = bar().await;
|
LL | let _ = bar().await;
|
||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:85:13
|
--> $DIR/incorrect-syntax-suggestions.rs:85:18
|
||||||
|
|
|
|
||||||
LL | fn foo16() -> Result<(), ()> {
|
LL | fn foo16() -> Result<(), ()> {
|
||||||
| ----- this is not `async`
|
| ----- this is not `async`
|
||||||
LL | let _ = bar().await?;
|
LL | let _ = bar().await?;
|
||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:90:17
|
--> $DIR/incorrect-syntax-suggestions.rs:90:22
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Result<(), ()> {
|
LL | fn foo() -> Result<(), ()> {
|
||||||
| --- this is not `async`
|
| --- this is not `async`
|
||||||
LL | let _ = bar().await?;
|
LL | let _ = bar().await?;
|
||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:97:17
|
--> $DIR/incorrect-syntax-suggestions.rs:97:22
|
||||||
|
|
|
|
||||||
LL | let foo = || {
|
LL | let foo = || {
|
||||||
| -- this is not `async`
|
| -- this is not `async`
|
||||||
LL | let _ = bar().await?;
|
LL | let _ = bar().await?;
|
||||||
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:113:17
|
--> $DIR/incorrect-syntax-suggestions.rs:113:29
|
||||||
|
|
|
|
||||||
LL | fn foo() -> Result<(), ()> {
|
LL | fn foo() -> Result<(), ()> {
|
||||||
| --- this is not `async`
|
| --- this is not `async`
|
||||||
LL | let _ = await!(bar())?;
|
LL | let _ = await!(bar())?;
|
||||||
| ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/incorrect-syntax-suggestions.rs:121:17
|
--> $DIR/incorrect-syntax-suggestions.rs:121:29
|
||||||
|
|
|
|
||||||
LL | let foo = || {
|
LL | let foo = || {
|
||||||
| -- this is not `async`
|
| -- this is not `async`
|
||||||
LL | let _ = await!(bar())?;
|
LL | let _ = await!(bar())?;
|
||||||
| ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error: aborting due to 33 previous errors
|
error: aborting due to 33 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@ LL | is_sync(bar());
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
|
= help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
|
||||||
note: future is not `Sync` as this value is used across an await
|
note: future is not `Sync` as this value is used across an await
|
||||||
--> $DIR/issue-64130-1-sync.rs:15:5
|
--> $DIR/issue-64130-1-sync.rs:15:10
|
||||||
|
|
|
|
||||||
LL | let x = Foo;
|
LL | let x = Foo;
|
||||||
| - has type `Foo` which is not `Sync`
|
| - has type `Foo` which is not `Sync`
|
||||||
LL | baz().await;
|
LL | baz().await;
|
||||||
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later
|
| ^^^^^^ await occurs here, with `x` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` is later dropped here
|
| - `x` is later dropped here
|
||||||
note: required by a bound in `is_sync`
|
note: required by a bound in `is_sync`
|
||||||
|
|
|
@ -6,12 +6,12 @@ LL | is_send(bar());
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Foo`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Foo`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-64130-2-send.rs:15:5
|
--> $DIR/issue-64130-2-send.rs:15:10
|
||||||
|
|
|
|
||||||
LL | let x = Foo;
|
LL | let x = Foo;
|
||||||
| - has type `Foo` which is not `Send`
|
| - has type `Foo` which is not `Send`
|
||||||
LL | baz().await;
|
LL | baz().await;
|
||||||
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later
|
| ^^^^^^ await occurs here, with `x` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` is later dropped here
|
| - `x` is later dropped here
|
||||||
note: required by a bound in `is_send`
|
note: required by a bound in `is_send`
|
||||||
|
|
|
@ -8,12 +8,12 @@ LL | is_qux(bar());
|
||||||
| ^^^^^ within `impl Future<Output = ()>`, the trait `Qux` is not implemented for `Foo`
|
| ^^^^^ within `impl Future<Output = ()>`, the trait `Qux` is not implemented for `Foo`
|
||||||
|
|
|
|
||||||
note: future does not implement `Qux` as this value is used across an await
|
note: future does not implement `Qux` as this value is used across an await
|
||||||
--> $DIR/issue-64130-3-other.rs:18:5
|
--> $DIR/issue-64130-3-other.rs:18:10
|
||||||
|
|
|
|
||||||
LL | let x = Foo;
|
LL | let x = Foo;
|
||||||
| - has type `Foo` which does not implement `Qux`
|
| - has type `Foo` which does not implement `Qux`
|
||||||
LL | baz().await;
|
LL | baz().await;
|
||||||
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later
|
| ^^^^^^ await occurs here, with `x` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` is later dropped here
|
| - `x` is later dropped here
|
||||||
note: required by a bound in `is_qux`
|
note: required by a bound in `is_qux`
|
||||||
|
|
|
@ -6,13 +6,13 @@ LL | pub fn foo() -> impl Future + Send {
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
|
= help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-64130-4-async-move.rs:21:26
|
--> $DIR/issue-64130-4-async-move.rs:21:31
|
||||||
|
|
|
|
||||||
LL | match client.status() {
|
LL | match client.status() {
|
||||||
| ------ has type `&Client` which is not `Send`
|
| ------ has type `&Client` which is not `Send`
|
||||||
LL | 200 => {
|
LL | 200 => {
|
||||||
LL | let _x = get().await;
|
LL | let _x = get().await;
|
||||||
| ^^^^^^^^^^^ await occurs here, with `client` maybe used later
|
| ^^^^^^ await occurs here, with `client` maybe used later
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `client` is later dropped here
|
| - `client` is later dropped here
|
||||||
|
|
|
@ -6,12 +6,12 @@ LL | is_send(foo());
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-64130-non-send-future-diags.rs:17:5
|
--> $DIR/issue-64130-non-send-future-diags.rs:17:10
|
||||||
|
|
|
|
||||||
LL | let g = x.lock().unwrap();
|
LL | let g = x.lock().unwrap();
|
||||||
| - has type `MutexGuard<'_, u32>` which is not `Send`
|
| - has type `MutexGuard<'_, u32>` which is not `Send`
|
||||||
LL | baz().await;
|
LL | baz().await;
|
||||||
| ^^^^^^^^^^^ await occurs here, with `g` maybe used later
|
| ^^^^^^ await occurs here, with `g` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `g` is later dropped here
|
| - `g` is later dropped here
|
||||||
note: required by a bound in `is_send`
|
note: required by a bound in `is_send`
|
||||||
|
|
|
@ -6,12 +6,12 @@ LL | spawn(async {
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*mut ()`
|
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*mut ()`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-67252-unnamed-future.rs:20:9
|
--> $DIR/issue-67252-unnamed-future.rs:20:16
|
||||||
|
|
|
|
||||||
LL | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
|
LL | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
|
||||||
| -- has type `*mut ()` which is not `Send`
|
| -- has type `*mut ()` which is not `Send`
|
||||||
LL | AFuture.await;
|
LL | AFuture.await;
|
||||||
| ^^^^^^^^^^^^^ await occurs here, with `_a` maybe used later
|
| ^^^^^^ await occurs here, with `_a` maybe used later
|
||||||
LL | });
|
LL | });
|
||||||
| - `_a` is later dropped here
|
| - `_a` is later dropped here
|
||||||
note: required by a bound in `spawn`
|
note: required by a bound in `spawn`
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-70594.rs:4:9
|
--> $DIR/issue-70594.rs:4:11
|
||||||
|
|
|
|
||||||
LL | async fn fun() {
|
LL | async fn fun() {
|
||||||
| --- this is not `async`
|
| --- this is not `async`
|
||||||
LL | [1; ().await];
|
LL | [1; ().await];
|
||||||
| ^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0744]: `.await` is not allowed in a `const`
|
error[E0744]: `.await` is not allowed in a `const`
|
||||||
--> $DIR/issue-70594.rs:4:9
|
--> $DIR/issue-70594.rs:4:9
|
||||||
|
@ -13,20 +13,25 @@ LL | [1; ().await];
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
error[E0744]: `.await` is not allowed in a `const`
|
error[E0744]: `.await` is not allowed in a `const`
|
||||||
--> $DIR/issue-70594.rs:4:9
|
--> $DIR/issue-70594.rs:4:11
|
||||||
|
|
|
|
||||||
LL | [1; ().await];
|
LL | [1; ().await];
|
||||||
| ^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error[E0277]: `()` is not a future
|
error[E0277]: `()` is not a future
|
||||||
--> $DIR/issue-70594.rs:4:9
|
--> $DIR/issue-70594.rs:4:11
|
||||||
|
|
|
|
||||||
LL | [1; ().await];
|
LL | [1; ().await];
|
||||||
| ^^^^^^^^ `()` is not a future
|
| ^^^^^^ `()` is not a future
|
||||||
|
|
|
|
||||||
= help: the trait `Future` is not implemented for `()`
|
= help: the trait `Future` is not implemented for `()`
|
||||||
= note: () must be a future or must implement `IntoFuture` to be awaited
|
= note: () must be a future or must implement `IntoFuture` to be awaited
|
||||||
= note: required because of the requirements on the impl of `IntoFuture` for `()`
|
= note: required because of the requirements on the impl of `IntoFuture` for `()`
|
||||||
|
help: remove the `.await`
|
||||||
|
|
|
||||||
|
LL - [1; ().await];
|
||||||
|
LL + [1; ()];
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -6,25 +6,20 @@ LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
|
||||||
|
|
|
|
||||||
= help: the trait `Sync` is not implemented for `Sender<i32>`
|
= help: the trait `Sync` is not implemented for `Sender<i32>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-70935-complex-spans.rs:13:9
|
--> $DIR/issue-70935-complex-spans.rs:15:11
|
||||||
|
|
|
|
||||||
LL | / baz(|| async{
|
LL | baz(|| async{
|
||||||
|
| _____________-
|
||||||
LL | | foo(tx.clone());
|
LL | | foo(tx.clone());
|
||||||
LL | | }).await;
|
LL | | }).await;
|
||||||
| |________________^ first, await occurs here, with the value maybe used later...
|
| | - ^^^^^^ await occurs here, with the value maybe used later
|
||||||
|
| |_________|
|
||||||
|
| has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send`
|
||||||
note: the value is later dropped here
|
note: the value is later dropped here
|
||||||
--> $DIR/issue-70935-complex-spans.rs:15:17
|
--> $DIR/issue-70935-complex-spans.rs:15:17
|
||||||
|
|
|
|
||||||
LL | }).await;
|
LL | }).await;
|
||||||
| ^
|
| ^
|
||||||
note: this has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send`
|
|
||||||
--> $DIR/issue-70935-complex-spans.rs:13:13
|
|
||||||
|
|
|
||||||
LL | baz(|| async{
|
|
||||||
| _____________^
|
|
||||||
LL | | foo(tx.clone());
|
|
||||||
LL | | }).await;
|
|
||||||
| |_________^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@ LL | fake_spawn(wrong_mutex());
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-71137.rs:14:5
|
--> $DIR/issue-71137.rs:14:25
|
||||||
|
|
|
|
||||||
LL | let mut guard = m.lock().unwrap();
|
LL | let mut guard = m.lock().unwrap();
|
||||||
| --------- has type `MutexGuard<'_, i32>` which is not `Send`
|
| --------- has type `MutexGuard<'_, i32>` which is not `Send`
|
||||||
LL | (async { "right"; }).await;
|
LL | (async { "right"; }).await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `mut guard` maybe used later
|
| ^^^^^^ await occurs here, with `mut guard` maybe used later
|
||||||
LL | *guard += 1;
|
LL | *guard += 1;
|
||||||
LL | }
|
LL | }
|
||||||
| - `mut guard` is later dropped here
|
| - `mut guard` is later dropped here
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-51719.rs:8:19
|
--> $DIR/issue-51719.rs:8:24
|
||||||
|
|
|
|
||||||
LL | let _gen = || foo().await;
|
LL | let _gen = || foo().await;
|
||||||
| -- ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| -- ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
| |
|
| |
|
||||||
| this is not `async`
|
| this is not `async`
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-51751.rs:9:20
|
--> $DIR/issue-51751.rs:9:26
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ---- this is not `async`
|
| ---- this is not `async`
|
||||||
LL | let result = inc(10000);
|
LL | let result = inc(10000);
|
||||||
LL | let finished = result.await;
|
LL | let finished = result.await;
|
||||||
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ fn main() {
|
||||||
async { let (); }.await;
|
async { let (); }.await;
|
||||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||||
async {
|
async {
|
||||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
|
||||||
let task1 = print_dur().await;
|
let task1 = print_dur().await;
|
||||||
}.await;
|
}.await;
|
||||||
|
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||||
(|_| 2333).await;
|
(|_| 2333).await;
|
||||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||||
//~^^ ERROR
|
//~| ERROR is not a future
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,43 @@
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-62009-1.rs:6:5
|
--> $DIR/issue-62009-1.rs:6:22
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ---- this is not `async`
|
| ---- this is not `async`
|
||||||
LL | async { let (); }.await;
|
LL | async { let (); }.await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-62009-1.rs:8:5
|
--> $DIR/issue-62009-1.rs:10:6
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ---- this is not `async`
|
| ---- this is not `async`
|
||||||
...
|
...
|
||||||
LL | / async {
|
LL | }.await;
|
||||||
LL | |
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
LL | | let task1 = print_dur().await;
|
|
||||||
LL | | }.await;
|
|
||||||
| |___________^ only allowed inside `async` functions and blocks
|
|
||||||
|
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-62009-1.rs:12:5
|
--> $DIR/issue-62009-1.rs:12:15
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ---- this is not `async`
|
| ---- this is not `async`
|
||||||
...
|
...
|
||||||
LL | (|_| 2333).await;
|
LL | (|_| 2333).await;
|
||||||
| ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
|
error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
|
||||||
--> $DIR/issue-62009-1.rs:12:5
|
--> $DIR/issue-62009-1.rs:12:15
|
||||||
|
|
|
|
||||||
LL | (|_| 2333).await;
|
LL | (|_| 2333).await;
|
||||||
| ^^^^^^^^^^^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
|
| ^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
|
||||||
|
|
|
|
||||||
= help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
|
= help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
|
||||||
= note: [closure@$DIR/issue-62009-1.rs:12:5: 12:15] must be a future or must implement `IntoFuture` to be awaited
|
= note: [closure@$DIR/issue-62009-1.rs:12:5: 12:15] must be a future or must implement `IntoFuture` to be awaited
|
||||||
= note: required because of the requirements on the impl of `IntoFuture` for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
|
= note: required because of the requirements on the impl of `IntoFuture` for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
|
||||||
|
help: remove the `.await`
|
||||||
|
|
|
||||||
|
LL - (|_| 2333).await;
|
||||||
|
LL + (|_| 2333);
|
||||||
|
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-62009-2.rs:8:5
|
--> $DIR/issue-62009-2.rs:8:22
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ---- this is not `async`
|
| ---- this is not `async`
|
||||||
LL | (async || 2333)().await;
|
LL | (async || 2333)().await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,17 @@ LL | assert_send(async {
|
||||||
|
|
|
|
||||||
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*const u8`
|
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*const u8`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:9
|
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:35
|
||||||
|
|
|
|
||||||
LL | bar(Foo(std::ptr::null())).await;
|
LL | bar(Foo(std::ptr::null())).await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first, await occurs here, with `std::ptr::null()` maybe used later...
|
| ---------------- ^^^^^^ await occurs here, with `std::ptr::null()` maybe used later
|
||||||
|
| |
|
||||||
|
| has type `*const u8` which is not `Send`
|
||||||
note: `std::ptr::null()` is later dropped here
|
note: `std::ptr::null()` is later dropped here
|
||||||
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:41
|
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:41
|
||||||
|
|
|
|
||||||
LL | bar(Foo(std::ptr::null())).await;
|
LL | bar(Foo(std::ptr::null())).await;
|
||||||
| ---------------- ^
|
| ^
|
||||||
| |
|
|
||||||
| has type `*const u8` which is not `Send`
|
|
||||||
help: consider moving this into a `let` binding to create a shorter lived borrow
|
help: consider moving this into a `let` binding to create a shorter lived borrow
|
||||||
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:13
|
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:13
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/non-async-enclosing-span.rs:9:13
|
--> $DIR/non-async-enclosing-span.rs:9:27
|
||||||
|
|
|
|
||||||
LL | fn main() {
|
LL | fn main() {
|
||||||
| ---- this is not `async`
|
| ---- this is not `async`
|
||||||
LL | let x = move || {};
|
LL | let x = move || {};
|
||||||
LL | let y = do_the_thing().await;
|
LL | let y = do_the_thing().await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
14
src/test/ui/async-await/unnecessary-await.rs
Normal file
14
src/test/ui/async-await/unnecessary-await.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// edition:2018
|
||||||
|
|
||||||
|
async fn foo () { }
|
||||||
|
fn bar() -> impl std::future::Future { async {} }
|
||||||
|
fn boo() {}
|
||||||
|
|
||||||
|
async fn baz() -> std::io::Result<()> {
|
||||||
|
foo().await;
|
||||||
|
boo().await; //~ ERROR `()` is not a future
|
||||||
|
bar().await;
|
||||||
|
std::io::Result::Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
24
src/test/ui/async-await/unnecessary-await.stderr
Normal file
24
src/test/ui/async-await/unnecessary-await.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
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 `()`
|
||||||
|
= note: () must be a future or must implement `IntoFuture` to be awaited
|
||||||
|
= note: required because of the requirements on the impl of `IntoFuture` for `()`
|
||||||
|
help: remove the `.await`
|
||||||
|
|
|
||||||
|
LL - boo().await;
|
||||||
|
LL + boo();
|
||||||
|
|
|
||||||
|
help: alternatively, consider making `fn boo` asynchronous
|
||||||
|
|
|
||||||
|
LL | async fn boo() {}
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
|
@ -5,10 +5,10 @@ LL | bar().await;
|
||||||
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
||||||
|
|
|
|
||||||
note: the type is part of the `async fn` body because of this `await`
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:10
|
||||||
|
|
|
|
||||||
LL | bar().await;
|
LL | bar().await;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error[E0698]: type inside `async fn` body must be known in this context
|
error[E0698]: type inside `async fn` body must be known in this context
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
@ -17,10 +17,10 @@ LL | bar().await;
|
||||||
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
||||||
|
|
|
|
||||||
note: the type is part of the `async fn` body because of this `await`
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:10
|
||||||
|
|
|
|
||||||
LL | bar().await;
|
LL | bar().await;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error[E0698]: type inside `async fn` body must be known in this context
|
error[E0698]: type inside `async fn` body must be known in this context
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
@ -29,10 +29,10 @@ LL | bar().await;
|
||||||
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
||||||
|
|
|
|
||||||
note: the type is part of the `async fn` body because of this `await`
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:10
|
||||||
|
|
|
|
||||||
LL | bar().await;
|
LL | bar().await;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error[E0698]: type inside `async fn` body must be known in this context
|
error[E0698]: type inside `async fn` body must be known in this context
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
@ -41,10 +41,10 @@ LL | bar().await;
|
||||||
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
||||||
|
|
|
|
||||||
note: the type is part of the `async fn` body because of this `await`
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:10
|
||||||
|
|
|
|
||||||
LL | bar().await;
|
LL | bar().await;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error[E0698]: type inside `async fn` body must be known in this context
|
error[E0698]: type inside `async fn` body must be known in this context
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:5
|
||||||
|
@ -53,10 +53,10 @@ LL | bar().await;
|
||||||
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
| ^^^ cannot infer type for type parameter `T` declared on the function `bar`
|
||||||
|
|
|
|
||||||
note: the type is part of the `async fn` body because of this `await`
|
note: the type is part of the `async fn` body because of this `await`
|
||||||
--> $DIR/unresolved_type_param.rs:9:5
|
--> $DIR/unresolved_type_param.rs:9:10
|
||||||
|
|
|
|
||||||
LL | bar().await;
|
LL | bar().await;
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _,
|
||||||
--> $DIR/issue-33941.rs:4:14
|
--> $DIR/issue-33941.rs:4:14
|
||||||
|
|
|
|
||||||
LL | for _ in HashMap::new().iter().cloned() {}
|
LL | for _ in HashMap::new().iter().cloned() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found tuple
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
|
||||||
|
|
|
|
||||||
= note: expected reference `&_`
|
= note: expected tuple `(&_, &_)`
|
||||||
found tuple `(&_, &_)`
|
found reference `&_`
|
||||||
= note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
|
= note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
|
||||||
= note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
|
= note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: boxed `Umm` held across a suspend point, but should not be
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/boxed.rs:3:9
|
--> $DIR/boxed.rs:3:9
|
||||||
|
|
|
@ -2,7 +2,7 @@ error: `No` held across a suspend point, but should not be
|
||||||
--> $DIR/dedup.rs:16:12
|
--> $DIR/dedup.rs:16:12
|
||||||
|
|
|
|
||||||
LL | wheeee(No {}).await;
|
LL | wheeee(No {}).await;
|
||||||
| -------^^^^^------- the value is held across this suspend point
|
| ^^^^^ ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/dedup.rs:3:9
|
--> $DIR/dedup.rs:3:9
|
||||||
|
|
|
@ -31,7 +31,7 @@ error: `MutexGuard` held across a suspend point, but should not be
|
||||||
LL | let _guard = m.lock().unwrap();
|
LL | let _guard = m.lock().unwrap();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/gated.rs:2:9
|
--> $DIR/gated.rs:2:9
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: `MutexGuard` held across a suspend point, but should not be
|
||||||
LL | let _guard = m.lock().unwrap();
|
LL | let _guard = m.lock().unwrap();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/mutex.rs:3:9
|
--> $DIR/mutex.rs:3:9
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | let guard = &mut self.u;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL |
|
LL |
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/ref.rs:3:9
|
--> $DIR/ref.rs:3:9
|
||||||
|
|
|
@ -5,7 +5,7 @@ LL | let _guard1 = r#impl();
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
...
|
...
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/trait.rs:3:9
|
--> $DIR/trait.rs:3:9
|
||||||
|
@ -25,7 +25,7 @@ LL | let _guard2 = r#dyn();
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
LL |
|
LL |
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
|
||||||
--> $DIR/trait.rs:22:9
|
--> $DIR/trait.rs:22:9
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: `Umm` held across a suspend point, but should not be
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/unit.rs:3:9
|
--> $DIR/unit.rs:3:9
|
||||||
|
|
|
@ -4,7 +4,7 @@ warning: `Umm` held across a suspend point, but should not be
|
||||||
LL | let _guard = bar();
|
LL | let _guard = bar();
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
LL | other().await;
|
LL | other().await;
|
||||||
| ------------- the value is held across this suspend point
|
| ------ the value is held across this suspend point
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/warn.rs:4:9
|
--> $DIR/warn.rs:4:9
|
||||||
|
|
|
@ -204,7 +204,7 @@ fn parse_iter_usage(
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ExprKind::Call(
|
ExprKind::Call(
|
||||||
Expr {
|
Expr {
|
||||||
kind: ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, _)),
|
kind: ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)),
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
_,
|
_,
|
||||||
|
|
|
@ -73,7 +73,7 @@ fn contains_assign_expr<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) ->
|
||||||
seen
|
seen
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
struct LocalAssign {
|
struct LocalAssign {
|
||||||
lhs_id: HirId,
|
lhs_id: HirId,
|
||||||
lhs_span: Span,
|
lhs_span: Span,
|
||||||
|
@ -154,9 +154,14 @@ fn assignment_suggestions<'tcx>(
|
||||||
assignments.push(assign);
|
assignments.push(assign);
|
||||||
}
|
}
|
||||||
|
|
||||||
let suggestions = assignments
|
let suggestions = assignments.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|assignment| Some((assignment.span, snippet_opt(cx, assignment.rhs_span)?)))
|
.map(|assignment| Some((assignment.span.until(assignment.rhs_span), String::new())))
|
||||||
|
.chain(
|
||||||
|
assignments
|
||||||
|
.into_iter()
|
||||||
|
.map(|assignment| Some((assignment.rhs_span.shrink_to_hi().with_hi(assignment.span.hi()), String::new())))
|
||||||
|
)
|
||||||
.collect::<Option<Vec<(Span, String)>>>()?;
|
.collect::<Option<Vec<(Span, String)>>>()?;
|
||||||
|
|
||||||
let applicability = if suggestions.len() > 1 {
|
let applicability = if suggestions.len() > 1 {
|
||||||
|
|
|
@ -105,7 +105,7 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
};
|
};
|
||||||
if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar) = &arg.kind;
|
if let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar) = &arg.kind;
|
||||||
if let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind;
|
if let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind;
|
||||||
if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, _)) = &called.kind;
|
if let ExprKind::Path(QPath::LangItem(LangItem::TryTraitBranch, ..)) = &called.kind;
|
||||||
if expr.span.ctxt() == inner_expr.span.ctxt();
|
if expr.span.ctxt() == inner_expr.span.ctxt();
|
||||||
let expr_ty = cx.typeck_results().expr_ty(expr);
|
let expr_ty = cx.typeck_results().expr_ty(expr);
|
||||||
let inner_ty = cx.typeck_results().expr_ty(inner_expr);
|
let inner_ty = cx.typeck_results().expr_ty(inner_expr);
|
||||||
|
|
|
@ -260,7 +260,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
|
||||||
if method_names[0] == sym!(as_bytes);
|
if method_names[0] == sym!(as_bytes);
|
||||||
|
|
||||||
// Check for slicer
|
// Check for slicer
|
||||||
if let ExprKind::Struct(QPath::LangItem(LangItem::Range, _), _, _) = right.kind;
|
if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), _, _) = right.kind;
|
||||||
|
|
||||||
then {
|
then {
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for TryErr {
|
||||||
if let ExprKind::Match(match_arg, _, MatchSource::TryDesugar) = expr.kind;
|
if let ExprKind::Match(match_arg, _, MatchSource::TryDesugar) = expr.kind;
|
||||||
if let ExprKind::Call(match_fun, try_args) = match_arg.kind;
|
if let ExprKind::Call(match_fun, try_args) = match_arg.kind;
|
||||||
if let ExprKind::Path(ref match_fun_path) = match_fun.kind;
|
if let ExprKind::Path(ref match_fun_path) = match_fun.kind;
|
||||||
if matches!(match_fun_path, QPath::LangItem(LangItem::TryTraitBranch, _));
|
if matches!(match_fun_path, QPath::LangItem(LangItem::TryTraitBranch, ..));
|
||||||
if let Some(try_arg) = try_args.get(0);
|
if let Some(try_arg) = try_args.get(0);
|
||||||
if let ExprKind::Call(err_fun, err_args) = try_arg.kind;
|
if let ExprKind::Call(err_fun, err_args) = try_arg.kind;
|
||||||
if let Some(err_arg) = err_args.get(0);
|
if let Some(err_arg) = err_args.get(0);
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
|
||||||
if let hir::ExprKind::Call(func, [ref arg_0, ..]) = res.kind {
|
if let hir::ExprKind::Call(func, [ref arg_0, ..]) = res.kind {
|
||||||
if matches!(
|
if matches!(
|
||||||
func.kind,
|
func.kind,
|
||||||
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, _))
|
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
|
||||||
) {
|
) {
|
||||||
check_map_error(cx, arg_0, expr);
|
check_map_error(cx, arg_0, expr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qpath(&self, qpath: &Binding<&QPath<'_>>) {
|
fn qpath(&self, qpath: &Binding<&QPath<'_>>) {
|
||||||
if let QPath::LangItem(lang_item, _) = *qpath.value {
|
if let QPath::LangItem(lang_item, ..) = *qpath.value {
|
||||||
out!("if matches!({qpath}, QPath::LangItem(LangItem::{lang_item:?}, _));");
|
out!("if matches!({qpath}, QPath::LangItem(LangItem::{lang_item:?}, _));");
|
||||||
} else {
|
} else {
|
||||||
out!("if match_qpath({qpath}, &[{}]);", path_to_string(qpath.value));
|
out!("if match_qpath({qpath}, &[{}]);", path_to_string(qpath.value));
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl<'a> Range<'a> {
|
||||||
hir::ExprKind::Call(path, args)
|
hir::ExprKind::Call(path, args)
|
||||||
if matches!(
|
if matches!(
|
||||||
path.kind,
|
path.kind,
|
||||||
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, _))
|
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, ..))
|
||||||
) =>
|
) =>
|
||||||
{
|
{
|
||||||
Some(Range {
|
Some(Range {
|
||||||
|
@ -228,27 +228,27 @@ impl<'a> Range<'a> {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
hir::ExprKind::Struct(path, fields, None) => match &path {
|
hir::ExprKind::Struct(path, fields, None) => match &path {
|
||||||
hir::QPath::LangItem(hir::LangItem::RangeFull, _) => Some(Range {
|
hir::QPath::LangItem(hir::LangItem::RangeFull, ..) => Some(Range {
|
||||||
start: None,
|
start: None,
|
||||||
end: None,
|
end: None,
|
||||||
limits: ast::RangeLimits::HalfOpen,
|
limits: ast::RangeLimits::HalfOpen,
|
||||||
}),
|
}),
|
||||||
hir::QPath::LangItem(hir::LangItem::RangeFrom, _) => Some(Range {
|
hir::QPath::LangItem(hir::LangItem::RangeFrom, ..) => Some(Range {
|
||||||
start: Some(get_field("start", fields)?),
|
start: Some(get_field("start", fields)?),
|
||||||
end: None,
|
end: None,
|
||||||
limits: ast::RangeLimits::HalfOpen,
|
limits: ast::RangeLimits::HalfOpen,
|
||||||
}),
|
}),
|
||||||
hir::QPath::LangItem(hir::LangItem::Range, _) => Some(Range {
|
hir::QPath::LangItem(hir::LangItem::Range, ..) => Some(Range {
|
||||||
start: Some(get_field("start", fields)?),
|
start: Some(get_field("start", fields)?),
|
||||||
end: Some(get_field("end", fields)?),
|
end: Some(get_field("end", fields)?),
|
||||||
limits: ast::RangeLimits::HalfOpen,
|
limits: ast::RangeLimits::HalfOpen,
|
||||||
}),
|
}),
|
||||||
hir::QPath::LangItem(hir::LangItem::RangeToInclusive, _) => Some(Range {
|
hir::QPath::LangItem(hir::LangItem::RangeToInclusive, ..) => Some(Range {
|
||||||
start: None,
|
start: None,
|
||||||
end: Some(get_field("end", fields)?),
|
end: Some(get_field("end", fields)?),
|
||||||
limits: ast::RangeLimits::Closed,
|
limits: ast::RangeLimits::Closed,
|
||||||
}),
|
}),
|
||||||
hir::QPath::LangItem(hir::LangItem::RangeTo, _) => Some(Range {
|
hir::QPath::LangItem(hir::LangItem::RangeTo, ..) => Some(Range {
|
||||||
start: None,
|
start: None,
|
||||||
end: Some(get_field("end", fields)?),
|
end: Some(get_field("end", fields)?),
|
||||||
limits: ast::RangeLimits::HalfOpen,
|
limits: ast::RangeLimits::HalfOpen,
|
||||||
|
|
|
@ -346,7 +346,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||||
(&QPath::TypeRelative(lty, lseg), &QPath::TypeRelative(rty, rseg)) => {
|
(&QPath::TypeRelative(lty, lseg), &QPath::TypeRelative(rty, rseg)) => {
|
||||||
self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg)
|
self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg)
|
||||||
},
|
},
|
||||||
(&QPath::LangItem(llang_item, _), &QPath::LangItem(rlang_item, _)) => llang_item == rlang_item,
|
(&QPath::LangItem(llang_item, ..), &QPath::LangItem(rlang_item, ..)) => llang_item == rlang_item,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,22 +6,22 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
|
||||||
|
|
|
|
||||||
= note: `-D clippy::future-not-send` implied by `-D warnings`
|
= note: `-D clippy::future-not-send` implied by `-D warnings`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/future_not_send.rs:8:5
|
--> $DIR/future_not_send.rs:8:19
|
||||||
|
|
|
|
||||||
LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
|
LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
|
||||||
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
|
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
|
||||||
LL | async { true }.await
|
LL | async { true }.await
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `rc` maybe used later
|
| ^^^^^^ await occurs here, with `rc` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `rc` is later dropped here
|
| - `rc` is later dropped here
|
||||||
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
|
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/future_not_send.rs:8:5
|
--> $DIR/future_not_send.rs:8:19
|
||||||
|
|
|
|
||||||
LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
|
LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
|
||||||
| ---- has type `&std::cell::Cell<usize>` which is not `Send`
|
| ---- has type `&std::cell::Cell<usize>` which is not `Send`
|
||||||
LL | async { true }.await
|
LL | async { true }.await
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `cell` maybe used later
|
| ^^^^^^ await occurs here, with `cell` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `cell` is later dropped here
|
| - `cell` is later dropped here
|
||||||
= note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
|
= note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
|
||||||
|
@ -33,12 +33,12 @@ LL | pub async fn public_future(rc: Rc<[u8]>) {
|
||||||
| ^ future returned by `public_future` is not `Send`
|
| ^ future returned by `public_future` is not `Send`
|
||||||
|
|
|
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/future_not_send.rs:12:5
|
--> $DIR/future_not_send.rs:12:19
|
||||||
|
|
|
|
||||||
LL | pub async fn public_future(rc: Rc<[u8]>) {
|
LL | pub async fn public_future(rc: Rc<[u8]>) {
|
||||||
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
|
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
|
||||||
LL | async { true }.await;
|
LL | async { true }.await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `rc` maybe used later
|
| ^^^^^^ await occurs here, with `rc` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `rc` is later dropped here
|
| - `rc` is later dropped here
|
||||||
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
|
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
|
||||||
|
@ -82,12 +82,12 @@ LL | async fn private_future(&self) -> usize {
|
||||||
| ^^^^^ future returned by `private_future` is not `Send`
|
| ^^^^^ future returned by `private_future` is not `Send`
|
||||||
|
|
|
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/future_not_send.rs:35:9
|
--> $DIR/future_not_send.rs:35:23
|
||||||
|
|
|
|
||||||
LL | async fn private_future(&self) -> usize {
|
LL | async fn private_future(&self) -> usize {
|
||||||
| ----- has type `&Dummy` which is not `Send`
|
| ----- has type `&Dummy` which is not `Send`
|
||||||
LL | async { true }.await;
|
LL | async { true }.await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `&self` maybe used later
|
| ^^^^^^ await occurs here, with `&self` maybe used later
|
||||||
LL | self.rc.len()
|
LL | self.rc.len()
|
||||||
LL | }
|
LL | }
|
||||||
| - `&self` is later dropped here
|
| - `&self` is later dropped here
|
||||||
|
@ -100,12 +100,12 @@ LL | pub async fn public_future(&self) {
|
||||||
| ^ future returned by `public_future` is not `Send`
|
| ^ future returned by `public_future` is not `Send`
|
||||||
|
|
|
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/future_not_send.rs:40:9
|
--> $DIR/future_not_send.rs:40:30
|
||||||
|
|
|
|
||||||
LL | pub async fn public_future(&self) {
|
LL | pub async fn public_future(&self) {
|
||||||
| ----- has type `&Dummy` which is not `Send`
|
| ----- has type `&Dummy` which is not `Send`
|
||||||
LL | self.private_future().await;
|
LL | self.private_future().await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `&self` maybe used later
|
| ^^^^^^ await occurs here, with `&self` maybe used later
|
||||||
LL | }
|
LL | }
|
||||||
| - `&self` is later dropped here
|
| - `&self` is later dropped here
|
||||||
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
|
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
|
||||||
|
@ -117,12 +117,12 @@ LL | async fn generic_future<T>(t: T) -> T
|
||||||
| ^ future returned by `generic_future` is not `Send`
|
| ^ future returned by `generic_future` is not `Send`
|
||||||
|
|
|
|
||||||
note: future is not `Send` as this value is used across an await
|
note: future is not `Send` as this value is used across an await
|
||||||
--> $DIR/future_not_send.rs:54:5
|
--> $DIR/future_not_send.rs:54:19
|
||||||
|
|
|
|
||||||
LL | let rt = &t;
|
LL | let rt = &t;
|
||||||
| -- has type `&T` which is not `Send`
|
| -- has type `&T` which is not `Send`
|
||||||
LL | async { true }.await;
|
LL | async { true }.await;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `rt` maybe used later
|
| ^^^^^^ await occurs here, with `rt` maybe used later
|
||||||
LL | t
|
LL | t
|
||||||
LL | }
|
LL | }
|
||||||
| - `rt` is later dropped here
|
| - `rt` is later dropped here
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
// run-rustfix
|
|
||||||
|
|
||||||
#![allow(unused, clippy::assign_op_pattern)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
|
|
||||||
let a = "zero";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let b = 1;
|
|
||||||
let c = 2;
|
|
||||||
|
|
||||||
|
|
||||||
let d: usize = 1;
|
|
||||||
|
|
||||||
|
|
||||||
let mut e = 1;
|
|
||||||
e = 2;
|
|
||||||
|
|
||||||
|
|
||||||
let f = match 1 {
|
|
||||||
1 => "three",
|
|
||||||
_ => return,
|
|
||||||
}; // has semi
|
|
||||||
|
|
||||||
|
|
||||||
let g: usize = if true {
|
|
||||||
5
|
|
||||||
} else {
|
|
||||||
panic!();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let h = format!("{}", e);
|
|
||||||
|
|
||||||
println!("{}", a);
|
|
||||||
}
|
|
|
@ -1,5 +1,3 @@
|
||||||
// run-rustfix
|
|
||||||
|
|
||||||
#![allow(unused, clippy::assign_op_pattern)]
|
#![allow(unused, clippy::assign_op_pattern)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:6:5
|
--> $DIR/needless_late_init_fixable.rs:4:5
|
||||||
|
|
|
|
||||||
LL | let a;
|
LL | let a;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -11,7 +11,7 @@ LL | let a = "zero";
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:9:5
|
--> $DIR/needless_late_init_fixable.rs:7:5
|
||||||
|
|
|
|
||||||
LL | let b;
|
LL | let b;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -22,7 +22,7 @@ LL | let b = 1;
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:10:5
|
--> $DIR/needless_late_init_fixable.rs:8:5
|
||||||
|
|
|
|
||||||
LL | let c;
|
LL | let c;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -33,7 +33,7 @@ LL | let c = 2;
|
||||||
| ~~~~~
|
| ~~~~~
|
||||||
|
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:14:5
|
--> $DIR/needless_late_init_fixable.rs:12:5
|
||||||
|
|
|
|
||||||
LL | let d: usize;
|
LL | let d: usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -44,7 +44,7 @@ LL | let d: usize = 1;
|
||||||
| ~~~~~~~~~~~~
|
| ~~~~~~~~~~~~
|
||||||
|
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:17:5
|
--> $DIR/needless_late_init_fixable.rs:15:5
|
||||||
|
|
|
|
||||||
LL | let mut e;
|
LL | let mut e;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -55,7 +55,7 @@ LL | let mut e = 1;
|
||||||
| ~~~~~~~~~
|
| ~~~~~~~~~
|
||||||
|
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:21:5
|
--> $DIR/needless_late_init_fixable.rs:19:5
|
||||||
|
|
|
|
||||||
LL | let f;
|
LL | let f;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -66,11 +66,12 @@ LL | let f = match 1 {
|
||||||
| +++++++
|
| +++++++
|
||||||
help: remove the assignments from the `match` arms
|
help: remove the assignments from the `match` arms
|
||||||
|
|
|
|
||||||
LL | 1 => "three",
|
LL - 1 => f = "three",
|
||||||
| ~~~~~~~
|
LL + 1 => "three",
|
||||||
|
|
|
||||||
|
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:27:5
|
--> $DIR/needless_late_init_fixable.rs:25:5
|
||||||
|
|
|
|
||||||
LL | let g: usize;
|
LL | let g: usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -81,7 +82,8 @@ LL | let g: usize = if true {
|
||||||
| ++++++++++++++
|
| ++++++++++++++
|
||||||
help: remove the assignments from the branches
|
help: remove the assignments from the branches
|
||||||
|
|
|
|
||||||
LL | 5
|
LL - g = 5;
|
||||||
|
LL + 5
|
||||||
|
|
|
|
||||||
help: add a semicolon after the `if` expression
|
help: add a semicolon after the `if` expression
|
||||||
|
|
|
|
||||||
|
@ -89,7 +91,7 @@ LL | };
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error: unneeded late initalization
|
error: unneeded late initalization
|
||||||
--> $DIR/needless_late_init_fixable.rs:34:5
|
--> $DIR/needless_late_init_fixable.rs:32:5
|
||||||
|
|
|
|
||||||
LL | let h;
|
LL | let h;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue