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)
}

```
This commit is contained in:
surechen 2024-06-29 14:23:33 +08:00
parent 4e63822fc4
commit 50edb32939
6 changed files with 127 additions and 11 deletions

View File

@ -1459,8 +1459,25 @@ fn infer_return_ty_for_fn_sig<'tcx>(
Some(ty) => { Some(ty) => {
let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id]; let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
// Typeck doesn't expect erased regions to be returned from `type_of`. // 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 { 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, _ => r,
}); });

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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`.

View File

@ -47,7 +47,7 @@ fn test10(&self, _x : _) { }
fn test11(x: &usize) -> &_ { fn test11(x: &usize) -> &_ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types //~^ 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 _ { unsafe fn test12(x: *const usize) -> *const *const _ {

View File

@ -158,7 +158,7 @@ LL | fn test11(x: &usize) -> &_ {
| -^ | -^
| || | ||
| |not allowed in type signatures | |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 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/typeck_type_placeholder_item.rs:53:52 --> $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)] LL + #![feature(const_trait_impl)]
| |
error[E0515]: cannot return reference to function parameter `x` error: aborting due to 74 previous errors
--> $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 Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403.
Some errors have detailed explanations: E0015, E0046, E0121, E0282, E0403, E0515.
For more information about an error, try `rustc --explain E0015`. For more information about an error, try `rustc --explain E0015`.