Auto merge of #50473 - petrochenkov:pmapi, r=alexcrichton

Review proc macro API 1.2

cc https://github.com/rust-lang/rust/issues/38356

Summary of applied changes:
- Documentation for proc macro API 1.2 is expanded.
- Renamed APIs: `Term` -> `Ident`, `TokenTree::Term` -> `TokenTree::Ident`, `Op` -> `Punct`, `TokenTree::Op` -> `TokenTree::Punct`, `Op::op` -> `Punct::as_char`.
- Removed APIs: `Ident::as_str`, use `Display` impl for `Ident` instead.
- New APIs (not stabilized in 1.2): `Ident::new_raw` for creating a raw identifier (I'm not sure `new_x` it's a very idiomatic name though).
- Runtime changes:
    - `Punct::new` now ensures that the input `char` is a valid punctuation character in Rust.
    - `Ident::new` ensures that the input `str` is a valid identifier in Rust.
    - Lifetimes in proc macros are now represented as two joint tokens - `Punct('\'', Spacing::Joint)` and `Ident("lifetime_name_without_quote")` similarly to multi-character operators.
- Stabilized APIs: None yet.

A bit of motivation for renaming (although it was already stated in the review comments):
- With my compiler frontend glasses on `Ident` is the single most appropriate name for this thing, *especially* if we are doing input validation on construction. `TokenTree::Ident` effectively wraps `token::Ident` or `ast::Ident + is_raw`, its meaning is "identifier" and it's already named `ident` in declarative macros.
- Regarding `Punct`, the motivation is that `Op` is actively misleading. The thing doesn't mean an operator, it's neither a subset of operators (there is non-operator punctuation in the language), nor superset (operators can be multicharacter while this thing is always a single character). So I named it `Punct` (first proposed in [the original RFC](https://github.com/rust-lang/rfcs/pull/1566), then [by @SimonSapin](https://github.com/rust-lang/rust/issues/38356#issuecomment-276676526)) , together with input validation it's now a subset of ASCII punctuation character category (`u8::is_ascii_punctuation`).
This commit is contained in:
bors 2018-05-16 11:18:05 +00:00
commit 2a3f5367a2
53 changed files with 595 additions and 210 deletions

View file

@ -53,7 +53,7 @@ pub fn bar(attr: TokenStream, input: TokenStream) -> TokenStream {
fn assert_inline(slice: &mut &[TokenTree]) {
match &slice[0] {
TokenTree::Op(tt) => assert_eq!(tt.op(), '#'),
TokenTree::Punct(tt) => assert_eq!(tt.as_char(), '#'),
_ => panic!("expected '#' char"),
}
match &slice[1] {
@ -65,8 +65,8 @@ fn assert_inline(slice: &mut &[TokenTree]) {
fn assert_doc(slice: &mut &[TokenTree]) {
match &slice[0] {
TokenTree::Op(tt) => {
assert_eq!(tt.op(), '#');
TokenTree::Punct(tt) => {
assert_eq!(tt.as_char(), '#');
assert_eq!(tt.spacing(), Spacing::Alone);
}
_ => panic!("expected #"),
@ -86,12 +86,12 @@ fn assert_doc(slice: &mut &[TokenTree]) {
}
match &tokens[0] {
TokenTree::Term(tt) => assert_eq!("doc", &*tt.to_string()),
TokenTree::Ident(tt) => assert_eq!("doc", &*tt.to_string()),
_ => panic!("expected `doc`"),
}
match &tokens[1] {
TokenTree::Op(tt) => {
assert_eq!(tt.op(), '=');
TokenTree::Punct(tt) => {
assert_eq!(tt.as_char(), '=');
assert_eq!(tt.spacing(), Spacing::Alone);
}
_ => panic!("expected equals"),
@ -106,7 +106,7 @@ fn assert_doc(slice: &mut &[TokenTree]) {
fn assert_invoc(slice: &mut &[TokenTree]) {
match &slice[0] {
TokenTree::Op(tt) => assert_eq!(tt.op(), '#'),
TokenTree::Punct(tt) => assert_eq!(tt.as_char(), '#'),
_ => panic!("expected '#' char"),
}
match &slice[1] {
@ -118,11 +118,11 @@ fn assert_invoc(slice: &mut &[TokenTree]) {
fn assert_foo(slice: &mut &[TokenTree]) {
match &slice[0] {
TokenTree::Term(tt) => assert_eq!(&*tt.to_string(), "fn"),
TokenTree::Ident(tt) => assert_eq!(&*tt.to_string(), "fn"),
_ => panic!("expected fn"),
}
match &slice[1] {
TokenTree::Term(tt) => assert_eq!(&*tt.to_string(), "foo"),
TokenTree::Ident(tt) => assert_eq!(&*tt.to_string(), "foo"),
_ => panic!("expected foo"),
}
match &slice[2] {
@ -148,8 +148,8 @@ fn fold_tree(input: TokenTree) -> TokenTree {
TokenTree::Group(b) => {
TokenTree::Group(Group::new(b.delimiter(), fold_stream(b.stream())))
}
TokenTree::Op(b) => TokenTree::Op(b),
TokenTree::Term(a) => TokenTree::Term(a),
TokenTree::Punct(b) => TokenTree::Punct(b),
TokenTree::Ident(a) => TokenTree::Ident(a),
TokenTree::Literal(a) => {
if a.to_string() != "\"foo\"" {
TokenTree::Literal(a)

View file

@ -11,7 +11,6 @@
// force-host
// no-prefer-dynamic
#![feature(proc_macro, proc_macro_lib)]
#![crate_type = "proc-macro"]
extern crate proc_macro;

View file

@ -11,8 +11,6 @@
// aux-build:issue_38586.rs
// ignore-stage1
#![feature(proc_macro)]
#[macro_use]
extern crate issue_38586;

View file

@ -11,7 +11,7 @@
// aux-build:bang_proc_macro2.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(use_extern_macros, proc_macro_non_items)]
#![allow(unused_macros)]
extern crate bang_proc_macro2;

View file

@ -10,7 +10,7 @@
// aux-build:bang_proc_macro.rs
#![feature(proc_macro, proc_macro_non_items)]
#![feature(proc_macro_non_items)]
#[macro_use]
extern crate bang_proc_macro;

View file

@ -10,7 +10,7 @@
// aux-build:proc-macro-gates.rs
#![feature(proc_macro, stmt_expr_attributes)]
#![feature(use_extern_macros, stmt_expr_attributes)]
extern crate proc_macro_gates as foo;

View file

@ -33,7 +33,7 @@ pub fn cond(input: TokenStream) -> TokenStream {
panic!("Invalid macro usage in cond: {}", cond);
}
let is_else = match test {
TokenTree::Term(word) => &*word.to_string() == "else",
TokenTree::Ident(ref word) => &*word.to_string() == "else",
_ => false,
};
conds.push(if is_else || input.peek().is_none() {

View file

@ -11,7 +11,7 @@
// no-prefer-dynamic
#![crate_type = "proc-macro"]
#![feature(proc_macro, proc_macro_lib, proc_macro_non_items)]
#![feature(proc_macro, proc_macro_non_items)]
extern crate proc_macro;

View file

@ -11,7 +11,7 @@
// no-prefer-dynamic
#![crate_type = "proc-macro"]
#![feature(proc_macro, proc_macro_lib, proc_macro_non_items)]
#![feature(proc_macro, proc_macro_non_items)]
extern crate proc_macro;

View file

@ -11,7 +11,7 @@
// aux-build:cond_plugin.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(use_extern_macros, proc_macro_non_items)]
extern crate cond_plugin;

View file

@ -13,7 +13,7 @@
// aux-build:hello_macro.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(use_extern_macros, proc_macro_non_items)]
extern crate hello_macro;

View file

@ -28,7 +28,7 @@ fn count_compound_ops_helper(input: TokenStream) -> u32 {
let mut count = 0;
for token in input {
match &token {
TokenTree::Op(tt) if tt.spacing() == Spacing::Alone => {
TokenTree::Punct(tt) if tt.spacing() == Spacing::Alone => {
count += 1;
}
TokenTree::Group(tt) => {

View file

@ -9,7 +9,7 @@
// except according to those terms.
// no-prefer-dynamic
#![feature(proc_macro)]
#![crate_type = "proc-macro"]
extern crate proc_macro;

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(proc_macro)]
#![feature(use_extern_macros)]
extern crate hygiene_example_codegen;

View file

@ -0,0 +1,36 @@
// Copyright 2018 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.
// no-prefer-dynamic
#![feature(proc_macro)]
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::*;
#[proc_macro]
pub fn lifetimes_bang(input: TokenStream) -> TokenStream {
// Roundtrip through token trees
input.into_iter().collect()
}
#[proc_macro_attribute]
pub fn lifetimes_attr(_: TokenStream, input: TokenStream) -> TokenStream {
// Roundtrip through AST
input
}
#[proc_macro_derive(Lifetimes)]
pub fn lifetimes_derive(input: TokenStream) -> TokenStream {
// Roundtrip through a string
format!("mod m {{ {} }}", input).parse().unwrap()
}

View file

@ -38,14 +38,14 @@ fn assert_eq(a: TokenStream, b: TokenStream) {
assert_eq!(a.delimiter(), b.delimiter());
assert_eq(a.stream(), b.stream());
}
(TokenTree::Op(a), TokenTree::Op(b)) => {
assert_eq!(a.op(), b.op());
(TokenTree::Punct(a), TokenTree::Punct(b)) => {
assert_eq!(a.as_char(), b.as_char());
assert_eq!(a.spacing(), b.spacing());
}
(TokenTree::Literal(a), TokenTree::Literal(b)) => {
assert_eq!(a.to_string(), b.to_string());
}
(TokenTree::Term(a), TokenTree::Term(b)) => {
(TokenTree::Ident(a), TokenTree::Ident(b)) => {
assert_eq!(a.to_string(), b.to_string());
}
(a, b) => panic!("{:?} != {:?}", a, b),

View file

@ -11,7 +11,7 @@
// aux-build:bang-macro.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(use_extern_macros, proc_macro_non_items)]
extern crate bang_macro;
use bang_macro::rewrite;

View file

@ -11,7 +11,7 @@
// aux-build:count_compound_ops.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(use_extern_macros, proc_macro_non_items)]
extern crate count_compound_ops;
use count_compound_ops::count_compound_ops;

View file

@ -11,7 +11,7 @@
// aux-build:derive-attr-cfg.rs
// ignore-stage1
#![feature(proc_macro)]
#![feature(use_extern_macros)]
extern crate derive_attr_cfg;
use derive_attr_cfg::Foo;

View file

@ -12,7 +12,7 @@
// aux-build:hygiene_example.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(use_extern_macros, proc_macro_non_items)]
extern crate hygiene_example;
use hygiene_example::hello;

View file

@ -11,7 +11,7 @@
// aux-build:issue-39889.rs
// ignore-stage1
#![feature(proc_macro)]
#![feature(use_extern_macros)]
#![allow(unused)]
extern crate issue_39889;

View file

@ -11,7 +11,7 @@
// aux-build:issue-40001-plugin.rs
// ignore-stage1
#![feature(proc_macro, plugin)]
#![feature(plugin)]
#![plugin(issue_40001_plugin)]
#[whitelisted_attr]

View file

@ -0,0 +1,36 @@
// 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:lifetimes.rs
// ignore-stage1
#![feature(proc_macro)]
extern crate lifetimes;
use lifetimes::*;
lifetimes_bang! {
fn bang<'a>() -> &'a u8 { &0 }
}
#[lifetimes_attr]
fn attr<'a>() -> &'a u8 { &1 }
#[derive(Lifetimes)]
pub struct Lifetimes<'a> {
pub field: &'a u8,
}
fn main() {
assert_eq!(bang::<'static>(), &0);
assert_eq!(attr::<'static>(), &1);
let l1 = Lifetimes { field: &0 };
let l2 = m::Lifetimes { field: &1 };
}

View file

@ -11,7 +11,7 @@
// aux-build:negative-token.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(proc_macro_non_items)]
extern crate negative_token;

View file

@ -13,7 +13,7 @@
// ignore-pretty
#![feature(proc_macro)]
#![feature(use_extern_macros)]
#[macro_use]
extern crate span_test_macros;

View file

@ -0,0 +1,38 @@
// Copyright 2017 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.
// force-host
// no-prefer-dynamic
#![feature(proc_macro)]
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::*;
#[proc_macro]
pub fn invalid_punct(_: TokenStream) -> TokenStream {
TokenTree::from(Punct::new('`', Spacing::Alone)).into()
}
#[proc_macro]
pub fn invalid_ident(_: TokenStream) -> TokenStream {
TokenTree::from(Ident::new("*", Span::call_site())).into()
}
#[proc_macro]
pub fn invalid_raw_ident(_: TokenStream) -> TokenStream {
TokenTree::from(Ident::new_raw("self", Span::call_site())).into()
}
#[proc_macro]
pub fn lexer_failure(_: TokenStream) -> TokenStream {
"a b ) c".parse().expect("parsing failed without panic")
}

View file

@ -0,0 +1,30 @@
// Copyright 2018 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.
// no-prefer-dynamic
#![feature(proc_macro)]
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::*;
#[proc_macro]
pub fn single_quote_alone(_: TokenStream) -> TokenStream {
// `&'a u8`, but the `'` token is not joint
let trees: Vec<TokenTree> = vec![
Punct::new('&', Spacing::Alone).into(),
Punct::new('\'', Spacing::Alone).into(),
Ident::new("a", Span::call_site()).into(),
Ident::new("u8", Span::call_site()).into(),
];
trees.into_iter().collect()
}

View file

@ -11,7 +11,6 @@
// no-prefer-dynamic
#![crate_type = "proc-macro"]
#![feature(proc_macro, proc_macro_lib)]
extern crate proc_macro;

View file

@ -11,8 +11,6 @@
// aux-build:plugin.rs
// ignore-stage1
#![feature(proc_macro)]
#[macro_use] extern crate plugin;
#[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked

View file

@ -1,5 +1,5 @@
error: proc-macro derive panicked
--> $DIR/issue-36935.rs:18:15
--> $DIR/issue-36935.rs:16:15
|
LL | #[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked
| ^^^

View file

@ -0,0 +1,16 @@
// Copyright 2018 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:invalid-punct-ident.rs
#[macro_use]
extern crate invalid_punct_ident;
invalid_punct!(); //~ ERROR proc macro panicked

View file

@ -0,0 +1,10 @@
error: proc macro panicked
--> $DIR/invalid-punct-ident-1.rs:16:1
|
LL | invalid_punct!(); //~ ERROR proc macro panicked
| ^^^^^^^^^^^^^^^^^
|
= help: message: unsupported character `'`'`
error: aborting due to previous error

View file

@ -0,0 +1,16 @@
// Copyright 2018 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:invalid-punct-ident.rs
#[macro_use]
extern crate invalid_punct_ident;
invalid_ident!(); //~ ERROR proc macro panicked

View file

@ -0,0 +1,10 @@
error: proc macro panicked
--> $DIR/invalid-punct-ident-2.rs:16:1
|
LL | invalid_ident!(); //~ ERROR proc macro panicked
| ^^^^^^^^^^^^^^^^^
|
= help: message: `"*"` is not a valid identifier
error: aborting due to previous error

View file

@ -0,0 +1,16 @@
// Copyright 2018 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:invalid-punct-ident.rs
#[macro_use]
extern crate invalid_punct_ident;
invalid_raw_ident!(); //~ ERROR proc macro panicked

View file

@ -0,0 +1,10 @@
error: proc macro panicked
--> $DIR/invalid-punct-ident-3.rs:16:1
|
LL | invalid_raw_ident!(); //~ ERROR proc macro panicked
| ^^^^^^^^^^^^^^^^^^^^^
|
= help: message: `"self"` is not a valid raw identifier
error: aborting due to previous error

View file

@ -0,0 +1,17 @@
// Copyright 2018 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:invalid-punct-ident.rs
#[macro_use]
extern crate invalid_punct_ident;
lexer_failure!(); //~ ERROR proc macro panicked
//~| ERROR unexpected close delimiter: `)`

View file

@ -0,0 +1,14 @@
error: unexpected close delimiter: `)`
--> $DIR/invalid-punct-ident-4.rs:16:1
|
LL | lexer_failure!(); //~ ERROR proc macro panicked
| ^^^^^^^^^^^^^^^^^
error: proc macro panicked
--> $DIR/invalid-punct-ident-4.rs:16:1
|
LL | lexer_failure!(); //~ ERROR proc macro panicked
| ^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors

View file

@ -0,0 +1,19 @@
// 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:lifetimes.rs
#![feature(proc_macro, proc_macro_non_items)]
extern crate lifetimes;
use lifetimes::*;
type A = single_quote_alone!(); //~ ERROR expected type, found `'`

View file

@ -0,0 +1,8 @@
error: expected type, found `'`
--> $DIR/lifetimes.rs:19:10
|
LL | type A = single_quote_alone!(); //~ ERROR expected type, found `'`
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View file

@ -27,8 +27,8 @@ fn parse(input: TokenStream) -> Result<(), Diagnostic> {
.help("input must be: `===`"))
}
if let TokenTree::Op(tt) = tree {
if tt.op() == '=' {
if let TokenTree::Punct(ref tt) = tree {
if tt.as_char() == '=' {
count += 1;
last_span = span;
continue

View file

@ -11,7 +11,7 @@
// aux-build:parent-source-spans.rs
// ignore-stage1
#![feature(proc_macro, decl_macro, proc_macro_non_items)]
#![feature(use_extern_macros, decl_macro, proc_macro_non_items)]
extern crate parent_source_spans;

View file

@ -11,7 +11,7 @@
// aux-build:three-equals.rs
// ignore-stage1
#![feature(proc_macro, proc_macro_non_items)]
#![feature(use_extern_macros, proc_macro_non_items)]
extern crate three_equals;

View file

@ -14,7 +14,6 @@
// aux-build:bang_proc_macro.rs
#![feature(proc_macro)]
#![allow(unused_macros)]
#[macro_use]
extern crate derive_foo;

View file

@ -1,59 +1,59 @@
error: cannot find derive macro `FooWithLongNan` in this scope
--> $DIR/resolve-error.rs:37:10
--> $DIR/resolve-error.rs:36:10
|
LL | #[derive(FooWithLongNan)]
| ^^^^^^^^^^^^^^ help: try: `FooWithLongName`
error: cannot find attribute macro `attr_proc_macra` in this scope
--> $DIR/resolve-error.rs:41:3
--> $DIR/resolve-error.rs:40:3
|
LL | #[attr_proc_macra]
| ^^^^^^^^^^^^^^^ help: try: `attr_proc_macro`
error: cannot find attribute macro `FooWithLongNan` in this scope
--> $DIR/resolve-error.rs:45:3
--> $DIR/resolve-error.rs:44:3
|
LL | #[FooWithLongNan]
| ^^^^^^^^^^^^^^
error: cannot find derive macro `Dlone` in this scope
--> $DIR/resolve-error.rs:49:10
--> $DIR/resolve-error.rs:48:10
|
LL | #[derive(Dlone)]
| ^^^^^ help: try: `Clone`
error: cannot find derive macro `Dlona` in this scope
--> $DIR/resolve-error.rs:53:10
--> $DIR/resolve-error.rs:52:10
|
LL | #[derive(Dlona)]
| ^^^^^ help: try: `Clona`
error: cannot find derive macro `attr_proc_macra` in this scope
--> $DIR/resolve-error.rs:57:10
--> $DIR/resolve-error.rs:56:10
|
LL | #[derive(attr_proc_macra)]
| ^^^^^^^^^^^^^^^
error: cannot find macro `FooWithLongNama!` in this scope
--> $DIR/resolve-error.rs:62:5
--> $DIR/resolve-error.rs:61:5
|
LL | FooWithLongNama!();
| ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam`
error: cannot find macro `attr_proc_macra!` in this scope
--> $DIR/resolve-error.rs:65:5
--> $DIR/resolve-error.rs:64:5
|
LL | attr_proc_macra!();
| ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac`
error: cannot find macro `Dlona!` in this scope
--> $DIR/resolve-error.rs:68:5
--> $DIR/resolve-error.rs:67:5
|
LL | Dlona!();
| ^^^^^
error: cannot find macro `bang_proc_macrp!` in this scope
--> $DIR/resolve-error.rs:71:5
--> $DIR/resolve-error.rs:70:5
|
LL | bang_proc_macrp!();
| ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro`