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

Prefer accessible paths in 'use' suggestions #72623

Merged
merged 1 commit into from
Jun 22, 2020

Conversation

da-x
Copy link
Member

@da-x da-x commented May 26, 2020

This PR addresses issue #26454, where use suggestions are made for paths that don't work. For example:

mod foo {
    mod bar {
        struct X;
    }
}

fn main() { X; } // suggests `use foo::bar::X;`

@rust-highfive
Copy link
Collaborator

r? @cramertj

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 26, 2020
@petrochenkov petrochenkov self-assigned this May 26, 2020
@rust-highfive

This comment has been minimized.

@petrochenkov
Copy link
Contributor

@da-x
Could you explain the used heuristic?
I don't understand what the in_reference conditions attempt to achieve exactly?

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 29, 2020
@da-x
Copy link
Member Author

da-x commented May 30, 2020

@petrochenkov First, reference is the source location that caused the error, where the missing name is, that is - where the user is.

Case 1

For is_visible_to_user, we don't care whether pub mod foo or mod foo in the next example, because visibility only matters for a user outside the current module:

pub mod foo { // Or `mod foo {`
    pub struct Bla;
}

fn main() {
    let x = Bar;
}

That's why in_reference || name_binding.vis == ty::Visibility::Public controls recursion. It's only on the first inner module that we start to care about visibility. For example, if we had:

mod extra_layer {
    mod foo { // Now `pub mod foo` or `mod foo` matter for `use` potential.
        pub struct Bar;
    }
}

fn main() {
    let x = Bar;
}

Case 2

Old code skips all imports in the in_module.for_each_child block. In general we don't want to skip imports because then we miss re-exported private items. e.g. crate::foo::bar::XinBar can be private while use crate::foo::XinBar; maybe be valid to due a public re-export of it, and we want the user to know.

What I did there, is to only skip imports that are at the reference, i.e. in_reference && name_binding.is_import() && !name_binding.is_extern_crate(). However while trying to explain this I figured that in_reference && in that place needs to move to be !in_reference in the collect results based on the filter function bit. I.e. we want to recourse into the imports, but we don't want to add weird suggestions like the following: use ItemUse;, which is what would otherwise happen (and it did, see your commit d1310dc).

I'm adding this as an extra commit. See mixed-site-span.stderr and lexical-scopes.stderr that were positively affected.

It would be probably a good idea to add more tests for this, and have them both work with edition 2015 and edition 2018.

@bors

This comment has been minimized.

@petrochenkov petrochenkov added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 30, 2020
@petrochenkov
Copy link
Contributor

@da-x
I see, thanks for the explanation!

#72789 shows how to pass the "reference module" in a better way and how to compare modules without spans.

Once that PR lands, could you split this PR into two PRs, one for the "suggest reexports" heuristic and one for the privacy check heuristic, so their effects on tests could be more clear.

@petrochenkov petrochenkov added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 30, 2020
@bors
Copy link
Contributor

bors commented Jun 4, 2020

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

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Jun 10, 2020
resolve: Do not suggest imports from the same module in which we are resolving

Based on the idea from rust-lang#72623.
@petrochenkov
Copy link
Contributor

#72789 has landed.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels Jun 11, 2020
@da-x
Copy link
Member Author

da-x commented Jun 11, 2020 via email

@da-x da-x force-pushed the use-suggest-public-path branch from fb920c6 to a584e44 Compare June 13, 2020 17:59
@da-x da-x changed the title Fix 'use' suggestions to show publicly exported paths Properly consider visibility for 'use' suggestions Jun 13, 2020
@da-x
Copy link
Member Author

da-x commented Jun 13, 2020

@petrochenkov rewrite is finished.

@petrochenkov petrochenkov added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 13, 2020
@da-x
Copy link
Member Author

da-x commented Jun 19, 2020

The move to use is_ancestor_of made it possible to clean up predicates further inside the loop. Also, the is_extern checks were cleaned up in a subsequent commit, as ancestry checks makes them redundant as well.

@petrochenkov petrochenkov added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 19, 2020
@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 20, 2020
@petrochenkov
Copy link
Contributor

r=me after squashing the commits.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 21, 2020
This fixes an issue with the following sample:

    mod foo {
	mod inaccessible {
	    pub struct X;
	}
	pub mod avail {
	    pub struct X;
	}
    }

    fn main() { X; }

Instead of suggesting both `use crate::foo::inaccessible::X;` and `use
crate::foo::avail::X;`, it should only suggest the latter.

It is done by trimming the list of suggestions from inaccessible paths
if accessible paths are present.

Visibility is checked with `is_accessible_from` now instead of being
hard-coded.

-

Some tests fixes are trivial, and others require a bit more explaining,
here are my comments:

src/test/ui/issues/issue-35675.stderr: Only needs to make the enum
public to have the suggestion make sense.

src/test/ui/issues/issue-42944.stderr: Importing the tuple struct won't
help because its constructor is not visible, so the attempted
constructor does not work. In that case, it's better not to suggest it.
The case where the constructor is public is covered in `issue-26545.rs`.
@da-x da-x force-pushed the use-suggest-public-path branch from e62f828 to fea5ab1 Compare June 21, 2020 15:55
@da-x
Copy link
Member Author

da-x commented Jun 21, 2020

Done. Also, consider for a follow-up PR, maybe to fix the following:

mod foo {
    mod bar {
        pub struct X;
    }
    pub use self::bar::X;
}

fn main() { X; }

This still suggests use foo::bar::X; instead of use foo::X. Fixing this will require not skipping imports in the in_module.for_each_child loop.

@da-x da-x changed the title Properly consider visibility for 'use' suggestions Prefer accessible paths in 'use' suggestions Jun 21, 2020
@da-x
Copy link
Member Author

da-x commented Jun 21, 2020

r? @petrochenkov

@petrochenkov
Copy link
Contributor

Yeah, not skipping imports would be useful, and it can be done as a separate PR.
@bors r+

@bors
Copy link
Contributor

bors commented Jun 21, 2020

📌 Commit fea5ab1 has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 21, 2020
Manishearth added a commit to Manishearth/rust that referenced this pull request Jun 21, 2020
…rochenkov

Prefer accessible paths in 'use' suggestions

This PR addresses issue rust-lang#26454, where `use` suggestions are made for paths that don't work. For example:

```rust
mod foo {
    mod bar {
        struct X;
    }
}

fn main() { X; } // suggests `use foo::bar::X;`
```
Manishearth added a commit to Manishearth/rust that referenced this pull request Jun 21, 2020
…rochenkov

Prefer accessible paths in 'use' suggestions

This PR addresses issue rust-lang#26454, where `use` suggestions are made for paths that don't work. For example:

```rust
mod foo {
    mod bar {
        struct X;
    }
}

fn main() { X; } // suggests `use foo::bar::X;`
```
Manishearth added a commit to Manishearth/rust that referenced this pull request Jun 22, 2020
…rochenkov

Prefer accessible paths in 'use' suggestions

This PR addresses issue rust-lang#26454, where `use` suggestions are made for paths that don't work. For example:

```rust
mod foo {
    mod bar {
        struct X;
    }
}

fn main() { X; } // suggests `use foo::bar::X;`
```
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 22, 2020
Rollup of 6 pull requests

Successful merges:

 - rust-lang#71660 (impl PartialEq<Vec<B>> for &[A], &mut [A])
 - rust-lang#72623 (Prefer accessible paths in 'use' suggestions)
 - rust-lang#73502 (Add E0765)
 - rust-lang#73580 (deprecate wrapping_offset_from)
 - rust-lang#73582 (Miri: replace many bug! by span_bug!)
 - rust-lang#73585 (Do not send a notification for P-high stable regressions)

Failed merges:

 - rust-lang#73581 (Create 0766 error code)

r? @ghost
@bors bors merged commit fdd241f into rust-lang:master Jun 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants