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

Check paths for privacy as they are resolved and refactor away LastPrivate #31824

Merged
merged 7 commits into from
Mar 3, 2016

Conversation

jseyfried
Copy link
Contributor

This PR privacy checks paths as they are resolved instead of in librustc_privacy (fixes #12334 and fixes #31779). This removes the need for the LastPrivate system introduced in PR #9735, the limitations of which cause #31779.

This PR also reports privacy violations in paths to intra- and inter-crate items the same way -- it always reports the first inaccessible segment of the path.

Since it fixes #31779, this is a [breaking-change]. For example, the following code would break:

mod foo {
    pub use foo::bar::S;
    mod bar { // `bar` should be private to `foo`
        pub struct S;
    }
}

impl foo::S {
    fn f() {}
}

fn main() {
    foo::bar::S::f(); // This is now a privacy error
}

r? @alexcrichton

@jseyfried
Copy link
Contributor Author

cc @nrc @petrochenkov @nikomatsakis

@jseyfried jseyfried force-pushed the privacy_in_resolve branch 2 times, most recently from 33ead2a to 5c3c877 Compare February 23, 2016 01:21
@petrochenkov
Copy link
Contributor

Reviewed.

@alexcrichton
Copy link
Member

Thanks for the PR @jseyfried! I may unfortunately not be the best reviewer for this as so much of resolve and privacy have changed since this was originally implemented, but I can at least add my 2cents!

Historically privacy and resolve were entangled, but this ended up leading to tons of really weird resolution problems. The major motivation for moving all of privacy to its own separate pass was to improve all these errors. At that point, the only privacy-related parts of resolve were that glob imports didn't bring private names into a module.

Since then, though, maybe resolve has changed to be much more robust? I've definitely seen some awesome work of yours fly by in the interim :).

I suspect that the buggy program you've linked here can possibly be fixed by not jettisoning LastPrivate but patching up support for it. It looks like this approach may be cleaner, though? It at least has a negative diffstat!

@alexcrichton
Copy link
Member

Looking over the tests, it looks like the error messages related to privacy get even better than where they are today. Specifically the messages seem much more precise in terms of what's actually private along the chain of a path.

With that in mind, if you're confident that this fits nicely into resolve as-is today and it won't regress resolution error messages, then it seems like a fine shift to me! I forget now what the rustc_privacy pass would actually do if this is removed, but it seems large enough that it surely does something.

@jseyfried
Copy link
Contributor Author

@alexcrichton Thanks for the history and feedback! Resolve is indeed more robust now :)

I'm confident that this PR won't regress resolution error messages since it doesn't change the observable behavior of the import resolver or crate resolver; instead, it silently collects privacy errors during resolution and reports them after resolution is complete.

rustc_privacy still does a couple of passes that are unaffected by this PR, including checking for public types in private interfaces. The pass that used to privacy check paths, PrivacyChecker, still privacy checks struct fields (including the sometimes implicit fields in struct constructors) and non-UFCS methods. Some field checking can be moved into resolve and the rest can be moved into typeck, but that is for another PR.

@jseyfried
Copy link
Contributor Author

I may unfortunately not be the best reviewer for this

r? @nikomatsakis

@jseyfried
Copy link
Contributor Author

I added a commit addressing @petrochenkov's comments (and a comment of mine).

@jseyfried jseyfried force-pushed the privacy_in_resolve branch 5 times, most recently from afde9e3 to 068eb82 Compare February 24, 2016 15:04
@@ -3614,6 +3606,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
}

fn report_privacy_errors(&self) {
for (span, string) in self.privacy_errors.iter() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since privacy_errors is a HashMap, this will result in nondeterministic error ordering. Maybe the map should be changed to an FnvHashMap or a BTreeMap?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, I'll change it.

@bors
Copy link
Contributor

bors commented Feb 25, 2016

☔ The latest upstream changes (presumably #31882) made this pull request unmergeable. Please resolve the merge conflicts.

@petrochenkov
Copy link
Contributor

I've added a couple more comments since you are going to rebase this anyway.

@nikomatsakis
Copy link
Contributor

This seems like a big improvement. r=me.

@nikomatsakis
Copy link
Contributor

To be clear: r=me after rebase + nits that others have already listed are addressed.

@jseyfried
Copy link
Contributor Author

@nikomatsakis I rebased, addressed the comments, and cleaned up the history. Given that there was breakage in rustc_metadata, do you think this needs a crater run?

@nikomatsakis
Copy link
Contributor

@jseyfried unclear, but I kicked off one just in case

@nikomatsakis
Copy link
Contributor

The crater run somehow failed. I'm inclined to just land this, since the next beta has branched.

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Mar 3, 2016

📌 Commit e67590b has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Mar 3, 2016

⌛ Testing commit e67590b with merge 7cee8b9...

bors added a commit that referenced this pull request Mar 3, 2016
This PR privacy checks paths as they are resolved instead of in `librustc_privacy` (fixes #12334 and fixes #31779). This removes the need for the `LastPrivate` system introduced in PR #9735, the limitations of which cause #31779.

This PR also reports privacy violations in paths to intra- and inter-crate items the same way -- it always reports the first inaccessible segment of the path.

Since it fixes #31779, this is a [breaking-change]. For example, the following code would break:
```rust
mod foo {
    pub use foo::bar::S;
    mod bar { // `bar` should be private to `foo`
        pub struct S;
    }
}

impl foo::S {
    fn f() {}
}

fn main() {
    foo::bar::S::f(); // This is now a privacy error
}
```

r? @alexcrichton
@bors bors merged commit e67590b into rust-lang:master Mar 3, 2016
@bors bors mentioned this pull request Mar 3, 2016
@jseyfried jseyfried deleted the privacy_in_resolve branch March 25, 2016 22:57
@sanxiyn sanxiyn mentioned this pull request Apr 4, 2016
steveklabnik added a commit to steveklabnik/rust that referenced this pull request Apr 6, 2016
Remove outdated comment

The corresponding code was removed in rust-lang#31824. Also remove code duplication and rename the function.
steveklabnik added a commit to steveklabnik/rust that referenced this pull request Apr 6, 2016
Remove outdated comment

The corresponding code was removed in rust-lang#31824. Also remove code duplication and rename the function.
steveklabnik added a commit to steveklabnik/rust that referenced this pull request Apr 6, 2016
Remove outdated comment

The corresponding code was removed in rust-lang#31824. Also remove code duplication and rename the function.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants