diff options
| author | bors <bors@rust-lang.org> | 2017-05-25 22:31:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-05-25 22:31:34 +0000 |
| commit | 4f9c9ed1a53d176fb0650042f226222f401c21eb (patch) | |
| tree | 4032674e5d87460e1483240a2471c3b031d9b0cc /src/rustllvm/RustWrapper.cpp | |
| parent | 5f39668642e445fedcf477493f206905dc51c2c8 (diff) | |
| parent | dc34ea092976ab9a87e68f1b255b4afbe31a9475 (diff) | |
| download | rust-4f9c9ed1a53d176fb0650042f226222f401c21eb.tar.gz rust-4f9c9ed1a53d176fb0650042f226222f401c21eb.zip | |
Auto merge of #40847 - jseyfried:decl_macro, r=nrc
Initial implementation of declarative macros 2.0
Implement declarative macros 2.0 (rust-lang/rfcs#1584) behind `#![feature(decl_macro)]`.
Differences from `macro_rules!` include:
- new syntax: `macro m(..) { .. }` instead of `macro_rules! m { (..) => { .. } }`
- declarative macros are items:
```rust
// crate A:
pub mod foo {
m!(); // use before definition; declaration order is irrelevant
pub macro m() {} // `pub`, `pub(super)`, etc. work
}
fn main() {
foo::m!(); // named like other items
{ use foo::m as n; n!(); } // imported like other items
}
pub use foo::m; // re-exported like other items
// crate B:
extern crate A; // no need for `#[macro_use]`
A::foo::m!(); A::m!();
```
- Racket-like hygiene for items, imports, methods, fields, type parameters, privacy, etc.
- Intuitively, names in a macro definition are resolved in the macro definition's scope, not the scope in which the macro is used.
- This [explaination](http://beautifulracket.com/explainer/hygiene.html) of hygiene for Racket applies here (except for the "Breaking Hygiene" section). I wrote a similar [explanation](https://github.com/jseyfried/rfcs/blob/hygiene/text/0000-hygiene.md) for Rust.
- Generally speaking, if `fn f() { <body> }` resolves, `pub macro m() { <body> } ... m!()` also resolves, even if `m!()` is in a separate crate.
- `::foo::bar` in a `macro` behaves like `$crate::foo::bar` in a `macro_rules!`, except it can access everything visible from the `macro` (thus more permissive).
- See [`src/test/{run-pass, compile-fail}/hygiene`](https://github.com/rust-lang/rust/pull/40847/commits/afe7d89858fd72b983e24727d6f4058293153c19) for examples. Small example:
```rust
mod foo {
fn f() { println!("hello world"); }
pub macro m() { f(); }
}
fn main() { foo::m!(); }
```
Limitations:
- This does not address planned changes to matchers (`expr`,`ty`, etc.), c.f. #26361.
- Lints (including stability and deprecation) and `unsafe` are not hygienic.
- adding hygiene here will be mostly or entirely backwards compatible
- Nested macro definitions (a `macro` inside another `macro`) don't always work correctly when invoked from external crates.
- pending improvements in how we encode macro definitions in crate metadata
- There is no way to "escape" hygiene without using a procedural macro.
r? @nrc
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
0 files changed, 0 insertions, 0 deletions
