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,
|
AsyncFn,
|
||||||
/// A desugared `<expr>.await`.
|
/// A desugared `<expr>.await`.
|
||||||
AwaitDesugar,
|
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.
|
/// The span is that of the `=` sign.
|
||||||
AssignDesugar(Span),
|
AssignDesugar(Span),
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,10 @@ fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
|
|||||||
if !matches!(local.pat.kind, hir::PatKind::Wild) {
|
if !matches!(local.pat.kind, hir::PatKind::Wild) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matches!(local.source, rustc_hir::LocalSource::AsyncFn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if let Some(init) = local.init {
|
if let Some(init) = local.init {
|
||||||
let init_ty = cx.typeck_results().expr_ty(init);
|
let init_ty = cx.typeck_results().expr_ty(init);
|
||||||
// If the type has a trivial Drop implementation, then it doesn't
|
// 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,
|
suggestion: local.pat.span,
|
||||||
multi_suggestion_start: local.span.until(init.span),
|
multi_suggestion_start: local.span.until(init.span),
|
||||||
multi_suggestion_end: init.span.shrink_to_hi(),
|
multi_suggestion_end: init.span.shrink_to_hi(),
|
||||||
|
is_assign_desugar: matches!(local.source, rustc_hir::LocalSource::AssignDesugar(_)),
|
||||||
};
|
};
|
||||||
if is_sync_lock {
|
if is_sync_lock {
|
||||||
let mut span = MultiSpan::from_spans(vec![local.pat.span, init.span]);
|
let mut span = MultiSpan::from_spans(vec![local.pat.span, init.span]);
|
||||||
|
@ -950,6 +950,7 @@ pub struct NonBindingLetSub {
|
|||||||
pub suggestion: Span,
|
pub suggestion: Span,
|
||||||
pub multi_suggestion_start: Span,
|
pub multi_suggestion_start: Span,
|
||||||
pub multi_suggestion_end: Span,
|
pub multi_suggestion_end: Span,
|
||||||
|
pub is_assign_desugar: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddToDiagnostic for NonBindingLetSub {
|
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,
|
||||||
) -> rustc_errors::SubdiagnosticMessage,
|
) -> rustc_errors::SubdiagnosticMessage,
|
||||||
{
|
{
|
||||||
|
let prefix = if self.is_assign_desugar { "let " } else { "" };
|
||||||
diag.span_suggestion_verbose(
|
diag.span_suggestion_verbose(
|
||||||
self.suggestion,
|
self.suggestion,
|
||||||
fluent::lint_non_binding_let_suggestion,
|
fluent::lint_non_binding_let_suggestion,
|
||||||
"_unused",
|
format!("{prefix}_unused"),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
diag.multipart_suggestion(
|
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