-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
don't ask what edition we are in; ask what edition a span is in #50999
don't ask what edition we are in; ask what edition a span is in #50999
Conversation
We now track the edition of each span. Using that info when gating the Rust 2018 interpretation means that macros from Rust 2015 crates "just work" when used in Rust 2018 crates (at least in the case of `use` paths).
e32d992
to
24529d9
Compare
oh, my. |
Hmm, I'm not sure this is behaving right in some of the corner cases. I'll come back to it in a bit. But for example, when I add a macro to the Rust 2015 helper like this: #[macro_export]
macro_rules! print_me {
($p:path) => {
{
use $p as V;
println!("{}", V);
}
}
} I expect the paths supplied to the macro from the Rust 2018 crate to use Rust 2018 semantics. I'm not 100% sure if they are or not yet :p I have to dig into the output a bit deeper. |
(Obviously once you start concatenating paths and things it becomes less clear what is right -- I wanted to add some tests where we build paths like |
🗻 |
The job Click to expand the log.
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 |
/// particular span: that way, when you are looking at code | ||
/// creating a macro from a Rust 2015 crate, you will use the Rust | ||
/// 2015 Edition rules. | ||
pub fn local_edition(&self) -> Edition { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can probably just implement Default
for Edition
.
"Local edition" needs to be kept in global data anyway because it's an "edition of SyntaxContext(0)
aka not-a-macro-expansion" and it's set from default-default Edition2015
to self.opts.edition
immediately after options are parsed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. True, though I'm not wild about the fact that we rely so heavily on global / TLS data for this stuff.
Paths currently have spans from the "concatenation context" (see In general, we can strictly rely only on spans of "atomic" tokens, for multi-token things like paths there are always multiple choices (#50122). |
☔ The latest upstream changes (presumably #48309) made this pull request unmergeable. Please resolve the merge conflicts. |
I've written up a comment about a recent chat @nikomatsakis and I had where the conclusion was to basically punt on this PR for now. It's not clear whether this is the right strategy amongst alternatives, so we're going to not worry about solving this for the edition (as it doesn't seem all that pressing) and fix it if we uncover it later. As a result, I'm removing the milestone from this PR. |
Does this mean this PR can just be closed for now? |
Heh if I recall right @nikomatsakis felt bad closing the PR himself so I mentioned we can let normal triage processes close the PR. I'll perhaps preempt that slightly by closing it myself... |
I'm of two minds because I do still want to see this reach some conclusion =) but keeping this PR open serves no real purpose. |
[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
We now track the edition of each span. Using that info when gating the Rust 2018 interpretation means that macros from Rust 2015 crates "just work" when used in Rust 2018 crates (at least in the case of
use
paths).Fixes #50172
r? @petrochenkov
cc @Manishearth @alexcrichton