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
b166642c35
@ -204,7 +204,7 @@ fn parse_iter_usage(
|
||||
match e.kind {
|
||||
ExprKind::Call(
|
||||
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
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct LocalAssign {
|
||||
lhs_id: HirId,
|
||||
lhs_span: Span,
|
||||
@ -154,9 +154,14 @@ fn assignment_suggestions<'tcx>(
|
||||
assignments.push(assign);
|
||||
}
|
||||
|
||||
let suggestions = assignments
|
||||
let suggestions = assignments.clone()
|
||||
.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)>>>()?;
|
||||
|
||||
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::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();
|
||||
let expr_ty = cx.typeck_results().expr_ty(expr);
|
||||
let inner_ty = cx.typeck_results().expr_ty(inner_expr);
|
||||
|
@ -260,7 +260,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
|
||||
if method_names[0] == sym!(as_bytes);
|
||||
|
||||
// Check for slicer
|
||||
if let ExprKind::Struct(QPath::LangItem(LangItem::Range, _), _, _) = right.kind;
|
||||
if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), _, _) = right.kind;
|
||||
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
|
@ -65,7 +65,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Match(match_arg, _, MatchSource::TryDesugar) = expr.kind;
|
||||
if let ExprKind::Call(match_fun, try_args) = match_arg.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 ExprKind::Call(err_fun, err_args) = try_arg.kind;
|
||||
if let Some(err_arg) = err_args.get(0);
|
||||
|
@ -49,7 +49,7 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
|
||||
if let hir::ExprKind::Call(func, [ref arg_0, ..]) = res.kind {
|
||||
if matches!(
|
||||
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);
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ fn symbol(&self, symbol: &Binding<Symbol>) {
|
||||
}
|
||||
|
||||
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:?}, _));");
|
||||
} else {
|
||||
out!("if match_qpath({qpath}, &[{}]);", path_to_string(qpath.value));
|
||||
|
@ -218,7 +218,7 @@ fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c hir
|
||||
hir::ExprKind::Call(path, args)
|
||||
if matches!(
|
||||
path.kind,
|
||||
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, _))
|
||||
hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, ..))
|
||||
) =>
|
||||
{
|
||||
Some(Range {
|
||||
@ -228,27 +228,27 @@ fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c hir
|
||||
})
|
||||
},
|
||||
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,
|
||||
end: None,
|
||||
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)?),
|
||||
end: None,
|
||||
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)?),
|
||||
end: Some(get_field("end", fields)?),
|
||||
limits: ast::RangeLimits::HalfOpen,
|
||||
}),
|
||||
hir::QPath::LangItem(hir::LangItem::RangeToInclusive, _) => Some(Range {
|
||||
hir::QPath::LangItem(hir::LangItem::RangeToInclusive, ..) => Some(Range {
|
||||
start: None,
|
||||
end: Some(get_field("end", fields)?),
|
||||
limits: ast::RangeLimits::Closed,
|
||||
}),
|
||||
hir::QPath::LangItem(hir::LangItem::RangeTo, _) => Some(Range {
|
||||
hir::QPath::LangItem(hir::LangItem::RangeTo, ..) => Some(Range {
|
||||
start: None,
|
||||
end: Some(get_field("end", fields)?),
|
||||
limits: ast::RangeLimits::HalfOpen,
|
||||
|
@ -346,7 +346,7 @@ fn eq_qpath(&mut self, left: &QPath<'_>, right: &QPath<'_>) -> bool {
|
||||
(&QPath::TypeRelative(lty, lseg), &QPath::TypeRelative(rty, 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,
|
||||
}
|
||||
}
|
||||
|
@ -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: 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 {
|
||||
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
|
||||
LL | async { true }.await
|
||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `rc` maybe used later
|
||||
| ^^^^^^ await occurs here, with `rc` maybe used later
|
||||
LL | }
|
||||
| - `rc` is later dropped here
|
||||
= note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
|
||||
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 {
|
||||
| ---- has type `&std::cell::Cell<usize>` which is not `Send`
|
||||
LL | async { true }.await
|
||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `cell` maybe used later
|
||||
| ^^^^^^ await occurs here, with `cell` maybe used later
|
||||
LL | }
|
||||
| - `cell` is later dropped here
|
||||
= 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`
|
||||
|
|
||||
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]>) {
|
||||
| -- has type `std::rc::Rc<[u8]>` which is not `Send`
|
||||
LL | async { true }.await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `rc` maybe used later
|
||||
| ^^^^^^ await occurs here, with `rc` maybe used later
|
||||
LL | }
|
||||
| - `rc` is later dropped here
|
||||
= 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`
|
||||
|
|
||||
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 {
|
||||
| ----- has type `&Dummy` which is not `Send`
|
||||
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` is later dropped here
|
||||
@ -100,12 +100,12 @@ LL | pub async fn public_future(&self) {
|
||||
| ^ future returned by `public_future` is not `Send`
|
||||
|
|
||||
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) {
|
||||
| ----- has type `&Dummy` which is not `Send`
|
||||
LL | self.private_future().await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `&self` maybe used later
|
||||
| ^^^^^^ await occurs here, with `&self` maybe used later
|
||||
LL | }
|
||||
| - `&self` is later dropped here
|
||||
= 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`
|
||||
|
|
||||
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;
|
||||
| -- has type `&T` which is not `Send`
|
||||
LL | async { true }.await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ await occurs here, with `rt` maybe used later
|
||||
| ^^^^^^ await occurs here, with `rt` maybe used later
|
||||
LL | t
|
||||
LL | }
|
||||
| - `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)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:6:5
|
||||
--> $DIR/needless_late_init_fixable.rs:4:5
|
||||
|
|
||||
LL | let a;
|
||||
| ^^^^^^
|
||||
@ -11,7 +11,7 @@ LL | let a = "zero";
|
||||
| ~~~~~
|
||||
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:9:5
|
||||
--> $DIR/needless_late_init_fixable.rs:7:5
|
||||
|
|
||||
LL | let b;
|
||||
| ^^^^^^
|
||||
@ -22,7 +22,7 @@ LL | let b = 1;
|
||||
| ~~~~~
|
||||
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:10:5
|
||||
--> $DIR/needless_late_init_fixable.rs:8:5
|
||||
|
|
||||
LL | let c;
|
||||
| ^^^^^^
|
||||
@ -33,7 +33,7 @@ LL | let c = 2;
|
||||
| ~~~~~
|
||||
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:14:5
|
||||
--> $DIR/needless_late_init_fixable.rs:12:5
|
||||
|
|
||||
LL | let d: usize;
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -44,7 +44,7 @@ LL | let d: usize = 1;
|
||||
| ~~~~~~~~~~~~
|
||||
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:17:5
|
||||
--> $DIR/needless_late_init_fixable.rs:15:5
|
||||
|
|
||||
LL | let mut e;
|
||||
| ^^^^^^^^^^
|
||||
@ -55,7 +55,7 @@ LL | let mut e = 1;
|
||||
| ~~~~~~~~~
|
||||
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:21:5
|
||||
--> $DIR/needless_late_init_fixable.rs:19:5
|
||||
|
|
||||
LL | let f;
|
||||
| ^^^^^^
|
||||
@ -66,11 +66,12 @@ LL | let f = match 1 {
|
||||
| +++++++
|
||||
help: remove the assignments from the `match` arms
|
||||
|
|
||||
LL | 1 => "three",
|
||||
| ~~~~~~~
|
||||
LL - 1 => f = "three",
|
||||
LL + 1 => "three",
|
||||
|
|
||||
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:27:5
|
||||
--> $DIR/needless_late_init_fixable.rs:25:5
|
||||
|
|
||||
LL | let g: usize;
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -81,15 +82,16 @@ LL | let g: usize = if true {
|
||||
| ++++++++++++++
|
||||
help: remove the assignments from the branches
|
||||
|
|
||||
LL | 5
|
||||
|
|
||||
LL - g = 5;
|
||||
LL + 5
|
||||
|
|
||||
help: add a semicolon after the `if` expression
|
||||
|
|
||||
LL | };
|
||||
| +
|
||||
|
||||
error: unneeded late initalization
|
||||
--> $DIR/needless_late_init_fixable.rs:34:5
|
||||
--> $DIR/needless_late_init_fixable.rs:32:5
|
||||
|
|
||||
LL | let h;
|
||||
| ^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user