-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial implementation of declarative macros 2.0 #40847
Conversation
0b2df87
to
d82defb
Compare
cc @rust-lang/compiler @durka @Ericson2314 @SergioBenitez @tikue |
(I'm going to review this too in a few days.) |
src/libsyntax/parse/parser.rs
Outdated
token::Ident(ident) if ident.name == keywords::Macro.name() => { | ||
self.bump(); | ||
let ident = self.parse_ident()?; | ||
let tokens = if self.token == token::OpenDelim(token::Brace) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's usually better to use self.check(&token::OpenDelim(token::Brace))
to populate expected tokens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, will do.
src/libsyntax/parse/parser.rs
Outdated
TokenTree::Delimited(_, ref delimited) => delimited.stream(), | ||
_ => unreachable!(), | ||
} | ||
} else if self.token == token::OpenDelim(token::Paren) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.check(...)
as well
src/libsyntax/parse/parser.rs
Outdated
} | ||
} else if self.token == token::OpenDelim(token::Paren) { | ||
let args = self.parse_token_tree(); | ||
let body = if self.token == token::OpenDelim(token::Brace) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here, plus self.unexpected()
can be used for the else clause.
@@ -783,7 +783,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { | |||
}; | |||
|
|||
if binding.vis == ty::Visibility::Public && | |||
(binding.is_import() || binding.is_extern_crate()) { | |||
(binding.is_import() || binding.is_macro_def()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what this change does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing binding.is_extern_crate()
is a no-op (it's implied by binding.is_import()
), adding binding.is_macro_def()
allows the binding to be accessed from external crates.
src/librustc_resolve/lib.rs
Outdated
@@ -1107,7 +1107,7 @@ pub struct Resolver<'a> { | |||
|
|||
prelude: Option<Module<'a>>, | |||
|
|||
trait_item_map: FxHashMap<(DefId, Name, Namespace), (Def, bool /* has self */)>, | |||
has_self: FxHashSet<DefId>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you leave a comment that this is used only for better diagnostics, not for the resolution algorithm.
(Maybe group all resolver fields of this kind together.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
The RFC draft contains this exception from hygiene rules - "except when matching against names in patterns". |
@petrochenkov I mean something like this: macro n($i:ident) {
m!($i, x); // The resolution of `x` depends on whether `$i` is `foo` or `bar`
}
// Here, we are "matching against names in patterns" with `foo` and `bar`:
macro m {
(foo, $j:ident) => { let $j = 0; $j },
(bar, $j:ident) => { $j },
} |
src/libsyntax_pos/hygiene.rs
Outdated
scope | ||
} | ||
|
||
pub fn glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you leave some, maybe minimal, documentation for the new public interface of SyntaxContext
? What is the intent of these adjustments, where are they used, how do they correspond to Rust code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, added comments.
src/libsyntax/ext/base.rs
Outdated
@@ -530,12 +530,15 @@ pub enum SyntaxExtension { | |||
|
|||
/// An attribute-like procedural macro that derives a builtin trait. | |||
BuiltinDerive(BuiltinDeriveFn), | |||
|
|||
DeclMacro(Box<TTMacroExpander>, Option<Span>), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doc comment here as well, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
fdfd619
to
eaa9bb4
Compare
@petrochenkov I documented the |
@jseyfried |
ca341e3
to
afe7d89
Compare
☔ The latest upstream changes (presumably #40224) made this pull request unmergeable. Please resolve the merge conflicts. |
FWIW, I finished reading (more or less). I'm unhappy with greatly raised complexity and leakage of macros and hygiene into later stages of compilation, I can only hope it will worth it, because the general idea of per-identifier hygiene/resolution/privacy is very attractive. It looks like private-in-public checks are left alone. They are still unhygienic, right? The embargo visitor is terribly pessimistic, if I understand it correctly, but it all can be improved in the future.
I see, I though about pattern-patterns, not macro-patterns. |
I'm afraid this is unavoidable if we want names in macro definitions to have reliable resolutions (as defined in the draft RFC).
Yeah, this doesn't address private-in-public hygiene. I'm currently leaning towards: macro m($i:ident) {
fn $i(_: <type>) {} // <type> must be accessible from the use site (enforced today)
fn f(_: <type>){} // <type> must be accessible from the use site *or* the def site
} After we address #30476, inferred types would also need to be accessible from the use site or the def site.
Indeed. However, this pessimism is needed with the current implementation of procedural macros (#40939), since a procedural macro can rename an identifier and leave the hygiene information (in the span) unchanged. Thus, we must be prepared to resolve arbitrary names at the def site of exported declarative macros. |
@tikue Yeah, in general it's a bug if invoking a macro in an external crate behaves differently than invoking it locally. Could you open an issue (just copy the comment) and cc me? |
Thanks @jseyfried, will do. |
Extend the unused macro lint to macros 2.0 Extends the unused macro lint (added in PR #41907) to macros 2.0 (added in PR #40847). r? @jseyfried
Check types for privacy This PR implements late post factum checking of type privacy, as opposed to early preventive "private-in-public" checking. This will allow to turn private-in-public checks into a lint and make them more heuristic-based, and more aligned with what people may expect (e.g. reachability-based behavior). Types are privacy-checked if they are written explicitly, and also if they are inferred as expression or pattern types. This PR checks "semantic" types and does it unhygienically, this significantly restricts what macros 2.0 (as implemented in #40847) can do (sorry @jseyfried) - they still can use private *names*, but can't use private *types*. This is the most conservative solution, but hopefully it's temporary and can be relaxed in the future, probably using macro contexts of expression/pattern spans. Traits are also checked in preparation for [trait aliases](#41517), which will be able to leak private traits, and macros 2.0 which will be able to leak pretty much anything. This is a [breaking-change], but the code that is not contrived and can be broken by this patch should be guarded by `private_in_public` lint. [Previous crater run](#34537 (comment)) discovered a few abandoned crates that weren't updated since `private_in_public` has been introduced in 2015. cc #34537 https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504 Fixes #30476 Fixes #33479 cc @nikomatsakis r? @eddyb
I'm not entirely sure if this should be happening but it seems that you can't actually implement a trait from outside of a macro while inside a macro unless the Trait doesn't have anything to implement. While the code in #40847 (comment) seems to compile, it only compiles because #![feature(decl_macro)]
trait Tr {
fn f(&self) {
println!("This shouldn't happen");
}
}
pub macro m($t:ty) {
impl Tr for $t {
fn f(&self) {
println!("Run me");
}
}
}
struct S;
m!(S);
fn main() {
S.f(); // "This shouldn't happen"
} |
@whataloadofwhat |
proc_macro: implement `TokenTree`, `TokenKind`, hygienic `quote!`, and other API All new API is gated behind `#![feature(proc_macro)]` and may be used with `#[proc_macro]`, `#[proc_macro_attribute]`, and `#[proc_macro_derive]` procedural macros. More specifically, this PR adds the following in `proc_macro`: ```rust // `TokenStream` constructors: impl TokenStream { fn empty() -> TokenStream { ... } } impl From<TokenTree> for TokenStream { ... } impl From<TokenKind> for TokenStream { ... } impl<T: Into<TokenStream>> FromIterator<T> for TokenStream { ... } macro quote($($t:tt)*) { ... } // A hygienic `TokenStream` quoter // `TokenStream` destructuring: impl TokenStream { fn is_empty(&self) -> bool { ... } } impl IntoIterator for TokenStream { type Item = TokenTree; ... } struct TokenTree { span: Span, kind: TokenKind } impl From<TokenKind> for TokenTree { ... } impl Display for TokenTree { ... } struct Span { ... } // a region of source code along with expansion/hygiene information impl Default for Span { ... } // a span from the current procedural macro definition impl Span { fn call_site() -> Span { ... } } // the call site of the current expansion fn quote_span(span: Span) -> TokenStream; enum TokenKind { Group(Delimiter, TokenStream), // A delimited sequence, e.g. `( ... )` Term(Term), // a unicode identifier, lifetime ('a), or underscore Op(char, Spacing), // a punctuation character (`+`, `,`, `$`, etc.). Literal(Literal), // a literal character (`'a'`), string (`"hello"`), or number (`2.3`) } enum Delimiter { Parenthesis, // `( ... )` Brace, // `[ ... ]` Bracket, // `{ ... }` None, // an implicit delimiter, e.g. `$var`, where $var is `...`. } struct Term { ... } // An interned string impl Term { fn intern(string: &str) -> Symbol { ... } fn as_str(&self) -> &str { ... } } enum Spacing { Alone, // not immediately followed by another `Op`, e.g. `+` in `+ =`. Joint, // immediately followed by another `Op`, e.g. `+` in `+=` } struct Literal { ... } impl Display for Literal { ... } impl Literal { fn integer(n: i128) -> Literal { .. } // unsuffixed integer literal fn float(n: f64) -> Literal { .. } // unsuffixed floating point literal fn u8(n: u8) -> Literal { ... } // similarly: i8, u16, i16, u32, i32, u64, i64, f32, f64 fn string(string: &str) -> Literal { ... } fn character(ch: char) -> Literal { ... } fn byte_string(bytes: &[u8]) -> Literal { ... } } ``` For details on `quote!` hygiene, see [this example](20a9048) and [declarative macros 2.0](#40847). r? @nrc
Check types for privacy This PR implements late post factum checking of type privacy, as opposed to early preventive "private-in-public" checking. This will allow to turn private-in-public checks into a lint and make them more heuristic-based, and more aligned with what people may expect (e.g. reachability-based behavior). Types are privacy-checked if they are written explicitly, and also if they are inferred as expression or pattern types. This PR checks "semantic" types and does it unhygienically, this significantly restricts what macros 2.0 (as implemented in #40847) can do (sorry @jseyfried) - they still can use private *names*, but can't use private *types*. This is the most conservative solution, but hopefully it's temporary and can be relaxed in the future, probably using macro contexts of expression/pattern spans. Traits are also checked in preparation for [trait aliases](#41517), which will be able to leak private traits, and macros 2.0 which will be able to leak pretty much anything. This is a [breaking-change], but the code that is not contrived and can be broken by this patch should be guarded by `private_in_public` lint. [Previous crater run](#34537 (comment)) discovered a few abandoned crates that weren't updated since `private_in_public` has been introduced in 2015. cc #34537 https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504 Fixes #30476 Fixes #33479 cc @nikomatsakis r? @eddyb
Improve resolution of associated types in declarative macros 2.0 Make various identifier comparisons for associated types (and sometimes other associated items) hygienic. Now declarative macros 2.0 can use `Self::AssocTy`, `TyParam::AssocTy`, `Trait<AssocTy = u8>` where `AssocTy` is an associated type of a trait `Trait` visible from the macro. Also, `Trait` can now be implemented inside the macro and specialization should work properly (fixes #40847 (comment)). r? @jseyfried or @eddyb
Improve resolution of associated types in declarative macros 2.0 Make various identifier comparisons for associated types (and sometimes other associated items) hygienic. Now declarative macros 2.0 can use `Self::AssocTy`, `TyParam::AssocTy`, `Trait<AssocTy = u8>` where `AssocTy` is an associated type of a trait `Trait` visible from the macro. Also, `Trait` can now be implemented inside the macro and specialization should work properly (fixes #40847 (comment)). r? @jseyfried or @eddyb
…chenkov Move some tests to more reasonable directories - 4 cc rust-lang#73494 r? `@petrochenkov` - [issues/issue-4201.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-4201.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/4201)</sup>: expr 1.000 - [old-suffixes-are-really-forbidden.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/old-suffixes-are-really-forbidden.rs) <sup>unknown</sup>: parser 1.031 - [typeclasses-eq-example-static.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/typeclasses-eq-example-static.rs) <sup>unknown</sup>: binding 1.033 - [issues/issue-33537.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33537.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/33537)</sup>: consts 1.036 - [issues/issue-31924-non-snake-ffi.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-31924-non-snake-ffi.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/31924)</sup>: lint 1.046 - [issues/issue-44406.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-44406.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/44406)</sup>: parser 1.051 - [type-id-higher-rank.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/type-id-higher-rank.rs) <sup>unknown</sup>: unboxed-closures 1.074 - [issues/issue-20616-3.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-20616-3.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/20616)</sup>: parser 1.077 - [html-literals.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/html-literals.rs) <sup>unknown</sup>: macros 1.083 - [issues/issue-13837.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-13837.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/13837)</sup>: consts 1.089 - [issues/issue-21726.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-21726.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/21726)</sup>: associated-types 1.095 - [one-tuple.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/one-tuple.rs) <sup>unknown</sup>: binding 1.107 - [issues/issue-43784-associated-type.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-43784-associated-type.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/43784)</sup>: associated-types 1.108 - [project-defer-unification.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/project-defer-unification.rs) <sup>unknown</sup>: associated-types 1.109 - [struct-literal-variant-in-if.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/struct-literal-variant-in-if.rs) <sup>unknown</sup>: parser 1.110 - [rvalue-static-promotion.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/rvalue-static-promotion.rs) <sup>unknown</sup>: consts 1.114 - [nullable-pointer-ffi-compat.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/nullable-pointer-ffi-compat.rs) <sup>unknown</sup>: regions 1.129 - [range_inclusive_gate.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/range_inclusive_gate.rs) <sup>unknown</sup>: for-loop-while 1.174 - [simd-type-generic-monomorphisation.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/simd-type-generic-monomorphisation.rs) <sup>unknown</sup>: simd 1.175 - [issues/issue-77993-2.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-77993-2.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/77993)</sup>: async-await 1.183 - [issues/issue-23595-2.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-23595-2.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/23595)</sup>: associated-types 1.194 - [issues/issue-40847.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-40847.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/40847)</sup>: macros 1.194 - [issues/issue-6157.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-6157.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/6157)</sup>: regions 1.195 - [issues/issue-32829.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-32829.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/32829)</sup>: consts 1.241 - [type-sizes.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/type-sizes.rs) <sup>unknown</sup>: structs-enums 1.281 - [issues/issue-24204.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-24204.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/24204)</sup>: associated-types 1.305 - [issues/issue-22560.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-22560.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/22560)</sup>: associated-types 1.354 - [emit-artifact-notifications.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/emit-artifact-notifications.rs) <sup>unknown</sup>: rmeta 1.368 - [repeat_count_const_in_async_fn.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/repeat_count_const_in_async_fn.rs) <sup>unknown</sup>: async-await 1.370 - [expr-if-panic.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/expr-if-panic.rs) <sup>unknown</sup>: expr 1.371 - [cleanup-rvalue-during-if-and-while.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/cleanup-rvalue-during-if-and-while.rs) <sup>unknown</sup>: for-loop-while 1.378 - [write-to-static-mut-in-static.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/write-to-static-mut-in-static.rs) <sup>unknown</sup>: consts 1.381 - [issues/issue-17718-references.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-17718-references.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/17718)</sup>: consts 1.404 - [dotdotdot-expr.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/dotdotdot-expr.rs) <sup>unknown</sup>: parser 1.784 - [regions-fn-subtyping-return-static-fail.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/regions-fn-subtyping-return-static-fail.rs) <sup>unknown</sup>: regions 1.959
…chenkov Move some tests to more reasonable directories - 4 cc rust-lang#73494 r? `@petrochenkov` - [issues/issue-4201.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-4201.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/4201)</sup>: expr 1.000 - [old-suffixes-are-really-forbidden.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/old-suffixes-are-really-forbidden.rs) <sup>unknown</sup>: parser 1.031 - [typeclasses-eq-example-static.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/typeclasses-eq-example-static.rs) <sup>unknown</sup>: binding 1.033 - [issues/issue-33537.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33537.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/33537)</sup>: consts 1.036 - [issues/issue-31924-non-snake-ffi.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-31924-non-snake-ffi.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/31924)</sup>: lint 1.046 - [issues/issue-44406.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-44406.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/44406)</sup>: parser 1.051 - [type-id-higher-rank.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/type-id-higher-rank.rs) <sup>unknown</sup>: unboxed-closures 1.074 - [issues/issue-20616-3.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-20616-3.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/20616)</sup>: parser 1.077 - [html-literals.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/html-literals.rs) <sup>unknown</sup>: macros 1.083 - [issues/issue-13837.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-13837.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/13837)</sup>: consts 1.089 - [issues/issue-21726.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-21726.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/21726)</sup>: associated-types 1.095 - [one-tuple.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/one-tuple.rs) <sup>unknown</sup>: binding 1.107 - [issues/issue-43784-associated-type.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-43784-associated-type.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/43784)</sup>: associated-types 1.108 - [project-defer-unification.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/project-defer-unification.rs) <sup>unknown</sup>: associated-types 1.109 - [struct-literal-variant-in-if.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/struct-literal-variant-in-if.rs) <sup>unknown</sup>: parser 1.110 - [rvalue-static-promotion.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/rvalue-static-promotion.rs) <sup>unknown</sup>: consts 1.114 - [nullable-pointer-ffi-compat.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/nullable-pointer-ffi-compat.rs) <sup>unknown</sup>: regions 1.129 - [range_inclusive_gate.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/range_inclusive_gate.rs) <sup>unknown</sup>: for-loop-while 1.174 - [simd-type-generic-monomorphisation.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/simd-type-generic-monomorphisation.rs) <sup>unknown</sup>: simd 1.175 - [issues/issue-77993-2.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-77993-2.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/77993)</sup>: async-await 1.183 - [issues/issue-23595-2.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-23595-2.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/23595)</sup>: associated-types 1.194 - [issues/issue-40847.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-40847.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/40847)</sup>: macros 1.194 - [issues/issue-6157.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-6157.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/6157)</sup>: regions 1.195 - [issues/issue-32829.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-32829.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/32829)</sup>: consts 1.241 - [type-sizes.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/type-sizes.rs) <sup>unknown</sup>: structs-enums 1.281 - [issues/issue-24204.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-24204.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/24204)</sup>: associated-types 1.305 - [issues/issue-22560.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-22560.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/22560)</sup>: associated-types 1.354 - [emit-artifact-notifications.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/emit-artifact-notifications.rs) <sup>unknown</sup>: rmeta 1.368 - [repeat_count_const_in_async_fn.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/repeat_count_const_in_async_fn.rs) <sup>unknown</sup>: async-await 1.370 - [expr-if-panic.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/expr-if-panic.rs) <sup>unknown</sup>: expr 1.371 - [cleanup-rvalue-during-if-and-while.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/cleanup-rvalue-during-if-and-while.rs) <sup>unknown</sup>: for-loop-while 1.378 - [write-to-static-mut-in-static.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/write-to-static-mut-in-static.rs) <sup>unknown</sup>: consts 1.381 - [issues/issue-17718-references.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-17718-references.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/17718)</sup>: consts 1.404 - [dotdotdot-expr.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/dotdotdot-expr.rs) <sup>unknown</sup>: parser 1.784 - [regions-fn-subtyping-return-static-fail.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/regions-fn-subtyping-return-static-fail.rs) <sup>unknown</sup>: regions 1.959
…chenkov Move some tests to more reasonable directories - 4 cc rust-lang#73494 r? ``@petrochenkov`` - [issues/issue-4201.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-4201.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/4201)</sup>: expr 1.000 - [old-suffixes-are-really-forbidden.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/old-suffixes-are-really-forbidden.rs) <sup>unknown</sup>: parser 1.031 - [typeclasses-eq-example-static.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/typeclasses-eq-example-static.rs) <sup>unknown</sup>: binding 1.033 - [issues/issue-33537.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-33537.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/33537)</sup>: consts 1.036 - [issues/issue-31924-non-snake-ffi.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-31924-non-snake-ffi.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/31924)</sup>: lint 1.046 - [issues/issue-44406.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-44406.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/44406)</sup>: parser 1.051 - [type-id-higher-rank.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/type-id-higher-rank.rs) <sup>unknown</sup>: unboxed-closures 1.074 - [issues/issue-20616-3.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-20616-3.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/20616)</sup>: parser 1.077 - [html-literals.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/html-literals.rs) <sup>unknown</sup>: macros 1.083 - [issues/issue-13837.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-13837.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/13837)</sup>: consts 1.089 - [issues/issue-21726.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-21726.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/21726)</sup>: associated-types 1.095 - [one-tuple.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/one-tuple.rs) <sup>unknown</sup>: binding 1.107 - [issues/issue-43784-associated-type.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-43784-associated-type.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/43784)</sup>: associated-types 1.108 - [project-defer-unification.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/project-defer-unification.rs) <sup>unknown</sup>: associated-types 1.109 - [struct-literal-variant-in-if.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/struct-literal-variant-in-if.rs) <sup>unknown</sup>: parser 1.110 - [rvalue-static-promotion.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/rvalue-static-promotion.rs) <sup>unknown</sup>: consts 1.114 - [nullable-pointer-ffi-compat.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/nullable-pointer-ffi-compat.rs) <sup>unknown</sup>: regions 1.129 - [range_inclusive_gate.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/range_inclusive_gate.rs) <sup>unknown</sup>: for-loop-while 1.174 - [simd-type-generic-monomorphisation.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/simd-type-generic-monomorphisation.rs) <sup>unknown</sup>: simd 1.175 - [issues/issue-77993-2.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-77993-2.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/77993)</sup>: async-await 1.183 - [issues/issue-23595-2.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-23595-2.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/23595)</sup>: associated-types 1.194 - [issues/issue-40847.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-40847.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/40847)</sup>: macros 1.194 - [issues/issue-6157.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-6157.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/6157)</sup>: regions 1.195 - [issues/issue-32829.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-32829.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/32829)</sup>: consts 1.241 - [type-sizes.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/type-sizes.rs) <sup>unknown</sup>: structs-enums 1.281 - [issues/issue-24204.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-24204.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/24204)</sup>: associated-types 1.305 - [issues/issue-22560.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-22560.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/22560)</sup>: associated-types 1.354 - [emit-artifact-notifications.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/emit-artifact-notifications.rs) <sup>unknown</sup>: rmeta 1.368 - [repeat_count_const_in_async_fn.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/repeat_count_const_in_async_fn.rs) <sup>unknown</sup>: async-await 1.370 - [expr-if-panic.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/expr-if-panic.rs) <sup>unknown</sup>: expr 1.371 - [cleanup-rvalue-during-if-and-while.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/cleanup-rvalue-during-if-and-while.rs) <sup>unknown</sup>: for-loop-while 1.378 - [write-to-static-mut-in-static.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/write-to-static-mut-in-static.rs) <sup>unknown</sup>: consts 1.381 - [issues/issue-17718-references.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/issues/issue-17718-references.rs) <sup>[issue](https://github.com/rust-lang/rust/issues/17718)</sup>: consts 1.404 - [dotdotdot-expr.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/dotdotdot-expr.rs) <sup>unknown</sup>: parser 1.784 - [regions-fn-subtyping-return-static-fail.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/regions-fn-subtyping-return-static-fail.rs) <sup>unknown</sup>: regions 1.959
Implement declarative macros 2.0 (rust-lang/rfcs#1584) behind
#![feature(decl_macro)]
.Differences from
macro_rules!
include:macro m(..) { .. }
instead ofmacro_rules! m { (..) => { .. } }
fn f() { <body> }
resolves,pub macro m() { <body> } ... m!()
also resolves, even ifm!()
is in a separate crate.::foo::bar
in amacro
behaves like$crate::foo::bar
in amacro_rules!
, except it can access everything visible from themacro
(thus more permissive).src/test/{run-pass, compile-fail}/hygiene
for examples. Small example:Limitations:
expr
,ty
, etc.), c.f. Macro matching is incorrect for macros invoked in macro expansions #26361.unsafe
are not hygienic.macro
inside anothermacro
) don't always work correctly when invoked from external crates.r? @nrc