about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-06-29 22:10:58 +0200
committerGitHub <noreply@github.com>2024-06-29 22:10:58 +0200
commit80cf576f59db72852b8b6fe25e8d697645dd20c8 (patch)
treed7b6c53352ab581e15d996f64a4e7572d8e14ba4
parent77152955b8a1911d6a1f9f6ed07bf77e8531490c (diff)
parent50edb32939898fa6c22f3e2b2596317a031acaa7 (diff)
downloadrust-80cf576f59db72852b8b6fe25e8d697645dd20c8.tar.gz
rust-80cf576f59db72852b8b6fe25e8d697645dd20c8.zip
Rollup merge of #127110 - surechen:fix_125488_06, r=compiler-errors
Fix a error suggestion for E0121 when using placeholder _ as return types on function signature.

Recommit after refactoring based on comment:
https://github.com/rust-lang/rust/pull/126017#issuecomment-2189149361

But when changing return type's lifetime to `ReError` will affect the subsequent borrow check process and cause test11 in typeck_type_placeholder_item.rs to lost E0515 message.
```rust
fn test11(x: &usize) -> &_ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
    &x //~ ERROR cannot return reference to function parameter(this E0515 msg will disappear)
}
```

fixes #125488

r? ``@pnkfelix``
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs19
-rw-r--r--tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed33
-rw-r--r--tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs33
-rw-r--r--tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr39
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.rs2
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr12
6 files changed, 127 insertions, 11 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 18aff6a4d5a..276aaec4141 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1459,8 +1459,25 @@ fn infer_return_ty_for_fn_sig<'tcx>(
         Some(ty) => {
             let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
             // Typeck doesn't expect erased regions to be returned from `type_of`.
+            // This is a heuristic approach. If the scope has region paramters,
+            // we should change fn_sig's lifetime from `ReErased` to `ReError`,
+            // otherwise to `ReStatic`.
+            let has_region_params = generics.params.iter().any(|param| match param.kind {
+                GenericParamKind::Lifetime { .. } => true,
+                _ => false,
+            });
             let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r {
-                ty::ReErased => tcx.lifetimes.re_static,
+                ty::ReErased => {
+                    if has_region_params {
+                        ty::Region::new_error_with_message(
+                            tcx,
+                            DUMMY_SP,
+                            "erased region is not allowed here in return type",
+                        )
+                    } else {
+                        tcx.lifetimes.re_static
+                    }
+                }
                 _ => r,
             });
 
diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed
new file mode 100644
index 00000000000..442ade6abf1
--- /dev/null
+++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.fixed
@@ -0,0 +1,33 @@
+//@ run-rustfix
+
+#[allow(dead_code)]
+
+fn main() {
+    struct S<'a>(&'a ());
+
+    fn f1(s: S<'_>) -> S<'_> {
+        //~^ ERROR the placeholder `_` is not allowed
+        s
+    }
+
+    fn f2(s: S<'_>) -> S<'_> {
+        //~^ ERROR the placeholder `_` is not allowed
+        let x = true;
+        if x {
+            s
+        } else {
+            s
+        }
+    }
+
+    fn f3(s: S<'_>) -> S<'_> {
+        //~^ ERROR the placeholder `_` is not allowed
+        return s;
+    }
+
+    fn f4(s: S<'_>) -> S<'_> {
+        //~^ ERROR the placeholder `_` is not allowed
+        let _x = 1;
+        return s;
+    }
+}
diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs
new file mode 100644
index 00000000000..04ea3a28add
--- /dev/null
+++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.rs
@@ -0,0 +1,33 @@
+//@ run-rustfix
+
+#[allow(dead_code)]
+
+fn main() {
+    struct S<'a>(&'a ());
+
+    fn f1(s: S<'_>) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed
+        s
+    }
+
+    fn f2(s: S<'_>) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed
+        let x = true;
+        if x {
+            s
+        } else {
+            s
+        }
+    }
+
+    fn f3(s: S<'_>) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed
+        return s;
+    }
+
+    fn f4(s: S<'_>) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed
+        let _x = 1;
+        return s;
+    }
+}
diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr
new file mode 100644
index 00000000000..8b7c5e1681a
--- /dev/null
+++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr
@@ -0,0 +1,39 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:8:24
+   |
+LL |     fn f1(s: S<'_>) -> _ {
+   |                        ^
+   |                        |
+   |                        not allowed in type signatures
+   |                        help: replace with the correct return type: `S<'_>`
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:13:24
+   |
+LL |     fn f2(s: S<'_>) -> _ {
+   |                        ^
+   |                        |
+   |                        not allowed in type signatures
+   |                        help: replace with the correct return type: `S<'_>`
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:23:24
+   |
+LL |     fn f3(s: S<'_>) -> _ {
+   |                        ^
+   |                        |
+   |                        not allowed in type signatures
+   |                        help: replace with the correct return type: `S<'_>`
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:28:24
+   |
+LL |     fn f4(s: S<'_>) -> _ {
+   |                        ^
+   |                        |
+   |                        not allowed in type signatures
+   |                        help: replace with the correct return type: `S<'_>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index a95b44e807c..29a21a1f45f 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -47,7 +47,7 @@ impl Test9 {
 
 fn test11(x: &usize) -> &_ {
 //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
-    &x //~ ERROR cannot return reference to function parameter
+    &x
 }
 
 unsafe fn test12(x: *const usize) -> *const *const _ {
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index 7977504dae1..9d295f88da5 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -158,7 +158,7 @@ LL | fn test11(x: &usize) -> &_ {
    |                         -^
    |                         ||
    |                         |not allowed in type signatures
-   |                         help: replace with the correct return type: `&'static &'static usize`
+   |                         help: replace with the correct return type: `&&usize`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
   --> $DIR/typeck_type_placeholder_item.rs:53:52
@@ -687,13 +687,7 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
 LL + #![feature(const_trait_impl)]
    |
 
-error[E0515]: cannot return reference to function parameter `x`
-  --> $DIR/typeck_type_placeholder_item.rs:50:5
-   |
-LL |     &x
-   |     ^^ returns a reference to data owned by the current function
-
-error: aborting due to 75 previous errors
+error: aborting due to 74 previous errors
 
-Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403, E0515.
+Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403.
 For more information about an error, try `rustc --explain E0015`.