Fix 2 variable binding issues in let_underscore
This commit is contained in:
parent
f688dd684f
commit
75df38e816
@ -2017,7 +2017,7 @@ pub enum LocalSource {
|
||||
AsyncFn,
|
||||
/// A desugared `<expr>.await`.
|
||||
AwaitDesugar,
|
||||
/// A desugared `expr = expr`, where the LHS is a tuple, struct or array.
|
||||
/// A desugared `expr = expr`, where the LHS is a tuple, struct, array or underscore expression.
|
||||
/// The span is that of the `=` sign.
|
||||
AssignDesugar(Span),
|
||||
}
|
||||
|
@ -108,6 +108,10 @@ fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
|
||||
if !matches!(local.pat.kind, hir::PatKind::Wild) {
|
||||
return;
|
||||
}
|
||||
|
||||
if matches!(local.source, rustc_hir::LocalSource::AsyncFn) {
|
||||
return;
|
||||
}
|
||||
if let Some(init) = local.init {
|
||||
let init_ty = cx.typeck_results().expr_ty(init);
|
||||
// If the type has a trivial Drop implementation, then it doesn't
|
||||
@ -126,6 +130,7 @@ fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
|
||||
suggestion: local.pat.span,
|
||||
multi_suggestion_start: local.span.until(init.span),
|
||||
multi_suggestion_end: init.span.shrink_to_hi(),
|
||||
is_assign_desugar: matches!(local.source, rustc_hir::LocalSource::AssignDesugar(_)),
|
||||
};
|
||||
if is_sync_lock {
|
||||
let mut span = MultiSpan::from_spans(vec![local.pat.span, init.span]);
|
||||
|
@ -950,6 +950,7 @@ pub struct NonBindingLetSub {
|
||||
pub suggestion: Span,
|
||||
pub multi_suggestion_start: Span,
|
||||
pub multi_suggestion_end: Span,
|
||||
pub is_assign_desugar: bool,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for NonBindingLetSub {
|
||||
@ -960,10 +961,11 @@ fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
|
||||
rustc_errors::SubdiagnosticMessage,
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
{
|
||||
let prefix = if self.is_assign_desugar { "let " } else { "" };
|
||||
diag.span_suggestion_verbose(
|
||||
self.suggestion,
|
||||
fluent::lint_non_binding_let_suggestion,
|
||||
"_unused",
|
||||
format!("{prefix}_unused"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
diag.multipart_suggestion(
|
||||
|
21
tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
Normal file
21
tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// edition: 2021
|
||||
|
||||
#![deny(let_underscore_drop)]
|
||||
fn main() {
|
||||
let _ = foo(); //~ ERROR non-binding let on a type that implements `Drop`
|
||||
}
|
||||
|
||||
async fn from_config(_: Config) {}
|
||||
|
||||
async fn foo() {
|
||||
from_config(Config {
|
||||
nickname: None,
|
||||
..Default::default()
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Config {
|
||||
nickname: Option<Box<u8>>,
|
||||
}
|
22
tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
Normal file
22
tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error: non-binding let on a type that implements `Drop`
|
||||
--> $DIR/issue-119696-err-on-fn.rs:5:5
|
||||
|
|
||||
LL | let _ = foo();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-119696-err-on-fn.rs:3:9
|
||||
|
|
||||
LL | #![deny(let_underscore_drop)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
help: consider binding to an unused variable to avoid immediately dropping the value
|
||||
|
|
||||
LL | let _unused = foo();
|
||||
| ~~~~~~~
|
||||
help: consider immediately dropping the value
|
||||
|
|
||||
LL | drop(foo());
|
||||
| ~~~~~ +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
21
tests/ui/lint/let_underscore/issue-119697-extra-let.rs
Normal file
21
tests/ui/lint/let_underscore/issue-119697-extra-let.rs
Normal file
@ -0,0 +1,21 @@
|
||||
#![deny(let_underscore_drop)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub struct Foo {
|
||||
/// This type must have nontrivial drop glue
|
||||
field: String,
|
||||
}
|
||||
|
||||
pub type Tait = impl Sized;
|
||||
|
||||
pub fn ice_cold(beverage: Tait) {
|
||||
// Must destructure at least one field of `Foo`
|
||||
let Foo { field } = beverage;
|
||||
// boom
|
||||
_ = field; //~ ERROR non-binding let on a type that implements `Drop`
|
||||
|
||||
let _ = field; //~ ERROR non-binding let on a type that implements `Drop`
|
||||
}
|
||||
|
||||
|
||||
pub fn main() {}
|
37
tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
Normal file
37
tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
Normal file
@ -0,0 +1,37 @@
|
||||
error: non-binding let on a type that implements `Drop`
|
||||
--> $DIR/issue-119697-extra-let.rs:15:5
|
||||
|
|
||||
LL | _ = field;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-119697-extra-let.rs:1:9
|
||||
|
|
||||
LL | #![deny(let_underscore_drop)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
help: consider binding to an unused variable to avoid immediately dropping the value
|
||||
|
|
||||
LL | let _unused = field;
|
||||
| ~~~~~~~~~~~
|
||||
help: consider immediately dropping the value
|
||||
|
|
||||
LL | drop(field);
|
||||
| ~~~~~ +
|
||||
|
||||
error: non-binding let on a type that implements `Drop`
|
||||
--> $DIR/issue-119697-extra-let.rs:17:5
|
||||
|
|
||||
LL | let _ = field;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider binding to an unused variable to avoid immediately dropping the value
|
||||
|
|
||||
LL | let _unused = field;
|
||||
| ~~~~~~~
|
||||
help: consider immediately dropping the value
|
||||
|
|
||||
LL | drop(field);
|
||||
| ~~~~~ +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user