Auto merge of #52081 - alexcrichton:proc-macro-stable, r=petrochenkov
rustc: Stabilize the `proc_macro` feature This commit stabilizes some of the `proc_macro` language feature as well as a number of APIs in the `proc_macro` crate as [previously discussed][1]. This means that on stable Rust you can now define custom procedural macros which operate as attributes attached to items or `macro_rules!`-like bang-style invocations. This extends the suite of currently stable procedural macros, custom derives, with custom attributes and custom bang macros. Note though that despite the stabilization in this commit procedural macros are still not usable on stable Rust. To stabilize that we'll need to stabilize at least part of the `use_extern_macros` feature. Currently you can define a procedural macro attribute but you can't import it to call it! A summary of the changes made in this PR (as well as the various consequences) is: * The `proc_macro` language and library features are now stable. * Other APIs not stabilized in the `proc_macro` crate are now named under a different feature, such as `proc_macro_diagnostic` or `proc_macro_span`. * A few checks in resolution for `proc_macro` being enabled have switched over to `use_extern_macros` being enabled. This means that code using `#![feature(proc_macro)]` today will likely need to move to `#![feature(use_extern_macros)]`. It's intended that this PR, once landed, will be followed up with an attempt to stabilize a small slice of `use_extern_macros` just for procedural macros to make this feature 100% usable on stable. [1]: https://internals.rust-lang.org/t/help-stabilize-a-subset-of-macros-2-0/7252
This commit is contained in:
commit
1ecf6929dc
@ -1,241 +0,0 @@
|
||||
# `proc_macro`
|
||||
|
||||
The tracking issue for this feature is: [#38356]
|
||||
|
||||
[#38356]: https://github.com/rust-lang/rust/issues/38356
|
||||
|
||||
------------------------
|
||||
|
||||
This feature flag guards the new procedural macro features as laid out by [RFC 1566], which alongside the now-stable
|
||||
[custom derives], provide stabilizable alternatives to the compiler plugin API (which requires the use of
|
||||
perma-unstable internal APIs) for programmatically modifying Rust code at compile-time.
|
||||
|
||||
The two new procedural macro kinds are:
|
||||
|
||||
* Function-like procedural macros which are invoked like regular declarative macros, and:
|
||||
|
||||
* Attribute-like procedural macros which can be applied to any item which built-in attributes can
|
||||
be applied to, and which can take arguments in their invocation as well.
|
||||
|
||||
Additionally, this feature flag implicitly enables the [`use_extern_macros`](language-features/use-extern-macros.html) feature,
|
||||
which allows macros to be imported like any other item with `use` statements, as compared to
|
||||
applying `#[macro_use]` to an `extern crate` declaration. It is important to note that procedural macros may
|
||||
**only** be imported in this manner, and will throw an error otherwise.
|
||||
|
||||
You **must** declare the `proc_macro` feature in both the crate declaring these new procedural macro kinds as well as
|
||||
in any crates that use them.
|
||||
|
||||
### Common Concepts
|
||||
|
||||
As with custom derives, procedural macros may only be declared in crates of the `proc-macro` type, and must be public
|
||||
functions. No other public items may be declared in `proc-macro` crates, but private items are fine.
|
||||
|
||||
To declare your crate as a `proc-macro` crate, simply add:
|
||||
|
||||
```toml
|
||||
[lib]
|
||||
proc-macro = true
|
||||
```
|
||||
|
||||
to your `Cargo.toml`.
|
||||
|
||||
Unlike custom derives, however, the name of the function implementing the procedural macro is used directly as the
|
||||
procedural macro's name, so choose carefully.
|
||||
|
||||
Additionally, both new kinds of procedural macros return a `TokenStream` which *wholly* replaces the original
|
||||
invocation and its input.
|
||||
|
||||
#### Importing
|
||||
|
||||
As referenced above, the new procedural macros are not meant to be imported via `#[macro_use]` and will throw an
|
||||
error if they are. Instead, they are meant to be imported like any other item in Rust, with `use` statements:
|
||||
|
||||
```rust,ignore
|
||||
#![feature(proc_macro)]
|
||||
|
||||
// Where `my_proc_macros` is some crate of type `proc_macro`
|
||||
extern crate my_proc_macros;
|
||||
|
||||
// And declares a `#[proc_macro] pub fn my_bang_macro()` at its root.
|
||||
use my_proc_macros::my_bang_macro;
|
||||
|
||||
fn main() {
|
||||
println!("{}", my_bang_macro!());
|
||||
}
|
||||
```
|
||||
|
||||
#### Error Reporting
|
||||
|
||||
Any panics in a procedural macro implementation will be caught by the compiler and turned into an error message pointing
|
||||
to the problematic invocation. Thus, it is important to make your panic messages as informative as possible: use
|
||||
`Option::expect` instead of `Option::unwrap` and `Result::expect` instead of `Result::unwrap`, and inform the user of
|
||||
the error condition as unambiguously as you can.
|
||||
|
||||
#### `TokenStream`
|
||||
|
||||
The `proc_macro::TokenStream` type is hardcoded into the signatures of procedural macro functions for both input and
|
||||
output. It is a wrapper around the compiler's internal representation for a given chunk of Rust code.
|
||||
|
||||
### Function-like Procedural Macros
|
||||
|
||||
These are procedural macros that are invoked like regular declarative macros. They are declared as public functions in
|
||||
crates of the `proc_macro` type and using the `#[proc_macro]` attribute. The name of the declared function becomes the
|
||||
name of the macro as it is to be imported and used. The function must be of the kind `fn(TokenStream) -> TokenStream`
|
||||
where the sole argument is the input to the macro and the return type is the macro's output.
|
||||
|
||||
This kind of macro can expand to anything that is valid for the context it is invoked in, including expressions and
|
||||
statements, as well as items.
|
||||
|
||||
**Note**: invocations of this kind of macro require a wrapping `[]`, `{}` or `()` like regular macros, but these do not
|
||||
appear in the input, only the tokens between them. The tokens between the braces do not need to be valid Rust syntax.
|
||||
|
||||
<span class="filename">my_macro_crate/src/lib.rs</span>
|
||||
|
||||
```rust,ignore
|
||||
#![feature(proc_macro)]
|
||||
|
||||
// This is always necessary to get the `TokenStream` typedef.
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro]
|
||||
pub fn say_hello(_input: TokenStream) -> TokenStream {
|
||||
// This macro will accept any input because it ignores it.
|
||||
// To enforce correctness in macros which don't take input,
|
||||
// you may want to add `assert!(_input.to_string().is_empty());`.
|
||||
"println!(\"Hello, world!\")".parse().unwrap()
|
||||
}
|
||||
```
|
||||
|
||||
<span class="filename">my_macro_user/Cargo.toml</span>
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
my_macro_crate = { path = "<relative path to my_macro_crate>" }
|
||||
```
|
||||
|
||||
<span class="filename">my_macro_user/src/lib.rs</span>
|
||||
|
||||
```rust,ignore
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate my_macro_crate;
|
||||
|
||||
use my_macro_crate::say_hello;
|
||||
|
||||
fn main() {
|
||||
say_hello!();
|
||||
}
|
||||
```
|
||||
|
||||
As expected, this prints `Hello, world!`.
|
||||
|
||||
### Attribute-like Procedural Macros
|
||||
|
||||
These are arguably the most powerful flavor of procedural macro as they can be applied anywhere attributes are allowed.
|
||||
|
||||
They are declared as public functions in crates of the `proc-macro` type, using the `#[proc_macro_attribute]` attribute.
|
||||
The name of the function becomes the name of the attribute as it is to be imported and used. The function must be of the
|
||||
kind `fn(TokenStream, TokenStream) -> TokenStream` where:
|
||||
|
||||
The first argument represents any metadata for the attribute (see [the reference chapter on attributes][refr-attr]).
|
||||
Only the metadata itself will appear in this argument, for example:
|
||||
|
||||
* `#[my_macro]` will get an empty string.
|
||||
* `#[my_macro = "string"]` will get `= "string"`.
|
||||
* `#[my_macro(ident)]` will get `(ident)`.
|
||||
* etc.
|
||||
|
||||
The second argument is the item that the attribute is applied to. It can be a function, a type definition,
|
||||
an impl block, an `extern` block, or a module—attribute invocations can take the inner form (`#![my_attr]`)
|
||||
or outer form (`#[my_attr]`).
|
||||
|
||||
The return type is the output of the macro which *wholly* replaces the item it was applied to. Thus, if your intention
|
||||
is to merely modify an item, it *must* be copied to the output. The output must be an item; expressions, statements
|
||||
and bare blocks are not allowed.
|
||||
|
||||
There is no restriction on how many items an attribute-like procedural macro can emit as long as they are valid in
|
||||
the given context.
|
||||
|
||||
<span class="filename">my_macro_crate/src/lib.rs</span>
|
||||
|
||||
```rust,ignore
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
/// Adds a `/// ### Panics` docstring to the end of the input's documentation
|
||||
///
|
||||
/// Does not assert that its receiver is a function or method.
|
||||
#[proc_macro_attribute]
|
||||
pub fn panics_note(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let args = args.to_string();
|
||||
let mut input = input.to_string();
|
||||
|
||||
assert!(args.starts_with("= \""), "`#[panics_note]` requires an argument of the form \
|
||||
`#[panics_note = \"panic note here\"]`");
|
||||
|
||||
// Get just the bare note string
|
||||
let panics_note = args.trim_matches(&['=', ' ', '"'][..]);
|
||||
|
||||
// The input will include all docstrings regardless of where the attribute is placed,
|
||||
// so we need to find the last index before the start of the item
|
||||
let insert_idx = idx_after_last_docstring(&input);
|
||||
|
||||
// And insert our `### Panics` note there so it always appears at the end of an item's docs
|
||||
input.insert_str(insert_idx, &format!("/// # Panics \n/// {}\n", panics_note));
|
||||
|
||||
input.parse().unwrap()
|
||||
}
|
||||
|
||||
// `proc-macro` crates can contain any kind of private item still
|
||||
fn idx_after_last_docstring(input: &str) -> usize {
|
||||
// Skip docstring lines to find the start of the item proper
|
||||
input.lines().skip_while(|line| line.trim_left().starts_with("///")).next()
|
||||
// Find the index of the first non-docstring line in the input
|
||||
// Note: assumes this exact line is unique in the input
|
||||
.and_then(|line_after| input.find(line_after))
|
||||
// No docstrings in the input
|
||||
.unwrap_or(0)
|
||||
}
|
||||
```
|
||||
|
||||
<span class="filename">my_macro_user/Cargo.toml</span>
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
my_macro_crate = { path = "<relative path to my_macro_crate>" }
|
||||
```
|
||||
|
||||
<span class="filename">my_macro_user/src/lib.rs</span>
|
||||
|
||||
```rust,ignore
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate my_macro_crate;
|
||||
|
||||
use my_macro_crate::panics_note;
|
||||
|
||||
/// Do the `foo` thing.
|
||||
#[panics_note = "Always."]
|
||||
pub fn foo() {
|
||||
panic!()
|
||||
}
|
||||
```
|
||||
|
||||
Then the rendered documentation for `pub fn foo` will look like this:
|
||||
|
||||
> `pub fn foo()`
|
||||
>
|
||||
> ----
|
||||
> Do the `foo` thing.
|
||||
> # Panics
|
||||
> Always.
|
||||
|
||||
[RFC 1566]: https://github.com/rust-lang/rfcs/blob/master/text/1566-proc-macros.md
|
||||
[custom derives]: https://doc.rust-lang.org/book/procedural-macros.html
|
||||
[rust-lang/rust#41430]: https://github.com/rust-lang/rust/issues/41430
|
||||
[refr-attr]: https://doc.rust-lang.org/reference/attributes.html
|
@ -13,7 +13,7 @@ use Span;
|
||||
use rustc_errors as rustc;
|
||||
|
||||
/// An enum representing a diagnostic level.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum Level {
|
||||
/// An error.
|
||||
@ -30,7 +30,7 @@ pub enum Level {
|
||||
|
||||
/// A structure representing a diagnostic message and associated children
|
||||
/// messages.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Diagnostic {
|
||||
level: Level,
|
||||
@ -43,7 +43,7 @@ macro_rules! diagnostic_child_methods {
|
||||
($spanned:ident, $regular:ident, $level:expr) => (
|
||||
/// Add a new child diagnostic message to `self` with the level
|
||||
/// identified by this methods name with the given `span` and `message`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub fn $spanned<T: Into<String>>(mut self, span: Span, message: T) -> Diagnostic {
|
||||
self.children.push(Diagnostic::spanned(span, $level, message));
|
||||
self
|
||||
@ -51,7 +51,7 @@ macro_rules! diagnostic_child_methods {
|
||||
|
||||
/// Add a new child diagnostic message to `self` with the level
|
||||
/// identified by this method's name with the given `message`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub fn $regular<T: Into<String>>(mut self, message: T) -> Diagnostic {
|
||||
self.children.push(Diagnostic::new($level, message));
|
||||
self
|
||||
@ -61,7 +61,7 @@ macro_rules! diagnostic_child_methods {
|
||||
|
||||
impl Diagnostic {
|
||||
/// Create a new diagnostic with the given `level` and `message`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
|
||||
Diagnostic {
|
||||
level: level,
|
||||
@ -73,7 +73,7 @@ impl Diagnostic {
|
||||
|
||||
/// Create a new diagnostic with the given `level` and `message` pointing to
|
||||
/// the given `span`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub fn spanned<T: Into<String>>(span: Span, level: Level, message: T) -> Diagnostic {
|
||||
Diagnostic {
|
||||
level: level,
|
||||
@ -89,13 +89,13 @@ impl Diagnostic {
|
||||
diagnostic_child_methods!(span_help, help, Level::Help);
|
||||
|
||||
/// Returns the diagnostic `level` for `self`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub fn level(&self) -> Level {
|
||||
self.level
|
||||
}
|
||||
|
||||
/// Emit the diagnostic.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub fn emit(self) {
|
||||
::__internal::with_sess(move |sess, _| {
|
||||
let handler = &sess.span_diagnostic;
|
||||
|
@ -46,7 +46,7 @@ extern crate rustc_data_structures;
|
||||
|
||||
mod diagnostic;
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub use diagnostic::{Diagnostic, Level};
|
||||
|
||||
use std::{ascii, fmt, iter};
|
||||
@ -94,13 +94,13 @@ impl !Sync for LexError {}
|
||||
|
||||
impl TokenStream {
|
||||
/// Returns an empty `TokenStream` containing no token trees.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn new() -> TokenStream {
|
||||
TokenStream(tokenstream::TokenStream::empty())
|
||||
}
|
||||
|
||||
/// Checks if this `TokenStream` is empty.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
@ -146,7 +146,7 @@ impl fmt::Debug for TokenStream {
|
||||
}
|
||||
|
||||
/// Creates a token stream containing a single token tree.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl From<TokenTree> for TokenStream {
|
||||
fn from(tree: TokenTree) -> TokenStream {
|
||||
TokenStream(tree.to_internal())
|
||||
@ -154,7 +154,7 @@ impl From<TokenTree> for TokenStream {
|
||||
}
|
||||
|
||||
/// Collects a number of token trees into a single stream.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl iter::FromIterator<TokenTree> for TokenStream {
|
||||
fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
|
||||
trees.into_iter().map(TokenStream::from).collect()
|
||||
@ -175,7 +175,7 @@ impl iter::FromIterator<TokenStream> for TokenStream {
|
||||
}
|
||||
|
||||
/// Public implementation details for the `TokenStream` type, such as iterators.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub mod token_stream {
|
||||
use syntax::tokenstream;
|
||||
use {TokenTree, TokenStream, Delimiter};
|
||||
@ -184,13 +184,13 @@ pub mod token_stream {
|
||||
/// The iteration is "shallow", e.g. the iterator doesn't recurse into delimited groups,
|
||||
/// and returns whole groups as token trees.
|
||||
#[derive(Clone)]
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub struct IntoIter {
|
||||
cursor: tokenstream::Cursor,
|
||||
stack: Vec<TokenTree>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl Iterator for IntoIter {
|
||||
type Item = TokenTree;
|
||||
|
||||
@ -219,7 +219,7 @@ pub mod token_stream {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl IntoIterator for TokenStream {
|
||||
type Item = TokenTree;
|
||||
type IntoIter = IntoIter;
|
||||
@ -238,7 +238,7 @@ pub mod token_stream {
|
||||
/// To quote `$` itself, use `$$`.
|
||||
///
|
||||
/// This is a dummy macro, the actual implementation is in quote::Quoter
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_quote", issue = "38356")]
|
||||
#[macro_export]
|
||||
macro_rules! quote { () => {} }
|
||||
|
||||
@ -248,26 +248,26 @@ mod quote;
|
||||
|
||||
/// Quote a `Span` into a `TokenStream`.
|
||||
/// This is needed to implement a custom quoter.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_quote", issue = "38356")]
|
||||
pub fn quote_span(span: Span) -> TokenStream {
|
||||
quote::Quote::quote(span)
|
||||
}
|
||||
|
||||
/// A region of source code, along with macro expansion information.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Span(syntax_pos::Span);
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Send for Span {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Sync for Span {}
|
||||
|
||||
macro_rules! diagnostic_method {
|
||||
($name:ident, $level:expr) => (
|
||||
/// Create a new `Diagnostic` with the given `message` at the span
|
||||
/// `self`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
|
||||
pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
|
||||
Diagnostic::spanned(self, $level, message)
|
||||
}
|
||||
@ -276,7 +276,7 @@ macro_rules! diagnostic_method {
|
||||
|
||||
impl Span {
|
||||
/// A span that resolves at the macro definition site.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn def_site() -> Span {
|
||||
::__internal::with_sess(|_, data| data.def_site)
|
||||
}
|
||||
@ -285,13 +285,13 @@ impl Span {
|
||||
/// Identifiers created with this span will be resolved as if they were written
|
||||
/// directly at the macro call location (call-site hygiene) and other code
|
||||
/// at the macro call site will be able to refer to them as well.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn call_site() -> Span {
|
||||
::__internal::with_sess(|_, data| data.call_site)
|
||||
}
|
||||
|
||||
/// The original source file into which this span points.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn source_file(&self) -> SourceFile {
|
||||
SourceFile {
|
||||
filemap: __internal::lookup_char_pos(self.0.lo()).file,
|
||||
@ -300,7 +300,7 @@ impl Span {
|
||||
|
||||
/// The `Span` for the tokens in the previous macro expansion from which
|
||||
/// `self` was generated from, if any.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn parent(&self) -> Option<Span> {
|
||||
self.0.parent().map(Span)
|
||||
}
|
||||
@ -308,13 +308,13 @@ impl Span {
|
||||
/// The span for the origin source code that `self` was generated from. If
|
||||
/// this `Span` wasn't generated from other macro expansions then the return
|
||||
/// value is the same as `*self`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn source(&self) -> Span {
|
||||
Span(self.0.source_callsite())
|
||||
}
|
||||
|
||||
/// Get the starting line/column in the source file for this span.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn start(&self) -> LineColumn {
|
||||
let loc = __internal::lookup_char_pos(self.0.lo());
|
||||
LineColumn {
|
||||
@ -324,7 +324,7 @@ impl Span {
|
||||
}
|
||||
|
||||
/// Get the ending line/column in the source file for this span.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn end(&self) -> LineColumn {
|
||||
let loc = __internal::lookup_char_pos(self.0.hi());
|
||||
LineColumn {
|
||||
@ -336,7 +336,7 @@ impl Span {
|
||||
/// Create a new span encompassing `self` and `other`.
|
||||
///
|
||||
/// Returns `None` if `self` and `other` are from different files.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn join(&self, other: Span) -> Option<Span> {
|
||||
let self_loc = __internal::lookup_char_pos(self.0.lo());
|
||||
let other_loc = __internal::lookup_char_pos(other.0.lo());
|
||||
@ -348,20 +348,20 @@ impl Span {
|
||||
|
||||
/// Creates a new span with the same line/column information as `self` but
|
||||
/// that resolves symbols as though it were at `other`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn resolved_at(&self, other: Span) -> Span {
|
||||
Span(self.0.with_ctxt(other.0.ctxt()))
|
||||
}
|
||||
|
||||
/// Creates a new span with the same name resolution behavior as `self` but
|
||||
/// with the line/column information of `other`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn located_at(&self, other: Span) -> Span {
|
||||
other.resolved_at(*self)
|
||||
}
|
||||
|
||||
/// Compares to spans to see if they're equal.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn eq(&self, other: &Span) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
@ -373,7 +373,7 @@ impl Span {
|
||||
}
|
||||
|
||||
/// Prints a span in a form convenient for debugging.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl fmt::Debug for Span {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?} bytes({}..{})",
|
||||
@ -384,33 +384,33 @@ impl fmt::Debug for Span {
|
||||
}
|
||||
|
||||
/// A line-column pair representing the start or end of a `Span`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct LineColumn {
|
||||
/// The 1-indexed line in the source file on which the span starts or ends (inclusive).
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub line: usize,
|
||||
/// The 0-indexed column (in UTF-8 characters) in the source file on which
|
||||
/// the span starts or ends (inclusive).
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub column: usize
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl !Send for LineColumn {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl !Sync for LineColumn {}
|
||||
|
||||
/// The source file of a given `Span`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
#[derive(Clone)]
|
||||
pub struct SourceFile {
|
||||
filemap: Lrc<FileMap>,
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl !Send for SourceFile {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl !Sync for SourceFile {}
|
||||
|
||||
impl SourceFile {
|
||||
@ -424,14 +424,14 @@ impl SourceFile {
|
||||
/// the command line, the path as given may not actually be valid.
|
||||
///
|
||||
/// [`is_real`]: #method.is_real
|
||||
# [unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn path(&self) -> &FileName {
|
||||
&self.filemap.name
|
||||
}
|
||||
|
||||
/// Returns `true` if this source file is a real source file, and not generated by an external
|
||||
/// macro's expansion.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
pub fn is_real(&self) -> bool {
|
||||
// This is a hack until intercrate spans are implemented and we can have real source files
|
||||
// for spans generated in external macros.
|
||||
@ -440,14 +440,14 @@ impl SourceFile {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl AsRef<FileName> for SourceFile {
|
||||
fn as_ref(&self) -> &FileName {
|
||||
self.path()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl fmt::Debug for SourceFile {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("SourceFile")
|
||||
@ -457,17 +457,17 @@ impl fmt::Debug for SourceFile {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl PartialEq for SourceFile {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Lrc::ptr_eq(&self.filemap, &other.filemap)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl Eq for SourceFile {}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_span", issue = "38356")]
|
||||
impl PartialEq<FileName> for SourceFile {
|
||||
fn eq(&self, other: &FileName) -> bool {
|
||||
self.as_ref() == other
|
||||
@ -475,28 +475,44 @@ impl PartialEq<FileName> for SourceFile {
|
||||
}
|
||||
|
||||
/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
#[derive(Clone)]
|
||||
pub enum TokenTree {
|
||||
/// A token stream surrounded by bracket delimiters.
|
||||
Group(Group),
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Group(
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Group
|
||||
),
|
||||
/// An identifier.
|
||||
Ident(Ident),
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Ident(
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Ident
|
||||
),
|
||||
/// A single punctuation character (`+`, `,`, `$`, etc.).
|
||||
Punct(Punct),
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Punct(
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Punct
|
||||
),
|
||||
/// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
|
||||
Literal(Literal),
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Literal(
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Literal
|
||||
),
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Send for TokenTree {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Sync for TokenTree {}
|
||||
|
||||
impl TokenTree {
|
||||
/// Returns the span of this tree, delegating to the `span` method of
|
||||
/// the contained token or a delimited stream.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
TokenTree::Group(ref t) => t.span(),
|
||||
@ -511,7 +527,7 @@ impl TokenTree {
|
||||
/// Note that if this token is a `Group` then this method will not configure
|
||||
/// the span of each of the internal tokens, this will simply delegate to
|
||||
/// the `set_span` method of each variant.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn set_span(&mut self, span: Span) {
|
||||
match *self {
|
||||
TokenTree::Group(ref mut t) => t.set_span(span),
|
||||
@ -523,7 +539,7 @@ impl TokenTree {
|
||||
}
|
||||
|
||||
/// Prints token treee in a form convenient for debugging.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl fmt::Debug for TokenTree {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Each of these has the name in the struct type in the derived debug,
|
||||
@ -537,28 +553,28 @@ impl fmt::Debug for TokenTree {
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl From<Group> for TokenTree {
|
||||
fn from(g: Group) -> TokenTree {
|
||||
TokenTree::Group(g)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl From<Ident> for TokenTree {
|
||||
fn from(g: Ident) -> TokenTree {
|
||||
TokenTree::Ident(g)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl From<Punct> for TokenTree {
|
||||
fn from(g: Punct) -> TokenTree {
|
||||
TokenTree::Punct(g)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl From<Literal> for TokenTree {
|
||||
fn from(g: Literal) -> TokenTree {
|
||||
TokenTree::Literal(g)
|
||||
@ -568,7 +584,7 @@ impl From<Literal> for TokenTree {
|
||||
/// Prints the token tree as a string that is supposed to be losslessly convertible back
|
||||
/// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
|
||||
/// with `Delimiter::None` delimiters and negative numeric literals.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl fmt::Display for TokenTree {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
@ -584,33 +600,37 @@ impl fmt::Display for TokenTree {
|
||||
///
|
||||
/// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
|
||||
#[derive(Clone, Debug)]
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub struct Group {
|
||||
delimiter: Delimiter,
|
||||
stream: TokenStream,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Send for Group {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Sync for Group {}
|
||||
|
||||
/// Describes how a sequence of token trees is delimited.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub enum Delimiter {
|
||||
/// `( ... )`
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Parenthesis,
|
||||
/// `{ ... }`
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Brace,
|
||||
/// `[ ... ]`
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Bracket,
|
||||
/// `Ø ... Ø`
|
||||
/// An implicit delimiter, that may, for example, appear around tokens coming from a
|
||||
/// "macro variable" `$var`. It is important to preserve operator priorities in cases like
|
||||
/// `$var * 3` where `$var` is `1 + 2`.
|
||||
/// Implicit delimiters may not survive roundtrip of a token stream through a string.
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
None,
|
||||
}
|
||||
|
||||
@ -620,7 +640,7 @@ impl Group {
|
||||
/// This constructor will set the span for this group to
|
||||
/// `Span::call_site()`. To change the span you can use the `set_span`
|
||||
/// method below.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
|
||||
Group {
|
||||
delimiter: delimiter,
|
||||
@ -630,7 +650,7 @@ impl Group {
|
||||
}
|
||||
|
||||
/// Returns the delimiter of this `Group`
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn delimiter(&self) -> Delimiter {
|
||||
self.delimiter
|
||||
}
|
||||
@ -639,14 +659,14 @@ impl Group {
|
||||
///
|
||||
/// Note that the returned token stream does not include the delimiter
|
||||
/// returned above.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn stream(&self) -> TokenStream {
|
||||
self.stream.clone()
|
||||
}
|
||||
|
||||
/// Returns the span for the delimiters of this token stream, spanning the
|
||||
/// entire `Group`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
@ -657,7 +677,7 @@ impl Group {
|
||||
/// This method will **not** set the span of all the internal tokens spanned
|
||||
/// by this group, but rather it will only set the span of the delimiter
|
||||
/// tokens at the level of the `Group`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
@ -666,7 +686,7 @@ impl Group {
|
||||
/// Prints the group as a string that should be losslessly convertible back
|
||||
/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
|
||||
/// with `Delimiter::None` delimiters.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl fmt::Display for Group {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
TokenStream::from(TokenTree::from(self.clone())).fmt(f)
|
||||
@ -677,7 +697,7 @@ impl fmt::Display for Group {
|
||||
///
|
||||
/// Multicharacter operators like `+=` are represented as two instances of `Punct` with different
|
||||
/// forms of `Spacing` returned.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Punct {
|
||||
ch: char,
|
||||
@ -685,20 +705,22 @@ pub struct Punct {
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Send for Punct {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Sync for Punct {}
|
||||
|
||||
/// Whether an `Punct` is followed immediately by another `Punct` or
|
||||
/// followed by another token or whitespace.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub enum Spacing {
|
||||
/// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Alone,
|
||||
/// E.g. `+` is `Joint` in `+=` or `'#`.
|
||||
/// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`.
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
Joint,
|
||||
}
|
||||
|
||||
@ -709,7 +731,7 @@ impl Punct {
|
||||
///
|
||||
/// The returned `Punct` will have the default span of `Span::call_site()`
|
||||
/// which can be further configured with the `set_span` method below.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn new(ch: char, spacing: Spacing) -> Punct {
|
||||
const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^',
|
||||
'&', '|', '@', '.', ',', ';', ':', '#', '$', '?', '\''];
|
||||
@ -724,7 +746,7 @@ impl Punct {
|
||||
}
|
||||
|
||||
/// Returns the value of this punctuation character as `char`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn as_char(&self) -> char {
|
||||
self.ch
|
||||
}
|
||||
@ -733,19 +755,19 @@ impl Punct {
|
||||
/// followed by another `Punct` in the token stream, so they can potentially be combined into
|
||||
/// a multicharacter operator (`Joint`), or it's followed by some other token or whitespace
|
||||
/// (`Alone`) so the operator has certainly ended.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn spacing(&self) -> Spacing {
|
||||
self.spacing
|
||||
}
|
||||
|
||||
/// Returns the span for this punctuation character.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
|
||||
/// Configure the span for this punctuation character.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
@ -753,7 +775,7 @@ impl Punct {
|
||||
|
||||
/// Prints the punctuation character as a string that should be losslessly convertible
|
||||
/// back into the same character.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl fmt::Display for Punct {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
TokenStream::from(TokenTree::from(self.clone())).fmt(f)
|
||||
@ -762,16 +784,16 @@ impl fmt::Display for Punct {
|
||||
|
||||
/// An identifier (`ident`).
|
||||
#[derive(Clone, Debug)]
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub struct Ident {
|
||||
sym: Symbol,
|
||||
span: Span,
|
||||
is_raw: bool,
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Send for Ident {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Sync for Ident {}
|
||||
|
||||
impl Ident {
|
||||
@ -794,7 +816,7 @@ impl Ident {
|
||||
///
|
||||
/// Due to the current importance of hygiene this constructor, unlike other
|
||||
/// tokens, requires a `Span` to be specified at construction.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn new(string: &str, span: Span) -> Ident {
|
||||
if !lexer::is_valid_ident(string) {
|
||||
panic!("`{:?}` is not a valid identifier", string)
|
||||
@ -807,7 +829,7 @@ impl Ident {
|
||||
}
|
||||
|
||||
/// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[unstable(feature = "proc_macro_raw_ident", issue = "38356")]
|
||||
pub fn new_raw(string: &str, span: Span) -> Ident {
|
||||
let mut ident = Ident::new(string, span);
|
||||
if ident.sym == keywords::Underscore.name() ||
|
||||
@ -820,13 +842,13 @@ impl Ident {
|
||||
|
||||
/// Returns the span of this `Ident`, encompassing the entire string returned
|
||||
/// by `as_str`.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
|
||||
/// Configures the span of this `Ident`, possibly changing its hygiene context.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
@ -834,7 +856,7 @@ impl Ident {
|
||||
|
||||
/// Prints the identifier as a string that should be losslessly convertible
|
||||
/// back into the same identifier.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl fmt::Display for Ident {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.is_raw {
|
||||
@ -849,16 +871,16 @@ impl fmt::Display for Ident {
|
||||
/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
|
||||
/// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
|
||||
#[derive(Clone, Debug)]
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub struct Literal {
|
||||
lit: token::Lit,
|
||||
suffix: Option<ast::Name>,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Send for Literal {}
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl !Sync for Literal {}
|
||||
|
||||
macro_rules! suffixed_int_literals {
|
||||
@ -874,7 +896,7 @@ macro_rules! suffixed_int_literals {
|
||||
/// Literals created through this method have the `Span::call_site()`
|
||||
/// span by default, which can be configured with the `set_span` method
|
||||
/// below.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn $name(n: $kind) -> Literal {
|
||||
Literal {
|
||||
lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
|
||||
@ -900,7 +922,7 @@ macro_rules! unsuffixed_int_literals {
|
||||
/// Literals created through this method have the `Span::call_site()`
|
||||
/// span by default, which can be configured with the `set_span` method
|
||||
/// below.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn $name(n: $kind) -> Literal {
|
||||
Literal {
|
||||
lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
|
||||
@ -954,7 +976,7 @@ impl Literal {
|
||||
///
|
||||
/// This function requires that the specified float is finite, for
|
||||
/// example if it is infinity or NaN this function will panic.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn f32_unsuffixed(n: f32) -> Literal {
|
||||
if !n.is_finite() {
|
||||
panic!("Invalid float literal {}", n);
|
||||
@ -979,7 +1001,7 @@ impl Literal {
|
||||
///
|
||||
/// This function requires that the specified float is finite, for
|
||||
/// example if it is infinity or NaN this function will panic.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn f32_suffixed(n: f32) -> Literal {
|
||||
if !n.is_finite() {
|
||||
panic!("Invalid float literal {}", n);
|
||||
@ -1003,7 +1025,7 @@ impl Literal {
|
||||
///
|
||||
/// This function requires that the specified float is finite, for
|
||||
/// example if it is infinity or NaN this function will panic.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn f64_unsuffixed(n: f64) -> Literal {
|
||||
if !n.is_finite() {
|
||||
panic!("Invalid float literal {}", n);
|
||||
@ -1028,7 +1050,7 @@ impl Literal {
|
||||
///
|
||||
/// This function requires that the specified float is finite, for
|
||||
/// example if it is infinity or NaN this function will panic.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn f64_suffixed(n: f64) -> Literal {
|
||||
if !n.is_finite() {
|
||||
panic!("Invalid float literal {}", n);
|
||||
@ -1041,7 +1063,7 @@ impl Literal {
|
||||
}
|
||||
|
||||
/// String literal.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn string(string: &str) -> Literal {
|
||||
let mut escaped = String::new();
|
||||
for ch in string.chars() {
|
||||
@ -1055,7 +1077,7 @@ impl Literal {
|
||||
}
|
||||
|
||||
/// Character literal.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn character(ch: char) -> Literal {
|
||||
let mut escaped = String::new();
|
||||
escaped.extend(ch.escape_unicode());
|
||||
@ -1067,7 +1089,7 @@ impl Literal {
|
||||
}
|
||||
|
||||
/// Byte string literal.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn byte_string(bytes: &[u8]) -> Literal {
|
||||
let string = bytes.iter().cloned().flat_map(ascii::escape_default)
|
||||
.map(Into::<char>::into).collect::<String>();
|
||||
@ -1079,13 +1101,13 @@ impl Literal {
|
||||
}
|
||||
|
||||
/// Returns the span encompassing this literal.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
|
||||
/// Configures the span associated for this literal.
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
pub fn set_span(&mut self, span: Span) {
|
||||
self.span = span;
|
||||
}
|
||||
@ -1093,7 +1115,7 @@ impl Literal {
|
||||
|
||||
/// Prints the literal as a string that should be losslessly convertible
|
||||
/// back into the same literal (except for possible rounding for floating point literals).
|
||||
#[unstable(feature = "proc_macro", issue = "38356")]
|
||||
#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
||||
impl fmt::Display for Literal {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
TokenStream::from(TokenTree::from(self.clone())).fmt(f)
|
||||
|
@ -1412,9 +1412,6 @@ pub struct Resolver<'a> {
|
||||
/// Avoid duplicated errors for "name already defined".
|
||||
name_already_seen: FxHashMap<Name, Span>,
|
||||
|
||||
/// If `#![feature(proc_macro)]` is set
|
||||
proc_macro_enabled: bool,
|
||||
|
||||
/// A set of procedural macros imported by `#[macro_use]` that have already been warned about
|
||||
warned_proc_macros: FxHashSet<Name>,
|
||||
|
||||
@ -1713,7 +1710,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
// The `proc_macro` and `decl_macro` features imply `use_extern_macros`
|
||||
use_extern_macros:
|
||||
features.use_extern_macros || features.proc_macro || features.decl_macro,
|
||||
features.use_extern_macros || features.decl_macro,
|
||||
|
||||
crate_loader,
|
||||
macro_names: FxHashSet(),
|
||||
@ -1727,7 +1724,6 @@ impl<'a> Resolver<'a> {
|
||||
local_macro_def_scopes: FxHashMap(),
|
||||
name_already_seen: FxHashMap(),
|
||||
whitelisted_legacy_custom_derives: Vec::new(),
|
||||
proc_macro_enabled: features.proc_macro,
|
||||
warned_proc_macros: FxHashSet(),
|
||||
potentially_unused_imports: Vec::new(),
|
||||
struct_constructors: DefIdMap(),
|
||||
@ -4509,7 +4505,7 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
fn check_proc_macro_attrs(&mut self, attrs: &[ast::Attribute]) {
|
||||
if self.proc_macro_enabled { return; }
|
||||
if self.use_extern_macros { return; }
|
||||
|
||||
for attr in attrs {
|
||||
if attr.path.segments.len() > 1 {
|
||||
|
@ -429,7 +429,7 @@ impl<'a> Resolver<'a> {
|
||||
*item = mem::replace(item, dummy_item).map_attrs(|mut attrs| {
|
||||
let inert_attr = attr.take().unwrap();
|
||||
attr::mark_known(&inert_attr);
|
||||
if self.proc_macro_enabled {
|
||||
if self.use_extern_macros {
|
||||
*attr = expand::find_attr_invoc(&mut attrs);
|
||||
}
|
||||
attrs.push(inert_attr);
|
||||
|
@ -1073,7 +1073,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
if self.cx.ecfg.proc_macro_enabled() {
|
||||
if self.cx.ecfg.use_extern_macros_enabled() {
|
||||
attr = find_attr_invoc(&mut attrs);
|
||||
}
|
||||
traits = collect_derives(&mut self.cx, &mut attrs);
|
||||
@ -1096,7 +1096,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
if self.cx.ecfg.proc_macro_enabled() {
|
||||
if self.cx.ecfg.use_extern_macros_enabled() {
|
||||
attr = find_attr_invoc(&mut attrs);
|
||||
}
|
||||
attrs
|
||||
@ -1406,7 +1406,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
|
||||
foreign_item: ast::ForeignItem) -> SmallVector<ast::ForeignItem> {
|
||||
let (attr, traits, foreign_item) = self.classify_item(foreign_item);
|
||||
|
||||
let explain = if self.cx.ecfg.proc_macro_enabled() {
|
||||
let explain = if self.cx.ecfg.use_extern_macros_enabled() {
|
||||
feature_gate::EXPLAIN_PROC_MACROS_IN_EXTERN
|
||||
} else {
|
||||
feature_gate::EXPLAIN_MACROS_IN_EXTERN
|
||||
@ -1592,7 +1592,7 @@ impl<'feat> ExpansionConfig<'feat> {
|
||||
fn enable_trace_macros = trace_macros,
|
||||
fn enable_allow_internal_unstable = allow_internal_unstable,
|
||||
fn enable_custom_derive = custom_derive,
|
||||
fn proc_macro_enabled = proc_macro,
|
||||
fn use_extern_macros_enabled = use_extern_macros,
|
||||
fn macros_in_extern_enabled = macros_in_extern,
|
||||
fn proc_macro_mod = proc_macro_mod,
|
||||
fn proc_macro_gen = proc_macro_gen,
|
||||
|
@ -39,13 +39,6 @@ use symbol::{keywords, Symbol};
|
||||
use std::{env, path};
|
||||
|
||||
macro_rules! set {
|
||||
(proc_macro) => {{
|
||||
fn f(features: &mut Features, span: Span) {
|
||||
features.declared_lib_features.push((Symbol::intern("proc_macro"), span));
|
||||
features.proc_macro = true;
|
||||
}
|
||||
f as fn(&mut Features, Span)
|
||||
}};
|
||||
($field: ident) => {{
|
||||
fn f(features: &mut Features, _: Span) {
|
||||
features.$field = true;
|
||||
@ -303,9 +296,6 @@ declare_features! (
|
||||
// rustc internal
|
||||
(active, abi_unadjusted, "1.16.0", None, None),
|
||||
|
||||
// Procedural macros 2.0.
|
||||
(active, proc_macro, "1.16.0", Some(38356), Some(Edition::Edition2018)),
|
||||
|
||||
// Declarative macros 2.0 (`macro`).
|
||||
(active, decl_macro, "1.17.0", Some(39412), None),
|
||||
|
||||
@ -626,6 +616,8 @@ declare_features! (
|
||||
(accepted, global_allocator, "1.28.0", Some(27389), None),
|
||||
// Allows `#[repr(transparent)]` attribute on newtype structs
|
||||
(accepted, repr_transparent, "1.28.0", Some(43036), None),
|
||||
// Defining procedural macros in `proc-macro` crates
|
||||
(accepted, proc_macro, "1.29.0", Some(38356), None),
|
||||
);
|
||||
|
||||
// If you change this, please modify src/doc/unstable-book as well. You must
|
||||
@ -1033,15 +1025,8 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
|
||||
|
||||
("windows_subsystem", Whitelisted, Ungated),
|
||||
|
||||
("proc_macro_attribute", Normal, Gated(Stability::Unstable,
|
||||
"proc_macro",
|
||||
"attribute proc macros are currently unstable",
|
||||
cfg_fn!(proc_macro))),
|
||||
|
||||
("proc_macro", Normal, Gated(Stability::Unstable,
|
||||
"proc_macro",
|
||||
"function-like proc macros are currently unstable",
|
||||
cfg_fn!(proc_macro))),
|
||||
("proc_macro_attribute", Normal, Ungated),
|
||||
("proc_macro", Normal, Ungated),
|
||||
|
||||
("rustc_derive_registrar", Normal, Gated(Stability::Unstable,
|
||||
"rustc_derive_registrar",
|
||||
@ -1542,7 +1527,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
if self.context.features.proc_macro && attr::is_known(attr) {
|
||||
if self.context.features.use_extern_macros && attr::is_known(attr) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1990,7 +1975,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
/// A collector for mutually exclusive and interdependent features and their flag spans.
|
||||
#[derive(Default)]
|
||||
struct FeatureChecker {
|
||||
proc_macro: Option<Span>,
|
||||
use_extern_macros: Option<Span>,
|
||||
custom_attribute: Option<Span>,
|
||||
}
|
||||
|
||||
@ -1999,9 +1984,9 @@ impl FeatureChecker {
|
||||
// the branching can be eliminated by modifying `set!()` to set these spans
|
||||
// only for the features that need to be checked for mutual exclusion.
|
||||
fn collect(&mut self, features: &Features, span: Span) {
|
||||
if features.proc_macro {
|
||||
// If self.proc_macro is None, set to Some(span)
|
||||
self.proc_macro = self.proc_macro.or(Some(span));
|
||||
if features.use_extern_macros {
|
||||
// If self.use_extern_macros is None, set to Some(span)
|
||||
self.use_extern_macros = self.use_extern_macros.or(Some(span));
|
||||
}
|
||||
|
||||
if features.custom_attribute {
|
||||
@ -2010,8 +1995,8 @@ impl FeatureChecker {
|
||||
}
|
||||
|
||||
fn check(self, handler: &Handler) {
|
||||
if let (Some(pm_span), Some(ca_span)) = (self.proc_macro, self.custom_attribute) {
|
||||
handler.struct_span_err(pm_span, "Cannot use `#![feature(proc_macro)]` and \
|
||||
if let (Some(pm_span), Some(ca_span)) = (self.use_extern_macros, self.custom_attribute) {
|
||||
handler.struct_span_err(pm_span, "Cannot use `#![feature(use_extern_macros)]` and \
|
||||
`#![feature(custom_attribute)] at the same time")
|
||||
.span_note(ca_span, "`#![feature(custom_attribute)]` declared here")
|
||||
.emit();
|
||||
|
@ -12,7 +12,7 @@
|
||||
// ignore-stage1
|
||||
// compile-flags: -D crate-not-okay
|
||||
|
||||
#![feature(plugin, custom_attribute)] //~ ERROR crate is not marked with #![crate_okay]
|
||||
#![feature(plugin)] //~ ERROR crate is not marked with #![crate_okay]
|
||||
#![plugin(lint_for_crate)]
|
||||
|
||||
pub fn main() { }
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
//! Attributes producing expressions in invalid locations
|
||||
|
||||
#![feature(proc_macro, stmt_expr_attributes, proc_macro_expr)]
|
||||
#![feature(use_extern_macros, stmt_expr_attributes, proc_macro_expr)]
|
||||
|
||||
extern crate attr_stmt_expr;
|
||||
use attr_stmt_expr::{duplicate, no_output};
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:attr-stmt-expr.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro, proc_macro_expr)]
|
||||
#![feature(use_extern_macros, proc_macro_expr)]
|
||||
|
||||
extern crate attr_stmt_expr;
|
||||
use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr};
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:attribute-with-error.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate attribute_with_error;
|
||||
|
||||
|
@ -10,23 +10,25 @@
|
||||
|
||||
// aux-build:attributes-included.rs
|
||||
// ignore-stage1
|
||||
// compile-pass
|
||||
|
||||
#![feature(proc_macro, rustc_attrs, proc_macro_path_invoc)]
|
||||
#![feature(use_extern_macros)]
|
||||
#![warn(unused)]
|
||||
|
||||
extern crate attributes_included;
|
||||
|
||||
#[attributes_included::bar]
|
||||
use attributes_included::*;
|
||||
|
||||
#[bar]
|
||||
#[inline]
|
||||
/// doc
|
||||
#[attributes_included::foo]
|
||||
#[foo]
|
||||
#[inline]
|
||||
/// doc
|
||||
fn foo() {
|
||||
let a: i32 = "foo"; //~ WARN: unused variable
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() { //~ ERROR: compilation successful
|
||||
fn main() {
|
||||
foo()
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -12,7 +12,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -12,7 +12,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
|
@ -11,7 +11,6 @@
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro, proc_macro_lib)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
// force-host
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:attr_proc_macro.rs
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate attr_proc_macro;
|
||||
use attr_proc_macro::attr_proc_macro;
|
||||
|
||||
#[attr_proc_macro]
|
||||
//~^ ERROR: attribute procedural macros are experimental
|
||||
struct Foo;
|
||||
|
||||
fn main() {
|
||||
let _ = Foo;
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
// FIXME: https://github.com/rust-lang/rust/issues/41430
|
||||
// This is a temporary regression test for the ICE reported in #41211
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
#![emit_unchanged]
|
||||
//~^ ERROR: cannot find attribute macro `emit_unchanged` in this scope
|
||||
extern crate issue_41211;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:attr_proc_macro.rs
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
#[macro_use] extern crate attr_proc_macro;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
// ignore-stage1
|
||||
// ignore-wasm32
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate test_macros;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// aux-build:more-gates.rs
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate more_gates as foo;
|
||||
|
||||
|
@ -9,9 +9,10 @@
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:attr_proc_macro.rs
|
||||
// ignore-tidy-linelength
|
||||
|
||||
#![feature(proc_macro, custom_attribute)]
|
||||
//~^ ERROR Cannot use `#![feature(proc_macro)]` and `#![feature(custom_attribute)] at the same time
|
||||
#![feature(use_extern_macros, custom_attribute)]
|
||||
//~^ ERROR Cannot use `#![feature(use_extern_macros)]` and `#![feature(custom_attribute)] at the same time
|
||||
|
||||
extern crate attr_proc_macro;
|
||||
use attr_proc_macro::attr_proc_macro;
|
||||
|
@ -16,7 +16,7 @@
|
||||
// gate-test-proc_macro_mod
|
||||
// gate-test-proc_macro_gen
|
||||
|
||||
#![feature(proc_macro, stmt_expr_attributes)]
|
||||
#![feature(use_extern_macros, stmt_expr_attributes)]
|
||||
|
||||
extern crate proc_macro_gates as foo;
|
||||
|
||||
|
@ -35,7 +35,7 @@ use rustc_plugin::Registry;
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_syntax_extension(
|
||||
Symbol::intern("derive_TotalSum"),
|
||||
Symbol::intern("rustc_derive_TotalSum"),
|
||||
MultiDecorator(box expand));
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro, proc_macro_non_items)]
|
||||
#![feature(use_extern_macros, proc_macro_non_items, proc_macro_quote)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -57,19 +57,19 @@ declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]");
|
||||
fake_lint_pass! {
|
||||
PassOkay,
|
||||
lint_array!(CRATE_NOT_OKAY), // Single lint
|
||||
"crate_okay"
|
||||
"rustc_crate_okay"
|
||||
}
|
||||
|
||||
fake_lint_pass! {
|
||||
PassRedBlue,
|
||||
lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints
|
||||
"crate_red", "crate_blue"
|
||||
"rustc_crate_red", "rustc_crate_blue"
|
||||
}
|
||||
|
||||
fake_lint_pass! {
|
||||
PassGreyGreen,
|
||||
lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma
|
||||
"crate_grey", "crate_green"
|
||||
"rustc_crate_grey", "rustc_crate_green"
|
||||
}
|
||||
|
||||
#[plugin_registrar]
|
||||
|
@ -37,13 +37,13 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_macro("make_a_1", expand_make_a_1);
|
||||
reg.register_macro("identity", expand_identity);
|
||||
reg.register_syntax_extension(
|
||||
Symbol::intern("into_multi_foo"),
|
||||
Symbol::intern("rustc_into_multi_foo"),
|
||||
MultiModifier(Box::new(expand_into_foo_multi)));
|
||||
reg.register_syntax_extension(
|
||||
Symbol::intern("duplicate"),
|
||||
Symbol::intern("rustc_duplicate"),
|
||||
MultiDecorator(Box::new(expand_duplicate)));
|
||||
reg.register_syntax_extension(
|
||||
Symbol::intern("caller"),
|
||||
Symbol::intern("rustc_caller"),
|
||||
MultiDecorator(Box::new(expand_caller)));
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:custom_derive_plugin_attr.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(plugin, custom_derive, custom_attribute)]
|
||||
#![feature(plugin, custom_derive, rustc_attrs)]
|
||||
#![plugin(custom_derive_plugin_attr)]
|
||||
|
||||
trait TotalSum {
|
||||
@ -32,7 +32,7 @@ impl TotalSum for Seven {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(TotalSum)]
|
||||
#[rustc_derive_TotalSum]
|
||||
struct Foo {
|
||||
seven: Seven,
|
||||
bar: Bar,
|
||||
@ -41,7 +41,7 @@ struct Foo {
|
||||
nan: NaN,
|
||||
}
|
||||
|
||||
#[derive(TotalSum)]
|
||||
#[rustc_derive_TotalSum]
|
||||
struct Bar {
|
||||
quux: isize,
|
||||
bleh: isize,
|
||||
|
@ -12,12 +12,12 @@
|
||||
// ignore-stage1
|
||||
// compile-flags: -D crate-not-okay
|
||||
|
||||
#![feature(plugin, custom_attribute)]
|
||||
#![feature(plugin, rustc_attrs)]
|
||||
#![plugin(lint_for_crate)]
|
||||
#![crate_okay]
|
||||
#![crate_blue]
|
||||
#![crate_red]
|
||||
#![crate_grey]
|
||||
#![crate_green]
|
||||
#![rustc_crate_okay]
|
||||
#![rustc_crate_blue]
|
||||
#![rustc_crate_red]
|
||||
#![rustc_crate_grey]
|
||||
#![rustc_crate_green]
|
||||
|
||||
pub fn main() { }
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:macro_crate_test.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(plugin, custom_attribute, attr_literals)]
|
||||
#![feature(plugin, rustc_attrs, attr_literals)]
|
||||
#![plugin(macro_crate_test)]
|
||||
|
||||
#[macro_use]
|
||||
@ -30,16 +30,16 @@ extern crate macro_crate_test;
|
||||
// This results in a function named `simple` that calls `f(1, "hello", 3.14)`.
|
||||
// As a result, the expression `simple()` evaluates to `(1, "helllo", 3.14)`.
|
||||
|
||||
#[caller(simple, 1, "hello", 3.14)]
|
||||
#[caller(simple1, 2, "bye", 6.28)]
|
||||
#[caller(simple2, 3, "hi", 1.01)]
|
||||
#[rustc_caller(simple, 1, "hello", 3.14)]
|
||||
#[rustc_caller(simple1, 2, "bye", 6.28)]
|
||||
#[rustc_caller(simple2, 3, "hi", 1.01)]
|
||||
fn f(num: isize, string: &'static str, float: f32) -> (isize, &'static str, f32) {
|
||||
(num, string, float)
|
||||
}
|
||||
|
||||
#[caller(complex, true, 10)]
|
||||
#[caller(complex1, false, 15)]
|
||||
#[caller(complex2, true, 20)]
|
||||
#[rustc_caller(complex, true, 10)]
|
||||
#[rustc_caller(complex1, false, 15)]
|
||||
#[rustc_caller(complex2, true, 20)]
|
||||
fn g(emit: bool, num: i32) -> Option<i32> {
|
||||
match emit {
|
||||
true => Some(num),
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:macro_crate_test.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(plugin, custom_attribute)]
|
||||
#![feature(plugin, rustc_attrs)]
|
||||
#![plugin(macro_crate_test)]
|
||||
|
||||
#[macro_use]
|
||||
@ -20,27 +20,27 @@ extern crate macro_crate_test;
|
||||
|
||||
// The duplicate macro will create a copy of the item with the given identifier.
|
||||
|
||||
#[duplicate(MyCopy)]
|
||||
#[rustc_duplicate(MyCopy)]
|
||||
struct MyStruct {
|
||||
number: i32
|
||||
}
|
||||
|
||||
trait TestTrait {
|
||||
#[duplicate(TestType2)]
|
||||
#[rustc_duplicate(TestType2)]
|
||||
type TestType;
|
||||
|
||||
#[duplicate(required_fn2)]
|
||||
#[rustc_duplicate(required_fn2)]
|
||||
fn required_fn(&self);
|
||||
|
||||
#[duplicate(provided_fn2)]
|
||||
#[rustc_duplicate(provided_fn2)]
|
||||
fn provided_fn(&self) { }
|
||||
}
|
||||
|
||||
impl TestTrait for MyStruct {
|
||||
#[duplicate(TestType2)]
|
||||
#[rustc_duplicate(TestType2)]
|
||||
type TestType = f64;
|
||||
|
||||
#[duplicate(required_fn2)]
|
||||
#[rustc_duplicate(required_fn2)]
|
||||
fn required_fn(&self) { }
|
||||
}
|
||||
|
||||
|
@ -11,26 +11,26 @@
|
||||
// aux-build:macro_crate_test.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(plugin, custom_attribute)]
|
||||
#![feature(plugin, rustc_attrs)]
|
||||
#![plugin(macro_crate_test)]
|
||||
|
||||
#[macro_use] #[no_link]
|
||||
extern crate macro_crate_test;
|
||||
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
#[into_multi_foo]
|
||||
#[rustc_into_multi_foo]
|
||||
fn foo() -> AnotherFakeTypeThatHadBetterGoAway {}
|
||||
|
||||
// Check that the `#[into_multi_foo]`-generated `foo2` is configured away
|
||||
fn foo2() {}
|
||||
|
||||
trait Qux {
|
||||
#[into_multi_foo]
|
||||
#[rustc_into_multi_foo]
|
||||
fn bar();
|
||||
}
|
||||
|
||||
impl Qux for i32 {
|
||||
#[into_multi_foo]
|
||||
#[rustc_into_multi_foo]
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
|
@ -12,14 +12,13 @@
|
||||
// ignore-stage1
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(proc_macro, proc_macro_path_invoc)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate attr_args;
|
||||
use attr_args::attr_with_args;
|
||||
use attr_args::{attr_with_args, identity};
|
||||
|
||||
#[attr_with_args(text = "Hello, world!")]
|
||||
fn foo() {}
|
||||
|
||||
#[::attr_args::identity(
|
||||
fn main() { assert_eq!(foo(), "Hello, world!"); })]
|
||||
#[identity(fn main() { assert_eq!(foo(), "Hello, world!"); })]
|
||||
struct Dummy;
|
||||
|
@ -12,7 +12,7 @@
|
||||
// ignore-stage1
|
||||
// revisions: foo bar
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate attr_cfg;
|
||||
use attr_cfg::attr_cfg;
|
||||
|
@ -11,12 +11,14 @@
|
||||
// aux-build:attr-on-trait.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro, proc_macro_path_invoc)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate attr_on_trait;
|
||||
|
||||
use attr_on_trait::foo;
|
||||
|
||||
trait Foo {
|
||||
#[attr_on_trait::foo]
|
||||
#[foo]
|
||||
fn foo() {}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:attr-stmt-expr.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro, stmt_expr_attributes, proc_macro_stmt, proc_macro_expr)]
|
||||
#![feature(use_extern_macros, stmt_expr_attributes, proc_macro_stmt, proc_macro_expr)]
|
||||
|
||||
extern crate attr_stmt_expr;
|
||||
use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr,
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::*;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro, proc_macro_non_items)]
|
||||
#![feature(proc_macro_non_items, proc_macro_quote, use_extern_macros)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro, proc_macro_non_items)]
|
||||
#![feature(use_extern_macros, proc_macro_quote, proc_macro_non_items)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro as proc_macro_renamed; // This does not break `quote!`
|
||||
|
@ -7,6 +7,7 @@
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(box_syntax, plugin, plugin_registrar, rustc_private)]
|
||||
#![feature(macro_vis_matcher)]
|
||||
#![feature(macro_at_most_once_rep)]
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::TokenStream;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
#![feature(proc_macro_span)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:call-site.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro, proc_macro_non_items)]
|
||||
#![feature(proc_macro_non_items, use_extern_macros)]
|
||||
|
||||
extern crate call_site;
|
||||
use call_site::*;
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:derive-b.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro, proc_macro_path_invoc)]
|
||||
#![feature(use_extern_macros, proc_macro_path_invoc)]
|
||||
|
||||
extern crate derive_b;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// aux-build:gen-lifetime-token.rs
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate gen_lifetime_token as bar;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:issue-42708.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(decl_macro, proc_macro, proc_macro_path_invoc)]
|
||||
#![feature(decl_macro, use_extern_macros, proc_macro_path_invoc)]
|
||||
#![allow(unused)]
|
||||
|
||||
extern crate issue_42708;
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:issue-50061.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro, proc_macro_path_invoc, decl_macro)]
|
||||
#![feature(use_extern_macros, proc_macro_path_invoc, decl_macro)]
|
||||
|
||||
extern crate issue_50061;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// aux-build:lifetimes.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate lifetimes;
|
||||
use lifetimes::*;
|
||||
|
@ -12,7 +12,7 @@
|
||||
// ignore-stage1
|
||||
// ignore-wasm32
|
||||
|
||||
#![feature(proc_macro, macros_in_extern)]
|
||||
#![feature(use_extern_macros, macros_in_extern)]
|
||||
|
||||
extern crate test_macros;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// aux-build:modify-ast.rs
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate modify_ast;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// aux-build:not-joint.rs
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate not_joint as bar;
|
||||
use bar::{tokens, nothing};
|
||||
|
@ -12,7 +12,7 @@
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
|
||||
#![feature(proc_macro, proc_macro_non_items)]
|
||||
#![feature(use_extern_macros, proc_macro_non_items)]
|
||||
|
||||
extern crate proc_macro_def;
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro_raw_ident)]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::*;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// aux-build:lifetimes.rs
|
||||
|
||||
#![feature(proc_macro, proc_macro_non_items)]
|
||||
#![feature(use_extern_macros, proc_macro_non_items)]
|
||||
|
||||
extern crate lifetimes;
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate proc_macro;
|
||||
use proc_macro::*;
|
||||
|
@ -9,7 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![feature(proc_macro_diagnostic, proc_macro_span)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -9,8 +9,9 @@
|
||||
// except according to those terms.
|
||||
|
||||
// no-prefer-dynamic
|
||||
#![feature(proc_macro)]
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
#![feature(proc_macro_diagnostic, proc_macro_span)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
// aux-build:generate-mod.rs
|
||||
|
||||
#![feature(proc_macro, proc_macro_gen, proc_macro_path_invoc)]
|
||||
#![feature(use_extern_macros, proc_macro_gen, proc_macro_path_invoc)]
|
||||
|
||||
extern crate generate_mod;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// aux-build:macro-brackets.rs
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate macro_brackets as bar;
|
||||
use bar::doit;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
@ -13,7 +13,7 @@
|
||||
// aux-build:attr_proc_macro.rs
|
||||
// aux-build:bang_proc_macro.rs
|
||||
|
||||
#![feature(proc_macro)]
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate derive_foo;
|
||||
|
Loading…
Reference in New Issue
Block a user