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

[nightly] resolve: Implement uniform paths 2.0 #56042

Merged
merged 18 commits into from Nov 19, 2018

Conversation

Projects
None yet
2 participants
@petrochenkov
Contributor

petrochenkov commented Nov 18, 2018

Forward-port of #55884 to nightly.

r? @ghost

@petrochenkov

This comment has been minimized.

Contributor

petrochenkov commented Nov 18, 2018

@bors r+ p=1

@bors

This comment has been minimized.

Contributor

bors commented Nov 18, 2018

📌 Commit 38025e0 has been approved by petrochenkov

@bors

This comment has been minimized.

Contributor

bors commented Nov 18, 2018

⌛️ Testing commit 38025e0 with merge 8cfcc6d...

bors added a commit that referenced this pull request Nov 18, 2018

Auto merge of #56042 - petrochenkov:nuni, r=petrochenkov
[nightly] resolve: Implement uniform paths 2.0

Forward-port of #55884 to nightly.

r? @ghost
@bors

This comment has been minimized.

Contributor

bors commented Nov 18, 2018

💔 Test failed - status-appveyor

@petrochenkov

This comment has been minimized.

Contributor

petrochenkov commented Nov 18, 2018

a: Instant { t: 15676229486 }
b: Instant { t: 15676229487 }
dur: 445ns
thread '<unnamed>' panicked at 'Instant { t: 15676229487 } is not almost equal to Instant { t: 15676229486 }', libstd\time.rs:511:9
test time::tests::instant_math ... FAILED

Spurious, @bors retry

@bors

This comment has been minimized.

Contributor

bors commented Nov 19, 2018

⌛️ Testing commit 38025e0 with merge 7e82eda...

bors added a commit that referenced this pull request Nov 19, 2018

Auto merge of #56042 - petrochenkov:nuni, r=petrochenkov
[nightly] resolve: Implement uniform paths 2.0

Forward-port of #55884 to nightly.

r? @ghost
@bors

This comment has been minimized.

Contributor

bors commented Nov 19, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: petrochenkov
Pushing 7e82eda to master...

@bors bors merged commit 38025e0 into rust-lang:master Nov 19, 2018

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details

bors added a commit that referenced this pull request Nov 19, 2018

Auto merge of #56053 - petrochenkov:absedihyg, r=<try>
[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

bors added a commit that referenced this pull request Nov 25, 2018

Auto merge of #56053 - petrochenkov:absedihyg, r=<try>
[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

bors added a commit that referenced this pull request Nov 25, 2018

Auto merge of #56211 - petrochenkov:fwd, r=petrochenkov
[master] Forward-ports from beta

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

r? @ghost

pietroalbini added a commit to pietroalbini/rust that referenced this pull request Nov 25, 2018

Rollup merge of rust-lang#56211 - petrochenkov:fwd, r=petrochenkov
[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

bors added a commit that referenced this pull request Nov 26, 2018

Auto merge of #56053 - petrochenkov:absedihyg, r=nikomatsakis,alexcri…
…chton

[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.

#### UPDATE

After crater run the rules were updated to include fallback from 2015 edition behavior to 2018 edition behavior, see #56053 (comment) for more details.

---
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment