Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign uphygiene: Decouple transparencies from expansion IDs #51952
Conversation
rust-highfive
assigned
aturon
Jun 30, 2018
This comment has been minimized.
This comment has been minimized.
|
r? @aturon (rust_highfive has picked a reviewer for you, use r? to override) |
rust-highfive
added
the
S-waiting-on-review
label
Jun 30, 2018
This comment has been minimized.
This comment has been minimized.
|
r? @oli-obk |
rust-highfive
assigned
oli-obk
and unassigned
aturon
Jun 30, 2018
petrochenkov
added
S-waiting-on-crater
and removed
S-waiting-on-review
labels
Jun 30, 2018
This comment has been minimized.
This comment has been minimized.
|
Needs check-only crater run (stable derives are affected). |
petrochenkov
referenced this pull request
Jun 30, 2018
Closed
proc_macro! expansion can refer to items defined in the root w/o importing them #50504
This comment has been minimized.
This comment has been minimized.
|
@bors try |
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Jun 30, 2018
oli-obk
reviewed
Jun 30, 2018
| @@ -284,22 +285,31 @@ impl SyntaxContext { | |||
| }) | |||
| } | |||
|
|
|||
| /// Extend a syntax context with a given mark | |||
This comment has been minimized.
This comment has been minimized.
| #[proc_macro] | ||
| pub fn check(_: TokenStream) -> TokenStream { | ||
| " | ||
| struct Outer; |
This comment has been minimized.
This comment has been minimized.
oli-obk
Jun 30, 2018
Contributor
can you check that we can still access things outside the expansion here?
| " | ||
| struct Outer; | ||
| mod inner { | ||
| type Inner = Outer; // `Outer` shouldn't be available from here |
This comment has been minimized.
This comment has been minimized.
oli-obk
Jun 30, 2018
Contributor
and that we cannot access anything from outside the expansion without an import
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
cc @pietroalbini check-only crater run wanted (details are in the crater status spreadsheet already). |
This comment has been minimized.
This comment has been minimized.
|
Crater run started. It should finish in ~2 days. |
This comment has been minimized.
This comment has been minimized.
|
Hi @petrochenkov (crater requester), @oli-obk (PR reviewer)! Crater results are at: http://cargobomb-reports.s3.amazonaws.com/pr-51952/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file. (interested observers: Crater is a tool for testing the impact of changes on the crates.io ecosystem. You can find out more at the repo if you're curious) |
This comment has been minimized.
This comment has been minimized.
|
52 crates regressed. Seems both actix and diesel are broken by this. Dependency treeThe tool used to build the tree is not perfect, the tree might be a bit off. It only includes registry crates.
|
kennytm
added
S-waiting-on-review
and removed
S-waiting-on-crater
labels
Jul 4, 2018
petrochenkov
referenced this pull request
Jul 4, 2018
Closed
Tracking issue for RFC 1566: Procedural macros #38356
alexcrichton
referenced this pull request
Jul 5, 2018
Merged
rustc: Stabilize the `proc_macro` feature #52081
petrochenkov
added
S-waiting-on-author
and removed
S-waiting-on-review
labels
Jul 6, 2018
This comment has been minimized.
This comment has been minimized.
|
The common pattern is #[derive(Something)]
struct MyStruct;being expanded into struct MyStruct;
mod __implementation_details {
// Note, that `MyStruct` is not in scope here.
impl Something for MyStruct {
let x: SomethingElseFromTheParentModule = ...;
}
}The "universal solution" is to do this: mod __implementation_details {
use super::*; // <---
// Now `MyStruct` and `SomethingElseFromTheParentModule ` are in scope.
impl Something for MyStruct {
let x: SomethingElseFromTheParentModule = ...;
}
}Perhaps we can send fixes, release minor versions and land this fix. |
This comment has been minimized.
This comment has been minimized.
|
Thanks for investigating @petrochenkov! Out of curiosity, is it possible to apply this fix for just In any case I think we should send fixes upstream and publish ASAP. Hopefully that'll buy us as many possibilities as we can to fix this! |
This comment has been minimized.
This comment has been minimized.
|
Alternative "universal solution": fn __implementation_details() {
impl Something for MyStruct {
let x: SomethingElseFromTheParentModule = ...;
}
}This may look silly, but this may be even better solution for encapsulating implementation details than introducing a module (which acts as a "name barrier") and thus losing names in scope, including those that can't be recovered with For example, fn outer() {
#[derive(Something)]
struct MyStruct;
} |
This comment has been minimized.
This comment has been minimized.
This should be possible to do with a targeted hack, if I'm not mistaken about the root cause of the bug. |
sgrif
referenced this pull request
Jul 19, 2018
Closed
Rustdoc ignores traits implemented inside of a function #52545
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I've opened #52545 which is related to this. It sounds like the fix for that is not straightforward or easy. Currently there's no obvious migration path for crates which are affected by this. What do you think about reverting this for the time being until there's a clear path forward for existing crates? |
This comment has been minimized.
This comment has been minimized.
|
I'm also surprised that this change was made so quietly. This is a pretty major breaking change to a feature that's been stable for a year and a half. I would like to think this would have at least received an RFC. This is very clearly not a soundness issue, and whether it is even a bug is arguable IMO. This makes me extremely worried about whether Rust will actually live up to its stability promises. For a feature that has been stable for this long, where there were at least a dozen known cases of folks relying on this behavior, there really should have been more discussion -- not just on whether the behavior was intended or not, but on whether it's reasonable to change it at this point given that Rust is meant to be stable. |
This comment has been minimized.
This comment has been minimized.
|
We should not revert this PR as is and reintroduce the issues that were fixed here, that would be harmful for our hygiene system long-term. |
This comment has been minimized.
This comment has been minimized.
|
These are all consequences of rushed stabilization of macros 1.1 and low "bus factor" for hygiene system (not enough qualified reviewing was done). |
This comment has been minimized.
This comment has been minimized.
|
While I appreciate where you're coming from, stability should not mean "unless we decide we change our minds". I agree with you that this is something that should have been discussed before the feature became stable in the first place, but that does not mean that it should be OK for the rug to get pulled out from under the ecosystem on a stable feature. |
This comment has been minimized.
This comment has been minimized.
|
@sgrif did diesel or any other crates you know of stop compiling as a result of this change? This change was landed under the presumption that nothing was broken and crates continued to compile, if that's not the case we should fix that! If crates continued to compile, however, then I think it's a bit disingenous to say that the rug was pulled out from under you or that this is a major breaking change. This fixed bug exhibits behavior which is clearly a bug in procedural macros which has affected stable Rust for quite some time. We always try quite hard to keep crates compiling on stable. This does not mean that we will prevent ourselves from fixing bugs though as we're doing in this situation. We are tasked, however, with fixing the bug while keeping existing code compiling. |
This comment has been minimized.
This comment has been minimized.
|
@sgrif |
This comment has been minimized.
This comment has been minimized.
Yes, Diesel did. You also listed a ton of affected crates in #50504 (comment). Again, I think calling it a "fixed bug" is quite arguable. Personally I'd expect hygiene to mean that a given ident is resolved in the scope it was given from. My main point is that I don't think it's an obvious conclusion one way or the other, and I would have liked to see a discussion around it.
I agree. But there does become a point when folks start relying on behavior enough that there is a conversation to be had about whether fixing the "bug" does more harm than good (there are several cases like this in Rails for example). At a certain point something in the grey area ends up being a defacto feature. I think it's also important to define what "bug" means here. I couldn't find anything in the relevant RFCs which explicitly defines how this behavior should interact. At best this is a clarification of intent, but given that it's on a stable feature, I don't think that should be done without giving the community an opportunity to voice their opinion.
I agree. I do not think this is obviously a bug. It's also much more nuanced than you are making it out to be, see my above comments. |
This comment has been minimized.
This comment has been minimized.
|
@sgrif so to be clear, diesel compiled on stable, and then the exact same source code no longer compiles on nightly? I'm not talking about warnings, but literal compiler errors. The crater report you gisted is not even tied to this change, so I'd just want to be clear about what breaking is. If it's broken, can you also gist the error message you're getting? (steps to reproduce would also be great!) I agree there's possibility for a gray area, but I disagree that this is not obviously a bug. All of macros 1.1 is "call site" hygiene which is "as if the tokens are copy/pasted". That's clearly not the case when you're generating |
This comment has been minimized.
This comment has been minimized.
Most published versions of Diesel were shipped with
I linked to a discussion on the issue closed by this PR, not sure how it's unrelated. Pretty much every crate there is generating a module for the same reason -- to be able to have an isolated scope for
This is a fair point. Really there's a broader issue here is that proc macros (and derives in particular) have no way to isolate their scope, and want to do things that don't have obvious interactions with hygiene (such as |
This comment has been minimized.
This comment has been minimized.
I think this is what was specified in the RFC for 1.1 and announcement for 1.2, yes. |
This comment has been minimized.
This comment has been minimized.
|
@sgrif our stability policy does not consider new warnings or changes to warnings a breaking change due to The crater report you linked was a blanket denial of all procedural macros generating There is many many issues with procedural macros and how they do not have many hygiene controls, they're forced to just splat tokens into the user's program. These problems are well-known though and the solution is under development but is still not ready for stabilization. |
This comment has been minimized.
This comment has been minimized.
I understand that. This is not just a new default warn lint. This is a warning for what will end up being a breaking change. It also doesn't really matter in terms of the impact that this has on downstream crates. If someones build starts spamming warnings, we still get multiple reports a day (the most recent versions of Diesel do not
I looked through about half of them, and every single one I looked at is going to be affected by this change. As I said in my previous comment, there is very little reason to emit a module from a
Has there been an RFC for this? This is my main point. This is a stable feature, and it really feels like things about it are just being changed with no input from the community. |
This comment has been minimized.
This comment has been minimized.
|
Regardless of anything else, I hope you understand the frustration here. A lot of folks use Diesel with Rocket or other crates that require nightly, so we tend to feel pains from that pretty quick. Users on older versions that still had |
This comment has been minimized.
This comment has been minimized.
|
Sorry :( |
This comment has been minimized.
This comment has been minimized.
|
Even if we're able to allow it, that's at best a temporary fix. At the end of the day this is a compatibility warning for something that will be breaking eventually -- meaning that any version of Diesel (or any other affected crate) that doesn't handle it will stop working. Saying that this isn't a breaking change because it's a warning, or that there'll be a fix that lets us silence the warning is seriously sidestepping the issue here. From a library maintainer's point of view, being told "your code will stop working" is no different from it not working. My concern is both with the lack of a working migration path, but also with this happening at all. I understand that this is considered to be a bug by the relevant teams. However, I really don't think enough consideration has been given to existing code. @alexcrichton directly said:
Since the only code that's going to stop compiling is code using |
This comment has been minimized.
This comment has been minimized.
|
@sgrif yes I'm sorry that Diesel is going through these troubles, this particular migration could probably have gone more smoothly! The warnings here were intended to be like all other future incompatibility warnings the compiler issues: they don't break existing code (modulo lint denial) and they are supressable in the near term if necessary. The migration path here was thought to be simple enough but it wasn't exercised for Diesel's case specifically and you've discovered there's a bug or two which prevents a feasible migration path, but we'll work on that! The compiler has a well documented policy on how to fix a bug in the compiler. It appears we accidentally left out the tracking issue part of that, but otherwise that policy was followed. To reiterate some motivation of that policy, no future-incompatible compiler warning is turned into an error, ever, if enough of the ecosystem is still using it. We would never consider turning this into a hard error unless Diesel had successfully migrated to no longer have the warning issued. I disagree with your point of "is no different from it not working", this is the crucial distinction. |
petrochenkov commentedJun 30, 2018
•
edited
And remove fallback to parent modules during resolution of names in scope.
This is a breaking change for users of unstable macros 2.0 (both procedural and declarative), code like this:
or equivalent
stops working due to module boundaries being properly enforced.
For proc macro derives this is still reported as a compatibility warning to give
actix_derive,diesel_derivesandpalette_derivetime to fix their issues.Fixes #50504 in accordance with this comment.