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

You can never call your own fn borrow(&mut self, ...) method if you use std::borrow::Borrow; #54103

Open
bombless opened this issue Sep 10, 2018 · 7 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. A-traits Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-papercut Diagnostics: An error or lint that needs small tweaks. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bombless
Copy link
Contributor

bombless commented Sep 10, 2018

https://play.rust-lang.org/?gist=c36d8c617e66862b7bcaee05752ad313&version=stable&mode=debug&edition=2015

fn main() {
    use std::borrow::Borrow;
    struct S;
    impl S { fn borrow(&mut self, _: ()) {} }
    let mut s = S;
    s.borrow(())
}

(Just noticed that this might be the intended behaviour, since std::clone::Clone acts the same. But still, the error message here might need to be improved)

@bombless
Copy link
Contributor Author

it looks fishy since if you change the code to impl S { fn borrow(&self, _: ()) {} } it compiles, which doesn't look logical to me.

@csmoe csmoe added the A-traits Area: Trait system label Sep 10, 2018
@csmoe
Copy link
Member

csmoe commented Sep 10, 2018

cc https://doc.rust-lang.org/reference/expressions/method-call-expr.html#method-call-expressions
&self methods are looked up first, the trait method is found before the struct's &mut self method is found.

@ishitatsuyuki ishitatsuyuki added the A-diagnostics Area: Messages for errors, warnings, and lints label Sep 10, 2018
@ishitatsuyuki
Copy link
Contributor

This is how name resolution works, and yeah you need to use UFCS if you shadow such names.

Labeling this as a diagnostics feature request.

@ExpHP
Copy link
Contributor

ExpHP commented Sep 10, 2018

&self methods are looked up first, the trait method is found before the struct's &mut self method is found.

But... why?

Is this something that could perhaps one day change with a crater run? To me it looks like a terrible corner case with no useful outcome, and acts as little more than an exception to the "rule" that inherent methods come before trait methods. (a rule that is actually useful!)

@steveklabnik
Copy link
Member

The error message:

error[E0061]: this function takes 0 parameters but 1 parameter was supplied
 --> src/main.rs:6:7
  |
6 |     s.borrow(())
  |       ^^^^^^ expected 0 parameters

error[E0308]: mismatched types
 --> src/main.rs:6:5
  |
1 | fn main() {
  |           - expected `()` because of default return type
...
6 |     s.borrow(())
  |     ^^^^^^^^^^^^- help: try adding a semicolon: `;`
  |     |
  |     expected (), found &main::S
  |
  = note: expected type `()`
             found type `&main::S`

@estebank
Copy link
Contributor

This should suggest to alternatively write S::borrow(&mut s, ());.

@estebank estebank added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-papercut Diagnostics: An error or lint that needs small tweaks. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 25, 2020
@estebank
Copy link
Contributor

estebank commented Nov 7, 2023

Slight change. It now points at the definition of Borrow::borrow, but it still doesn't mention the inherent impl fn.

error[E0061]: this method takes 0 arguments but 1 argument was supplied
 --> src/main.rs:6:7
  |
6 |     s.borrow(())
  |       ^^^^^^ --
  |              |
  |              unexpected argument of type `()`
  |              help: remove the extra argument
  |
note: method defined here
 --> /rustc/fee5518cdd4435c60a57fe3bb734fc1a14abeb7a/library/core/src/borrow.rs:178:8

error[E0308]: mismatched types
 --> src/main.rs:6:5
  |
1 | fn main() {
  |          - expected `()` because of default return type
...
6 |     s.borrow(())
  |     ^^^^^^^^^^^^- help: consider using a semicolon here: `;`
  |     |
  |     expected `()`, found `&S`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. A-traits Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-papercut Diagnostics: An error or lint that needs small tweaks. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants