Incorrect suggestion in error when accessing field on raw pointer

54ee597
Opened by jethrogb at 2020-06-11 18:01:46

When compiling this code:

struct A {
    n: i32
}
struct B {
    n: i32
}

fn main() {
    let x = A{n:3};
    let a = &x as *const _;
    unsafe { println!("{}", (a as *const B).n); }
}

You get the following error message:

error: no field `n` on type `*const B`
  --> <anon>:11:45
   |
11 |     unsafe { println!("{}", (a as *const B).n); }
   |                                             ^
   |
   = note: `a as *const B` is a native pointer; perhaps you need to deref with `(*a as *const B).n`

The suggested deref (*a as *const B) doesn't work, what you need to write is (*(a as *const B)).

  1. The perils of cobbling together code advice with string formatting rather than grammar? The error message formats (*{0}).{1} using a call of node_to_pretty_string as the first argument. The second, inner parentheses in the correct replacement are necessary specifically because dereference binds more strongly than as: but the code that formats the pointer cast HIR expression doesn't, can't, know about the * in the format string. Can we ... can we make our own HIR node incorporating both the deference and the cast, and let the hir::print machinery deal with it??

    Zack M. Davis at 2017-07-16 02:40:44

  2. In clippy we addressed this by writing a suggestion builder: https://github.com/rust-lang-nursery/rust-clippy/blob/master/clippy_lints/src/utils/sugg.rs

    Maybe that one should simply be upstreamed into rustc?

    Oli Scherer at 2017-08-10 15:23:35