提交 827e57c2 编写于 作者: B bors

Auto merge of #53459 - petrochenkov:stabmore, r=nrc

Stabilize a few secondary macro features

- `tool_attributes` - closes https://github.com/rust-lang/rust/issues/44690
- `proc_macro_path_invoc` - this feature was created due to issues with tool attributes (https://github.com/rust-lang/rust/issues/51277), those issues are now fixed (https://github.com/rust-lang/rust/pull/52841)
- partially `proc_macro_gen` - this feature was created due to issue https://github.com/rust-lang/rust/issues/50504, the issue is now fixed (https://github.com/rust-lang/rust/pull/51952), so proc macros can generate modules. They still can't generate `macro_rules` items though due to unclear hygiene interactions.
# `tool_attributes`
The tracking issue for this feature is: [#44690]
[#44690]: https://github.com/rust-lang/rust/issues/44690
------------------------
Tool attributes let you use scoped attributes to control the behavior
of certain tools.
Currently tool names which can be appear in scoped attributes are restricted to
`clippy` and `rustfmt`.
## An example
```rust
#![feature(tool_attributes)]
#[rustfmt::skip]
fn foo() { println!("hello, world"); }
fn main() {
foo();
}
```
......@@ -368,17 +368,6 @@ fn resolve_macro_to_def(&mut self, path: &ast::Path, kind: MacroKind, scope: Mar
let def = def?;
if path.segments.len() > 1 {
if kind != MacroKind::Bang {
if def != Def::NonMacroAttr(NonMacroAttrKind::Tool) &&
!self.session.features_untracked().proc_macro_path_invoc {
let msg = format!("non-ident {} paths are unstable", kind.descr());
emit_feature_err(&self.session.parse_sess, "proc_macro_path_invoc",
path.span, GateIssue::Language, &msg);
}
}
}
match def {
Def::Macro(def_id, macro_kind) => {
self.unused_macros.remove(&def_id);
......@@ -391,10 +380,6 @@ fn resolve_macro_to_def(&mut self, path: &ast::Path, kind: MacroKind, scope: Mar
Def::NonMacroAttr(attr_kind) => {
if kind == MacroKind::Attr {
let features = self.session.features_untracked();
if attr_kind == NonMacroAttrKind::Tool && !features.tool_attributes {
feature_err(&self.session.parse_sess, "tool_attributes", path.span,
GateIssue::Language, "tool attributes are unstable").emit();
}
if attr_kind == NonMacroAttrKind::Custom {
assert!(path.segments.len() == 1);
let name = path.segments[0].ident.name.as_str();
......
......@@ -666,30 +666,25 @@ fn gate_proc_macro_expansion(&self, span: Span, fragment: &Option<AstFragment>)
None => return,
};
fragment.visit_with(&mut DisallowModules {
fragment.visit_with(&mut DisallowMacros {
span,
parse_sess: self.cx.parse_sess,
});
struct DisallowModules<'a> {
struct DisallowMacros<'a> {
span: Span,
parse_sess: &'a ParseSess,
}
impl<'ast, 'a> Visitor<'ast> for DisallowModules<'a> {
impl<'ast, 'a> Visitor<'ast> for DisallowMacros<'a> {
fn visit_item(&mut self, i: &'ast ast::Item) {
let name = match i.node {
ast::ItemKind::Mod(_) => Some("modules"),
ast::ItemKind::MacroDef(_) => Some("macro definitions"),
_ => None,
};
if let Some(name) = name {
if let ast::ItemKind::MacroDef(_) = i.node {
emit_feature_err(
self.parse_sess,
"proc_macro_gen",
self.span,
GateIssue::Language,
&format!("procedural macros cannot expand to {}", name),
&format!("procedural macros cannot expand to macro definitions"),
);
}
visit::walk_item(self, i);
......
......@@ -441,9 +441,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
(active, tbm_target_feature, "1.27.0", Some(44839), None),
(active, wasm_target_feature, "1.30.0", Some(44839), None),
// Allows macro invocations of the form `#[foo::bar]`
(active, proc_macro_path_invoc, "1.27.0", Some(38356), None),
// Allows macro invocations on modules expressions and statements and
// procedural macros to expand to non-items.
(active, proc_macro_mod, "1.27.0", Some(38356), None),
......@@ -457,8 +454,6 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
// Access to crate names passed via `--extern` through prelude
(active, extern_prelude, "1.27.0", Some(44660), Some(Edition::Edition2018)),
// Scoped attributes
(active, tool_attributes, "1.25.0", Some(44690), None),
// Scoped lints
(active, tool_lints, "1.28.0", Some(44690), None),
......@@ -655,6 +650,10 @@ pub fn walk_feature_fields<F>(&self, mut f: F)
(accepted, use_extern_macros, "1.30.0", Some(35896), None),
// Allows keywords to be escaped for use as identifiers
(accepted, raw_identifiers, "1.30.0", Some(48589), None),
// Attributes scoped to tools
(accepted, tool_attributes, "1.30.0", Some(44690), None),
// Allows multi-segment paths in attributes and derives
(accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
);
// If you change this, please modify src/doc/unstable-book as well. You must
......
......@@ -16,11 +16,6 @@
use proc_macro::*;
#[proc_macro_attribute]
pub fn attr2mod(_: TokenStream, _: TokenStream) -> TokenStream {
"mod test {}".parse().unwrap()
}
#[proc_macro_attribute]
pub fn attr2mac1(_: TokenStream, _: TokenStream) -> TokenStream {
"macro_rules! foo1 { (a) => (a) }".parse().unwrap()
......@@ -31,11 +26,6 @@ pub fn attr2mac2(_: TokenStream, _: TokenStream) -> TokenStream {
"macro foo2(a) { a }".parse().unwrap()
}
#[proc_macro]
pub fn mac2mod(_: TokenStream) -> TokenStream {
"mod test2 {}".parse().unwrap()
}
#[proc_macro]
pub fn mac2mac1(_: TokenStream) -> TokenStream {
"macro_rules! foo3 { (a) => (a) }".parse().unwrap()
......@@ -49,7 +39,6 @@ pub fn mac2mac2(_: TokenStream) -> TokenStream {
#[proc_macro]
pub fn tricky(_: TokenStream) -> TokenStream {
"fn foo() {
mod test {}
macro_rules! foo { (a) => (a) }
}".parse().unwrap()
}
......@@ -14,9 +14,6 @@
use foo::*;
#[attr2mod]
//~^ ERROR: cannot expand to modules
pub fn a() {}
#[attr2mac1]
//~^ ERROR: cannot expand to macro definitions
pub fn a() {}
......@@ -24,12 +21,10 @@ pub fn a() {}
//~^ ERROR: cannot expand to macro definitions
pub fn a() {}
mac2mod!(); //~ ERROR: cannot expand to modules
mac2mac1!(); //~ ERROR: cannot expand to macro definitions
mac2mac2!(); //~ ERROR: cannot expand to macro definitions
tricky!();
//~^ ERROR: cannot expand to modules
//~| ERROR: cannot expand to macro definitions
//~^ ERROR: cannot expand to macro definitions
fn main() {}
......@@ -10,7 +10,6 @@
// aux-build:proc-macro-gates.rs
// gate-test-proc_macro_non_items
// gate-test-proc_macro_path_invoc
// gate-test-proc_macro_mod line
// gate-test-proc_macro_expr
// gate-test-proc_macro_mod
......@@ -22,20 +21,15 @@
use foo::*;
#[foo::a] //~ ERROR: non-ident attribute macro paths are unstable
fn _test() {}
fn _test_inner() {
#![a] // OK
}
#[a] //~ ERROR: custom attributes cannot be applied to modules
//~| ERROR: procedural macros cannot expand to modules
mod _test2 {}
mod _test2_inner {
#![a] //~ ERROR: custom attributes cannot be applied to modules
//~| ERROR: procedural macros cannot expand to modules
}
#[a = y] //~ ERROR: must only be followed by a delimiter token
......
......@@ -11,7 +11,7 @@
// aux-build:derive-b.rs
// ignore-stage1
#![feature(proc_macro_path_invoc, unrestricted_attribute_tokens)]
#![feature(unrestricted_attribute_tokens)]
extern crate derive_b;
......
......@@ -11,7 +11,7 @@
// aux-build:issue-42708.rs
// ignore-stage1
#![feature(decl_macro, proc_macro_path_invoc)]
#![feature(decl_macro)]
#![allow(unused)]
extern crate issue_42708;
......
......@@ -11,7 +11,7 @@
// aux-build:issue-50061.rs
// ignore-stage1
#![feature(proc_macro_path_invoc, decl_macro)]
#![feature(decl_macro)]
extern crate issue_50061;
......
......@@ -10,7 +10,6 @@
// Scoped attributes should not trigger an unused attributes lint.
#![feature(tool_attributes)]
#![deny(unused_attributes)]
fn main() {
......
......@@ -12,8 +12,6 @@
// aux-build:generate-mod.rs
#![feature(proc_macro_gen, proc_macro_path_invoc)]
extern crate generate_mod;
struct FromOutside;
......
error[E0412]: cannot find type `FromOutside` in this scope
--> $DIR/generate-mod.rs:21:1
--> $DIR/generate-mod.rs:19:1
|
LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `Outer` in this scope
--> $DIR/generate-mod.rs:21:1
--> $DIR/generate-mod.rs:19:1
|
LL | generate_mod::check!(); //~ ERROR cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `FromOutside` in this scope
--> $DIR/generate-mod.rs:24:1
--> $DIR/generate-mod.rs:22:1
|
LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `OuterAttr` in this scope
--> $DIR/generate-mod.rs:24:1
--> $DIR/generate-mod.rs:22:1
|
LL | #[generate_mod::check_attr] //~ ERROR cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
warning: cannot find type `FromOutside` in this scope
--> $DIR/generate-mod.rs:28:10
--> $DIR/generate-mod.rs:26:10
|
LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
......@@ -33,7 +33,7 @@ LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside
= note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
warning: cannot find type `OuterDerive` in this scope
--> $DIR/generate-mod.rs:28:10
--> $DIR/generate-mod.rs:26:10
|
LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
......@@ -42,7 +42,7 @@ LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside
= note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
warning: cannot find type `FromOutside` in this scope
--> $DIR/generate-mod.rs:35:14
--> $DIR/generate-mod.rs:33:14
|
LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
......@@ -51,7 +51,7 @@ LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOut
= note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
warning: cannot find type `OuterDerive` in this scope
--> $DIR/generate-mod.rs:35:14
--> $DIR/generate-mod.rs:33:14
|
LL | #[derive(generate_mod::CheckDerive)] //~ WARN cannot find type `FromOutside` in this scope
| ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import
......
......@@ -10,7 +10,7 @@
// Unresolved multi-segment attributes are not treated as custom.
#![feature(custom_attribute, proc_macro_path_invoc)]
#![feature(custom_attribute)]
mod existent {}
......
// 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.
fn main() {
#[rustfmt::skip] //~ ERROR tool attributes are unstable
let x = 3
;
}
error[E0658]: tool attributes are unstable (see issue #44690)
--> $DIR/feature-gate-tool_attributes.rs:12:7
|
LL | #[rustfmt::skip] //~ ERROR tool attributes are unstable
| ^^^^^^^^^^^^^
|
= help: add #![feature(tool_attributes)] to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.
......@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(tool_attributes, custom_attribute)]
#![feature(custom_attribute)]
type A = rustfmt; //~ ERROR expected type, found tool module `rustfmt`
type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::skip`
......
......@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(tool_attributes)]
#[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute
struct S;
......
error: expected a macro, found tool attribute
--> $DIR/tool-attributes-misplaced-2.rs:13:10
--> $DIR/tool-attributes-misplaced-2.rs:11:10
|
LL | #[derive(rustfmt::skip)] //~ ERROR expected a macro, found tool attribute
| ^^^^^^^^^^^^^
error: expected a macro, found tool attribute
--> $DIR/tool-attributes-misplaced-2.rs:17:5
--> $DIR/tool-attributes-misplaced-2.rs:15:5
|
LL | rustfmt::skip!(); //~ ERROR expected a macro, found tool attribute
| ^^^^^^^^^^^^^
......
......@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(tool_attributes, proc_macro_path_invoc)]
mod rustfmt {}
#[rustfmt::skip] //~ ERROR failed to resolve. Could not find `skip` in `rustfmt`
......
error[E0433]: failed to resolve. Could not find `skip` in `rustfmt`
--> $DIR/tool-attributes-shadowing.rs:15:12
--> $DIR/tool-attributes-shadowing.rs:13:12
|
LL | #[rustfmt::skip] //~ ERROR failed to resolve. Could not find `skip` in `rustfmt`
| ^^^^ Could not find `skip` in `rustfmt`
......
......@@ -8,7 +8,5 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(proc_macro_path_invoc)]
#[foo::bar] //~ ERROR failed to resolve. Use of undeclared type or module `foo`
fn main() {}
error[E0433]: failed to resolve. Use of undeclared type or module `foo`
--> $DIR/unknown-tool-name.rs:13:3
--> $DIR/unknown-tool-name.rs:11:3
|
LL | #[foo::bar] //~ ERROR failed to resolve. Use of undeclared type or module `foo`
| ^^^ Use of undeclared type or module `foo`
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册