Commit Graph

162 Commits

Author SHA1 Message Date
Alex Crichton
e5e7021ca5 rustc: Tweak expansion order of custom derive
This commit alters the expansion order of custom macros-1.1 style `#[derive]`
modes. Instead of left-to-right the expansion now happens in three categories,
each of which is internally left-to-right:

* Old-style custom derive (`#[derive_Foo]`) is expanded
* New-style custom derive (macros 1.1) is expanded
* Built in derive modes are expanded

This gives built in derive modes maximal knowledge about the struct that's being
expanded and also avoids pesky issues like exposing `#[structural_match]` or
`#[rustc_copy_clone_marker]`.

cc #35900
2016-09-27 12:41:02 -07:00
Tim Neumann
b0dba7439d make emit_feature_err take a ParseSess 2016-09-26 07:07:41 +02:00
Jeffrey Seyfried
b4906a93a0 Load macros from #[macro_use] extern crates in resolve. 2016-09-24 20:22:25 +00:00
bors
3a5d975fdc Auto merge of #36154 - nrc:proc-macro-init, r=@jseyfried
Adds a `ProcMacro` form of syntax extension

This commit adds syntax extension forms matching the types for procedural macros 2.0 (RFC #1566), these still require the usual syntax extension boiler plate, but this is a first step towards proper implementation and should be useful for macros 1.1 stuff too.

Supports both attribute-like and function-like macros.

Note that RFC #1566 has not been accepted yet, but I think there is consensus that we want to head in vaguely that direction and so this PR will be useful in any case. It is also fairly easy to undo and does not break any existing programs.

This is related to #35957 in that I hope it can be used in the implementation of macros 1.1, however, there is no direct overlap and is more of a complement than a competing proposal. There is still a fair bit of work to do before the two can be combined.

r? @jseyfried

cc @alexcrichton, @cgswords, @eddyb, @aturon
2016-09-22 16:33:41 -07:00
Nick Cameron
3863834d9c reviewer comments and rebasing 2016-09-23 07:19:31 +12:00
Eduard Burtescu
fc363cb482 rustc_metadata: go only through rustc_serialize in astencode. 2016-09-20 20:07:54 +03:00
Jeffrey Seyfried
2abdc8805c Remove MacroRulesTT. 2016-09-15 21:16:51 +00:00
Manish Goregaokar
bab9238a1e Rollup merge of #36438 - jseyfried:node_ids_in_expansion, r=nrc
Assign node ids during macro expansion

After this PR,
 - The `ExtCtxt` can access `resolve`'s `Resolver` through the trait object `ext::base::Resolver`.
  - The `Resolver` trait object can load macros and replaces today's `MacroLoader` trait object.
  - The macro expander uses the `Resolver` trait object to resolve macro invocations.
 - The macro expander assigns node ids and builds the `Resolver`'s `macros_at_scope` map.
   - This is groundwork for merging import resolution and expansion.
 - Performance of expansion together with node id assignment improves by ~5%.

**EDIT:** Since Github is reordering the commits, here is `git log`:
 - b54e1e3997: Differentiate between monotonic and non-monotonic expansion and only assign node ids during monotonic expansion.
 - 78c0039878: Expand generated test harnesses and macro registries.
 - f3c2dca353: Remove scope placeholders from the crate root.
 - c86c8d41a2: Perform node id assignment and `macros_at_scope` construction during the `InvocationCollector` and `PlaceholderExpander` folds.
 - 72a636975f: Move macro resolution into `librustc_resolve`.
 - 20b43b2323: Rewrite the unit tests in `ext/expand.rs` as a `compile-fail` test.
 - a9821e1658: Refactor `ExtCtxt` to use a `Resolver` instead of a `MacroLoader`.
 - 60440b226d: Refactor `noop_fold_stmt_kind` out of `noop_fold_stmt`.
 - 50f94f6c95: Avoid needless reexpansions.

r? @nrc
2016-09-15 18:16:21 +05:30
Manish Goregaokar
726850170d Rollup merge of #36384 - petrochenkov:derclone, r=alexcrichton
Improve shallow `Clone` deriving

`Copy` unions now support `#[derive(Clone)]`.
Less code is generated for `#[derive(Clone, Copy)]`.
+
Unions now support `#[derive(Eq)]`.
Less code is generated for `#[derive(Eq)]`.

---
Example of code reduction:
```
enum E {
	A { a: u8, b: u16 },
	B { c: [u8; 100] },
}
```
Before:
```
fn clone(&self) -> E {
    match (&*self,) {
        (&E::A { a: ref __self_0, b: ref __self_1 },) => {
            ::std::clone::assert_receiver_is_clone(&(*__self_0));
            ::std::clone::assert_receiver_is_clone(&(*__self_1));
            *self
        }
        (&E::B { c: ref __self_0 },) => {
            ::std::clone::assert_receiver_is_clone(&(*__self_0));
            *self
        }
    }
}
```
After:
```
fn clone(&self) -> E {
    {
        let _: ::std::clone::AssertParamIsClone<u8>;
        let _: ::std::clone::AssertParamIsClone<u16>;
        let _: ::std::clone::AssertParamIsClone<[u8; 100]>;
        *self
    }
}
```

All the matches are removed, bound assertions are more lightweight.
`let _: Checker<CheckMe>;`, unlike `checker(&check_me);`, doesn't have to be translated by rustc_trans and then inlined by LLVM, it doesn't even exist in MIR, this means faster compilation.

---
Union impls are generated like this:
```
union U {
	a: u8,
	b: u16,
	c: [u8; 100],
}
```
```
fn clone(&self) -> U {
    {
        let _: ::std::clone::AssertParamIsCopy<Self>;
        *self
    }
}
```

Fixes https://github.com/rust-lang/rust/issues/36043
cc @durka
r? @alexcrichton
2016-09-15 18:16:19 +05:30
Jeffrey Seyfried
b54e1e3997 Differentiate between monotonic and non-monotonic expansion and
only assign node ids during monotonic expansion.
2016-09-13 09:40:28 +00:00
Jeffrey Seyfried
78c0039878 Expand generated test harnesses and macro registries. 2016-09-13 09:40:28 +00:00
Jeffrey Seyfried
72a636975f Move macro resolution into librustc_resolve. 2016-09-13 09:40:26 +00:00
Jeffrey Seyfried
a9821e1658 Refactor ExtCtxt to use a Resolver instead of a MacroLoader. 2016-09-13 05:31:16 +00:00
Jeffrey Seyfried
50f94f6c95 Avoid needless reexpansions. 2016-09-13 05:11:45 +00:00
bors
0be88eb794 Auto merge of #36308 - dtolnay:inputitem, r=alexcrichton
Point macros 1.1 errors to the input item

Moved from https://github.com/alexcrichton/rust/pull/6 to continue discussion. Fixes #36218.

Before:

```rust
error[E0106]: missing lifetime specifier
  --> src/main.rs:10:10
   |
10 | #[derive(Serialize, Deserialize)]
   |          ^ expected lifetime parameter

error[E0038]: the trait `T` cannot be made into an object
  --> src/main.rs:15:15
   |
15 | #[derive(Serialize, Deserialize)]
   |          ^^^^^^^^^^ the trait `T` cannot be made into an object
```

After:

```rust
error[E0106]: missing lifetime specifier
  --> src/main.rs:11:1
   |
11 | struct A {
   | ^ expected lifetime parameter

error[E0038]: the trait `T` cannot be made into an object
  --> src/main.rs:16:1
   |
16 | struct B<'a> {
   | ^ the trait `T` cannot be made into an object
```
2016-09-11 15:12:27 -07:00
Vadim Petrochenkov
62cb7510ac Improve Eq deriving 2016-09-10 22:37:06 +03:00
Vadim Petrochenkov
2a2c9d38c7 Improve shallow Clone deriving 2016-09-10 18:43:27 +03:00
David Tolnay
fe41520fce Add ExpnId to expanded procedural macro code 2016-09-09 18:50:05 -07:00
Jeffrey Seyfried
f84d081a7e Avoid instaiblity errors in code generated by syntax_ext::deriving::call_intrinsic(). 2016-09-07 07:38:26 +00:00
David Tolnay
3784067edc Point macros 1.1 errors to the input item
Before:

```rust
error[E0106]: missing lifetime specifier
  --> src/main.rs:10:10
   |
10 | #[derive(Serialize, Deserialize)]
   |          ^ expected lifetime parameter

error[E0038]: the trait `T` cannot be made into an object
  --> src/main.rs:15:15
   |
15 | #[derive(Serialize, Deserialize)]
   |          ^^^^^^^^^^ the trait `T` cannot be made into an object
```

After:

```rust
error[E0106]: missing lifetime specifier
  --> src/main.rs:11:1
   |
11 | struct A {
   | ^ expected lifetime parameter

error[E0038]: the trait `T` cannot be made into an object
  --> src/main.rs:16:1
   |
16 | struct B<'a> {
   | ^ the trait `T` cannot be made into an object
```
2016-09-06 14:11:19 -07:00
Vadim Petrochenkov
e05e74ac83 Replace _, _ with .. 2016-09-04 12:30:33 +03:00
Vadim Petrochenkov
59ccb7b6db Support deriving some traits for unions 2016-09-03 13:39:35 +03:00
Alex Crichton
ecc6c39e87 rustc: Implement custom derive (macros 1.1)
This commit is an implementation of [RFC 1681] which adds support to the
compiler for first-class user-define custom `#[derive]` modes with a far more
stable API than plugins have today.

[RFC 1681]: https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md

The main features added by this commit are:

* A new `rustc-macro` crate-type. This crate type represents one which will
  provide custom `derive` implementations and perhaps eventually flower into the
  implementation of macros 2.0 as well.

* A new `rustc_macro` crate in the standard distribution. This crate will
  provide the runtime interface between macro crates and the compiler. The API
  here is particularly conservative right now but has quite a bit of room to
  expand into any manner of APIs required by macro authors.

* The ability to load new derive modes through the `#[macro_use]` annotations on
  other crates.

All support added here is gated behind the `rustc_macro` feature gate, both for
the library support (the `rustc_macro` crate) as well as the language features.

There are a few minor differences from the implementation outlined in the RFC,
such as the `rustc_macro` crate being available as a dylib and all symbols are
`dlsym`'d directly instead of having a shim compiled. These should only affect
the implementation, however, not the public interface.

This commit also ended up touching a lot of code related to `#[derive]`, making
a few notable changes:

* Recognized derive attributes are no longer desugared to `derive_Foo`. Wasn't
  sure how to keep this behavior and *not* expose it to custom derive.

* Derive attributes no longer have access to unstable features by default, they
  have to opt in on a granular level.

* The `derive(Copy,Clone)` optimization is now done through another "obscure
  attribute" which is just intended to ferry along in the compiler that such an
  optimization is possible. The `derive(PartialEq,Eq)` optimization was also
  updated to do something similar.

---

One part of this PR which needs to be improved before stabilizing are the errors
and exact interfaces here. The error messages are relatively poor quality and
there are surprising spects of this such as `#[derive(PartialEq, Eq, MyTrait)]`
not working by default. The custom attributes added by the compiler end up
becoming unstable again when going through a custom impl.

Hopefully though this is enough to start allowing experimentation on crates.io!

syntax-[breaking-change]
2016-09-02 12:52:56 -07:00
Jeffrey Seyfried
02f081c0b5 Future proof libsyntax_ext for union. 2016-08-30 05:53:33 +00:00
Jeffrey Seyfried
c14ff2884d Rollup merge of #35917 - jseyfried:remove_attr_ext_traits, r=nrc
syntax: Remove traits `AttrMetaMethods`, `AttributeMethods`, and `AttrNestedMetaItemMethods`
2016-08-28 10:40:04 +00:00
Jeffrey Seyfried
6303640e85 Rollup merge of #35850 - SergioBenitez:master, r=nrc
Implement RFC#1559: allow all literals in attributes

Implemented rust-lang/rfcs#1559, tracked by #34981.
2016-08-28 10:38:19 +00:00
Jeffrey Seyfried
413ecdee30 Rollup merge of #35728 - petrochenkov:empderive, r=manishearth
Fix #[derive] for empty tuple structs/variants

This was missing from https://github.com/rust-lang/rust/pull/35138
2016-08-28 10:34:50 +00:00
Jeffrey Seyfried
bd38e890ee Rollup merge of #35480 - KiChjang:e0379-bonus, r=nikomatsakis
Move E0379 check from typeck to ast validation

Part of #35233.
Extension of #35338, #35364.
Fixes #35404.
2016-08-28 10:32:52 +00:00
Keith Yeung
aa5c4bb05d Change Constness to Spanned<Constness> 2016-08-27 22:43:51 -07:00
Jeffrey Seyfried
bfb01bbb26 Refactor away AttrMetaMethods. 2016-08-25 20:41:40 +00:00
Jeffrey Seyfried
4eb08bb2ab Refactor away AttrNestedMetaItemMethods. 2016-08-25 20:41:32 +00:00
Sergio Benitez
8250a26b5b Implement RFC#1559: allow all literals in attributes. 2016-08-25 13:25:22 -07:00
Guillaume Gomez
5948182367 Add Span field for Generics structs 2016-08-18 18:23:36 +02:00
Vadim Petrochenkov
f6e06a8a36 Split AstBuilder::pat_enum into pat_tuple_struct and pat_path 2016-08-18 01:33:18 +03:00
Vadim Petrochenkov
28ed8b1592 Fix #[derive] for empty tuple structs/variants 2016-08-18 01:07:32 +03:00
Srinivas Reddy Thatiparthy
d652639524
run rustfmt on libsyntax_ext folder 2016-08-12 09:40:12 +05:30
Manish Goregaokar
0b64a561f6 Rollup merge of #35106 - xen0n:issue-35082, r=alexcrichton
syntax_ext: format: fix ICE with bad named arguments

Fixes #35082 by guarding against a new case of malformed invocation not previously covered.

r? @alexcrichton
2016-07-30 13:44:47 +05:30
Wang Xuerui
2a41b31a88
syntax_ext: format: fix ICE with bad named arguments 2016-07-29 16:40:10 +08:00
cgswords
a5e5ea1646 General MetaItem encapsulation rewrites. 2016-07-25 14:27:10 -07:00
Srinivas Reddy Thatiparthy
9652fcbb6e
Run rustfmt on libsyntax_ext/deriving folder 2016-07-19 23:07:57 +05:30
Wang Xuerui
51e54e57a4
syntax_ext: format: better code documentation 2016-07-14 03:10:47 +08:00
Wang Xuerui
718099435b
syntax_ext: format: de-duplicate argument objects 2016-07-14 03:10:46 +08:00
Wang Xuerui
f457e6c3e0
syntax_ext: format: process counts uniquely and separately 2016-07-14 03:10:46 +08:00
Wang Xuerui
5e55a44116
syntax_ext: format: allow multiple formats for one argument
This commit removed the restriction of only allowing one type per argument.
This is achieved by adding mappings between macro arguments and format
placeholders, then taking the mapping into consideration when emitting
the Arguments expression.

syntax_ext: format: fix implicit positional arguments

syntax_ext: format: don't panic if no args given for implicit positional args

Check the list lengths before use.
Fixes regression of `compile-fail/macro-backtrace-println.rs`.

syntax_ext: format: also map CountIsParam indices to expanded args

syntax_ext: format: fix ICE in case of malformed format args
2016-07-14 03:10:45 +08:00
Wang Xuerui
eb5417bf12
syntax_ext: format: rename variants of ArgumentType for clarity 2016-07-14 03:10:45 +08:00
Wang Xuerui
1ace7f0d49
syntax_ext: format: resolve named arguments early
Converts named argument references into indices, right after
verification as suggested by @alexcrichton. This drastically simplifies
the whole process!
2016-07-14 03:10:44 +08:00
Wang Xuerui
0e2a96321a
syntax_ext: format: separate verification and translation of pieces 2016-07-14 02:55:33 +08:00
Wang Xuerui
06b034ae8b
format: remove all implicit ref handling outside of libfmt_macros
format: beautifully get rid of ArgumentNext and CountIsNextParam

Now that CountIsNextParam and ArgumentNext are resolved during parse,
the need for handling them outside of libfmt_macros is obviated.

Note: *one* instance of implicit reference handling still remains, and
that's for implementing `all_args_simple`. It's trivial enough though,
so in this case it may be tolerable.
2016-07-14 02:54:47 +08:00
CensoredUsername
e32da12753 Correct inline assembly clobber formatting.
Fixes the formatting for inline assembly clobbers used in the book.
As this causes llvm to silently ignore the clobber an error is also
added to catch cases in which the wrong formatting was used.
Additionally a test case is added to confirm that this error works.
2016-07-06 15:02:49 +02:00
Zack M. Davis
d37edef9dd prefer if let to match with None => {} arm in some places
This is a spiritual succesor to #34268/8531d581, in which we replaced a
number of matches of None to the unit value with `if let` conditionals
where it was judged that this made for clearer/simpler code (as would be
recommended by Manishearth/rust-clippy's `single_match` lint). The same
rationale applies to matches of None to the empty block.
2016-07-03 16:27:02 -07:00