rust/tests/ui/proc-macro/inner-attrs.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

88 lines
1.7 KiB
Rust
Raw Normal View History

// gate-test-custom_inner_attributes
2021-02-28 13:51:44 -06:00
// compile-flags: -Z span-debug --error-format human
// aux-build:test-macros.rs
// edition:2018
2021-02-28 13:51:44 -06:00
#![feature(custom_inner_attributes)]
#![feature(proc_macro_hygiene)]
#![feature(stmt_expr_attributes)]
#![feature(rustc_attrs)]
2021-02-28 13:51:44 -06:00
#![no_std] // Don't load unnecessary hygiene information from std
extern crate std;
#[macro_use]
extern crate test_macros;
#[print_target_and_args(first)]
#[print_target_and_args(second)]
fn foo() {
#![print_target_and_args(third)]
#![print_target_and_args(fourth)]
}
#[print_target_and_args(mod_first)]
#[print_target_and_args(mod_second)]
mod inline_mod {
#![print_target_and_args(mod_third)]
#![print_target_and_args(mod_fourth)]
}
2021-02-28 13:51:44 -06:00
struct MyStruct {
field: bool
}
#[derive(Print)]
struct MyDerivePrint {
field: [u8; {
match true {
_ => {
Implement token-based handling of attributes during expansion This PR modifies the macro expansion infrastructure to handle attributes in a fully token-based manner. As a result: * Derives macros no longer lose spans when their input is modified by eager cfg-expansion. This is accomplished by performing eager cfg-expansion on the token stream that we pass to the derive proc-macro * Inner attributes now preserve spans in all cases, including when we have multiple inner attributes in a row. This is accomplished through the following changes: * New structs `AttrAnnotatedTokenStream` and `AttrAnnotatedTokenTree` are introduced. These are very similar to a normal `TokenTree`, but they also track the position of attributes and attribute targets within the stream. They are built when we collect tokens during parsing. An `AttrAnnotatedTokenStream` is converted to a regular `TokenStream` when we invoke a macro. * Token capturing and `LazyTokenStream` are modified to work with `AttrAnnotatedTokenStream`. A new `ReplaceRange` type is introduced, which is created during the parsing of a nested AST node to make the 'outer' AST node aware of the attributes and attribute target stored deeper in the token stream. * When we need to perform eager cfg-expansion (either due to `#[derive]` or `#[cfg_eval]`), we tokenize and reparse our target, capturing additional information about the locations of `#[cfg]` and `#[cfg_attr]` attributes at any depth within the target. This is a performance optimization, allowing us to perform less work in the typical case where captured tokens never have eager cfg-expansion run.
2020-11-28 17:33:17 -06:00
#![cfg_attr(not(FALSE), rustc_dummy(third))]
true
}
};
0
}]
}
2021-02-28 13:51:44 -06:00
fn bar() {
#[print_target_and_args(tuple_attrs)] (
3, 4, {
#![cfg_attr(not(FALSE), rustc_dummy(innermost))]
5
}
);
#[print_target_and_args(tuple_attrs)] (
3, 4, {
#![cfg_attr(not(FALSE), rustc_dummy(innermost))]
5
}
);
for _ in &[true] {
#![print_attr] //~ ERROR expected non-macro inner attribute
}
let _ = {
#![print_attr] //~ ERROR expected non-macro inner attribute
};
let _ = async {
#![print_attr] //~ ERROR expected non-macro inner attribute
};
{
#![print_attr] //~ ERROR expected non-macro inner attribute
};
2021-02-28 13:51:44 -06:00
}
2021-02-28 13:51:44 -06:00
extern {
fn weird_extern() {
#![print_target_and_args_consume(tenth)]
}
}
fn main() {}