about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2024-01-08 01:15:02 +0800
committeryukang <moorekang@gmail.com>2024-01-08 16:50:14 +0800
commit75df38e8165622e623fc24266ef4da49fd093933 (patch)
treebe69117402b74ea9b2b7d760081a2df129404338
parentf688dd684faca5b31b156fac2c6e0ae81fc9bc90 (diff)
downloadrust-75df38e8165622e623fc24266ef4da49fd093933.tar.gz
rust-75df38e8165622e623fc24266ef4da49fd093933.zip
Fix 2 variable binding issues in let_underscore
-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 2c34fc13919..cb7a766d049 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -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),
 }
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 ca6408bdf3d..588b1541c4b 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -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 @@ 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(
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
+