5

I've noticed that, given a P<SomeStruct>, accessing fields of the SomeStruct directly on the pointer seems to work, and I'm not sure why that is. For example, this code compiles and works as expected (prints "1234"):

#![feature(rustc_private)]

extern crate syntax;
use syntax::ptr::P;

struct Baz {
    id: String,
}

fn foo() {
    let mut struct_pointer: P<Baz> = P(Baz {
        id: "1234".to_string(),
    });
    println!("{}", struct_pointer.id);
}

What language feature is allowing me to access the id field on the struct_pointer binding? Dereferencing? Coercion? And is there any way to tell that this sort of thing will work by looking at the docs for P?

Marcus Buffett
  • 1,289
  • 1
  • 14
  • 32
  • 3
    Your example is incomplete and not reproducible. Please include your definitions of `P` and `Baz`. – E_net4 May 22 '17 at 16:37
  • 1
    I take it `P` is a `syntax::ptr::P`, and `Baz` a random struct ? Given the implementation of `Deref` for `P`, it must be dereferencing coercion. In fact the same goes for `"1234".to_string`. – Procrade May 22 '17 at 16:47
  • @E_net4, Procrade is right, I thought that would be clear enough, sorry for the confusion. I've updated the example. – Marcus Buffett May 22 '17 at 17:45
  • @MarcusBuffett Admittedly, I did not know [`P`](https://doc.rust-lang.org/1.1.0/syntax/ptr/struct.P.html), but that's because it's unstable and part of the Rust compiler's private components. Are you developing for the Rust compiler? – E_net4 May 22 '17 at 17:52
  • 1
    @E_net4 I didn't realize that `P` was specific to the rust compiler actually, thought it was a commonly used thing in rust for pointers (you can tell I'm a bit of a rust noob). I'm making a simple compiler plugin. – Marcus Buffett May 22 '17 at 17:58
  • 4
    I'm honestly surprised. Where did you even hear about it? The book should only suggest the use of references, `Box` and reference-counted pointers (`Rc` and `Arc`). – E_net4 May 22 '17 at 18:16
  • 1
    @E_net4 Maybe something has changed on nightly? Everything seems to return a P, ex. [ExprKind](https://manishearth.github.io/rust-internals-docs/syntax/ast/enum.ExprKind.html) is full of them. – Marcus Buffett May 22 '17 at 18:44
  • 1
    Again, that is _specific_ to the `syntax` crate. I can't think of a reason to use it in other contexts. Regardless, what @Procrade said could be turned into an actual answer. – E_net4 May 22 '17 at 19:32
  • 2
    @E_net4 Yeah I'm aware of that, the reason I have a P in the first place is because I'm getting it from an ExprKind. The example was just meant to be a simplified version of what I'm working with. – Marcus Buffett May 22 '17 at 19:34

1 Answers1

4

It's implemented using the Deref trait.

In Rust . automatically dereferences when needed, so the compiler can interpret foo.bar as (*foo).bar.

Kornel
  • 97,764
  • 37
  • 219
  • 309
  • 1
    is there also a way to do it explicitly other than `(*foo).bar` (like e.g. `foo->bar`? – lucidbrot Sep 17 '19 at 14:51
  • 1
    @lucidbrot Intentionally there is no other syntax for dereferencing. It's something that Rust wants to hide and doesn't want programmers to micromanage. The compiler and the type system ensures there's no ambiguity. – Kornel Sep 18 '19 at 14:27