-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
resolve: refactor path resolution #38014
Conversation
8254908
to
f8e5593
Compare
Hey, I have a relatively large rewrite of high level path resolution and error reporting in progress: https://github.com/petrochenkov/rust/tree/altname. |
Reviewed. The changes are mostly orthogonal to my branch, the main contention is about |
@@ -71,13 +71,13 @@ pub struct LoweringContext<'a> { | |||
|
|||
pub trait Resolver { | |||
// Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc. | |||
fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def; | |||
fn resolve_hir_path(&mut self, path: &hir::Path, is_value: bool) -> PathResolution; |
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.
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.
I'll wait for #37676 to merge and then rebase.
f8e5593
to
cc0383b
Compare
@bors: r+ |
📌 Commit 84be399 has been approved by |
@nrc See #38014 (comment). @bors r- |
84be399
to
f0fddcc
Compare
☔ The latest upstream changes (presumably #37676) made this pull request unmergeable. Please resolve the merge conflicts. |
@@ -191,10 +189,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, | |||
span: syntax_pos::Span, | |||
resolution_error: ResolutionError<'c>) | |||
-> DiagnosticBuilder<'a> { | |||
if !resolver.emit_errors { | |||
return resolver.session.diagnostic().struct_dummy(); |
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.
There should be a way to do speculative resolution without reporting errors.
It's used at least once now in fresh binding disambiguation and I'm using it in my error reporting branch as well.
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.
@petrochenkov You can still do speculative resolution by passing record_used: None
to resolve_path
, resolve_ident_in_lexical_scope
, or resolve_name_in_module
.
f0fddcc
to
8fe525d
Compare
Rebased and added a new commit -- r? @eddyb for new commit. |
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.
r=me with nit fixed
@@ -353,9 +350,6 @@ impl<'a> LoweringContext<'a> { | |||
// `<I as Iterator>::Item::default`. | |||
let ty = self.ty(p.span, hir::TyPath(hir::QPath::Resolved(qself, path))); | |||
|
|||
// Associate that innermost path type with the base Def. | |||
self.resolver.record_resolution(ty.id, resolution.base_def); | |||
|
|||
ty |
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.
You can avoid the ty
variable.
a2ebc4c
to
c871637
Compare
@bors r=nrc |
📌 Commit c871637 has been approved by |
resolve: refactor path resolution This is a pure refactoring, modulo minor diagnostics improvements. r? @nrc
More systematic error reporting in path resolution Path resolution for types, expressions and patterns used various heuristics to give more helpful messages on unresolved or incorrectly resolved paths. This PR combines these heuristics and applies them to all non-import paths. First a path is resolved in all namespaces, starting from its primary namespace (to give messages like "expected function, found macro, you probably forgot `!`"). If this resolution doesn't give a desired result we create a base error - either "path is not resolved" or "path is resolved, but the resolution is not acceptable in this context". Other helps and notes are applied to this base error using heuristics. Here's the list of heuristics for a path with a last segment `name` in order. First we issue special messages for unresolved `Self` and `self`. Second we try to find free items named `name` in other modules and suggest to import them. Then we try to find fields and associated items named `name` and suggest `self.name` or `Self::name`. After that we try several deterministic context dependent heuristics like "expected value, found struct, you probably forgot `{}`". If nothing of the above works we try to find candidates with other names using Levenshtein distance. --- Some alternatives/notes/unresolved questions: - ~~I had a strong desire to migrate all affected tests to `test/ui`, diagnostics comparison becomes much more meaningful, but I did this only for few tests so far.~~ (Done) - ~~Labels for "unresolved path" errors are mostly useless now, it may make sense to move some help/notes to these labels, help becomes closer to the error this way.~~ (Done) - ~~Currently only the first successful heuristic results in additional message shown to the user, it may make sense to print them all, they are rarely compatible, so the diagnostics bloat is unlikely.~~ (Done) - Now when #38014 landed `resolve_path` can potentially be replaced with `smart_resolve_path` in couple more places - e.g. ~~visibilities~~ (done), ~~import prefixes~~ (done), HIR paths. --- Some additional fixes: - Associated suggestions and typo suggestions are filtered with a context specific predicate to avoid inapplicable suggestions. - `adjust_local_def` works properly in speculative resolution. - I also fixed a recently introduced ICE in partially resolved UFCS paths (see test `ufcs-partially-resolved.rs`). Minimal reproduction: ``` enum E {} fn main() { <u8 as E>::A; } ``` Fixes #38409, fixes #38504 (duplicates). - Some bugs in resolution of visibilities are fixed - `pub(Enum)`, `pub(Trait)`, `pub(non::local::path)`. - Fixes #38012. --- r? @jseyfried for technical details + @jonathandturner for diagnostics changes How to read the patch: `smart_resolve_path(_fragment)/resolve_qpath_anywhere` are written anew and replace `resolve_trait_reference`/`resolve_type`/`resolve_pattern_path`/`resolve_struct_path`/`resolve_expr` for `ExprKind::Path`, everything else can be read as a diff.
This is a pure refactoring, modulo minor diagnostics improvements.
r? @nrc