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

Misleading message when attempting to call methods on a raw pointer #21596

Closed
kornelski opened this issue Jan 24, 2015 · 4 comments · Fixed by #61444
Closed

Misleading message when attempting to call methods on a raw pointer #21596

kornelski opened this issue Jan 24, 2015 · 4 comments · Fixed by #61444
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kornelski
Copy link
Contributor

When trying to call a method on a raw pointer Rust compiler says there's no such method.

It would be better to say that there is such method, but the pointer has to be explicitly dereferenced first.

let x = 8u8;
let y = &x;
let z: *const u8 = &x;
println!("{} {}", 
    y.to_string(), // OK
    z.to_string()  // Not OK
);

error: type *const u8 does not implement any method in scope named to_string

This is technically correct, but unexpected and help hint for this error suggests wrong solution.

I've read this message as "yada yada no such method", so I went to check whether I've spelled the method correctly, whether I've put the method in the appropriate impl block, etc. — all completely irrelevant to this error.

I'd find something like that more helpful:

error: method to_string requires type u8, but *const u8 cannot be automatically dereferenced. hint: use as_ref()

@kmcallister kmcallister added the A-diagnostics Area: Messages for errors, warnings, and lints label Jan 25, 2015
@nagisa
Copy link
Member

nagisa commented Jan 25, 2015

Implementing traits for raw pointers is possible, though. The best we could do here is to add some logic in trait suggestion mechanism to check whether traits for dereferenced values exist. Something along the lines of

help: std::string::ToString::to_string implemented for &u8, consider `z.as_ref()`
help: std::string::ToString::to_string implemented for u8, consider dereferencing `z`

Too many help messages will overwhelm messages that actually matter, though.

@steveklabnik
Copy link
Member

Triage: no change

@steveklabnik steveklabnik added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 9, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 22, 2017
@memoryruins
Copy link
Contributor

memoryruins commented Jan 30, 2019

Triage: the error message has improved

error[E0599]: no method named `to_string` found for type `*const u8` in the current scope
 --> src/main.rs:8:11
  |
8 |         z.to_string()  // Not OK
  |           ^^^^^^^^^
  |
  = note: the method `to_string` exists but the following trait bounds were not satisfied:
          `*const u8 : std::string::ToString`

rustc: 1.32.0 / rust version 1.34.0-nightly (c1c3c4e95 2019-01-29)

@estebank
Copy link
Contributor

estebank commented Jun 1, 2019

To suggest as_ref it would have to suggest unsafe {z.as_ref()}.unwrap(), which is taking the suggestions a bit far. We could add a note about as_ref though.

@estebank estebank added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. P-low Low priority labels Jun 1, 2019
Centril added a commit to Centril/rust that referenced this issue Jun 4, 2019
Centril added a commit to Centril/rust that referenced this issue Jun 4, 2019
Centril added a commit to Centril/rust that referenced this issue Jun 4, 2019
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 11, 2024
…ef, r=estebank

Rework ptr-to-ref conversion suggestion for method calls

If we have a value `z` of type `*const u8` and try to call `z.to_string()`, the upstream compiler will show you a note suggesting to call `<*const u8>::as_ref` first.

This PR extends that:
- The note will only be shown when the method would exist on the corresponding reference type
- It can now suggest any of `<*const u8>::as_ref`, `<*mut u8>::as_ref` and `<*mut u8>::as_mut`, depending on what the method needs.

I didn't introduce a `help` message because that's not a good idea with `unsafe` functions (and you'd also need to unwrap the `Option<&_>` somehow).
People should check the safety requirements.

For the simplest case
```rust
fn main() {
    let x = 8u8;
    let z: *const u8 = &x;
    // issue rust-lang#21596
    println!("{}", z.to_string()); //~ ERROR E0599
}
```
the output changes like this:
```diff
 error[E0599]: `*const u8` doesn't implement `std::fmt::Display`
   --> $DIR/suggest-convert-ptr-to-ref.rs:5:22
    |
 LL |     println!("{}", z.to_string());
    |                      ^^^^^^^^^ `*const u8` cannot be formatted with the default formatter
    |
-   = note: try using `<*const T>::as_ref()` to get a reference to the type behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
-   = note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior
+note: the method `to_string` exists on the type `&u8`
+  --> $SRC_DIR/alloc/src/string.rs:LL:COL
+   = note: try using the unsafe method `<*const T>::as_ref` to get an optional reference to the value behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
    = note: the following trait bounds were not satisfied:
            `*const u8: std::fmt::Display`
            which is required by `*const u8: ToString`
```

I removed the separate note about the safety requirements because it was incomplete and the linked doc page already has the information you need.

Fixes rust-lang#83695, but that's more of a side effect. The upstream compiler already suggests the right method name here.
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 11, 2024
…ef, r=estebank

Rework ptr-to-ref conversion suggestion for method calls

If we have a value `z` of type `*const u8` and try to call `z.to_string()`, the upstream compiler will show you a note suggesting to call `<*const u8>::as_ref` first.

This PR extends that:
- The note will only be shown when the method would exist on the corresponding reference type
- It can now suggest any of `<*const u8>::as_ref`, `<*mut u8>::as_ref` and `<*mut u8>::as_mut`, depending on what the method needs.

I didn't introduce a `help` message because that's not a good idea with `unsafe` functions (and you'd also need to unwrap the `Option<&_>` somehow).
People should check the safety requirements.

For the simplest case
```rust
fn main() {
    let x = 8u8;
    let z: *const u8 = &x;
    // issue rust-lang#21596
    println!("{}", z.to_string()); //~ ERROR E0599
}
```
the output changes like this:
```diff
 error[E0599]: `*const u8` doesn't implement `std::fmt::Display`
   --> $DIR/suggest-convert-ptr-to-ref.rs:5:22
    |
 LL |     println!("{}", z.to_string());
    |                      ^^^^^^^^^ `*const u8` cannot be formatted with the default formatter
    |
-   = note: try using `<*const T>::as_ref()` to get a reference to the type behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
-   = note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior
+note: the method `to_string` exists on the type `&u8`
+  --> $SRC_DIR/alloc/src/string.rs:LL:COL
+   = note: try using the unsafe method `<*const T>::as_ref` to get an optional reference to the value behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
    = note: the following trait bounds were not satisfied:
            `*const u8: std::fmt::Display`
            which is required by `*const u8: ToString`
```

I removed the separate note about the safety requirements because it was incomplete and the linked doc page already has the information you need.

Fixes rust-lang#83695, but that's more of a side effect. The upstream compiler already suggests the right method name here.
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 C-enhancement Category: An issue proposing an enhancement or a PR with one. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants