Skip to content

Commit

Permalink
Fix 2 variable binding issues in let_underscore
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Jan 8, 2024
1 parent f688dd6 commit 75df38e
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 2 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_lint/src/let_underscore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
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
Expand All @@ -126,6 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
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]);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -960,10 +961,11 @@ impl AddToDiagnostic for NonBindingLetSub {
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(
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 21 additions & 0 deletions tests/ui/lint/let_underscore/issue-119697-extra-let.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 37 additions & 0 deletions tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 75df38e

Please sign in to comment.