Repository: rust
Issue: Proc macros: ability to refer to a specific crate/symbol (something similar to `$crate`)
Labels: A-resolve,A-macros,T-lang,C-feature-request,A-proc-macros

### The problem

In macros-by-example we have `$crate` to refer to the crate the macro is defined in. This is very useful as the library author doesn't have to assume anything about how that crate is used in the user's crate (in particular, the user can rename the crate without breaking the world).

In the new proc macro system we don't seem to have this ability. It's important to note that just `$crate` won't be useful most of the time though, because right now most crates using proc macros are structured like that:
- `foo-{macros/derive/codegen}`: this crate is `proc-macro = true` and defines the actual proc macro.
- `foo`: defines all runtime dependency stuff, has `foo-{macros/derive/codegen}` as dependency and reexports the proc macro.
- The important part: the proc macro emits code that uses stuff from `foo`

An example:
<details>

**`foo-macros/src/lib.rs`**
```rust
#[proc_macro]
pub fn mac(_: TokenStream) -> TokenStream {
    quote! { ::foo::do_the_thing(); }
}
```

**`foo/src/lib.rs`**
```rust
pub fn do_the_thing() {
    println!("hello!");
}
```
When the user uses `mac!()` now, they have to have `do_the_thing` in scope, otherwise an error from inside the macro will occur. Not nice. Even worse: if the user has a `do_the_thing` in scope that is not from `foo`, strange things could happen.
</details>
<br />

So an equivalent of `$crate` would refer to the `foo-{macros/derive/codegen}` crate which is not all that useful, because we mostly want to refer to `foo`. The best way to solve this right now is to use absolute paths everywhere and hope that the user doesn't rename the crate `foo` to something else. 

The proc macro needs to be defined in a separate crate and the main crate `foo` wants to reexport the macro. That means that `foo-macros` doesn't know anything about `foo` and thus *blindly* emits code (tokens) hoping that the crate `foo` is in scope.

But this doesn't sound like a very robust solution. 

Furthermore, using the macro in `foo` itself (usually for testing) is not trivial. The macro assumes `foo` is an extern crate that can be referred to with `::foo`. But that's not the case for `foo` itself. In one of my codebases I used a hacky solution: when the first token of the macro invocation is `*`, I emit paths starting with `crate::` instead of `::foo::`. But again, a better solution would be really appreciated.

---

### How can we do better?

I'm really not sure, but I hope we can use this issue as place for discussion (I hope I didn't miss any previous discussion on IRLO).

However, I have one idea: **declaring dependencies of emitted code**. One could add another kind of dependencies (apart from `dependencies`, `dev-dependencies` and `build-dependencies`) that defines what crates the emitted code depends on. (Let's call them `emit-dependencies` for now, although that name should probably be changed.) So those dependencies wouldn't be checked/downloaded/compiled when the proc macro crate is compiled, but the compiler could make sure that those dependencies are present in the crate using the proc macro.

I guess defining those dependencies globally crate is not sufficient since different proc macros could emit code with different dependencies. So maybe we could define the `emit-dependencies` per proc macro. But I'm not sure if that makes the check too complicated (because then Cargo would have to check which proc macros the user actually uses to collect a set of `emit-dependencies`).

That's just one idea I wanted to throw out there.

---

### Related

- [Question on StackOverflow](https://stackoverflow.com/questions/44950574/using-crate-in-rusts-procedural-macros)
- [`serde` issue related to this](https://github.com/serde-rs/serde/issues/953)
- @Ekleog already asked about that [here](https://github.com/rust-lang/rust/issues/38356#issuecomment-412920528)
- https://github.com/rust-lang/rust/issues/54647
- https://github.com/dtolnay/syn/issues/507
- https://github.com/rust-lang/rust/issues/56409