about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-02 23:04:27 +0000
committerbors <bors@rust-lang.org>2023-08-02 23:04:27 +0000
commit736ef39a84cafc879818781094c897bfbb0bf7bc (patch)
tree745d6a92a3660c7f9b1d4f6f0815ee2683ce07ca
parent8131b9774ebcb6c162fcac71545a13543ec369e7 (diff)
parentac25636a8f1efa40d368eaec363b01b748e193a1 (diff)
downloadrust-736ef39a84cafc879818781094c897bfbb0bf7bc.tar.gz
rust-736ef39a84cafc879818781094c897bfbb0bf7bc.zip
Auto merge of #107254 - chenyukang:yukang/fix-107113-wrong-sugg-in-macro, r=estebank
Avoid wrong code suggesting for attribute macro

Fixes #107113
r? `@estebank`
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs3
-rw-r--r--compiler/rustc_middle/src/lint.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs16
-rw-r--r--tests/ui/coercion/coerce-block-tail-83783.fixed13
-rw-r--r--tests/ui/coercion/coerce-block-tail-83783.rs2
-rw-r--r--tests/ui/coercion/coerce-block-tail-83783.stderr4
-rw-r--r--tests/ui/proc-macro/auxiliary/issue-107113.rs13
-rw-r--r--tests/ui/proc-macro/issue-107113-wrap.rs8
-rw-r--r--tests/ui/proc-macro/issue-107113-wrap.stderr16
9 files changed, 85 insertions, 5 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 26fa3d80d55..48383bd90fe 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -880,6 +880,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         expr_ty: Ty<'tcx>,
     ) -> bool {
+        if in_external_macro(self.tcx.sess, expr.span) {
+            return false;
+        }
         if let ty::Adt(expected_adt, args) = expected.kind() {
             if let hir::ExprKind::Field(base, ident) = expr.kind {
                 let base_ty = self.typeck_results.borrow().expr_ty(base);
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 9ecc7580f5c..f62e406692a 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -449,7 +449,11 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
     match expn_data.kind {
         ExpnKind::Root
         | ExpnKind::Desugaring(
-            DesugaringKind::ForLoop | DesugaringKind::WhileLoop | DesugaringKind::OpaqueTy,
+            DesugaringKind::ForLoop
+            | DesugaringKind::WhileLoop
+            | DesugaringKind::OpaqueTy
+            | DesugaringKind::Async
+            | DesugaringKind::Await,
         ) => false,
         ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
@@ -459,3 +463,12 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
         ExpnKind::Macro { .. } => true, // definitely a plugin
     }
 }
+
+/// Return whether `span` is generated by `async` or `await`.
+pub fn is_from_async_await(span: Span) -> bool {
+    let expn_data = span.ctxt().outer_expn_data();
+    match expn_data.kind {
+        ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await) => true,
+        _ => false,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 140ae837a17..896bd79b20b 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -2,9 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::ty::needs_ordered_drop;
 use rustc_hir::def::Res;
-use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, HirId, Local, Node, Pat, PatKind, QPath};
+use rustc_hir::{
+    BindingAnnotation, ByRef, Expr, ExprKind, HirId, Local, Node, Pat, PatKind, QPath,
+};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_middle::lint::{in_external_macro, is_from_async_await};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::Ident;
 
@@ -65,6 +67,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
             // the local is user-controlled
             if !in_external_macro(cx.sess(), local.span);
             if !is_from_proc_macro(cx, expr);
+            // Async function parameters are lowered into the closure body, so we can't lint them.
+            // see `lower_maybe_async_body` in `rust_ast_lowering`
+            if !is_from_async_await(local.span);
             then {
                 span_lint_and_help(
                     cx,
@@ -93,7 +98,12 @@ fn find_binding(pat: &Pat<'_>, name: Ident) -> Option<BindingAnnotation> {
 }
 
 /// Check if a rebinding of a local affects the code's drop behavior.
-fn affects_drop_behavior<'tcx>(cx: &LateContext<'tcx>, bind: HirId, rebind: HirId, rebind_expr: &Expr<'tcx>) -> bool {
+fn affects_drop_behavior<'tcx>(
+    cx: &LateContext<'tcx>,
+    bind: HirId,
+    rebind: HirId,
+    rebind_expr: &Expr<'tcx>,
+) -> bool {
     let hir = cx.tcx.hir();
 
     // the rebinding is in a different scope than the original binding
diff --git a/tests/ui/coercion/coerce-block-tail-83783.fixed b/tests/ui/coercion/coerce-block-tail-83783.fixed
new file mode 100644
index 00000000000..0df0a64ac96
--- /dev/null
+++ b/tests/ui/coercion/coerce-block-tail-83783.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+// edition:2018
+fn _consume_reference<T: ?Sized>(_: &T) {}
+
+async fn _foo() {
+    _consume_reference::<i32>(&Box::new(7_i32));
+    _consume_reference::<i32>(&*async { Box::new(7_i32) }.await);
+    //~^ ERROR mismatched types
+    _consume_reference::<[i32]>(&vec![7_i32]);
+    _consume_reference::<[i32]>(&async { vec![7_i32] }.await);
+}
+
+fn main() { }
diff --git a/tests/ui/coercion/coerce-block-tail-83783.rs b/tests/ui/coercion/coerce-block-tail-83783.rs
index 18c8ae3bbba..ee6036b4d67 100644
--- a/tests/ui/coercion/coerce-block-tail-83783.rs
+++ b/tests/ui/coercion/coerce-block-tail-83783.rs
@@ -1,4 +1,4 @@
-// check-fail
+// run-rustfix
 // edition:2018
 fn _consume_reference<T: ?Sized>(_: &T) {}
 
diff --git a/tests/ui/coercion/coerce-block-tail-83783.stderr b/tests/ui/coercion/coerce-block-tail-83783.stderr
index d556d013bb5..da3c387773f 100644
--- a/tests/ui/coercion/coerce-block-tail-83783.stderr
+++ b/tests/ui/coercion/coerce-block-tail-83783.stderr
@@ -6,6 +6,10 @@ LL |     _consume_reference::<i32>(&async { Box::new(7_i32) }.await);
    |
    = note: expected type `i32`
             found struct `Box<i32>`
+help: consider unboxing the value
+   |
+LL |     _consume_reference::<i32>(&*async { Box::new(7_i32) }.await);
+   |                                +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/proc-macro/auxiliary/issue-107113.rs b/tests/ui/proc-macro/auxiliary/issue-107113.rs
new file mode 100644
index 00000000000..b27d3fd2fbd
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/issue-107113.rs
@@ -0,0 +1,13 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
+    "fn main() -> std::io::Result<()> { () } ".parse().unwrap()
+}
diff --git a/tests/ui/proc-macro/issue-107113-wrap.rs b/tests/ui/proc-macro/issue-107113-wrap.rs
new file mode 100644
index 00000000000..bc5b44963f7
--- /dev/null
+++ b/tests/ui/proc-macro/issue-107113-wrap.rs
@@ -0,0 +1,8 @@
+// edition:2021
+// aux-build:issue-107113.rs
+
+#[macro_use]
+extern crate issue_107113;
+
+#[issue_107113::main] //~ ERROR mismatched types [E0308]
+async fn main() -> std::io::Result<()> {}
diff --git a/tests/ui/proc-macro/issue-107113-wrap.stderr b/tests/ui/proc-macro/issue-107113-wrap.stderr
new file mode 100644
index 00000000000..4122253d22f
--- /dev/null
+++ b/tests/ui/proc-macro/issue-107113-wrap.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-107113-wrap.rs:7:1
+   |
+LL | #[issue_107113::main]
+   | ^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | expected `Result<(), Error>`, found `()`
+   | expected `Result<(), std::io::Error>` because of return type
+   |
+   = note:   expected enum `Result<(), std::io::Error>`
+           found unit type `()`
+   = note: this error originates in the attribute macro `issue_107113::main` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.