Skip to content

Commit

Permalink
Update //@ proc-macro aux build directive docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jieyouxu committed Nov 28, 2024
1 parent 299a6c8 commit 1b38a6c
Showing 1 changed file with 37 additions and 26 deletions.
63 changes: 37 additions & 26 deletions src/tests/compiletest.md
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ There are multiple [directives](directives.md) to assist with that:
- `aux-crate`
- `aux-bin`
- `aux-codegen-backend`
- `proc-macro`

`aux-build` will build a separate crate from the named source file. The source
file should be in a directory called `auxiliary` beside the test file.
Expand Down Expand Up @@ -618,45 +619,55 @@ for tests in `tests/ui-fulldeps`, since it requires the use of compiler crates.

### Auxiliary proc-macro

If you want a proc-macro dependency, then there currently is some ceremony
needed.
If you want a proc-macro dependency, then you can use the `proc-macro`
directive. This directive behaves just like `aux-build`, i.e. that you should
place the proc-macro test auxiliary file under a `auxiliary` folder under the
same parent folder as the main test file. However, it also has four additional
preset behavior compared to `aux-build` for the proc-macro test auxiliary:

1. The aux test file is built with `--crate-type=proc-macro`.
2. The aux test file is built without `-C prefer-dynamic`, i.e. it will not try
to produce a dylib for the aux crate.
3. The aux crate is made available to the test file via extern prelude with
`--extern <aux_crate_name>`. Note that since UI tests default to edition
2015, you still need to specify `extern <aux_crate_name>` unless the main
test file is using an edition that is 2018 or newer.
4. The `proc_macro` crate is made available as an extern prelude module. Same
edition 2015 vs newer edition distinction for `extern proc_macro;` applies.

For example, you might have a test `tests/ui/cat/meow.rs` and proc-macro
auxiliary `tests/ui/cat/auxiliary/whiskers.rs`:

Place the proc-macro itself in a file like `auxiliary/my-proc-macro.rs` with the
following structure:
```text
tests/ui/cat/
meow.rs # main test file
auxiliary/whiskers.rs # auxiliary
```

```rust,ignore
//@ force-host
//@ no-prefer-dynamic
```rs
// tests/ui/cat/meow.rs

#![crate_type = "proc-macro"]
//@ proc-macro: whiskers.rs

extern crate proc_macro;
use proc_macro::TokenStream;
extern crate whiskers; // needed as ui test defaults to edition 2015

#[proc_macro]
pub fn foo(input: TokenStream) -> TokenStream {
"".parse().unwrap()
fn main() {
whiskers::identity!();
}
```

The `force-host` is needed because proc-macros are loaded in the host compiler,
and `no-prefer-dynamic` is needed to tell compiletest to not use
`prefer-dynamic` which is not compatible with proc-macros. The `#![crate_type]`
attribute is needed to specify the correct crate-type.

Then in your test, you can build with `aux-build`:
```rs
// tests/ui/cat/auxiliary/whiskers.rs

```rust,ignore
//@ aux-build: my-proc-macro.rs
extern crate my_proc_macro;
extern crate proc_macro;
use proc_macro::*;

fn main() {
my_proc_macro::foo!();
#[proc_macro]
pub fn identity(ts: TokenStream) -> TokenStream {
ts
}
```


## Revisions

Revisions allow a single test file to be used for multiple tests. This is done
Expand Down

0 comments on commit 1b38a6c

Please sign in to comment.