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

Suggest to use . instead of :: when accessing a method of an object #101975

Merged
merged 1 commit into from
Dec 4, 2022

Conversation

chenyukang
Copy link
Member

@chenyukang chenyukang commented Sep 18, 2022

Fixes #101749
Fixes #101542

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Sep 18, 2022
@rust-highfive
Copy link
Collaborator

r? @TaKO8Ki

(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 Sep 18, 2022
@chenyukang chenyukang force-pushed the fix-101749 branch 2 times, most recently from 104f081 to aff89a6 Compare September 18, 2022 11:48
Copy link
Member

@TaKO8Ki TaKO8Ki left a comment

Choose a reason for hiding this comment

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

Sorry for the late review. I left a comment.

LL | println!("{}", rect1::area());
| ^^^^^ use of undeclared crate or module `rect1`
|
help: `rect1` is not a crate or module, maybe you meant to call instance method
Copy link
Member

Choose a reason for hiding this comment

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

I think this suggestion is emitted if rect1 does not have area method. Is it possible to check if rect has it before creating suggestion?

Given the following code:

// run-rustfix
struct Rectangle {
    width: i32,
    height: i32,
}
impl Rectangle {
    fn new(width: i32, height: i32) -> Self {
        Self { width, height }
    }
}

fn main() {
    let width = 3;
    let height = 4;
    let rect1 = Rectangle::new(width, height);
    println!("{}", rect1::area());
    //~^ ERROR failed to resolve: use of undeclared crate or module `rect1`
}

Current output is:

error[E0433]: failed to resolve: use of undeclared crate or module `rect1`
  --> src/main.rs:27:20
   |
27 |     println!("{}", rect1::area());
   |                    ^^^^^ use of undeclared crate or module `rect1`
   |
help: `rect1` is not a crate or module, maybe you meant to call instance method
   |
27 |     println!("{}", rect1.area());
   |                    ~~~~~~

For more information about this error, try `rustc --explain E0433`.

Copy link
Member Author

Choose a reason for hiding this comment

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

You are right.
This need to delay the suggestion to be emit in type checking phase, I will have a try.

Copy link
Member Author

Choose a reason for hiding this comment

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

Spent some time to trying this, I think it's complicated to make it work. We need to find the local binding of and ty of the ident, then to check whether it has the method.

See my branch:
chenyukang@9cf2a60

Not sure whether worth it for a corner case of suggestion.

Copy link
Member

@TaKO8Ki TaKO8Ki Oct 13, 2022

Choose a reason for hiding this comment

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

Adding a field to Resolver like the following for storing impl items might help you.

trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,

Copy link
Member Author

@chenyukang chenyukang Oct 28, 2022

Choose a reason for hiding this comment

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

I continue with my previous solution, delay diagnostic to checking method in type checking phase, now it works by checking whether the method name is valid (may need more tweak about the arguments checking).

I have a question for my current code, how can we find the binding according to a ident(then find out the type of it),

My code for this part is:
https://github.com/rust-lang/rust/pull/101975/files#diff-8dea1c54efc225f1b3a27454cbf2fc50f016073f51319b27d1b834bee7c5419eR1435

It's a little bit complicated to use a visitor for this, another issue is it can only handle the let expression, I want our suggestion works also for other scenarios, such as the binding is introduced by function arguments.

Copy link
Member Author

Choose a reason for hiding this comment

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

@compiler-errors do you know any better solution for this?

@rust-log-analyzer

This comment has been minimized.

@chenyukang chenyukang marked this pull request as ready for review October 29, 2022 14:05
@chenyukang chenyukang force-pushed the fix-101749 branch 3 times, most recently from 9f1685f to bccd912 Compare October 30, 2022 04:26
@rust-log-analyzer

This comment has been minimized.

@chenyukang chenyukang force-pushed the fix-101749 branch 4 times, most recently from 18a110d to 7a20d12 Compare November 4, 2022 04:55
@bors
Copy link
Contributor

bors commented Nov 4, 2022

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

@chenyukang
Copy link
Member Author

Hi @TaKO8Ki,
Any more suggestion on this PR?

@bors
Copy link
Contributor

bors commented Nov 21, 2022

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

compiler/rustc_resolve/src/diagnostics.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/diagnostics.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/diagnostics.rs Outdated Show resolved Hide resolved
let Ok(snippet) = sm.span_to_snippet(span) &&
snippet.starts_with("::") && snippet.matches("::").count() == 1 {
let local_span = *self.pat_span_map.get(&local_id).unwrap();
let mut err = self.session.struct_span_err(
Copy link
Member

Choose a reason for hiding this comment

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

Why are you making a new error here? Is it possible to pass this down to where the original error (use of undeclared crate or module) is being created?

Copy link
Member Author

@chenyukang chenyukang Nov 22, 2022

Choose a reason for hiding this comment

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

This is because I need to stash it, and if the method checking failed, I want cancel it, but the previous one use of undeclared crate or module should always emit?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, but there should not be two errors -- only one, and you can append a suggestion to it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Let' me try to stash use of undeclared crate or module, and only add help suggestion when method checking succeed.

Copy link
Member Author

Choose a reason for hiding this comment

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

oops, seems need many more changes, since report_path_resolution_error only report the error message and suggestions.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, you probably need to pass it down in the return statement and use it where that error is being created.

Copy link
Member Author

Choose a reason for hiding this comment

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

maybe this function is not the proper position to add this check...😛

Copy link
Member

@compiler-errors compiler-errors Nov 22, 2022

Choose a reason for hiding this comment

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

Maybe so... but I would prefer if we did it the correct way. Is it possible to investigate the correct way of doing it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, let me try it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Code updated!
There are some test case result changed, since the diagnostic order change.

let parent = self.tcx.hir().get_parent_node(seg1.hir_id);
if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) &&
let Some(expr) = visitor.result {
let self_ty = self.check_expr(expr);
Copy link
Member

Choose a reason for hiding this comment

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

This is checking an expression that should have already been checked. There should be a way of using the TypeckResults (or something else) to find the Ty of a local variable...

Copy link
Member Author

Choose a reason for hiding this comment

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

Use node_ty to get Ty now.

compiler/rustc_hir_typeck/src/method/suggest.rs Outdated Show resolved Hide resolved
compiler/rustc_hir_typeck/src/method/suggest.rs Outdated Show resolved Hide resolved
compiler/rustc_hir_typeck/src/method/suggest.rs Outdated Show resolved Hide resolved
@compiler-errors
Copy link
Member

Sorry for taking so long to review this even though I was cc'd. I gave this some reviews, let me know what you think @chenyukang. I like the idea of the diagnostic, though.

@compiler-errors
Copy link
Member

r? @compiler-errors

@rustbot rustbot assigned compiler-errors and unassigned TaKO8Ki Nov 22, 2022
@compiler-errors compiler-errors 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 Nov 22, 2022
@chenyukang chenyukang force-pushed the fix-101749 branch 2 times, most recently from 94f7c7e to 2a3edb5 Compare November 22, 2022 14:50
@compiler-errors
Copy link
Member

@chenyukang make sure to do:

@rustbot ready

When you're ready to review. Otherwise I might not see this, haha.

@rustbot rustbot 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 Nov 26, 2022
@chenyukang
Copy link
Member Author

@compiler-errors thanks for reminder! 😁

let sm = self.infcx.tcx.sess.source_map();
diag.span_suggestion_verbose(
sm.span_extend_while(seg1.ident.span.shrink_to_hi(), |c| c == ':').unwrap(),
"maybe you meant to call instance method",
Copy link
Member

@compiler-errors compiler-errors Dec 3, 2022

Choose a reason for hiding this comment

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

Suggested change
"maybe you meant to call instance method",
"you may have meant to call an instance method",

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

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

Thanks, this looks pretty good. I will give one last review once you fix the typo. Please ping me if I forget.

@chenyukang
Copy link
Member Author

Thanks, this looks pretty good. I will give one last review once you fix the typo. Please ping me if I forget.

Updated, thanks!

@compiler-errors
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Dec 4, 2022

📌 Commit fb004e9 has been approved by compiler-errors

It is now in the queue for this repository.

@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-review Status: Awaiting review from the assignee but also interested parties. labels Dec 4, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 4, 2022
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#101975 (Suggest to use . instead of :: when accessing a method of an object)
 - rust-lang#105141 (Fix ICE on invalid variable declarations in macro calls)
 - rust-lang#105224 (Properly substitute inherent associated types.)
 - rust-lang#105236 (Add regression test for rust-lang#47814)
 - rust-lang#105247 (Use parent function WfCheckingContext to check RPITIT.)
 - rust-lang#105253 (Update a couple of rustbuild deps)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors
Copy link
Contributor

bors commented Dec 4, 2022

⌛ Testing commit fb004e9 with merge 0f0d5d7...

@bors bors merged commit 7dbd160 into rust-lang:master Dec 4, 2022
@rustbot rustbot added this to the 1.67.0 milestone Dec 4, 2022
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. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
7 participants