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

Unsized rvalues: implement boxed closure impls. #55431

Closed
wants to merge 11 commits into from

Conversation

@qnighy
Copy link
Contributor

commented Oct 28, 2018

This pull request contains boxed_closure_impls that provides long-hoped three impls:

impl<A, F: FnOnce<A> + ?Sized> FnOnce<A> for Box<F> { .. }
impl<A, F: FnMut<A> + ?Sized> FnMut<A> for Box<F> { .. }
impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> { .. }

This has been blocked by several reasons; see FnBox #28796 for details.

Now that #48055 is (partly) implemented, we're ready to introduce the above impls, replacing existing FnBox workarounds.

There are two major concerns, however.

Major concern 1: instability

I think these impls should be introduced as an unstable feature first, mainly because it relies on unsized rvalues. However, impl itself can't stand as unstable; all existing unstable features are tied with functions, methods, or types. I tried putting #[unstable] on the impls but that didn't work. I'll mark this PR as [WIP] until it is resolved. I'll just remove [WIP] and let the compiler team decide how to deal with the instability.

Major concern 2: compatibility with FnBox

I'm not really sure, but FnBox may be widely used in the nightly world. Although unstable features may regress, it's good if there's a path for gradual migration. It can be done in the following way:

  • Make FnBox a subtrait of FnOnce. This ensures that dyn FnBox implements FnOnce.
  • Make use of specialization to avoid overlap between FnOnce impls for Box<impl FnOnce> and Box<dyn FnBox>.

I believe that this minimizes breakage of crates that use FnBox.

Minor concern: feature name and tracking issue

I currently assign boxed_closure_impls as the name and #48055 as the tracking issue. I'll prepare a separate tracking issue when the Major Concern 1 is resolved.

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented Oct 28, 2018

r? @frewsxcv

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

@rust-highfive

This comment was marked as resolved.

Copy link
Collaborator

commented Oct 28, 2018

The job x86_64-gnu-llvm-5.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:01148c20:start=1540709908911124858,finish=1540709963285862772,duration=54374737914
$ 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
Setting environment variables from .travis.yml
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
---
[00:48:58] .................................................................................................... 100/4972
[00:49:01] .................................................................................................... 200/4972
[00:49:04] .................................................................................................... 300/4972
[00:49:07] .................................................................................................... 400/4972
[00:49:11] ..................................FF................................................................ 500/4972
[00:49:19] .................................................................................................... 700/4972
[00:49:26] ...........................................................i...........i............................ 800/4972
[00:49:29] .............................................................................iiiii.................. 900/4972
[00:49:33] .................................................................................................... 1000/4972
---
[00:51:12] .................................................................................................... 4000/4972
[00:51:15] .................................................................................................... 4100/4972
[00:51:19] ......................................................................i............................. 4200/4972
[00:51:25] .................................................................................................... 4300/4972
[00:51:28] ........................................................F........................................... 4400/4972
[00:51:36] ..........................................i......................................................... 4600/4972
[00:51:40] .................................................................................................... 4700/4972
[00:51:46] .................................................................................................... 4900/4972
[00:51:46] .................................................................................................... 4900/4972
/two-phase-nonrecv-autoref.rs","byte_start":4970,"byte_end":4983,"line_start":139,"line_end":139,"column_start":5,"column_end":18,"is_primary":false,"text":[{"text":"    double_access(&mut a, &a);","highlight_start":5,"highlight_end":18}],"label":"mutable borrow later used by call","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable\n  --> /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:139:27\n   |\nLL |     double_access(&mut a, &a);\n   |     ------------- ------  ^^ immutable borrow occurs here\n   |     |             |\n   |     |             mutable borrow occurs here\n   |     mutable borrow later used by call\n\n"}
[00:51:48] {"message":"cannot borrow `i` as immutable because it is also borrowed as mutable","code":{"code":"E0502","explanation":"\nThis error indicates that you are trying to borrow a variable as mutable when it\nhas already been borrowed as immutable.\n\nExample of erroneous code:\n\n```compile_fail,E0502\nfn bar(x: &mut i32) {}\nfn foo(a: &mut i32) {\n    let ref y = a; // a is borrowed as immutable.\n    bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed\n            //        as immutable\n}\n```\n\nTo fix this error, ensure that you don't have any other references to the\nvariable before trying to access it mutably:\n\n```\nfn bar(x: &mut i32) {}\nfn foo(a: &mut i32) {\n    bar(a);\n    let ref y = a; // ok!\n}\n```\n\nFor more information on the rust ownership system, take a look at\nhttps://doc.rust-lang.org/stable/book/refstart":5787,"byte_end":5788,"line_start":167,"line_end":167,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":"    i[i[3]] = 4;","highlight_start":7,"highlight_end":8}],"label":"immutable borrow occurs here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"/checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs","byte_start":5785,"byte_end":5786,"line_start":167,"line_end":167,"column_start":5,"column_end":6,"is_primary":false,"text":[{"text":"    i[i[3]] = 4;","highlight_start":5,"highlight_end":6}],"label":"mutable borrow occurs here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"/checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs","byte_start":5791,"byte_end":5792,"line_start":167,"line_end":167,"column_start":11,"column_end":12,"is_primary":false,"text":[{"text":"    i[i[3]] = 4;","highlight_start":11,"highlight_end":12}],"label":"mutable borrow ends here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0502]: cannot borrow `i` as immutable because it is also borrowed as mutable\n  --> /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:167:7\n   |\nLL |     i[i[3]] = 4;\n   |     - ^   - mutable borrow ends here\n   |     | |\n   |     | immutable borrow occurs here\n   |     mutable borrow occurs here\n\n"}
[00:51:48] {"message":"cannot borrow `i` as immutable because it is also borrowed as mutable","code":{"code":"E0502","explanation":"\nThis error indicates that you are trying to borrow a variable as mutable when it\nhas already

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)

@rust-highfive

This comment was marked as resolved.

Copy link
Collaborator

commented Oct 28, 2018

The job x86_64-gnu-llvm-5.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:00658f30:start=1540726071786761911,finish=1540726164927521186,duration=93140759275
$ 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
Setting environment variables from .travis.yml
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
---
[00:47:19] .................................................................................................... 100/4972
[00:47:22] .................................................................................................... 200/4972
[00:47:25] .................................................................................................... 300/4972
[00:47:28] .................................................................................................... 400/4972
[00:47:31] .................................F.F................................................................ 500/4972
[00:47:39] .................................................................................................... 700/4972
[00:47:44] ...........................................................i...........i............................ 800/4972
[00:47:47] .............................................................................iiiii.................. 900/4972
[00:47:51] .................................................................................................... 1000/4972
---
[00:49:23] .................................................................................................... 4000/4972
[00:49:26] .................................................................................................... 4100/4972
[00:49:29] ......................................................................i............................. 4200/4972
[00:49:34] .................................................................................................... 4300/4972
[00:49:37] ........................................................F........................................... 4400/4972
[00:49:44] ..........................................i......................................................... 4600/4972
[00:49:48] .................................................................................................... 4700/4972
[00:49:50] .................................................................................................... 4800/4972
[00:49:53] .................................................................................................... 4900/4972
[00:49:53] .................................................................................................... 4900/4972
[00:49:55] ...........i............................................................
[00:49:55] failures:
[00:49:55] 
[00:49:55] ---- [ui] ui/borrowck/two-phase-nonrecv-autoref.rs#ast stdout ----
[00:49:55] 
[00:49:55] error in revision `ast`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:79: unexpected error: '79:11: 79:12: use of moved value: `f` [E0382]'
[00:49:55] 
[00:49:55] error in revision `ast`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:95: unexpected error: '95:11: 95:12: use of moved value: `f` [E0382]'
[00:49:55] 
[00:49:55] error in revision `ast`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:79: expected error not found: use of moved value: `*f`
[00:49:55] 
[00:49:55] error in revision `ast`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:95: expected error not found: use of moved value: `*f`
[00:49:55] 
[00:49:55] error in revision `ast`: 2 unexpected errors found, 2 expected errors not found
[00:49:55] status: exit code: 1
[00:49:55] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs" "--target=x86_64-unknown-linux-gnu" "--cfg" "ast" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/borrowck/two-phase-nonrecv-autoref.ast/a" "-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/borrowck/two-phase-nonrecv-autoref.ast/auxiliary" "-A" "unused"
[00:49:55]     Error {
[00:49:55]         line_num: 79,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "79:11: 79:12: use of moved value: `f` [E0382]"
[00:49:55]     Error {
[00:49:55]         line_num: 95,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "95:11: 95:12: use of moved value: `f` [E0382]"
[00:49:55] ]
[00:49:55] 
[00:49:55] not found errors (from test file): [
[00:49:55]     Error {
[00:49:55]     Error {
[00:49:55]         line_num: 79,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "use of moved value: `*f`"
[00:49:55]     Error {
[00:49:55]         line_num: 95,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "use of moved value: `*f`"
[00:49:55] ]
[00:49:55] 
[00:49:55] thread '[ui] ui/borrowck/two-phase-nonrecv-autoref.rs#ast' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1358:13
[00:49:55] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:49:55] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[00:49:55] 
[00:49:55] ---- [ui] ui/borrowck/two-phase-nonrecv-autoref.rs#nll stdout ----
[00:49:55] 
[00:49:55] error in revision `nll`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:79: unexpected error: '79:11: 79:12: use of moved value: `f` [E0382]'
[00:49:55] 
[00:49:55] error in revision `nll`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:95: unexpected error: '95:11: 95:12: use of moved value: `f` [E0382]'
[00:49:55] 
[00:49:55] error in revision `nll`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:79: expected error not found: use of moved value: `*f`
[00:49:55] 
[00:49:55] error in revision `nll`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:95: expected error not found: cannot move a value of type
[00:49:55] 
[00:49:55] error in revision `nll`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:95: expected error not found: cannot move a value of type
[00:49:55] 
[00:49:55] error in revision `nll`: /checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs:95: expected error not found: use of moved value: `*f`
[00:49:55] 
[00:49:55] error in revision `nll`: 2 unexpected errors found, 4 expected errors not found
[00:49:55] status: exit code: 1
[00:49:55] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/borrowck/two-phase-nonrecv-autoref.rs" "--target=x86_64-unknown-linux-gnu" "--cfg" "nll" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/borrowck/two-phase-nonrecv-autoref.nll/a" "-Crpath" "-O" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-Z" "borrowck=mir" "-Z" "two-phase-borrows" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/borrowck/two-phase-nonrecv-autoref.nll/auxiliary" "-A" "unused"
[00:49:55]     Error {
[00:49:55]         line_num: 79,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "79:11: 79:12: use of moved value: `f` [E0382]"
[00:49:55]     Error {
[00:49:55]         line_num: 95,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "95:11: 95:12: use of moved value: `f` [E0382]"
[00:49:55] ]
[00:49:55] 
[00:49:55] not found errors (from test file): [
[00:49:55]     Error {
[00:49:55]     Error {
[00:49:55]         line_num: 79,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "use of moved value: `*f`"
[00:49:55]     Error {
[00:49:55]         line_num: 95,
[00:49:55]         kind: Some(
[00:49:55]             Error
---
[00:49:55]         line_num: 95,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "use of moved value: `*f`"
[00:49:55] ]
[00:49:55] 
[00:49:55] thread '[ui] ui/borrowck/two-phase-nonrecv-autoref.rs#nll' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1358:13
[00:49:55] 
[00:49:55] 
[00:49:55] ---- [ui] ui/span/borrowck-call-is-borrow-issue-12224.rs stdout ----
[00:49:55] 
[00:49:55] error: /checkout/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs:44: unexpected error: '44:5: 44:8: cannot borrow field `f.f` of immutable binding as mutable [E0596]'
[00:49:55] 
[00:49:55] error: /checkout/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs:44: expected error not found: cannot borrow `Box` content `*f.f` of immutable binding as mutable
[00:49:55] error: 1 unexpected errors found, 1 expected errors not found
[00:49:55] status: exit code: 1
[00:49:55] status: exit code: 1
[00:49:55] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/span/borrowck-call-is-borrow-issue-12224.rs" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/span/borrowck-call-is-borrow-issue-12224/a" "-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/span/borrowck-call-is-borrow-issue-12224/auxiliary" "-A" "unused"
[00:49:55]     Error {
[00:49:55]         line_num: 44,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "44:5: 44:8: cannot borrow field `f.f` of immutable binding as mutable [E0596]"
[00:49:55] ]
[00:49:55] 
[00:49:55] not found errors (from test file): [
[00:49:55]     Error {
[00:49:55]     Error {
[00:49:55]         line_num: 44,
[00:49:55]         kind: Some(
[00:49:55]             Error
[00:49:55]         ),
[00:49:55]         msg: "cannot borrow `Box` content `*f.f` of immutable binding as mutable"
[00:49:55] ]
[00:49:55] 
[00:49:55] thread '[ui] ui/span/borrowck-call-is-borrow-issue-12224.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1358:13
[00:49:55] 
---
[00:49:55] 
[00:49:55] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:503:22
[00:49:55] 
[00:49:55] 
[00:49:55] 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-gnuout!\(.*\)|\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:06917076
travis_time:start:06917076
$ 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:0696c702
$ 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)

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented Oct 28, 2018

The job x86_64-gnu-llvm-5.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:0f20aec0:start=1540737014979086364,finish=1540737068428273499,duration=53449187135
$ 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
Setting environment variables from .travis.yml
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
---
[00:51:15] .................................................................................................... 2200/4972
[00:51:19] .................................................................................................... 2300/4972
[00:51:23] .................................................................................................... 2400/4972
[00:51:27] .................................................................................................... 2500/4972
[00:51:30] ............................................................iiiiiiiii............................... 2600/4972
[00:51:37] ..........ii........................................................................................ 2800/4972
[00:51:39] .................................................................................................... 2900/4972
[00:51:43] .................................................................................................... 3000/4972
[00:51:46] .....i.............................................................................................. 3100/4972
---
travis_time:start:test_codegen
Check compiletest suite=codegen mode=codegen (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:04:41] 
[01:04:41] running 112 tests
[01:04:44] i..ii...iii.......i...i.........i..iii...........i.....i.....ii...i..i.ii..............i...ii..ii.i. 100/112
[01:04:44] test result: ok. 82 passed; 0 failed; 30 ignored; 0 measured; 0 filtered out
[01:04:44] 
[01:04:44]  finished in 3.451
[01:04:44] travis_fold:end:test_codegen
---
[01:39:47] 
[01:39:47] 
[01:39:47] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:39:47] Build completed unsuccessfully in 0:53:20
[01:39:47] make: *** [check] Error 1
[01:39:47] Makefile:58: recipe for target 'check' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:03b33118
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
---
travis_time:end:133bb880:start=1540743076301033206,finish=1540743076305694415,duration=4661209
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0beb0618
$ 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 pr

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)

@bjorn3

This comment has been minimized.

Copy link
Contributor

commented Oct 28, 2018

@TimNN ^ not very helpful

@alexreg

This comment has been minimized.

Copy link
Contributor

commented Nov 5, 2018

FnBox was only ever a stop-gap solution, and highly unstable. I really wouldn't worry about migration, and would just obsolete it immediately in favour of this, if it works just as well/better in all circumstances.

@Mark-Simulacrum

This comment has been minimized.

Copy link
Member

commented Nov 15, 2018

I've re-assigned this to @nikomatsakis since I think it'll probably want lang/compiler team discussion or review.

@XAMPPRocky

This comment has been minimized.

Copy link
Contributor

commented Nov 25, 2018

Triage; @nikomatsakis Hello, have you been able to get back to this PR?

@Dylan-DPC

This comment has been minimized.

Copy link
Member

commented Dec 3, 2018

CI fails with:

[01:39:47] failures:
[01:39:47] 
[01:39:47] ---- /checkout/src/doc/unstable-book/src/library-features/boxed-closure-impls.md - boxed_closure_impls::Usage (line 27) stdout ----
[01:39:47] error[E0057]: this function takes 1 parameter but 0 parameters were supplied
[01:39:47]   --> /checkout/src/doc/unstable-book/src/library-features/boxed-closure-impls.md:40:5
[01:39:47]    |
[01:39:47] 14 |     f();
[01:39:47]    |     ^^^ expected 1 parameter
[01:39:47] 
[01:39:47] thread '/checkout/src/doc/unstable-book/src/library-features/boxed-closure-impls.md - boxed_closure_impls::Usage (line 27)' panicked at 'couldn't compile the test', librustdoc/test.rs:332:13
[01:39:47] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[01:39:47] 
[01:39:47] 
[01:39:47] failures:
[01:39:47]     /checkout/src/doc/unstable-book/src/library-features/boxed-closure-impls.md - boxed_closure_impls::Usage (line 27)
[01:39:47] 
[01:39:47] test result: FAILED. 0 passed; 1 failed; 4 ignored; 0 measured; 0 filtered out
[01:39:47] 
[01:39:47] 
[01:39:47] stderr ----
[01:39:47] 
[01:39:47] 
[01:39:47] 
[01:39:47] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:39:47] Build completed unsuccessfully in 0:53:20
[01:39:47] make: *** [check] Error 1
[01:39:47] Makefile:58: recipe for target 'check' failed
@Dylan-DPC

This comment has been minimized.

Copy link
Member

commented Dec 3, 2018

Pinging from triage @rust-lang/compiler can anyone review this?

@eddyb

This comment has been minimized.

Copy link
Member

commented Dec 3, 2018

This is not really a compiler change. Maybe @rust-lang/lang + @rust-lang/libs?

@cramertj

This comment has been minimized.

Copy link
Member

commented Dec 3, 2018

@eddyb I think it is compiler-relevant since one of the core questions in the PR description is how to make use of the new impls unstable:

However, impl itself can't stand as unstable; all existing unstable features are tied with functions, methods, or types. I tried putting #[unstable] on the impls but that didn't work. I'll mark this PR as [WIP] until it is resolved.

This isn't possible today, and it's hard for me to understand how it could become possible: we'd have to somehow gate all coercions, where clauses, transitive uses (e.g. trait MyTrait {} impl<T> MyTrait for T where T: FnOnce() { ... }) etc. I'm personally fine exposing this from the lang side as it seems obvious that these impls should exist somehow. The only hold-up I would have is if we accidentally make it backwards-incompatible to change the impl of FnOnce for Box<T> to avoid alloca by passing self by-pointer and dropping the allocated memory after the call. I can't think of many reasonable ways that a user could be relying on the alloca + move-to-stack occurring, though, so I think this is fine and I don't see a reason not to land these impls now that we finally can.

@eddyb

This comment has been minimized.

Copy link
Member

commented Dec 3, 2018

@cramertj I think that's a lang team discussion topic - that is, whether we should just stabilize now, given that feature-gating is hard (or even impossible).
Maybe we should start an FCP merge on this PR?

@cramertj

This comment has been minimized.

Copy link
Member

commented Dec 3, 2018

@rfcbot fcp merge

This change introduces the following (insta-stable) trait impls:

impl<A, F: FnOnce<A> + ?Sized> FnOnce<A> for Box<F> { .. }
impl<A, F: FnMut<A> + ?Sized> FnMut<A> for Box<F> { .. }
impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> { .. }

Defining these impls requires the use of the unsized_locals feature and we'd ideally like to gate these impls since they rely on unstable features in order to make it possible to implement them (i.e. it's not just this particular impl that is unstable as with e.g. most of std, but implementing them at all is impossible without the unstable feature or some extra-clever and probably UB hacks).

However, we don't have the machinery (and possibly won't ever have the machinery) to make trait impls unstable. As such, merging this PR makes Box<FnOnce()> instantly call-able on stable.

These implementations have been desired for a long time but have been impossible to add until now. I'm not sure of any other reasonable ways to implement them, or any ways that we might want to change the implementations going forward in a user-observable way.

@rfcbot

This comment has been minimized.

Copy link

commented Dec 3, 2018

Team member @cramertj has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@Centril

This comment has been minimized.

Copy link
Contributor

commented Dec 3, 2018

Is there a particular reason to stabilize these impls now rather than to wait until unsized_locals is stable?

@alexreg

This comment has been minimized.

Copy link
Contributor

commented Dec 3, 2018

@Centril The surface area is much smaller for these three impls, I guess, and they cover a large portion of the urgent demand for unsized locals at the same time.

@alexcrichton

This comment has been minimized.

Copy link
Member

commented Dec 4, 2018

@rfcbot concern unimplementable-if-unsized-does-not-pan-out

Historically we've avoiding expanding the stable API surface area of the standard library with unstable features. One of the best examples here is specialization where we've exclusively used it so far for performance improvements and we haven't started to use it for actually expanding trait impls yet. The rationale for this is that we can probably recover performance via other means if absolutely necessary if the unstable feature (specialization) doesn't pan out.

Do we have a similar recourse for this? What if the unstable feature doesn't pan out? Are we confident enough that we can provide this implementation for all of time?

@cramertj

This comment has been minimized.

Copy link
Member

commented Dec 4, 2018

@alexcrichton So I'd argue this is implementable even if the current unsized-rvalues-using-alloca proposal doesn't shake out-- we can still pass self by-pointer into the method and clean up the memory for the Box after the fact, or add a vtable shim to FnOnce specifically that takes Box<Self>. I think we definitely want self-by-value to be object-safe for all the benefits it gives, so I'd argue we want something that can provide this functionality regardless of whether the current feature as-implemented shakes out.

Compared with specialization, where exactly which implementations are allowed and when overlaps may occur is still open to soundness-related debate, the likelihood of the API surface needing to change here is far smaller. Basically the only thing that's being promised here is "there is some way to call FnOnce::call_once on a Box<dyn FnOnce()>". I think there are enough alternatives (pass-by-pointer, a special vtable shim which takes Box<Self>, etc.) that we can feel safe providing this API.

@cramertj

This comment has been minimized.

Copy link
Member

commented Dec 4, 2018

@Centril

Is there a particular reason to stabilize these impls now rather than to wait until unsized_locals is stable?

Box<dyn FnOnce(..) -> ...> working would be a massive improvement to the ergonomics of lots of code which currently relies on hacky custom traits for every function signature needed. As I said above in my response to @alexcrichton, I feel like the API surface being provided here is high value, small, and low-risk enough that it needn't be blocked by the much larger and more complex unsized_locals feature.

@alexcrichton

This comment has been minimized.

Copy link
Member

commented Dec 4, 2018

@rfcbot resolve unimplementable-if-unsized-does-not-pan-out

Sounds solid to me, thanks for the explanation!

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented Feb 12, 2019

The job dist-various-2 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.
[01:04:38] [RUSTC-TIMING] unwind test:false 0.204
[01:04:43] [RUSTC-TIMING] alloc test:false 6.820
[01:04:43]    Compiling panic_unwind v0.0.0 (/checkout/src/libpanic_unwind)
[01:04:43] [RUSTC-TIMING] panic_unwind test:false 0.330
[01:05:03] LLVM ERROR: Cannot emit physreg copy instruction
[01:05:03] error: Could not compile `std`.
[01:05:03] 
[01:05:03] To learn more, run the command again with --verbose.
[01:05:03] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnux32" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace" "--manifest-path" "/checkout/src/libstd/Cargo.toml" "--message-format" "json"
---
travis_time:end:113fb929:start=1549973353881619914,finish=1549973353900423172,duration=18803258
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:1f971700
$ 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:073fe639
travis_time:start:073fe639
$ 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:01269dbe
$ 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)

@bjorn3

This comment has been minimized.

Copy link
Contributor

commented Feb 12, 2019

[01:05:03] LLVM ERROR: Cannot emit physreg copy instruction

😭

@kennytm

This comment has been minimized.

Copy link
Member

commented Feb 12, 2019

Sounds like #45417

@cramertj

This comment has been minimized.

Copy link
Member

commented Feb 12, 2019

@kennytm Sorry, I see you marked this as waiting-on-author-- is there something that needs to be changed here, or is CI just flaking?

@kennytm

This comment has been minimized.

Copy link
Member

commented Feb 13, 2019

@cramertj the error is #55431 (comment) on the gnux32 target, and it doesn't look like an existing spurious error. Probably hit an LLVM bug. So this is waiting for the author (or anybody else) to debug why is this happening and how to fix/workaround it.

@qnighy

This comment has been minimized.

Copy link
Contributor Author

commented Feb 17, 2019

Easily reproduced in my machine by setting target = ["x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnux32"]. No further progress yet.

@Dylan-DPC

This comment has been minimized.

Copy link
Member

commented Feb 25, 2019

ping from triage @qnighy any updates?

@Dylan-DPC

This comment has been minimized.

Copy link
Member

commented Mar 11, 2019

ping frm triage @qnighy
Unfortunately we haven't heard from you on this in a while, so I'm closing the PR to keep things tidy. Don't worry though, if you'll have time again in the future please reopen this PR, we'll be happy to review it again! Thanks for contributing.

@cramertj

This comment has been minimized.

Copy link
Member

commented Mar 11, 2019

Procedurally it seems a bit odd to me to close a perfectly fine PR due to it being unmergable as a result of happening to trigger a suspected LLVM bug. To be clear, there's no requested change to the code in this PR-- only a change to LLVM to successfully compile it.

@Centril

This comment has been minimized.

Copy link
Contributor

commented Mar 11, 2019

@cramertj This is entirely by the book:

If the author’s been unresponsive for more than 14 days, close the PR due to inactivity and ask the author to reopen when they have a chance to make the necessary changes. Make sure to thank the author for the changes. Also tag the PR with S-inactive-closed.

If there has been no meaningful updates after two triage updates, with no meaningful being defined as no commits or no status updates that show progress (i.e. “Soon TM”). The PR should be closed due to prolonged inactivity and ask the author to reopen when they have a chance to make the necessary changes. Make sure to thank the author for the changes, and warn them not to push to the PR while it is closed as GitHub will prevent the PR from being reopened. Make sure to also tag the PR with S-inactive-closed.

Once the LLVM issues can be fixed the PR should be reopened.

@cramertj

This comment has been minimized.

Copy link
Member

commented Mar 11, 2019

ask the author to reopen when they have a chance to make the necessary changes

This sounds like we're asking the author for changes. There are no changes being requested here.

@Centril

This comment has been minimized.

Copy link
Contributor

commented Mar 11, 2019

Or generally actions (e.g. "fix LLVM") that unblocks the PR. Perhaps this should be labeled as S-blocked-closed.

@earthengine

This comment has been minimized.

Copy link

commented Mar 20, 2019

Are there any investigations have been done on LLVM? Can anyone find a workaround (maybe not optimal; we need it to be workable)?

bors added a commit that referenced this pull request Mar 28, 2019

Auto merge of #59500 - crlf0710:boxed-closure-impls, r=<try>
Unsized rvalues: implement boxed closure impls. (2nd try)

This is a rebase of S-blocked-closed PR #55431 to current master. LLVM has moved forward since then, so maybe we can check whether the new LLVM 8.0 version unblocked this work.

Centril added a commit to Centril/rust that referenced this pull request Apr 5, 2019

Rollup merge of rust-lang#59500 - crlf0710:boxed-closure-impls, r=cra…
…mertj

Unsized rvalues: implement boxed closure impls. (2nd try)

This is a rebase of S-blocked-closed PR rust-lang#55431 to current master. LLVM has moved forward since then, so maybe we can check whether the new LLVM 8.0 version unblocked this work.

Centril added a commit to Centril/rust that referenced this pull request Apr 5, 2019

Rollup merge of rust-lang#59500 - crlf0710:boxed-closure-impls, r=cra…
…mertj

Unsized rvalues: implement boxed closure impls. (2nd try)

This is a rebase of S-blocked-closed PR rust-lang#55431 to current master. LLVM has moved forward since then, so maybe we can check whether the new LLVM 8.0 version unblocked this work.

bors added a commit that referenced this pull request Apr 5, 2019

Auto merge of #59500 - crlf0710:boxed-closure-impls, r=cramertj
Unsized rvalues: implement boxed closure impls. (2nd try)

This is a rebase of S-blocked-closed PR #55431 to current master. LLVM has moved forward since then, so maybe we can check whether the new LLVM 8.0 version unblocked this work.
@alexreg

This comment has been minimized.

Copy link
Contributor

commented Apr 10, 2019

Has this bug been reported to LLVM? Does anyone have a link?

@kennytm

This comment has been minimized.

Copy link
Member

commented Apr 10, 2019

@alexreg Please follow #59674 for the LLVM bug.

@alexreg

This comment has been minimized.

Copy link
Contributor

commented Apr 11, 2019

So, it looks like this PR has effectively been implemented and merged in #59500. Great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.