about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-01-09 00:19:35 +0100
committerGitHub <noreply@github.com>2024-01-09 00:19:35 +0100
commit5efa69d979445dd5c96adbb8981508afd3be2aa1 (patch)
tree59e722d5fa945f750c3ead2c9a9ffa7c33894be8
parent867a87d3420324eb41ca88ce25f4e372b70672ed (diff)
parent75df38e8165622e623fc24266ef4da49fd093933 (diff)
downloadrust-5efa69d979445dd5c96adbb8981508afd3be2aa1.tar.gz
rust-5efa69d979445dd5c96adbb8981508afd3be2aa1.zip
Rollup merge of #119704 - chenyukang:yukang-fix-let_underscore, r=Nilstrieb
Fix two variable binding issues in lint let_underscore

Fixes #119696
Fixes #119697
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_lint/src/let_underscore.rs5
-rw-r--r--compiler/rustc_lint/src/lints.rs4
-rw-r--r--tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs21
-rw-r--r--tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr22
-rw-r--r--tests/ui/lint/let_underscore/issue-119697-extra-let.rs21
-rw-r--r--tests/ui/lint/let_underscore/issue-119697-extra-let.stderr37
7 files changed, 110 insertions, 2 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index e88b876534e..7585f7bc902 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1997,7 +1997,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),
 }
diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs
index 3eefd1b0e08..bdace8e01f6 100644
--- a/compiler/rustc_lint/src/let_underscore.rs
+++ b/compiler/rustc_lint/src/let_underscore.rs
@@ -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
@@ -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]);
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 614c3ecbcae..bc9a9d7b745 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -932,6 +932,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 {
@@ -939,10 +940,11 @@ impl AddToDiagnostic for NonBindingLetSub {
     where
         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> 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(
diff --git a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
new file mode 100644
index 00000000000..8e15b4da35a
--- /dev/null
+++ b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.rs
@@ -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>>,
+}
diff --git a/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
new file mode 100644
index 00000000000..86e521580b8
--- /dev/null
+++ b/tests/ui/lint/let_underscore/issue-119696-err-on-fn.stderr
@@ -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
+
diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.rs b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
new file mode 100644
index 00000000000..1dc80a123f6
--- /dev/null
+++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.rs
@@ -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() {}
diff --git a/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
new file mode 100644
index 00000000000..16df2c720ea
--- /dev/null
+++ b/tests/ui/lint/let_underscore/issue-119697-extra-let.stderr
@@ -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
+