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

typeck: Fix ICE with struct update syntax #50643

Merged
merged 1 commit into from
May 13, 2018
Merged

Conversation

dlrobertson
Copy link
Contributor

@dlrobertson dlrobertson commented May 11, 2018

If check_expr_struct_fields fails, do not continue to record update.
If we continue to record update, the struct may cause us to ICE later
on indexing a field that may or may not exist.

Fixes: #50618

@rust-highfive
Copy link
Collaborator

r? @eddyb

(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 11, 2018
@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-3.9 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.
Check compiletest suite=compile-fail mode=compile-fail (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
[01:00:21] 
[01:00:21] running 2311 tests
[01:00:26] ....................................................................................................
[01:00:32] ................................................................F...................................
[01:00:38] .......................................F..............F.............................................
[01:00:51] ....................i............................................................ii.iii.............
[01:00:58] ....................................................................................................
[01:01:05] ..........i..............................i..........................................................
[01:01:11] ....................................................................................................
---
[01:03:20] failures:
[01:03:20] 
[01:03:20] ---- [compile-fail] compile-fail/borrowck/borrowck-field-sensitivity.rs stdout ----
[01:03:20]  
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-field-sensitivity.rs:24: expected error not found: use of moved value: `*x.b`
[01:03:20] 
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-field-sensitivity.rs:37: expected error not found: use of moved value: `x.b`
[01:03:20] 
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-field-sensitivity.rs:51: expected error not found: cannot move out of `x.b` because it is borrowed
[01:03:20] 
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-field-sensitivity.rs:72: expected error not found: use of moved value: `x.b`
[01:03:20] 
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-field-sensitivity.rs:78: expected error not found: use of moved value: `x.b`
[01:03:20] 
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-field-sensitivity.rs:84: expected error not found: use of moved value: `x.b`
[01:03:20] 
[01:03:20] error: 0 unexpected errors found, 6 expected errors not found
[01:03:20] status: exit code: 101
[01:03:20] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/borrowck/borrowck-field-sensitivity.rs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--target=x86_64-unknown-linux-gnu" "--error-forma "use of moved value: `x.b`"
[01:03:20]     Error {
[01:03:20]         line_num: 84,
[01:03:20]         kind: Some(
[01:03:20]             Error
[01:03:20]             Error
[01:03:20]         ),
[01:03:20]         msg: "use of moved value: `x.b`"
[01:03:20] ]
[01:03:20] 
[01:03:20] thread '[compile-fail] compile-fail/borrowck/borrowck-field-sensitivity.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1312:13
[01:03:20] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[01:03:20] note: Run with `RUST_BACKTRACE=1` for a backtrace.
[01:03:20] 
[01:03:20] ---- [compile-fail] compile-fail/borrowck/borrowck-struct-update-with-dtor.rs stdout ----
[01:03:20]  
[01:03:20] error in revision `ast`: /checkout/src/test/compile-fail/borrowck/borrowck-struct-update-with-dtor.rs:31: expected error not found: cannot move out of type `T`, which implements the `Drop` trait
[01:03:20] 
[01:03:20] error in revision `ast`: 0 unexpected errors found, 1 expected errors not found
[01:03:20] status: exit code: 101
[01:03:20] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/borrowck/borrowck-struct-update-with-dtor.rs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--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/compile-fail/borrowck/borrowck-struct-update-with-dtor.stage2-x86_64-unknown-linux-gnu" "-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/compile-fail/borrowck/borrowck-struct-update-with-dtor.stage2-x86_64-unknown-linux-gnu.aux" "-A" "unused"
[01:03:20] not found errors (from test file): [
[01:03:20]     Error {
[01:03:20]         line_num: 31,
[01:03:20]         kind: Some(
[01:03:20]         ),
[01:03:20]         ),
[01:03:20]         msg: "cannot move out of type `T`, which implements the `Drop` trait"
[01:03:20] ]
[01:03:20] 
[01:03:20] thread '[compile-fail] compile-fail/borrowck/borrowck-struct-update-with-dtor.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1312:13
[01:03:20] 
[01:03:20] 
[01:03:20] ---- [compile-fail] compile-fail/borrowck/borrowck-use-mut-borrow.rs stdout ----
[01:03:20]  
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-use-mut-borrow.rs:49: expected error not found: cannot use `x.a` because it was mutably borrowed
[01:03:20] 
[01:03:20] error: /checkout/src/test/compile-fail/borrowck/borrowck-use-mut-borrow.rs:57: expected error not found: cannot use `x.a` because it was mutably borrowed
[01:03:20] 
[01:03:20] error: 0 unexpected errors found, 2 expected errors not found
[01:03:20] status: exit code: 101
[01:03:20] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/compile-fail/borrowck/borrowck-use-mut-borrow.rs" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail/borrowck/borrowck-use-mut-borrow.stage2-x86_64-unknown-linux-gnu" "-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/compile-fail/borrowck/borrowck-use-mut-borrow.stage2-x86_64-unknown-linux-gnu.aux" "-A" "unused"
[01:03:20] not found errors (from test file): [
[01:03:20]     Error {
[01:03:20]         line_num: 49,
[01:03:20]         kind: Some(
[01:03:20]         ),
[01:03:20]         ),
[01:03:20]         msg: "cannot use `x.a` because it was mutably borrowed"
[01:03:20]     Error {
[01:03:20]         line_num: 57,
[01:03:20]         kind: Some(
[01:03:20]             Error
[01:03:20]             Error
[01:03:20]         ),
[01:03:20]         msg: "cannot use `x.a` because it was mutably borrowed"
[01:03:20] ]
[01:03:20] 
[01:03:20] thread '[compile-fail] compile-fail/borrowck/borrowck-use-mut-borrow.rs' panicked at 'explicit panic', tools/compiletest/src/runtest.rs:1312:13
[01:03:20] 
---
[01:03:20] test result: FAILED. 2293 passed; 3 failed; 15 ignored; 0 measured; 0 filtered out
[01:03:20] 
[01:03:20] 
[01:03:20] 
[01:03:20] 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/compile-fail" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/compile-fail" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "compile-fail" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-3.9/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Zunstable-options " "--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" "3.9.1\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:03:20] 
[01:03:20] 
[01:03:20] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:03:20] Build completed unsuccessfully in 0:17:05
[01:03:20] Build completed unsuccessfully in 0:17:05
[01:03:20] Makefile:58: recipe for target 'check' failed
[01:03:20] make: *** [check] Error 1

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:008c38f0
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)

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)

@pietroalbini pietroalbini added the beta-nominated Nominated for backporting to the compiler in the beta channel. label May 11, 2018
@pietroalbini
Copy link
Member

Nominating for beta, this fixes a regression.

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

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

Please add the test case from the issue as a ui test with a // compile-pass comment to ensure that we don't regress this in the future

// If typeck failed we cannot trust this expr to be valid.
// Finding a index for a field cause us to panic if the
// structure does not have the field.
let is_mentioned = if !self.tcx().sess.has_errors() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This check aborts in more cases than necessary (as shown by the failing tests).

You replace the any-closure's body with

let hir_id = self.tcx().hir.node_to_hir_id(f.id);
self.mc.tables.field_indices().get(hir_id).cloned().map_or(true, |idx| ixd == f_index)

Which is essentially the body of the field_index function, but without the panic. Definitely keep the above comment and maybe add a note as to why we can't use the field_index function.

@oli-obk oli-obk assigned oli-obk and unassigned eddyb May 11, 2018
@nagisa nagisa added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 11, 2018
@dlrobertson dlrobertson changed the title middle: Do not index struct fields if typck failed typeck: Fix ICE with struct update syntax May 12, 2018
@dlrobertson
Copy link
Contributor Author

@oli-obk I should have commented on the PR as well. I posted on the issue that after looking at this again, I'm not sure that this is the correct approach. I think the real problem is here. Which is the reason why the example only hits the ICE if struct update syntax is used. I think a better fix would be to only use the base_expr if check_expr_struct_fields doesn't hit an error.

Please add the test case from the issue as a ui test with a // compile-pass comment to ensure that we don't regress this in the future

Will do.

@dlrobertson
Copy link
Contributor Author

I have a working example of this that doesn't hit the ICE. I'm just running some tests to make sure I didn't break anything else 😄

If check_expr_struct_fields fails, do not continue to record update.
If we continue to record update, the struct may cause us to ICE later
on indexing a field that may or may not exist.
@dlrobertson
Copy link
Contributor Author

Updated to fix the problem in typeck and added a test

@oli-obk
Copy link
Contributor

oli-obk commented May 12, 2018

Nice! The new fix is much cleaner, I agree

@bors r+

@bors
Copy link
Contributor

bors commented May 12, 2018

📌 Commit f6a46cf has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 12, 2018
@kennytm
Copy link
Member

kennytm commented May 13, 2018

@bors p=3

@bors
Copy link
Contributor

bors commented May 13, 2018

⌛ Testing commit f6a46cf with merge 0d48c96...

bors added a commit that referenced this pull request May 13, 2018
typeck: Fix ICE with struct update syntax

If check_expr_struct_fields fails, do not continue to record update.
If we continue to record update, the struct may cause us to ICE later
on indexing a field that may or may not exist.

Fixes: #50618
@bors
Copy link
Contributor

bors commented May 13, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: oli-obk
Pushing 0d48c96 to master...

@bors bors merged commit f6a46cf into rust-lang:master May 13, 2018
@alexcrichton alexcrichton added beta-accepted Accepted for backporting to the compiler in the beta channel. and removed beta-nominated Nominated for backporting to the compiler in the beta channel. labels May 13, 2018
@dlrobertson dlrobertson deleted the fix_ice branch May 13, 2018 17:27
bors added a commit that referenced this pull request May 13, 2018
[beta] Process backports

* #50622: rustc: leave space for fields of uninhabited types to allow partial initialization.
* #50643: typeck: Fix ICE with struct update syntax

r? @alexcrichton
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants