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 upprivacy: Rewrite VisiblePrivateTypesVisitor #29973
Conversation
rust-highfive
assigned
nikomatsakis
Nov 21, 2015
This comment has been minimized.
This comment has been minimized.
|
Edit: Fixed in 7b0f1d6 |
This comment has been minimized.
This comment has been minimized.
|
There are two ways to reduce the breakage:
will be permitted. I like this variant, it makes
Edit: as a minimum, type aliases should be substituted when determining publicity of |
This comment has been minimized.
This comment has been minimized.
|
|
petrochenkov
force-pushed the
petrochenkov:privinpub
branch
from
cf28bce
to
7b0f1d6
Nov 24, 2015
This comment has been minimized.
This comment has been minimized.
|
Rebased. |
This comment has been minimized.
This comment has been minimized.
|
Exciting! I was on PTO since Thu, I'll try to read this today or tomorrow. |
This comment has been minimized.
This comment has been minimized.
|
(I am scheduling a crater run now.) |
This comment has been minimized.
This comment has been minimized.
|
Preliminary crater report: https://gist.github.com/nikomatsakis/e7feaa7c4bc0ebcc6559 I've not dug into this at all. |
This comment has been minimized.
This comment has been minimized.
|
Note that the root regression division may mean that this change is underestimating the amount of breakage. |
This comment has been minimized.
This comment has been minimized.
|
TL;DR: People don't write quickcheck-0.2.24 - Private trait in where clause (out of date) Top non-root regressions are due to aho-corasick-0.3.4 (it has private type alias in trait methods, solvable by simple normalization) or due to xml-rs-0.2.2 1 By "simple normalization" I mean substitution of type alias
before checking. |
This comment has been minimized.
This comment has been minimized.
|
Proposed way forward:
|
This comment has been minimized.
This comment has been minimized.
|
Another more extreme variants:
|
This comment has been minimized.
This comment has been minimized.
I was going to propose mostly the same thing. But some quibbles:
It would be better to emit a lint, I think. I've been wanting to propose that we add a "future-compatibility" lint for this purpose. The reasons to prefer a lint are:
However, I wanted to try and advertise the idea of this lint a bit more broadly for some reason, but maybe we can just add it here and then tweak the design. (We have a bit of time before this change hits stable.)
Sorry, what is "simple type alias normalization"? |
This comment has been minimized.
This comment has been minimized.
Footnote 1 in the previous message #29973 (comment)
Yeah, I should have added an unresolved question "what kind of warning exactly?" to my proposed way forward. |
This comment has been minimized.
This comment has been minimized.
I'm not sure, but I think you can view this as a feature or a bug. That is, we have had regressions in rustc where RFC1214 warnings were not noticed because they occurred in stage1 and were not subject to deny(warnings). I tend to think you should give people what they ask for. As you say, it won't break dependencies, and you can always re-enable warnings. It also lets us get a more accurate crater measurement, since the issue of "root regressions" is moot. |
This comment has been minimized.
This comment has been minimized.
...ok, that makes sense. But what is "full normalization" then? In some sense, the type checker already does this sort of normalization (for better and worse). That is, it expands type aliases in its internal representation and keeps no record of them. But I don't think this is particularly useful for your check because, when it comes to privacy, you care about the path that people used to reach something, and not just the item they reached in the end (the type checker doesn't track the path). Anyway, privacy is (usually) not something the type checker should have to be overly concerned with I think. |
This comment has been minimized.
This comment has been minimized.
Substitution of type aliases beyond the simplest case - associated type aliases (when possible), type aliases with default type parameters.
I don't suggest to do it in type checker, but I presume that type checker has tools for doing it, which can be reused in rustc_privacy somehow. Anyway, the simplest substitution can be done trivially in privacy without involving anything from type checker. Without this "normalization" some regressions from the crater report look pretty silly, e.g. from
In place of the library authors I'd start to resent - "Hey, It's |
petrochenkov
referenced this pull request
Nov 25, 2015
Closed
Private variants can be publicly reexported #30055
This comment has been minimized.
This comment has been minimized.
Ah. I'm not sure this kind of normalization makes sense or is necessary. After all, there is no "path" to follow when you do associated type normalization, for example, and there are already privacy rules that guarantee that the types that result from associated type normalization will be publicly accessible. (Basically, things appearing in impls, must be declared
Yes, I certainly see your point, and I've been annoyed by this same thing in the past. Basically wanting some private aliases and shorthands that you don't necessarily want to expose. It's tricky though because sometimes the type aliases are important things that rustdoc probably wants to preserve (e.g., cc @rust-lang/lang thoughts on this? (Normalization of type aliases) |
This comment has been minimized.
This comment has been minimized.
That was my idea as well. After #29822 rustdoc has all the necessary information to discern between these two kinds of type aliases. |
petrochenkov
force-pushed the
petrochenkov:privinpub
branch
from
7b0f1d6
to
88c3441
Nov 26, 2015
This comment has been minimized.
This comment has been minimized.
|
Updated with the old visitor restored, warnings used instead of some errors, and lint used instead of a plain warning. |
This comment has been minimized.
This comment has been minimized.
|
Updated with (non-associated) type alias substitution. |
petrochenkov
referenced this pull request
Nov 27, 2015
Closed
Private structure can escape from its module through impl for another private structure #30079
This comment has been minimized.
This comment has been minimized.
|
I'll schedule another crater run. |
This comment has been minimized.
This comment has been minimized.
|
This time around crater reports one failure. |
This comment has been minimized.
This comment has been minimized.
This failure is expected, it's a result of the fix for resolve, I'm not sure it deserves a warning period, but if we want to be extra careful maybe it makes sense to put a warning there as well. |
This comment has been minimized.
This comment has been minimized.
|
Cool, good to know! I'll leave the review to @nikomatsakis, but I'm pretty excited to see the nuts and bolts tightened up here! |
This comment has been minimized.
This comment has been minimized.
|
OK, I did a first pass and by and large I think this is pretty nice. It's hard for me to be sure if there are corner cases not covered but it certainly seems like a big improvement. I'm not quite ready to r+ yet though, largely because there are a few policy issues I'd like to resolve:
One other point: I'd like to ensure that there is a comprehensive and systematic set of tests for all the edge cases we can come up with. This is hard for me to tell, since there are older tests and of course the newer tests you've added, and the tests don't seem to share any distinct naming scheme. One nit I have with your naming is that you added most of the new tests as Some things I came up with that I'd like to know whether there are tests for:
Anyway, I have encountered this same problem (how to manage and track what tests exist and which tests we may want to exist) in other contexts and still find it frustrating! I'd like some kind of side files in the test directory that show these matrices and which tests cover what. Obviously out of scope for this PR. |
This comment has been minimized.
This comment has been minimized.
I agree with this now. |
This comment has been minimized.
This comment has been minimized.
|
I'd like to leave the constant checking to a separate PR, because it needs discussion. It's also a new kind of restriction that can be unexpected for users. I'll create an issue for this. |
This comment has been minimized.
This comment has been minimized.
Heh, a good question. If we REALLY want to guarantee that one can freely change a constant, we are indeed forced to a pretty extreme position -- too extreme, in my view. For example,
Given the improvements to const fn evaluation that @eddyb and I have been talking about, it is certainly plausible that we could actually implement the above fn at some point in the not-that-distinct future. In that case, we could regard this as illegal, because it "exposes" Of course you don't need to go to such esoteric examples. It's enough to have something like:
I may want to keep the precise A compromise might be to say that we do not check for privacy in the RHS of a constant definition nor in a
but if you are going to do that, you have to at least do it explicitly. Put another way, we guarantee for you (I think?) that the only constants the caller can observe are those that are declared public, but we leave it to you to vet that this only exposes what you intended. I am not sure if I find that persuasive. It doesn't feel very consistent with the rest of the "private things appearing in public APIs" logic. Another compromise might be to say that we do not check the body of @rust-lang/lang, thoughts on these thorny questions about public constants? @petrochenkov, do you think any similar concerns arise for type aliases? I don't think so, particularly given your "normalization" rule, which effectively means that the body of the type alias would have to be "deeply" public anyhow (iow, type alias normalization is kind of implementing the stricter rule). We've certainly got to land some of this excellent code soon! |
This comment has been minimized.
This comment has been minimized.
I agree with this inclination. The only question in my mind is what to do about type alias normalization. Certainly if we revert it, we can always add it back in later (perhaps with an RFC). This sort of makes sense, since it is weakening existing, stable rules. |
This comment has been minimized.
This comment has been minimized.
|
One more comment about type alias normalization - it still has to be performed for impls:
so most of the code for it will stay in place. |
This comment has been minimized.
This comment has been minimized.
Ah, true. |
This comment has been minimized.
This comment has been minimized.
|
Updated with type aliases not substituted. |
This comment has been minimized.
This comment has been minimized.
|
@bors r+ p=2 |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Dec 18, 2015
bluss
added
the
relnotes
label
Dec 18, 2015
This comment has been minimized.
This comment has been minimized.
bors
merged commit 785cbe0
into
rust-lang:master
Dec 18, 2015
bors
referenced this pull request
Dec 18, 2015
Merged
Rewrite BTreeMap to use parent pointers. #30426
petrochenkov
referenced this pull request
Dec 19, 2015
Closed
Consider checking constants in public interfaces for privacy #30475
This comment has been minimized.
This comment has been minimized.
|
@petrochenkov are you aware of an open issue concerning the interactions between inference and privacy? |
This comment has been minimized.
This comment has been minimized.
I opened one yesterday - #30476 |
This comment has been minimized.
This comment has been minimized.
|
I'm investigating some breakage in Diesel, and I believe this PR is the source. Just to make sure I'm clear, the intention was to disallow using private type aliases that appear anywhere? I've been using them quite a bit to shorten some more gnarly where clauses. I can make the type aliases public and |
This comment has been minimized.
This comment has been minimized.
|
@sgrif
? If yes, then my intention was to allow this, that's why type aliases were originally substituted, but it was reverted later to follow the letter of the RFC. It can be fixed at any moment (by removing three lines of code), but it needs a decision from the lang team. |
petrochenkov
referenced this pull request
Dec 21, 2015
Closed
Consider substituting type aliases in "public-in-private" checker #30503
This comment has been minimized.
This comment has been minimized.
|
cc #16463 |
petrochenkov commentedNov 21, 2015
Some notes:
This patch enforces the rules from RFC 136 and makes "private in public" a module-level concept and not crate-level. Only
pubannotations are used by the new algorithm, crate-level exported node set produced byEmbargoVisitoris not used. The error messages are tweaked accordingly and don't use the word "exported" to avoid confusing people (#29668).The old algorithm tried to be extra smart with impls, but it mostly led to unpredictable behavior and bugs like #28325.
The new algorithm tries to be as simple as possible - an impl is considered public iff its type is public and its trait is public (if presents).
A type or trait is considered public if all its components are public, complications with private types leaking to other crates/modules through trait impls and type inference are deliberately ignored so far.
The new algorithm is not recursive and uses the nice new facility
Crate::visit_all_items!Obsolete pre-1.0 feature
visible_private_typesis removed.This is a [breaking-change].
The two main vectors of breakage are type aliases (#28450) and impls (#28325).
I need some statistics from a crater run (cc @alexcrichton) to decide on the breakage mitigation strategy.
UPDATE: All the new errors are reported as warnings controlled by a lint
private_in_publicand lint groupfuture_incompatible, but the intent is to make them hard errors eventually.Closes #28325
Closes #28450
Closes #29524
Closes #29627
Closes #29668
Closes #30055
r? @nikomatsakis