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

Hygiene 2.0: Avoid comparing fields by name #49718

Merged
merged 4 commits into from
Apr 13, 2018

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Apr 6, 2018

There are two separate commits here (not counting tests):

  • The first one unifies named (obj.name) and numeric (obj.0) field access expressions in AST and HIR. Before field references in these expressions are resolved it doesn't matter whether the field is named or numeric (it's just a symbol) and 99% of code is common. After field references are resolved we work with
    them by index for all fields (see the second commit), so it's again not important whether the field was named or numeric (this includes MIR where all fields were already by index).
    (This refactoring actually fixed some bugs in HIR-based borrow checker where borrows through names (S { 0: ref x }) and indices (&s.0) weren't considered overlapping.)
  • The second commit removes all by-name field comparison and instead resolves field references to their indices once, and then uses those resolutions. (There are still a few name comparisons in save-analysis, because save-analysis is weird, but they are made correctly hygienic).
    Thus we are fixing a bunch of "secondary" field hygiene bugs (in borrow checker, lints).

Fixes #46314

@rust-highfive
Copy link
Collaborator

r? @pnkfelix

(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 Apr 6, 2018
@petrochenkov
Copy link
Contributor Author

r? @eddyb

@TimNN
Copy link
Contributor

TimNN commented Apr 6, 2018

Your PR failed on Travis. 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.
Receiving objects: 100% (120/120), 15.82 KiB | 15.82 MiB/s, done.
---
Resolving deltas: 100% (105/105), completed with 75 local objects.
---
[00:00:45] configure: rust.quiet-tests     := True
---
[00:39:16] ..........................................................................i.........................
[00:39:22] .................i..................................................................................
---
[00:39:56] ..............................................................................................i.....
[00:40:03] ....................................................................i...............................
---
[00:40:57] .............................................i......................................................
---
[00:44:42] .............................i......................................................................
[00:44:56] ..............................................................i.....................................
[00:45:11] ...............................................i....................................................
[00:45:31] ....................................................................................................
[00:45:52] ....................................................................................................
[00:46:13] ....................................................................................................
[00:46:37] ..i...............................................................................................i.
[00:47:05] .....................................................................................test [run-pass] run-pass/mir_heavy_promoted.rs has been running for over 60 seconds
[00:47:13] ...............
[00:47:43] ....................................................................................................
[00:48:16] ..............................................................ii....................................
[00:49:03] .........................i....................................................i.ii............test [run-pass] run-pass/saturating-float-casts.rs has been running for over 60 seconds
[00:49:06] ......
[00:49:45] ......................................................................................iiiiiii.......
---
[00:51:51] ..................i............................................................ii.iii...............
[00:51:58] ....................................................................................................
[00:52:06] ........i..............................i............................................................
[00:52:13] ....................................................................................................
[00:52:20] ....................i...............................................................................
[00:52:28] ....................................................................................................
[00:52:37] ....................................................................................................
[00:52:48] ....................................................................................................
[00:52:58] ....................................................................................................
[00:53:11] ....................................................................................................
[00:53:19] .............i......................................................................................
[00:53:28] .................i..ii..............................................................................
[00:53:38] ....................................................................................................
[00:53:47] ....................................................................................................
[00:53:57] ....................................................................................i...............
[00:54:07] ..............................i.....................................................................
---
[00:54:43] ...........................i........................................................................
[00:54:45] ....................................................................i...............................
[00:54:46] ................i.......................................................
---
[00:55:00] ...........i........................
---
[00:55:09] ERROR 2018-04-06T02:28:40Z: compiletest::runtest: None
[00:55:21] ERROR 2018-04-06T02:28:53Z: compiletest::runtest: Some("    bb0: {")
[00:55:25] .................F..........................F.....
[00:55:25] failures:
[00:55:25]
[00:55:25] thread 'main' panicked at 'Some tests failed', tools/compiletest/src/main.rs:478:22
[00:55:25] ---- [mir-opt] mir-opt/end_region_cyclic.rs stdout ----
[00:55:25]  thread '[mir-opt] mir-opt/end_region_cyclic.rs' panicked at 'Did not find expected line, error: Mismatch in lines
[00:55:25] Current block: None
[00:55:25] Actual Line: "        let _2: S<\'36_0rs>;"
[00:55:25] Expected Line: "        let _2: S<\'35_0rs>;"
[00:55:25] Expected:
[00:55:25] ... (elided)
[00:55:25] fn main() -> () {
[00:55:25]     let mut _0: ();
[00:55:25]     scope 1 {
[00:55:25]         let _2: S<'35_0rs>;
[00:55:25]     }
[00:55:25] ... (elided)
[00:55:25]     let mut _1: ();
[00:55:25]     let mut _3: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
[00:55:25]     let mut _4: std::option::Option<&'35_0rs S<'35_0rs>>;
[00:55:25]     let mut _5: ();
[00:55:25]     let mut _6: &'16s std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
[00:55:25]     let mut _7: std::opti
[00:55:25]         StorageDead(_8);
[00:55:25]         _5 = const <std::cell::Cell<T>>::set(move _6, move _7) -> [return: bb5, unwind: bb3];
[00:55:25]     }
[00:55:25]     bb5: {
[00:55:25]         EndRegion('16s);
[00:55:25]         StorageDead(_7);
[00:55:25]         StorageDead(_6);
[00:55:25]         StorageDead(_9);
[00:55:25]         StorageLive(_11);
[00:55:25]         _11 = const query() -> [return: bb6, unwind: bb3];
[00:55:25]     }
[00:55:25]     bb6: {
[00:55:25]         switchInt(move _11) -> [false: bb8, otherwise: bb7];
[00:55:25]     }
[00:55:25]     bb7: {
[00:55:25]         _0 = ();
[00:55:25]         StorageDead(_11);
[00:55:25]         EndRegion('35_0rs);
[00:55:25]         StorageDead(_2);
[00:55:25]         return;
[00:55:25]     }
[00:55:25]     bb8: {
[00:55:25]         _10 = ();
[00:55:25]         StorageDead(_11);
[00:55:25]         StorageLive(_14);
[00:55:25]         _14 = &'33s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>);
[00:55:25]         StorageLive(_15);
[00:55:25]         StorageLive(_16);
[00:55:25]         StorageLive(_17);
[00:55:25]         _17 = &'35_0rs _2;
[00:55:25]         _16 = &'35_0rs (*_17);
[00:55:25]         _15 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(move _16,);
[00:55:25]         StorageDead(_16);
[00:55:25]         _13 = const <std::cell::Cell<T>>::set(move _14, move _15) -> [return: bb9, unwind: bb3];
[00:55:25]     }
[00:55:25]     bb9: {
[00:55:25]         EndRegion('33s);
[00:55:25]         StorageDead(_15);
[00:55:25]         StorageDead(_14);
[00:55:25]         StorageDead(_17);
[00:55:25]       j/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/mir-opt" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/mir-opt" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "mir-opt" "--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 -Zmiri -Zunstable-options " "--target-rustcflags" "-Crpath -O -Zmiri -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"
[00:55:25] expected success, got: exit code: 101
[00:55:25]
[00:55:25]
[00:55:25] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[00:55:25] Build completed unsuccessfully in 0:17:17
[00:55:25] Makefile:58: recipe for target 'check' failed
[00:55:25] make: *** [check] Error 1

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.

@bors
Copy link
Contributor

bors commented Apr 6, 2018

☔ The latest upstream changes (presumably #49154) made this pull request unmergeable. Please resolve the merge conflicts.

@petrochenkov
Copy link
Contributor Author

Updated with some tests.

@eddyb
Copy link
Member

eddyb commented Apr 10, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Apr 10, 2018

📌 Commit 8b2fcb0 has been approved by eddyb

@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 Apr 10, 2018
@bors
Copy link
Contributor

bors commented Apr 12, 2018

☔ The latest upstream changes (presumably #49875) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 12, 2018
@petrochenkov
Copy link
Contributor Author

@bors r=eddyb

@bors
Copy link
Contributor

bors commented Apr 12, 2018

📌 Commit fcf4852 has been approved by eddyb

@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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 12, 2018
@Mark-Simulacrum
Copy link
Member

@bors p=1

Looks relatively conflict prone and is blocking other work.

@bors
Copy link
Contributor

bors commented Apr 13, 2018

⌛ Testing commit fcf4852 with merge defcfe7...

bors added a commit that referenced this pull request Apr 13, 2018
Hygiene 2.0: Avoid comparing fields by name

There are two separate commits here (not counting tests):
- The first one unifies named (`obj.name`) and numeric (`obj.0`) field access expressions in AST and HIR. Before field references in these expressions are resolved it doesn't matter whether the field is named or numeric (it's just a symbol) and 99% of code is common. After field references are resolved we work with
them by index for all fields (see the second commit), so it's again not important whether the field was named or numeric (this includes MIR where all fields were already by index).
(This refactoring actually fixed some bugs in HIR-based borrow checker where borrows through names (`S {
0: ref x }`) and indices (`&s.0`) weren't considered overlapping.)
- The second commit removes all by-name field comparison and instead resolves field references to their indices  once, and then uses those resolutions. (There are still a few name comparisons in save-analysis, because save-analysis is weird, but they are made correctly hygienic).
Thus we are fixing a bunch of "secondary" field hygiene bugs (in borrow checker, lints).

Fixes #46314
@bors
Copy link
Contributor

bors commented Apr 13, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: eddyb
Pushing defcfe7 to master...

@bors bors merged commit fcf4852 into rust-lang:master Apr 13, 2018
@kennytm-githubbot
Copy link

📣 Toolstate changed by #49718!

Tested on commit defcfe7.
Direct link to PR: #49718

💔 clippy-driver on windows: test-pass → build-fail (cc @Manishearth @llogiq @mcarton @oli-obk).
💔 clippy-driver on linux: test-pass → build-fail (cc @Manishearth @llogiq @mcarton @oli-obk).

kennytm-githubbot added a commit to rust-lang-nursery/rust-toolstate that referenced this pull request Apr 13, 2018
Tested on commit rust-lang/rust@defcfe7.
Direct link to PR: <rust-lang/rust#49718>

💔 clippy-driver on windows: test-pass → build-fail (cc @Manishearth @llogiq @mcarton @oli-obk).
💔 clippy-driver on linux: test-pass → build-fail (cc @Manishearth @llogiq @mcarton @oli-obk).
@nrc
Copy link
Member

nrc commented Apr 13, 2018

Whoops, I missed this until just now - it breaks Rustfmt as well as Clippy.

But I wanted to comment on the strategy here, it seems that this is the kind of thing that should be done on the HIR, but not on the AST - it is useful for tools to be able to tell the two operations apart syntactically and the rest of the compiler could still unify code because it operates on the HIR. The lowering step could easily unify the two kinds of field access.

@nrc
Copy link
Member

nrc commented Apr 13, 2018

This is especially annoying for Rustfmt because formatting changes - we can output e.f.g but not e.0.1. This is exactly the kind of thing we have a separation between the AST and HIR for.

@petrochenkov
Copy link
Contributor Author

For the compiler itself it's more convenient to keep all fields as identifiers even in AST, there are no places where they would be treated differently + parsing logic and hygiene-keeping is simplified, so I optimized for that.
I suspect it may be more convenient even for rustfmt in general except for few cases where something like https://github.com/rust-lang/rust/blob/master/src/librustc/hir/mod.rs#L1976-L1979 can be used.

kngwyu added a commit to kngwyu/racer-nightly that referenced this pull request Apr 15, 2018
This update includes removal of
ExprKind::TupField(rust-lang/rust#49718).
With this change, I changed the logic of method completion for tuple
struct and added a related test.
@dtolnay dtolnay mentioned this pull request May 7, 2018
kngwyu added a commit to kngwyu/racer-nightly that referenced this pull request May 18, 2018
By rust-lang/rust#49718, ExprKind::TupField
was removed. This commit includes a temorary fix and a tests for this
removal.
bors added a commit that referenced this pull request May 26, 2018
Use `Ident`s for fields in HIR

Continuation of #49718, part of #49300
@petrochenkov petrochenkov deleted the fieldcmp branch June 5, 2019 16:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Broken move semantics in decl_macro
9 participants