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

[beta] resolve: Implement uniform paths 2.0 #55884

Merged
merged 18 commits into from
Nov 18, 2018
Merged

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Nov 12, 2018

With this PR paths in imports on 2018 edition are resolved as relative in the scope in which they are written, similarly to any other paths.
The previous implementation worked differently - it tried to resolve the import in the current module (self::import) and in the "crate universe" (::import), and then merge these two resolutions if possible.

The difference is that the new scheme can refer to strictly larger set of names in scope - names from unnamed blocks, names from all kinds of preludes, including macros imported with #[macro_use] extern crate, built-in types/macros, macros introduced with macro_rules.
This means strictly more potential ambiguities and therefore ambiguity errors, since we keep the rule that any two different candidate names in scope conflict with each other during import resolution. So this is a breaking change for 2018 edition, but it should be relatively minor.

All paths that don't start with an extern crate are also gated with the uniform_paths feature, paths that refer to extern crates are not gated (so we effectively get something like "future-proofed anchored paths" on stable).

Another difference is treatment of paths in visibilities (pub(in path)). Few people remember about paths in visibilities, so before this PR they still used the old 2015 rules even on 2018 edition. Namely, paths in visibilities were crate-relative, analogous to 2015 edition imports.
This PR resolves paths in visibilities as uniform as well, or rather future proofs them in this direction.
Paths in visibilities are restricted to parent modules, so relative paths almost never make sense there, and pub(in a) needs to be rewritten as pub(in crate::a) in the uniform scheme, de-facto cementing the discouraged status of non-pub(crate) and non-pub(super) fine-grained visibilities.
This is clearly a breaking change for 2018 edition as well, but also a minor one.

The in-scope resolution strategy for import paths mirrors what is currently done for macro paths on stable (on both editions), so it will continue working even if the "ambiguity always means error" restriction is relaxed in the future.

This PR also significantly improves diagnostics for all kinds of resolution ambiguities, from the newly introduced import ones to pretty old "glob vs glob" conflicts. (That's probably what I've spent most of the time on.)

Why beta:

  • This is a breaking change on 2018 edition.
  • This is a large PR, it's less risky to forward-port it to nightly, than back-port to beta.

cc #55618
cc #53130
cc rust-lang/rfcs#1289
Closes #18084
Closes #54525
Fixes #54390
Fixes #55668

r? @ghost

@petrochenkov petrochenkov added S-waiting-on-crater Status: Waiting on a crater run to be completed. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 12, 2018
@petrochenkov
Copy link
Contributor Author

r? @eddyb

@rust-highfive
Copy link
Collaborator

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:2487930c:start=1541988898209429937,finish=1541988951143632123,duration=52934202186
$ 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 IMAGE=x86_64-gnu-llvm-5.0
---
[00:48:54]     Checking rustc_msan v0.0.0 (/checkout/src/librustc_msan)
[00:48:54]     Checking rustc_tsan v0.0.0 (/checkout/src/librustc_tsan)
[00:48:54]     Checking rustc_asan v0.0.0 (/checkout/src/librustc_asan)
[00:48:55]  Documenting std v0.0.0 (/checkout/src/libstd)
[00:49:01] error: cannot find macro `Result::Ok!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `Weak::upgrade!` in this scope
[00:49:01] warning: `[Weak::upgrade]` cannot be resolved, ignoring it...
[00:49:01]     --> /checkout/src/liballoc/rc.rs:1181:29
[00:49:01]      |
[00:49:01] 1181 |     /// Calling [`upgrade`][Weak::upgrade] on the return value always gives [`None`].
---
[00:49:01]      |                             ^^^^^^^^^^^^^ cannot be resolved, ignoring
[00:49:01]      |
[00:49:01]      = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:49:01] 
[00:49:01] error: cannot find macro `u8!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `Default!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `PartialEq!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `BufWriter!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `crate::sync::atomic::compiler_fence!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `crate::sync::atomic::fence!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `crate::sync::atomic!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `crate::sync::Arc!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `crate::sync::Barrier!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `crate::sync::Condvar!` in this scope
[00:49:01] 
[00:49:01] error: cannot find macro `crate::sync::mpsc!` in this scope
[00:49:01] error: cannot find macro `[0m     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:49:01] 
[00:49:01] error: cannot find macro `String::push_str!` in this scope
[00:49:01] 
[00:49:01] 
[00:49:01] error: cannot find macro `chunks!` in this scope
[00:49:01] warning: `[chunks]` cannot be resolved, ignoring it...
[00:49:01]    --> /checkout/src/libcore/slice/mod.rs:861:52
[00:49:01]     |
[00:49:01] 861 |     /// resulting code better than in the case of [`chunks`].
[00:49:01] 861 |     /// resulting code better than in the case of [`chunks`].
[00:49:01]     |                                                    ^^^^^^^^ cannot be resolved, ignoring
[00:49:01]     |
[00:49:01]     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:49:01] 
[00:49:01] error: cannot find macro `chunks_mut!` in this scope
[00:49:01] warning: `[chunks_mut]` cannot be resolved, ignoring it...
[00:49:01]    --> /checkout/src/libcore/slice/mod.rs:901:52
[00:49:01]     |
[00:49:01] 901 |     /// resulting code better than in the case of [`chunks_mut`           ^^^^^^^^^^^^^^^ cannot be resolved, ignoring
[00:49:01] 901 |     /// resulting code better than in the case of [`chunks_mut`           ^^^^^^^^^^^^^^^ cannot be resolved, ignoring
[00:49:01]     |
[00:49:01]     = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
[00:49:01] 
[00:49:01] error: Could not document `std`.
[00:49:01] 
[00:49:01] Caused by:
[00:49:01]   process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustdoc --crate-name std libstd/lib.rs --color always --target x86_64-unknown-linux-gnu -o /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/doc --cfg 'feature="alloc_jemalloc"' --cfg 'feature="backtrace"' --cfg 'feature="jemalloc"' --cfg 'feature="panic-unwind"' --cfg 'feature="panic_unwind"' -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/release/deps --extern alloc=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liballoc-3c6fe18e3f940a16.rmeta --extern alloc_jemalloc=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liballoc_jemalloc-b50a2c2614451fcc.rmeta --extern alloc_system=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liballoc_system-18eadef5741d6149.rmeta --extern compiler_builtins=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcompiler_builtins-d4e445232d9f4530.rmeta --extern core=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcore-e99f7499326b08cb.rmeta --extern libc=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liblibc-1cb5d76dcefc713b.rmeta --extern panic_abort=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libpanic_abort-7f0db12775373ff1.rmeta --extern panic_unwind=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libpanic_unwind-c0e63a103f3008d6.rmeta --extern rustc_asan=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_asan-64369f3f20969201.rmeta --extern rustc_lsan=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_lsan-3faa3eaec1535088.rmeta --extern rustc_msan=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_msan-2277b67d89a761ca.rmeta --extern rustc_tsan=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_tsan-b11c67038d913a1c.rmeta --extern unwind=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libunwind-7d8e6e32e8b540cb.rmeta` (exit code: 1)
[00:49:01] 
[00:49:01] 
[00:49:01] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "doc" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/checkout/src/libs2 ./.git/modules/src/libcompiler_builtins/modules/compiler-rt
35596 ./.git/modules/src/libcompiler_builtins/modules/compiler-rt/objects
35588 ./.git/modules/src/libcompiler_builtins/modules/compiler-rt/objects/pack
34916 ./obj/build/x86_64-unknown-linux-gnu/native/jemalloc/src
34588 ./obj/build/x86_64-unknown-linux-gnu/native/jemalloc/lib
---
travis_time:end:06c19aa6:start=1541991903281908981,finish=1541991903286803878,duration=4894897
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:08e2fefe
$ 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:171ce140
travis_time:start:171ce140
$ 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:02c9e544
$ 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)

@eddyb
Copy link
Member

eddyb commented Nov 12, 2018

Closes #18084

Does that mean self now refers to the innermost scope? Isn't that a breaking change?

Copy link
Member

@eddyb eddyb left a comment

Choose a reason for hiding this comment

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

I won't pretend to fully understand the inner workings of early_resolve_ident_in_lexical_scope, but if it worked before for macros, this PR LGTM.

@eddyb
Copy link
Member

eddyb commented Nov 12, 2018

@Centril
Copy link
Contributor

Centril commented Nov 12, 2018

I'll check this later today. :)

@joshtriplett
Copy link
Member

I just read through all the commits. I'm not a compiler internals expert, so don't take this as a review on every aspect of the approach, but this makes sense to me.

Could you explain the last commit, the "acceptable regressions", a bit more please? Is it difficult to give suggestions to tell people to delete use foo;?

Thank you for your incredible and timely work on the edition.

@petrochenkov
Copy link
Contributor Author

petrochenkov commented Nov 12, 2018

@eddyb

Does that mean self now refers to the innermost scope? Isn't that a breaking change?

No, self still behaves the same way.
The issue is closed as kind of wontfix in the sense that self is not going to work like this, but now an alternative solution exists.

@joshtriplett

Is it difficult to give suggestions to tell people to delete use foo;?

I haven't looked how exactly it's reported yet, if it's easily fixable, then I'll fix it.
UPDATE: Fixed in c062c70

@petrochenkov petrochenkov removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 13, 2018
@petrochenkov
Copy link
Contributor Author

@bors try

@bors
Copy link
Contributor

bors commented Nov 13, 2018

⌛ Trying commit c062c70f18bb3417fd5eb2537ca28215c4f4a666 with merge 85be765f536ab3c0a9f44f64f87ef72027503423...

Copy link
Contributor

@Centril Centril left a comment

Choose a reason for hiding this comment

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

I mostly looked at the tests; Very nice work on the diagnostics!
I have some assorted questions that might not be totally relevant but which struck me when reviewing this.

src/test/ui/error-codes/E0659.stderr Show resolved Hide resolved
src/test/ui/extern/extern-macro.rs Outdated Show resolved Hide resolved
src/test/ui/rust-2018/local-path-suggestions-2018.rs Outdated Show resolved Hide resolved

mod exported {
// Exported macros are treated as private as well,
// some better rules need to be figured out later.
Copy link
Contributor

Choose a reason for hiding this comment

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

Later is before stabilizing uniform_paths, or more into the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Before.
Uniform paths can be stabilized in stages though - e.g. names in modules (named or unnamed) first, then everything else.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good 👍

@bors
Copy link
Contributor

bors commented Nov 13, 2018

💔 Test failed - status-travis

@rust-highfive
Copy link
Collaborator

The job dist-x86_64-linux 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_fold:end:services

travis_fold:start:git.checkout
travis_time:start:02cb88ee
$ git clone --depth=2 --branch=try https://github.com/rust-lang/rust.git rust-lang/rust
---
[01:56:37]    Compiling thread_local v0.3.6
[01:56:37]    Compiling idna v0.1.5
[01:56:37]    Compiling clippy_lints v0.0.212 (/checkout/src/tools/clippy/clippy_lints)
[01:56:39]    Compiling error-chain v0.12.0
[01:56:41] error: cannot find derive macro `Deserialize` in this scope
[01:56:41]     |
[01:56:41]     |
[01:56:41] 79  |               #[derive(Deserialize)]
[01:56:41] ...
[01:56:41] ...
[01:56:41] 118 | / define_Conf! {
[01:56:41] 119 | |     /// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about
[01:56:41] 120 | |     (blacklisted_names, "blacklisted_names", ["foo", "bar", "baz", "quux"] => Vec<String>),
[01:56:41] 121 | |     /// Lint: CYCLOMATIC_COMPLEXITY. The maximum cyclomatic complexity a function can have
[01:56:41] ...   |
[01:56:41] 157 | |     (trivial_copy_size_limit, "trivial_copy_size_limit", None => Option<u64>),
[01:56:41]     | |_- in this macro invocation
[01:56:41] 
[01:56:41] error: aborting due to previous error
[01:56:41] 
---
[01:57:17]    Compiling jsonrpc-core v8.0.1
[01:57:28]    Compiling rustc-rayon-core v0.1.1
[01:57:28]    Compiling clippy_lints v0.0.212 (/checkout/src/tools/clippy/clippy_lints)
[01:57:28]    Compiling languageserver-types v0.45.0
[01:57:31] error: cannot find derive macro `Deserialize` in this scope
[01:57:31]     |
[01:57:31]     |
[01:57:31] 79  |               #[derive(Deserialize)]
[01:57:31] ...
[01:57:31] ...
[01:57:31] 118 | / define_Conf! {
[01:57:31] 119 | |     /// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about
[01:57:31] 120 | |     (blacklisted_names, "blacklisted_names", ["foo", "bar", "baz", "quux"] => Vec<String>),
[01:57:31] 121 | |     /// Lint: CYCLOMATIC_COMPLEXITY. The maximum cyclomatic complexity a function can have
[01:57:31] ...   |
[01:57:31] 157 | |     (trivial_copy_size_limit, "trivial_copy_size_limit", None => Option<u64>),
[01:57:31]     | |_- in this macro invocation
[01:57:31] 
[01:57:31] error: aborting due to previous error
[01:57:31] 
---
[01:57:38] travis_fold:end:stage2-rls

[01:57:38] travis_time:end:stage2-rls:start=1542079108958249039,finish=1542079151790007330,duration=42831758291

[01:57:38] thread 'main' panicked at 'Unable to build RLS', bootstrap/dist.rs:73:9
[01:57:38] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap dist --host x86_64-unknown-linux-gnu --target x86_64-unknown-linux-gnu
[01:57:38] Build completed unsuccessfully in 1:51:35
travis_time:end:0295727c:start=1542072093704888703,finish=1542079152117122963,duration=7058412234260
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 1.
---
travis_time:end:0c76a0c8:start=1542079155915457733,finish=1542079155927756353,duration=12298620
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:19cd26aa
$ 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:033d2776
travis_time:start:033d2776
$ 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:270b43ff
$ 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)

@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-crater Status: Waiting on a crater run to be completed. labels Nov 13, 2018
@petrochenkov
Copy link
Contributor Author

I'll look why clippy build fails.

But why clippy prevents bors try from succeeding though?
cc @Mark-Simulacrum

@matthiaskrgr
Copy link
Member

@petrochenkov I think a tool breaking is fatal on beta/stable and only ok on the nightly channel.

@Mark-Simulacrum
Copy link
Member

Yes, beta and stable require all tools to build.

@petrochenkov
Copy link
Contributor Author

@bors try

@bors
Copy link
Contributor

bors commented Nov 14, 2018

⌛ Trying commit 2302ae6 with merge 0c8ba60...

bors added a commit that referenced this pull request Nov 18, 2018
[beta] resolve: Implement uniform paths 2.0

With this PR paths in imports on 2018 edition are resolved as relative in the scope in which they are written, similarly to any other paths.
The previous implementation worked differently - it tried to resolve the import in the current module (`self::import`) and in the "crate universe" (`::import`), and then merge these two resolutions if possible.

The difference is that the new scheme can refer to strictly larger set of names in scope - names from unnamed blocks, names from all kinds of preludes, including macros imported with `#[macro_use] extern crate`, built-in types/macros, macros introduced with `macro_rules`.
This means strictly more potential ambiguities and therefore ambiguity errors, since we keep the rule that any two different candidate names in scope conflict with each other during import resolution. So this is a breaking change for 2018 edition, but it should be relatively minor.

All paths that don't start with an extern crate are also gated with the `uniform_paths` feature, paths that refer to extern crates are not gated (so we effectively get something like "future-proofed anchored paths" on stable).

Another difference is treatment of paths in visibilities (`pub(in path)`). Few people remember about paths in visibilities, so before this PR they still used the old 2015 rules even on 2018 edition. Namely, paths in visibilities were crate-relative, analogous to 2015 edition imports.
This PR resolves paths in visibilities as uniform as well, or rather future proofs them in this direction.
Paths in visibilities are restricted to parent modules, so relative paths almost never make sense there, and `pub(in a)` needs to be rewritten as `pub(in crate::a)` in the uniform scheme, de-facto cementing the discouraged status of non-`pub(crate)` and non-`pub(super)` fine-grained visibilities.
This is clearly a breaking change for 2018 edition as well, but also a minor one.

The in-scope resolution strategy for import paths mirrors what is currently done for macro paths on stable (on both editions), so it will continue working even if the "ambiguity always means error" restriction is relaxed in the future.

This PR also significantly improves diagnostics for all kinds of resolution ambiguities, from the newly introduced import ones to pretty old "glob vs glob" conflicts. (That's probably what I've spent most of the time on.)

Why beta:
- This is a breaking change on 2018 edition.
- This is a large PR, it's less risky to forward-port it to nightly, than back-port to beta.

cc #55618
cc #53130
cc rust-lang/rfcs#1289
Closes #18084
Closes #54525
Fixes #54390
Fixes #55668

r? @ghost
@bors
Copy link
Contributor

bors commented Nov 18, 2018

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

@nagisa
Copy link
Member

nagisa commented Nov 18, 2018

Marked as beta-accepted and removed beta-nominated (as it has landed)

@nagisa nagisa removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Nov 18, 2018
bors added a commit that referenced this pull request Nov 19, 2018
[nightly] resolve: Implement uniform paths 2.0

Forward-port of #55884 to nightly.

r? @ghost
bors added a commit that referenced this pull request Nov 25, 2018
[beta] resolve: Implement edition hygiene for imports and absolute paths

The changes in behavior of imports and absolute paths are the most significant breaking changes of 2018 edition.
However, these changes are not covered by edition hygiene, so macros defined by 2015 edition crates expanded in 2018 edition crates are still interpreted in the 2018 edition way when they contain imports or absolute paths.
This means the promise of seamless integration of crates built with different editions, including use of macros, doesn't hold fully.
This PR fixes that and implements edition hygiene for imports and absolute paths, so they behave according to the edition in which they were written, even in macros.

### Detailed rules (mostly taken from #50376)
#### Preface
We keep edition data per-span in the compiler. This means each span knows its edition.
Each identifier has a span, so each identifier knows its edition.

#### Absolute paths

Explicitly written absolute paths `::ident::...` are desugared into something like `{{root}}::ident::...` in the compiler, where `{{root}}` is also treated as an identifier.
`{{root}}` inherits its span/hygienic-context from the token `::`.

If the span is from 2015 edition, then `{{root}}` is interpreted as the current crate root (`crate::...` with same hygienic context).
If the span is from 2018 edition, then `{{root}}` is interpreted as "crate universe" (`extern::...`).

#### Imports

To resolve an import `use ident::...` we need to resolve `ident` first.
The idea in this PR is that `ident` fully knows how to resolve itself.

If `ident`'s span is from 2015 edition, then the identifier is resolved in the current crate root (effectively `crate::ident::...` where `crate` has the same hygienic context as `ident`).
If `ident`'s span is from 2018 edition, then the identifier is resolved in the current scope, without prepending anything (well, at least with uniform paths).

There's one corner case in which there's no identifier - prefix-less glob import `use *;`.
In this case the span is inherited from the token `*`.
`use *;` && `is_2015(span(*))` -> `use crate::*;` && `span(crate) == span(*)`.
`use *;` && `is_2018(span(*))` -> error.

---
Why beta:
	- Compatibility of 2015 edition crates with 2018 edition crates, including macros, is one of the main promises of the edition initiative.
	- This is technically a breaking change for 2018 edition crates or crates depending on 2018 edition crates.
	- ~This PR is based on #55884 which hasn't landed on nightly yet :)~ No longer true (#56042).

Previous attempt #50999
Closes #50376
Closes #52848
Closes #53007

r? @ghost
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Nov 25, 2018
[master] Forward-ports from beta

rust-lang#56206 + one commit from rust-lang#55884 that was accidentally missing in rust-lang#56042 due to an off-by-one mistake in commit ranges

r? @ghost
@petrochenkov petrochenkov deleted the uni branch June 5, 2019 16:21
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.