Auto merge of #49124 - abonander:attr-macro-stmt-expr, r=abonander
Expand Attributes on Statements and Expressions This enables attribute-macro expansion on statements and expressions while retaining the `stmt_expr_attributes` feature requirement for attributes on expressions. closes #41475 cc #38356 @petrochenkov @jseyfried r? @nrc
This commit is contained in:
commit
097efa9a99
16 changed files with 335 additions and 34 deletions
|
|
@ -93,6 +93,8 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
|
|||
}
|
||||
})
|
||||
}
|
||||
// these are covered in proc_macro/attr-stmt-expr.rs
|
||||
Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,6 +147,8 @@ fn expand_duplicate(cx: &mut ExtCtxt,
|
|||
new_it.ident = copy_name;
|
||||
push(Annotatable::TraitItem(P(new_it)));
|
||||
}
|
||||
// covered in proc_macro/attr-stmt-expr.rs
|
||||
Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// 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:attr-stmt-expr.rs
|
||||
// ignore-stage1
|
||||
|
||||
//! Attributes producing expressions in invalid locations
|
||||
|
||||
#![feature(proc_macro, stmt_expr_attributes)]
|
||||
|
||||
extern crate attr_stmt_expr;
|
||||
use attr_stmt_expr::{duplicate, no_output};
|
||||
|
||||
fn main() {
|
||||
let _ = #[no_output] "Hello, world!";
|
||||
//~^ ERROR expected expression, found `<eof>`
|
||||
|
||||
let _ = #[duplicate] "Hello, world!";
|
||||
//~^ ERROR macro expansion ignores token `,` and any following
|
||||
|
||||
let _ = {
|
||||
#[no_output]
|
||||
"Hello, world!"
|
||||
};
|
||||
|
||||
let _ = {
|
||||
#[duplicate]
|
||||
//~^ ERROR macro expansion ignores token `,` and any following
|
||||
"Hello, world!"
|
||||
};
|
||||
}
|
||||
38
src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs
Normal file
38
src/test/compile-fail-fulldeps/proc-macro/attr-stmt-expr.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// 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:attr-stmt-expr.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate attr_stmt_expr;
|
||||
use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr};
|
||||
|
||||
fn print_str(string: &'static str) {
|
||||
// macros are handled a bit differently
|
||||
#[expect_print_expr]
|
||||
//~^ ERROR attributes on expressions are experimental
|
||||
//~| HELP add #![feature(stmt_expr_attributes)] to the crate attributes to enable
|
||||
println!("{}", string)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[expect_let]
|
||||
let string = "Hello, world!";
|
||||
|
||||
#[expect_print_stmt]
|
||||
println!("{}", string);
|
||||
|
||||
#[expect_expr]
|
||||
//~^ ERROR attributes on expressions are experimental
|
||||
//~| HELP add #![feature(stmt_expr_attributes)] to the crate attributes to enable
|
||||
print_str("string")
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// 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::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "let string = \"Hello, world!\";");
|
||||
item
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string);");
|
||||
item
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "print_str(\"string\")");
|
||||
item
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string)");
|
||||
item
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn duplicate(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
format!("{}, {}", item, item).parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn no_output(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert!(!item.to_string().is_empty());
|
||||
"".parse().unwrap()
|
||||
}
|
||||
|
|
@ -96,6 +96,8 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt,
|
|||
}
|
||||
})
|
||||
],
|
||||
// these are covered in proc_macro/attr-stmt-expr.rs
|
||||
Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +142,8 @@ fn expand_duplicate(cx: &mut ExtCtxt,
|
|||
new_it.ident = copy_name;
|
||||
push(Annotatable::TraitItem(P(new_it)));
|
||||
}
|
||||
// these are covered in proc_macro/attr-stmt-expr.rs
|
||||
Annotatable::Stmt(_) | Annotatable::Expr(_) => panic!("expected item")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
34
src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs
Normal file
34
src/test/run-pass-fulldeps/proc-macro/attr-stmt-expr.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// 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:attr-stmt-expr.rs
|
||||
// ignore-stage1
|
||||
|
||||
#![feature(proc_macro, stmt_expr_attributes)]
|
||||
|
||||
extern crate attr_stmt_expr;
|
||||
use attr_stmt_expr::{expect_let, expect_print_stmt, expect_expr, expect_print_expr};
|
||||
|
||||
fn print_str(string: &'static str) {
|
||||
// macros are handled a bit differently
|
||||
#[expect_print_expr]
|
||||
println!("{}", string)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
#[expect_let]
|
||||
let string = "Hello, world!";
|
||||
|
||||
#[expect_print_stmt]
|
||||
println!("{}", string);
|
||||
|
||||
#[expect_expr]
|
||||
print_str("string")
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// 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::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "let string = \"Hello, world!\";");
|
||||
item
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string);");
|
||||
item
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "print_str(\"string\")");
|
||||
item
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
assert!(attr.to_string().is_empty());
|
||||
assert_eq!(item.to_string(), "println!(\"{}\" , string)");
|
||||
item
|
||||
}
|
||||
|
|
@ -9,6 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
const X: i32 = #[allow(dead_code)] 8;
|
||||
//~^ ERROR attributes on non-item statements and expressions are experimental. (see issue #15701)
|
||||
//~^ ERROR attributes on expressions are experimental. (see issue #15701)
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error[E0658]: attributes on non-item statements and expressions are experimental. (see issue #15701)
|
||||
error[E0658]: attributes on expressions are experimental. (see issue #15701)
|
||||
--> $DIR/feature-gate-stmt_expr_attributes.rs:11:16
|
||||
|
|
||||
LL | const X: i32 = #[allow(dead_code)] 8;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue