This compiles without error:
fn foo(s: &i32) -> &i32 {
&0
}
Errors:
Compiling playground v0.0.1 (/playground)
warning: unused variable: `s`
--> src/lib.rs:1:8
|
1 | fn foo(s: &i32) -> &i32 {
| ^ help: if this is intentional, prefix it with an underscore: `_s`
|
= note: `#[warn(unused_variables)]` on by default
warning: function is never used: `foo`
--> src/lib.rs:1:4
|
1 | fn foo(s: &i32) -> &i32 {
| ^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 2 warnings emitted
Finished dev [unoptimized + debuginfo] target(s) in 0.73s
But this errors, even though there shouldn't be a difference as s is not used in the previous example:
fn foo() -> &i32 {
&0
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
--> src/lib.rs:1:13
|
1 | fn foo() -> &i32 {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
1 | fn foo() -> &'static i32 {
| ^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0106`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
Potentially related to #77910.
To be clear, I believe the bug occurs in the first example; I think the error in the second is correct.
When did this regress?
Both cases look correct to me. The first one uses lifetime elision.
Just finished bisecting :)
searched nightlies: from nightly-2019-01-01 to nightly-2020-10-13
regressed nightly: nightly-2020-05-03
searched commits: from https://github.com/rust-lang/rust/commit/7f65393b9abf5e70d0b9a8080558f17c5625bd40 to https://github.com/rust-lang/rust/commit/f05a5240440b3eaef1684a7965860fab40301947
regressed commit: https://github.com/rust-lang/rust/commit/dae90c195989b09475b6c0225a3018cbd7afa587
bisected with cargo-bisect-rustc v0.5.2
Host triple: x86_64-apple-darwin
Reproduce with:
cargo bisect-rustc --preserve --regress=success --start=2019-01-01
Both cases look correct to me. The first one uses lifetime elision.
How so? They should be no different in the errors they produce. This is the diff between them:
-fn foo(s: &i32) -> &i32 {
+fn foo() -> &i32 {
&0
}
Also the bitcode commit :/
Cc @alexcrichton
What was the behavior before that PR?
This documents the behavior: https://doc.rust-lang.org/reference/lifetime-elision.html?highlight=lifetime,elision#lifetime-elision-in-functions
I'm not sure; Godbolt is showing the same behavior throughout but bisect-rustc found a spot where it changed. Not sure what's going on...
Oops, this is why:
$ cargo +bisector-nightly-2020-05-02-x86_64-apple-darwin rustc
Compiling rust-issue-77912-a v0.1.0 (/Users/user/rust-issue-77912-a)
error: unknown codegen option: `embed-bitcode`
error: could not compile `rust-issue-77912-a`
To learn more, run the command again with --verbose.
I also think this behavior is expected, so I don't feel like there is a bug here
Sorry @alexcrichton I think that was a false positive.
Why would this be expected?
Example A takes _one argument_ (but does not use it) and does _not_ error, while Example B takes _no arguments_ and _does_ error.
Yeah, this is clearly working as specified in the reference (linked above), as well as here: https://rust-lang.github.io/rfcs/0141-lifetime-elision.html#examples
example a is desugared to
fn foo<'a>(s: &'a i32) -> &'a i32 {
&0
}
while we currently do not apply any desugarings in the second example. We may want to change this behavior in the future, but as of now the compiler agrees with the language specification here
Huh, yes I find that behavior very confusing. I guess this can be closed then. Thank you for walking me through this! It was really hurting my brain :)
Most helpful comment
Both cases look correct to me. The first one uses lifetime elision.