Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow lifetime elision in arbitrary_self_types #60944

Conversation

taiki-e
Copy link
Member

@taiki-e taiki-e commented May 18, 2019

Currently, self except &Self and &mut Self is skipped. By this, other selfs with lifetime is also ignored.
This PR changes it to only skip Self, &Self and &mut Self, and to handle other selfs like normal arguments.

Closes #52675

@rust-highfive
Copy link
Collaborator

r? @alexcrichton

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 18, 2019
@taiki-e
Copy link
Member Author

taiki-e commented May 19, 2019

@taiki-e
Copy link
Member Author

taiki-e commented May 20, 2019

Seems the current master accepts the following code:

#![allow(dead_code)]
#![feature(arbitrary_self_types)]
struct Foo;
impl Foo {
    fn b(self: &Box<Foo>, f: &Foo) -> &Foo { f }
}

I expected:

error[E0106]: missing lifetime specifier
   |
LL |     fn b(self: &Box<Foo>, f: &Foo) -> &Foo { f }
   |                                       ^ expected lifetime parameter
   |
   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `self` or `f`

or

error[E0623]: lifetime mismatch
   |
LL |     fn b(self: &Box<Foo>, f: &Foo) -> &Foo { f }
   |                              ----     ----   ^ ...but data from `f` is returned here
   |                              |
   |                              this parameter and the return type are declared with different lifetimes...

Playground

This PR rejects (fixes) this. I feel it is right, but I don't know how far it will affect.

@taiki-e
Copy link
Member Author

taiki-e commented May 20, 2019

@rustbot modify labels: T-compiler.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 20, 2019
@taiki-e
Copy link
Member Author

taiki-e commented May 20, 2019

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:31e52f32:start=1558345487257250998,finish=1558345572431079970,duration=85173828972
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
[01:10:47] .................................................................................................... 4400/5533
[01:10:51] .................................................................................................... 4500/5533
[01:10:54] .................................................................................................... 4600/5533
[01:10:58] .................................................................................................... 4700/5533
[01:11:04] .......................................................................................F............ 4800/5533
[01:11:11] .................................................................................................... 5000/5533
[01:11:16] .................................................................................................... 5100/5533
[01:11:19] .................................................................................................... 5200/5533
[01:11:22] .................................................................................................... 5300/5533
---
[01:11:29] 1 error[E0106]: missing lifetime specifier
[01:11:29] -   --> $DIR/arbitrary_self_types_lifetime-2.rs:7:39
[01:11:29] +   --> $DIR/arbitrary_self_types_inexact_lifetime.rs:7:39
[01:11:29] 3    |
[01:11:29] - LL |     fn b(self: &Box<Foo>, f: &Foo) -> &Foo { f }
[01:11:29] + LL |     fn a(self: &Box<Foo>, f: &Foo) -> &Foo { f }
[01:11:29] 6    |
[01:11:29] 6    |
[01:11:29] 7    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `self` or `f`
[01:11:29] 8 
[01:11:29] 9 error[E0106]: missing lifetime specifier
[01:11:29] -   --> $DIR/arbitrary_self_types_lifetime-2.rs:9:39
[01:11:29] +   --> $DIR/arbitrary_self_types_inexact_lifetime.rs:9:39
[01:11:29] +   --> $DIR/arbitrary_self_types_inexact_lifetime.rs:9:39
[01:11:29] 11    |
[01:11:29] - LL |     fn c(self: &Box<Foo>, f: &Foo) -> &Box<Foo> { self }
[01:11:29] + LL |     fn b(self: &Box<Foo>, f: &Foo) -> &Box<Foo> { self }
[01:11:29] 14    |
[01:11:29] 14    |
[01:11:29] 15    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `self` or `f`
[01:11:29] 16 
[01:11:29] 17 error[E0106]: missing lifetime specifier
[01:11:29] -   --> $DIR/arbitrary_self_types_lifetime-2.rs:11:39
[01:11:29] +   --> $DIR/arbitrary_self_types_inexact_lifetime.rs:11:39
[01:11:29] +   --> $DIR/arbitrary_self_types_inexact_lifetime.rs:11:39
[01:11:29] 19    |
[01:11:29] - LL |     fn d(this: &Box<Foo>, f: &Foo) -> &Foo { f }
[01:11:29] + LL |     fn c(this: &Box<Foo>, f: &Foo) -> &Foo { f }
[01:11:29] 22    |
[01:11:29] 22    |
[01:11:29] 23    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `this` or `f`
[01:11:29] 
[01:11:29] The actual stderr differed from the expected stderr.
[01:11:29] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_inexact_lifetime/arbitrary_self_types_inexact_lifetime.stderr
[01:11:29] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_inexact_lifetime/arbitrary_self_types_inexact_lifetime.stderr
[01:11:29] To update references, rerun the tests and pass the `--bless` flag
[01:11:29] To only update this specific test, also pass `--test-args self/arbitrary_self_types_inexact_lifetime.rs`
[01:11:29] error: 1 errors occurred comparing output.
[01:11:29] status: exit code: 1
[01:11:29] status: exit code: 1
[01:11:29] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/self/arbitrary_self_types_inexact_lifetime.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_inexact_lifetime" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_inexact_lifetime/auxiliary" "-A" "unused"
[01:11:29] ------------------------------------------
[01:11:29] 
[01:11:29] ------------------------------------------
[01:11:29] stderr:
[01:11:29] stderr:
[01:11:29] ------------------------------------------
[01:11:29] error[E0106]: missing lifetime specifier
[01:11:29]   --> /checkout/src/test/ui/self/arbitrary_self_types_inexact_lifetime.rs:7:39
[01:11:29]    |
[01:11:29] LL |     fn a(self: &Box<Foo>, f: &Foo) -> &Foo { f } //~ ERROR E0106
[01:11:29]    |
[01:11:29]    |
[01:11:29]    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `self` or `f`
[01:11:29] error[E0106]: missing lifetime specifier
[01:11:29]   --> /checkout/src/test/ui/self/arbitrary_self_types_inexact_lifetime.rs:9:39
[01:11:29]    |
[01:11:29]    |
[01:11:29] LL |     fn b(self: &Box<Foo>, f: &Foo) -> &Box<Foo> { self } //~ ERROR E0106
[01:11:29]    |
[01:11:29]    |
[01:11:29]    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `self` or `f`
[01:11:29] error[E0106]: missing lifetime specifier
[01:11:29]   --> /checkout/src/test/ui/self/arbitrary_self_types_inexact_lifetime.rs:11:39
[01:11:29]    |
[01:11:29]    |
[01:11:29] LL |     fn c(this: &Box<Foo>, f: &Foo) -> &Foo { f } //~ ERROR E0106
[01:11:29]    |
[01:11:29]    |
[01:11:29]    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `this` or `f`
[01:11:29] error: aborting due to 3 previous errors
[01:11:29] 
[01:11:29] For more information about this error, try `rustc --explain E0106`.
[01:11:29] 
---
[01:11:29] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:512:22
[01:11:29] note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
[01:11:29] 
[01:11:29] 
[01:11:29] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:11:29] 
[01:11:29] 
[01:11:29] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:11:29] Build completed unsuccessfully in 0:04:37
[01:11:29] Build completed unsuccessfully in 0:04:37
[01:11:29] make: *** [check] Error 1
[01:11:29] Makefile:48: recipe for target 'check' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:05540370
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Mon May 20 10:57:50 UTC 2019
---
travis_time:end:04f74f1e:start=1558349872089340102,finish=1558349872094391169,duration=5051067
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:06186118
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:246093c4
travis_time:start:246093c4
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:35fb4a88
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@taiki-e taiki-e force-pushed the arbitrary_self_types-lifetime-elision branch from 3ae4dc9 to 19c7915 Compare May 20, 2019 11:03
@alexcrichton
Copy link
Member

r? @Centril

@taiki-e taiki-e force-pushed the arbitrary_self_types-lifetime-elision branch 2 times, most recently from c04f346 to 8efcf41 Compare May 20, 2019 16:38
@cramertj cramertj added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label May 20, 2019
@cramertj
Copy link
Member

Seems like we should do a crater run-- this is certainly a breaking change, but it's also definitely something we want to fix. cc @rust-lang/lang

@cramertj
Copy link
Member

cramertj commented May 20, 2019

It also seems highly likely that this will affect code using futures, which is stabilized on nightly and soon-to-be-beta (1.36), so this also probably wants a beta backport. I don't know that there are significant other libraries making extensive use of this feature, so it seems like we might be able to fix this without an extra warning period.

@cramertj
Copy link
Member

@bors try (for crater)

@bors
Copy link
Contributor

bors commented May 20, 2019

⌛ Trying commit 8efcf41 with merge 42445de...

bors added a commit that referenced this pull request May 20, 2019
… r=<try>

Allow lifetime elision in arbitrary_self_types

Currently, `self` except `&Self` and `&mut Self` is skipped. By this, other `self`s with lifetime is also ignored.
This PR changes it to only skip `Self`, `&Self` and `&mut Self`, and to handle other `self`s like normal arguments.

Closes #52675
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:043dc8e6:start=1558370374253591278,finish=1558370461491867692,duration=87238276414
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
[01:12:23] .................................................................................................... 4400/5533
[01:12:26] .................................................................................................... 4500/5533
[01:12:30] .................................................................................................... 4600/5533
[01:12:34] .................................................................................................... 4700/5533
[01:12:41] ...........................................................................................F........ 4800/5533
[01:12:47] .................................................................................................... 5000/5533
[01:12:52] .................................................................................................... 5100/5533
[01:12:56] .................................................................................................... 5200/5533
[01:12:59] .................................................................................................... 5300/5533
---
[01:13:06] 
[01:13:06] ---- [ui] ui/self/arbitrary_self_types_lifetime.rs stdout ----
[01:13:06] diff of stderr:
[01:13:06] 
[01:13:06] 19 LL |     fn f(self: Bar<'_>) -> impl std::fmt::Debug + '_ {
[01:13:06] 21 
[01:13:06] - error: aborting due to previous error
[01:13:06] + error[E0034]: multiple applicable items in scope
[01:13:06] +   --> $DIR/arbitrary_self_types_lifetime.rs:73:17
[01:13:06] +   --> $DIR/arbitrary_self_types_lifetime.rs:73:17
[01:13:06] +    |
[01:13:06] + LL |     { Bar(&foo).c() };
[01:13:06] +    |                 ^ multiple `c` found
[01:13:06] +    |
[01:13:06] + note: candidate #1 is defined in an impl for the type `Foo`
[01:13:06] +   --> $DIR/arbitrary_self_types_lifetime.rs:26:5
[01:13:06] +    |
[01:13:06] + LL |     fn c(self: Bar<'_>) -> Bar<'_> {
[01:13:06] +    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[01:13:06] + note: candidate #2 is defined in an impl for the type `Bar<'_>`
[01:13:06] +   --> $DIR/arbitrary_self_types_lifetime.rs:51:5
[01:13:06] +    |
[01:13:06] + LL |     fn c(self: Bar<'a>, f: &Foo) -> (Self, &Foo) { (self, f) }
[01:13:06] 23 
[01:13:06] + error: aborting due to 2 previous errors
[01:13:06] + 
[01:13:06] + For more information about this error, try `rustc --explain E0034`.
[01:13:06] + For more information about this error, try `rustc --explain E0034`.
[01:13:06] 24 
[01:13:06] 
[01:13:06] 
[01:13:06] The actual stderr differed from the expected stderr.
[01:13:06] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_lifetime/arbitrary_self_types_lifetime.stderr
[01:13:06] To update references, rerun the tests and pass the `--bless` flag
[01:13:06] To only update this specific test, also pass `--test-args self/arbitrary_self_types_lifetime.rs`
[01:13:06] error: 1 errors occurred comparing output.
[01:13:06] status: exit code: 1
[01:13:06] status: exit code: 1
[01:13:06] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/self/arbitrary_self_types_lifetime.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_lifetime" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_lifetime/auxiliary" "-A" "unused"
[01:13:06] ------------------------------------------
[01:13:06] 
[01:13:06] ------------------------------------------
[01:13:06] stderr:
[01:13:06] stderr:
[01:13:06] ------------------------------------------
[01:13:06] error: cannot infer an appropriate lifetime
[01:13:06]   --> /checkout/src/test/ui/self/arbitrary_self_types_lifetime.rs:39:9
[01:13:06]    |
[01:13:06] LL |     fn f(self: Bar<'_>) -> impl std::fmt::Debug {
[01:13:06]    |                            -------------------- this return type evaluates to the `'static` lifetime...
[01:13:06]    |         ^^^^ ...but this borrow...
[01:13:06]    |
[01:13:06]    |
[01:13:06] note: ...can't outlive the anonymous lifetime #1 defined on the method body at 38:5
[01:13:06]   --> /checkout/src/test/ui/self/arbitrary_self_types_lifetime.rs:38:5
[01:13:06]    |
[01:13:06] LL | /     fn f(self: Bar<'_>) -> impl std::fmt::Debug {
[01:13:06] LL | |         //~^ ERROR cannot infer an appropriate lifetime
[01:13:06] LL | |     }
[01:13:06]    | |_____^
[01:13:06]    | |_____^
[01:13:06] help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 38:5
[01:13:06]    |
[01:13:06] LL |     fn f(self: Bar<'_>) -> impl std::fmt::Debug + '_ {
[01:13:06] 
[01:13:06] error[E0034]: multiple applicable items in scope
[01:13:06]   --> /checkout/src/test/ui/self/arbitrary_self_types_lifetime.rs:73:17
[01:13:06]    |
[01:13:06]    |
[01:13:06] LL |     { Bar(&foo).c() };
[01:13:06]    |                 ^ multiple `c` found
[01:13:06]    |
[01:13:06] note: candidate #1 is defined in an impl for the type `Foo`
[01:13:06]   --> /checkout/src/test/ui/self/arbitrary_self_types_lifetime.rs:26:5
[01:13:06]    |
[01:13:06] LL |     fn c(self: Bar<'_>) -> Bar<'_> {
[01:13:06]    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[01:13:06] note: candidate #2 is defined in an impl for the type `Bar<'_>`
[01:13:06]   --> /checkout/src/test/ui/self/arbitrary_self_types_lifetime.rs:51:5
[01:13:06]    |
[01:13:06] LL |     fn c(self: Bar<'a>, f: &Foo) -> (Self, &Foo) { (self, f) }
[01:13:06] 
[01:13:06] error: aborting due to 2 previous errors
[01:13:06] 
[01:13:06] For more information about this error, try `rustc --explain E0034`.
---
[01:13:06] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:512:22
[01:13:06] note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
[01:13:06] 
[01:13:06] 
[01:13:06] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:13:06] 
[01:13:06] 
[01:13:06] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:13:06] Build completed unsuccessfully in 0:04:48
[01:13:06] Build completed unsuccessfully in 0:04:48
[01:13:06] make: *** [check] Error 1
[01:13:06] Makefile:48: recipe for target 'check' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:20fb96cf
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Mon May 20 17:54:17 UTC 2019

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@bors
Copy link
Contributor

bors commented May 20, 2019

☀️ Try build successful - checks-travis
Build commit: 42445de

@cramertj
Copy link
Member

@craterbot run mode=check-only

@craterbot
Copy link
Collaborator

👌 Experiment pr-60944 created and queued.
🤖 Automatically detected try build 42445de
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@taiki-e taiki-e force-pushed the arbitrary_self_types-lifetime-elision branch from c799d4d to c0e3422 Compare May 21, 2019 02:58
bors added a commit that referenced this pull request May 21, 2019
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:0f2ed0e0:start=1558407553949009403,finish=1558407642786432471,duration=88837423068
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
[01:13:37] .................................................................................................... 4400/5534
[01:13:40] .................................................................................................... 4500/5534
[01:13:44] .................................................................................................... 4600/5534
[01:13:48] .................................................................................................... 4700/5534
[01:13:54] .........................................................................................F.......... 4800/5534
[01:14:01] .................................................................................................... 5000/5534
[01:14:05] .................................................................................................... 5100/5534
[01:14:08] .................................................................................................... 5200/5534
[01:14:12] .................................................................................................... 5300/5534
---
[01:14:19] normalized stderr:
[01:14:19] error: cannot infer an appropriate lifetime
[01:14:19]   --> $DIR/arbitrary_self_types_impl_trait_lifetime.rs:21:9
[01:14:19]    |
[01:14:19] LL |     fn f(self: Bar<'_>) -> impl std::fmt::Debug {
[01:14:19]    |                            -------------------- this return type evaluates to the `'static` lifetime...
[01:14:19]    |         ^^^^ ...but this borrow...
[01:14:19]    |
[01:14:19]    |
[01:14:19] note: ...can't outlive the anonymous lifetime #1 defined on the method body at 20:5
[01:14:19]   --> $DIR/arbitrary_self_types_impl_trait_lifetime.rs:20:5
[01:14:19]    |
[01:14:19] LL | /     fn f(self: Bar<'_>) -> impl std::fmt::Debug {
[01:14:19] LL | |
[01:14:19] LL | |     }
[01:14:19]    | |_____^
[01:14:19]    | |_____^
[01:14:19] help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 20:5
[01:14:19]    |
[01:14:19] LL |     fn f(self: Bar<'_>) -> impl std::fmt::Debug + '_ {
[01:14:19] 
[01:14:19] error: aborting due to previous error
[01:14:19] 
[01:14:19] 
[01:14:19] 
[01:14:19] 
[01:14:19] 
[01:14:19] The actual stderr differed from the expected stderr.
[01:14:19] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_impl_trait_lifetime/arbitrary_self_types_impl_trait_lifetime.stderr
[01:14:19] To update references, rerun the tests and pass the `--bless` flag
[01:14:19] To only update this specific test, also pass `--test-args self/arbitrary_self_types_impl_trait_lifetime.rs`
[01:14:19] error: 1 errors occurred comparing output.
[01:14:19] status: exit code: 1
[01:14:19] status: exit code: 1
[01:14:19] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/self/arbitrary_self_types_impl_trait_lifetime.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_impl_trait_lifetime" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/self/arbitrary_self_types_impl_trait_lifetime/auxiliary" "-A" "unused"
[01:14:19] ------------------------------------------
[01:14:19] 
[01:14:19] ------------------------------------------
[01:14:19] stderr:
[01:14:19] stderr:
[01:14:19] ------------------------------------------
[01:14:19] error: cannot infer an appropriate lifetime
[01:14:19]   --> /checkout/src/test/ui/self/arbitrary_self_types_impl_trait_lifetime.rs:21:9
[01:14:19]    |
[01:14:19] LL |     fn f(self: Bar<'_>) -> impl std::fmt::Debug {
[01:14:19]    |                            -------------------- this return type evaluates to the `'static` lifetime...
[01:14:19]    |         ^^^^ ...but this borrow...
[01:14:19]    |
[01:14:19]    |
[01:14:19] note: ...can't outlive the anonymous lifetime #1 defined on the method body at 20:5
[01:14:19]    |
[01:14:19]    |
[01:14:19] LL | /     fn f(self: Bar<'_>) -> impl std::fmt::Debug {
[01:14:19] LL | |         //~^ ERROR cannot infer an appropriate lifetime
[01:14:19] LL | |     }
[01:14:19]    | |_____^
[01:14:19]    | |_____^
[01:14:19] help: you can add a constraint to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 20:5
[01:14:19]    |
[01:14:19] LL |     fn f(self: Bar<'_>) -> impl std::fmt::Debug + '_ {
[01:14:19] 
[01:14:19] error: aborting due to previous error
[01:14:19] 
[01:14:19] 
---
[01:14:19] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:512:22
[01:14:19] note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
[01:14:19] 
[01:14:19] 
[01:14:19] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:14:19] 
[01:14:19] 
[01:14:19] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:14:19] Build completed unsuccessfully in 0:04:37
[01:14:19] Build completed unsuccessfully in 0:04:37
[01:14:19] Makefile:48: recipe for target 'check' failed
[01:14:19] make: *** [check] Error 1
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0c9b81a0
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue May 21 04:15:11 UTC 2019
---
travis_time:end:0a52291a:start=1558412113350049912,finish=1558412113357189671,duration=7139759
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:09191202
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:13d40990
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@taiki-e taiki-e force-pushed the arbitrary_self_types-lifetime-elision branch from c0e3422 to 76ab65a Compare May 21, 2019 11:27
@@ -2121,6 +2121,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
_ => false,
};

// Only skip `Self`, `&Self` and `&mut Self`,
// and to handle other `self`s like normal arguments.
let mut should_skip = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename this to skip_self_arg?

@eddyb
Copy link
Member

eddyb commented May 22, 2019

This was intentional, in that we didn't want self: &'b Foo<'a, T> (inside impl<'a, T> Foo<'a, T> {...}) to be ambiguous, but rather use 'b - this is due to how particular the original implementation was, and we didn't want breakage.

If you start relying on the is_self_ty helper closure in order to ignore self arguments, you don't even need arbitrary_self_types to observe breakage.
Behavior will change for things like self: TypeAliasToSelf.

Ideally elision would've been syntactic from the start (since it's meant to be syntactically intuitive), but we dropped the ball on that. If we do a crater run, I suggest also experimenting with this part commented out:

// Can't always rely on literal (or implied) `Self` due
// to the way elision rules were originally specified.
let impl_self = impl_self.map(|ty| &ty.node);
if let Some(&hir::TyKind::Path(hir::QPath::Resolved(None, ref path))) = impl_self {
match path.res {
// Whitelist the types that unambiguously always
// result in the same type constructor being used
// (it can't differ between `Self` and `self`).
Res::Def(DefKind::Struct, _)
| Res::Def(DefKind::Union, _)
| Res::Def(DefKind::Enum, _)
| Res::PrimTy(_) => {
return res == path.res
}
_ => {}
}
}

@cramertj Could we special-case Pin<&mut Self>? Or more generally, use self: &mut Self elision rules even if nested in a Pin?
The fully general case could be a nightmare to untangle, likely for any particular behavior set we may pick.

@craterbot
Copy link
Collaborator

🎉 Experiment pr-60944 is completed!
📊 1 regressed and 0 fixed (60951 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the blacklist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels May 22, 2019
@Centril
Copy link
Contributor

Centril commented May 22, 2019

Looks like we have an ICE in the only "regression".

@cramertj
Copy link
Member

@eddyb I'm sorry, I'm not sure I understand-- could you write an example or two of the kind of thing that you wanted to support, but which wouldn't be allowed under this PR?

@withoutboats
Copy link
Contributor

@eddyb from your comment it seems the concern has to do with self types containing multiple lifetimes. I notice in particular you highlight cases where users have opted for using the actual self type instead of the Self alias in their receivers, something I didn't even realize was possible.

My naive expectation around this behavior:

  • Lifetimes from within the type that Self aliases to are ignored
  • Let's not even bother with rules for multiple lifetimes outside the self alias, which on stable should not be possible with the set of valid receivers we have stabilized.

@eddyb
Copy link
Member

eddyb commented May 23, 2019

using the actual self type instead of the Self alias in their receivers, something I didn't even realize was possible.

@withoutboats It probably should've been disallowed, yeah. I'd be curious to see the results of a crater run where that is just banned (I suspect we couldn't "just do that", but it would perhaps be useful to know.)

@cramertj Our testsuite might be lacking these examples, but this works on stable:

struct Foo<'a>(&'a ());
impl<'a> Foo<'a> {
    fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
}

type Alias = Foo<'static>;
impl Alias {
    fn bar<'a>(self: &Alias, arg: &'a ()) -> &() { arg }
}

And AFAICT, this PR changes the behavior in at least the latter case, as it relies on the (rather brittle) is_self_ty predicate to special-case self: S and self: &(mut) S (i.e. when is_self_ty(S)).

It otherwise uses regular rules, even for the self argument, which is inconsistent with the current elision rules (however depressing they may be), and has the "unknown unknowns" scary implication to me.

So what I think we should do is change the special-case of self: &(mut) S to instead visit the type of self and look for &(mut) S (where is_self_ty(S)) within it, which would make Pin<&mut S> work.
And we would still be ignoring the self argument otherwise.

@scottmcm
Copy link
Member

I see that the reference says

In method signatures there is another rule

  • If the receiver has type &Self or &mut Self, then the lifetime of that reference to Self is assigned to all elided output lifetime parameters.

Is that an accurate statement of the current rule? Does the self rule override the other rule always (even if it's self-by-value)?

@eddyb
Copy link
Member

eddyb commented May 24, 2019

@scottmcm Note that the rule applies to self: &Self and self: &Foo, when you're inside impl Foo {...} and it's not a type alias (so it's semi-syntactical I guess?).
If self is not a reference to Self, then the self argument is ignored, no matter what type it may have, and the general rule is applied to the rest of the arguments.

@taiki-e
Copy link
Member Author

taiki-e commented May 26, 2019

Closing this PR in favor of #61207.

@taiki-e taiki-e closed this May 26, 2019
@taiki-e taiki-e deleted the arbitrary_self_types-lifetime-elision branch May 27, 2019 14:17
bors added a commit that referenced this pull request May 28, 2019
…2, r=<try>

Allow lifetime elision in `Pin<&(mut) Self>`

This replaces #60944.

~~This PR changes elision rules to apply `self: &(mut) Self` elision rules even if nested in `Pin`.~~
This PR changes `self: &(mut) S` elision rules to instead visit the type of `self` and look for `&(mut) S` (where `is_self_ty(S)`) within it

Closes #52675

r? @eddyb
cc @cramertj @Centril @withoutboats @scottmcm
Centril added a commit to Centril/rust that referenced this pull request Jul 26, 2019
…me-elision-2, r=Centril

Allow lifetime elision in `Pin<&(mut) Self>`

This PR changes `self: &(mut) S` elision rules to instead visit the type of `self` and look for `&(mut) S` (where `is_self_ty(S)`) within it

Replaces rust-lang#60944

Closes rust-lang#52675

r? @eddyb
cc @cramertj @Centril @withoutboats @scottmcm
Centril added a commit to Centril/rust that referenced this pull request Jul 27, 2019
…me-elision-2, r=Centril

Allow lifetime elision in `Pin<&(mut) Self>`

This PR changes `self: &(mut) S` elision rules to instead visit the type of `self` and look for `&(mut) S` (where `is_self_ty(S)`) within it

Replaces rust-lang#60944

Closes rust-lang#52675

r? @eddyb
cc @cramertj @Centril @withoutboats @scottmcm
Centril added a commit to Centril/rust that referenced this pull request Jul 27, 2019
…me-elision-2, r=Centril

Allow lifetime elision in `Pin<&(mut) Self>`

This PR changes `self: &(mut) S` elision rules to instead visit the type of `self` and look for `&(mut) S` (where `is_self_ty(S)`) within it

Replaces rust-lang#60944

Closes rust-lang#52675

r? @eddyb
cc @cramertj @Centril @withoutboats @scottmcm
Centril added a commit to Centril/rust that referenced this pull request Jul 28, 2019
…me-elision-2, r=Centril

Allow lifetime elision in `Pin<&(mut) Self>`

This PR changes `self: &(mut) S` elision rules to instead visit the type of `self` and look for `&(mut) S` (where `is_self_ty(S)`) within it

Replaces rust-lang#60944

Closes rust-lang#52675

r? @eddyb
cc @cramertj @Centril @withoutboats @scottmcm
Centril added a commit to Centril/rust that referenced this pull request Aug 20, 2019
…amertj

Stabilize `async_await` in Rust 1.39.0

Here we stabilize:
- free and inherent `async fn`s,
- the `<expr>.await` expression form,
- and the `async move? { ... }` block form.

Closes rust-lang#62149.
Closes rust-lang#50547.

All the blockers are now closed.

<details>
- [x] FCP in rust-lang#62149
- [x] rust-lang#61949; PR in rust-lang#62849.
- [x] rust-lang#62517; PR in rust-lang#63376.
- [x] rust-lang#63225; PR in rust-lang#63501
- [x] rust-lang#63388; PR in rust-lang#63499
- [x] rust-lang#63500; PR in rust-lang#63501
- [x] rust-lang#62121 (comment)
    - [x] Some tests for control flow (PR rust-lang#63387):
          - `?`
          - `return` in `async` blocks
          - `break`
    - [x] rust-lang#61775 (comment), i.e. tests for rust-lang#60944 with `async fn`s instead). PR in rust-lang#63383

</details>

r? @cramertj
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

arbitrary_self_types don't support lifetime elision