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-08-22 17:07:11 -07:00
|
|
|
use std::mem;
|
|
|
|
|
2020-02-29 20:37:32 +03:00
|
|
|
use rustc_ast::attr;
|
|
|
|
use rustc_ast::ptr::P;
|
|
|
|
use rustc_ast::visit::{self, Visitor};
|
2020-04-27 23:26:11 +05:30
|
|
|
use rustc_ast::{self as ast, NodeId};
|
2020-01-11 17:02:46 +01:00
|
|
|
use rustc_ast_pretty::pprust;
|
2021-07-10 17:16:53 +03:00
|
|
|
use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand};
|
2019-12-29 17:23:55 +03:00
|
|
|
use rustc_expand::expand::{AstFragment, ExpansionConfig};
|
2020-07-30 11:27:50 +10:00
|
|
|
use rustc_session::Session;
|
2019-12-31 20:15:40 +03:00
|
|
|
use rustc_span::hygiene::AstPass;
|
2020-03-22 12:38:50 +03:00
|
|
|
use rustc_span::source_map::SourceMap;
|
2020-04-19 13:00:18 +02:00
|
|
|
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
2019-12-31 20:15:40 +03:00
|
|
|
use rustc_span::{Span, DUMMY_SP};
|
2019-08-14 02:30:09 +03:00
|
|
|
use smallvec::smallvec;
|
2020-02-03 18:34:36 -05:00
|
|
|
use std::cell::RefCell;
|
2017-01-09 01:31:14 -08:00
|
|
|
|
2017-01-24 08:55:08 +10:30
|
|
|
struct ProcMacroDerive {
|
2020-02-03 18:34:36 -05:00
|
|
|
id: NodeId,
|
2020-04-19 13:00:18 +02:00
|
|
|
trait_name: Symbol,
|
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-08-22 17:07:11 -07:00
|
|
|
function_name: Ident,
|
|
|
|
span: Span,
|
2020-04-19 13:00:18 +02:00
|
|
|
attrs: Vec<Symbol>,
|
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-08-22 17:07:11 -07:00
|
|
|
}
|
|
|
|
|
2019-09-17 19:07:35 -04:00
|
|
|
enum ProcMacroDefType {
|
|
|
|
Attr,
|
2019-12-22 17:42:04 -05:00
|
|
|
Bang,
|
2019-09-17 19:07:35 -04:00
|
|
|
}
|
|
|
|
|
2017-02-27 12:03:19 -08:00
|
|
|
struct ProcMacroDef {
|
2020-02-03 18:34:36 -05:00
|
|
|
id: NodeId,
|
2017-01-09 01:31:14 -08:00
|
|
|
function_name: Ident,
|
|
|
|
span: Span,
|
2019-12-22 17:42:04 -05:00
|
|
|
def_type: ProcMacroDefType,
|
2019-09-17 19:07:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
enum ProcMacro {
|
|
|
|
Derive(ProcMacroDerive),
|
2019-12-22 17:42:04 -05:00
|
|
|
Def(ProcMacroDef),
|
2017-01-09 01:31:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
struct CollectProcMacros<'a> {
|
2020-07-30 11:27:50 +10:00
|
|
|
sess: &'a Session,
|
2019-09-17 19:07:35 -04:00
|
|
|
macros: Vec<ProcMacro>,
|
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-08-22 17:07:11 -07:00
|
|
|
in_root: bool,
|
2020-01-09 11:18:47 +01:00
|
|
|
handler: &'a rustc_errors::Handler,
|
2020-03-22 12:38:50 +03:00
|
|
|
source_map: &'a SourceMap,
|
2016-10-03 09:49:39 -07:00
|
|
|
is_proc_macro_crate: bool,
|
2016-11-17 22:06:36 +10:30
|
|
|
is_test_crate: bool,
|
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-08-22 17:07:11 -07:00
|
|
|
}
|
|
|
|
|
2019-12-22 17:42:04 -05:00
|
|
|
pub fn inject(
|
2020-07-30 11:27:50 +10:00
|
|
|
sess: &Session,
|
2020-06-27 23:51:28 +03:00
|
|
|
resolver: &mut dyn ResolverExpand,
|
2019-12-22 17:42:04 -05:00
|
|
|
mut krate: ast::Crate,
|
|
|
|
is_proc_macro_crate: bool,
|
|
|
|
has_proc_macro_decls: bool,
|
|
|
|
is_test_crate: bool,
|
|
|
|
num_crate_types: usize,
|
2020-01-09 11:18:47 +01:00
|
|
|
handler: &rustc_errors::Handler,
|
2019-12-22 17:42:04 -05:00
|
|
|
) -> ast::Crate {
|
2016-10-03 09:49:39 -07:00
|
|
|
let ecfg = ExpansionConfig::default("proc_macro".to_string());
|
2020-03-16 00:43:37 +01:00
|
|
|
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);
|
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-08-22 17:07:11 -07:00
|
|
|
|
2019-09-17 19:07:35 -04:00
|
|
|
let mut collect = CollectProcMacros {
|
2020-07-30 11:27:50 +10:00
|
|
|
sess,
|
2019-09-17 19:07:35 -04:00
|
|
|
macros: Vec::new(),
|
|
|
|
in_root: true,
|
|
|
|
handler,
|
2020-03-22 12:38:50 +03:00
|
|
|
source_map: sess.source_map(),
|
2019-09-17 19:07:35 -04:00
|
|
|
is_proc_macro_crate,
|
|
|
|
is_test_crate,
|
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-08-22 17:07:11 -07:00
|
|
|
};
|
|
|
|
|
2019-09-17 19:07:35 -04:00
|
|
|
if has_proc_macro_decls || is_proc_macro_crate {
|
|
|
|
visit::walk_crate(&mut collect, &krate);
|
|
|
|
}
|
|
|
|
let macros = collect.macros;
|
|
|
|
|
2016-10-03 09:49:39 -07:00
|
|
|
if !is_proc_macro_crate {
|
2019-12-22 17:42:04 -05:00
|
|
|
return krate;
|
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-08-22 17:07:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if num_crate_types > 1 {
|
2016-10-03 09:49:39 -07:00
|
|
|
handler.err("cannot mix `proc-macro` crate type with others");
|
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-08-22 17:07:11 -07:00
|
|
|
}
|
|
|
|
|
2016-11-22 00:02:58 +10:30
|
|
|
if is_test_crate {
|
|
|
|
return krate;
|
|
|
|
}
|
|
|
|
|
2020-02-03 18:34:36 -05:00
|
|
|
let decls = mk_decls(&mut krate, &mut cx, ¯os);
|
2021-02-14 21:14:12 +03:00
|
|
|
krate.items.push(decls);
|
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-08-22 17:07:11 -07:00
|
|
|
|
2017-03-05 05:15:58 +00:00
|
|
|
krate
|
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-08-22 17:07:11 -07:00
|
|
|
}
|
|
|
|
|
2017-01-09 01:31:14 -08:00
|
|
|
impl<'a> CollectProcMacros<'a> {
|
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-08-22 17:07:11 -07:00
|
|
|
fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
|
2020-08-21 19:11:00 -04:00
|
|
|
if self.is_proc_macro_crate && self.in_root && vis.kind.is_pub() {
|
2019-11-10 19:20:00 +01:00
|
|
|
self.handler.span_err(
|
|
|
|
sp,
|
|
|
|
"`proc-macro` crate types currently cannot export any items other \
|
|
|
|
than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, \
|
|
|
|
or `#[proc_macro_attribute]`",
|
|
|
|
);
|
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-08-22 17:07:11 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-09 01:31:14 -08:00
|
|
|
fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
|
2021-07-10 17:16:53 +03:00
|
|
|
let (trait_name, proc_attrs) =
|
|
|
|
match parse_macro_name_and_helper_attrs(self.handler, attr, "derive") {
|
|
|
|
Some(name_and_attrs) => name_and_attrs,
|
|
|
|
None => return,
|
|
|
|
};
|
2016-11-08 21:45:02 +10:30
|
|
|
|
2020-08-21 19:11:00 -04:00
|
|
|
if self.in_root && item.vis.kind.is_pub() {
|
2019-09-17 19:07:35 -04:00
|
|
|
self.macros.push(ProcMacro::Derive(ProcMacroDerive {
|
2020-02-03 18:34:36 -05:00
|
|
|
id: item.id,
|
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-08-22 17:07:11 -07:00
|
|
|
span: item.span,
|
2021-07-10 17:16:53 +03:00
|
|
|
trait_name,
|
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-08-22 17:07:11 -07:00
|
|
|
function_name: item.ident,
|
2016-11-08 21:45:02 +10:30
|
|
|
attrs: proc_attrs,
|
2019-09-17 19:07:35 -04:00
|
|
|
}));
|
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-08-22 17:07:11 -07:00
|
|
|
} else {
|
2016-12-03 02:00:17 +00:00
|
|
|
let msg = if !self.in_root {
|
|
|
|
"functions tagged with `#[proc_macro_derive]` must \
|
|
|
|
currently reside in the root of the crate"
|
|
|
|
} else {
|
|
|
|
"functions tagged with `#[proc_macro_derive]` must be `pub`"
|
|
|
|
};
|
2020-03-09 11:42:37 -07:00
|
|
|
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
|
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-08-22 17:07:11 -07:00
|
|
|
}
|
2017-01-09 01:31:14 -08:00
|
|
|
}
|
|
|
|
|
2019-01-02 02:21:05 +03:00
|
|
|
fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) {
|
2020-08-21 19:11:00 -04:00
|
|
|
if self.in_root && item.vis.kind.is_pub() {
|
2019-09-17 19:07:35 -04:00
|
|
|
self.macros.push(ProcMacro::Def(ProcMacroDef {
|
2020-02-03 18:34:36 -05:00
|
|
|
id: item.id,
|
2017-01-09 01:31:14 -08:00
|
|
|
span: item.span,
|
|
|
|
function_name: item.ident,
|
2019-12-22 17:42:04 -05:00
|
|
|
def_type: ProcMacroDefType::Attr,
|
2019-09-17 19:07:35 -04:00
|
|
|
}));
|
2017-01-09 01:31:14 -08:00
|
|
|
} else {
|
|
|
|
let msg = if !self.in_root {
|
|
|
|
"functions tagged with `#[proc_macro_attribute]` must \
|
|
|
|
currently reside in the root of the crate"
|
|
|
|
} else {
|
|
|
|
"functions tagged with `#[proc_macro_attribute]` must be `pub`"
|
|
|
|
};
|
2020-03-09 11:42:37 -07:00
|
|
|
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
|
2017-01-09 01:31:14 -08:00
|
|
|
}
|
|
|
|
}
|
2017-02-27 12:03:19 -08:00
|
|
|
|
2019-01-02 02:21:05 +03:00
|
|
|
fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
|
2020-08-21 19:11:00 -04:00
|
|
|
if self.in_root && item.vis.kind.is_pub() {
|
2019-09-17 19:07:35 -04:00
|
|
|
self.macros.push(ProcMacro::Def(ProcMacroDef {
|
2020-02-03 18:34:36 -05:00
|
|
|
id: item.id,
|
2017-02-27 12:03:19 -08:00
|
|
|
span: item.span,
|
|
|
|
function_name: item.ident,
|
2019-12-22 17:42:04 -05:00
|
|
|
def_type: ProcMacroDefType::Bang,
|
2019-09-17 19:07:35 -04:00
|
|
|
}));
|
2017-02-27 12:03:19 -08:00
|
|
|
} else {
|
|
|
|
let msg = if !self.in_root {
|
|
|
|
"functions tagged with `#[proc_macro]` must \
|
|
|
|
currently reside in the root of the crate"
|
|
|
|
} else {
|
|
|
|
"functions tagged with `#[proc_macro]` must be `pub`"
|
|
|
|
};
|
2020-03-09 11:42:37 -07:00
|
|
|
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
|
2017-02-27 12:03:19 -08:00
|
|
|
}
|
|
|
|
}
|
2017-01-09 01:31:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Visitor<'a> for CollectProcMacros<'a> {
|
|
|
|
fn visit_item(&mut self, item: &'a ast::Item) {
|
2019-09-26 17:51:36 +01:00
|
|
|
if let ast::ItemKind::MacroDef(..) = item.kind {
|
2020-07-30 11:27:50 +10:00
|
|
|
if self.is_proc_macro_crate && self.sess.contains_name(&item.attrs, sym::macro_export) {
|
2017-03-05 05:15:58 +00:00
|
|
|
let msg =
|
|
|
|
"cannot export macro_rules! macros from a `proc-macro` crate type currently";
|
2020-03-09 11:42:37 -07:00
|
|
|
self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
|
2017-03-05 05:15:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-09 01:31:14 -08:00
|
|
|
// First up, make sure we're checking a bare function. If we're not then
|
|
|
|
// we're just not interested in this item.
|
|
|
|
//
|
2019-02-28 22:43:53 +00:00
|
|
|
// If we find one, try to locate a `#[proc_macro_derive]` attribute on it.
|
2020-12-24 02:55:21 +01:00
|
|
|
let is_fn = matches!(item.kind, ast::ItemKind::Fn(..));
|
2017-01-09 01:31:14 -08:00
|
|
|
|
|
|
|
let mut found_attr: Option<&'a ast::Attribute> = None;
|
|
|
|
|
|
|
|
for attr in &item.attrs {
|
2020-07-30 11:27:50 +10:00
|
|
|
if self.sess.is_proc_macro_attr(&attr) {
|
2017-01-09 01:31:14 -08:00
|
|
|
if let Some(prev_attr) = found_attr {
|
2019-10-24 06:33:12 +11:00
|
|
|
let prev_item = prev_attr.get_normal_item();
|
|
|
|
let item = attr.get_normal_item();
|
|
|
|
let path_str = pprust::path_to_string(&item.path);
|
2019-12-22 17:42:04 -05:00
|
|
|
let msg = if item.path.segments[0].ident.name
|
|
|
|
== prev_item.path.segments[0].ident.name
|
|
|
|
{
|
2019-10-08 22:17:46 +02:00
|
|
|
format!(
|
|
|
|
"only one `#[{}]` attribute is allowed on any given function",
|
|
|
|
path_str,
|
|
|
|
)
|
2017-01-09 01:31:14 -08:00
|
|
|
} else {
|
2019-10-08 22:17:46 +02:00
|
|
|
format!(
|
|
|
|
"`#[{}]` and `#[{}]` attributes cannot both be applied
|
|
|
|
to the same function",
|
|
|
|
path_str,
|
2019-10-24 06:33:12 +11:00
|
|
|
pprust::path_to_string(&prev_item.path),
|
2019-10-08 22:17:46 +02:00
|
|
|
)
|
2017-01-09 01:31:14 -08:00
|
|
|
};
|
|
|
|
|
2019-12-22 17:42:04 -05:00
|
|
|
self.handler
|
|
|
|
.struct_span_err(attr.span, &msg)
|
2019-11-25 12:37:07 -08:00
|
|
|
.span_label(prev_attr.span, "previous attribute here")
|
2017-01-09 01:31:14 -08:00
|
|
|
.emit();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
found_attr = Some(attr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let attr = match found_attr {
|
|
|
|
None => {
|
2020-03-09 11:42:37 -07:00
|
|
|
self.check_not_pub_in_root(&item.vis, self.source_map.guess_head_span(item.span));
|
2018-07-13 01:59:41 +03:00
|
|
|
let prev_in_root = mem::replace(&mut self.in_root, false);
|
|
|
|
visit::walk_item(self, item);
|
|
|
|
self.in_root = prev_in_root;
|
|
|
|
return;
|
2019-12-22 17:42:04 -05:00
|
|
|
}
|
2017-01-09 01:31:14 -08:00
|
|
|
Some(attr) => attr,
|
|
|
|
};
|
|
|
|
|
|
|
|
if !is_fn {
|
2019-10-08 22:17:46 +02:00
|
|
|
let msg = format!(
|
|
|
|
"the `#[{}]` attribute may only be used on bare functions",
|
2019-10-24 06:33:12 +11:00
|
|
|
pprust::path_to_string(&attr.get_normal_item().path),
|
2019-10-08 22:17:46 +02:00
|
|
|
);
|
2017-01-09 01:31:14 -08:00
|
|
|
|
2019-03-03 20:56:24 +03:00
|
|
|
self.handler.span_err(attr.span, &msg);
|
2017-01-09 01:31:14 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.is_test_crate {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if !self.is_proc_macro_crate {
|
2019-10-08 22:17:46 +02:00
|
|
|
let msg = format!(
|
|
|
|
"the `#[{}]` attribute is only usable with crates of the `proc-macro` crate type",
|
2019-10-24 06:33:12 +11:00
|
|
|
pprust::path_to_string(&attr.get_normal_item().path),
|
2019-10-08 22:17:46 +02:00
|
|
|
);
|
2017-01-09 01:31:14 -08:00
|
|
|
|
2019-03-03 20:56:24 +03:00
|
|
|
self.handler.span_err(attr.span, &msg);
|
2017-01-09 01:31:14 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-07-29 12:00:41 -05:00
|
|
|
if attr.has_name(sym::proc_macro_derive) {
|
2017-01-09 01:31:14 -08:00
|
|
|
self.collect_custom_derive(item, attr);
|
2021-07-29 12:00:41 -05:00
|
|
|
} else if attr.has_name(sym::proc_macro_attribute) {
|
2019-01-02 02:21:05 +03:00
|
|
|
self.collect_attr_proc_macro(item);
|
2021-07-29 12:00:41 -05:00
|
|
|
} else if attr.has_name(sym::proc_macro) {
|
2019-01-02 02:21:05 +03:00
|
|
|
self.collect_bang_proc_macro(item);
|
2017-01-09 01:31:14 -08:00
|
|
|
};
|
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-08-22 17:07:11 -07:00
|
|
|
|
2018-07-13 01:59:41 +03:00
|
|
|
let prev_in_root = mem::replace(&mut self.in_root, false);
|
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-08-22 17:07:11 -07:00
|
|
|
visit::walk_item(self, item);
|
|
|
|
self.in_root = prev_in_root;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creates a new module which looks like:
|
|
|
|
//
|
2019-08-25 21:03:24 +01:00
|
|
|
// const _: () = {
|
2016-10-03 09:49:39 -07:00
|
|
|
// extern crate proc_macro;
|
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-08-22 17:07:11 -07:00
|
|
|
//
|
2018-03-16 01:09:22 +02:00
|
|
|
// use proc_macro::bridge::client::ProcMacro;
|
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-08-22 17:07:11 -07:00
|
|
|
//
|
2018-03-16 01:09:22 +02:00
|
|
|
// #[rustc_proc_macro_decls]
|
2019-10-22 00:08:14 +08:00
|
|
|
// #[allow(deprecated)]
|
2018-03-16 01:09:22 +02:00
|
|
|
// static DECLS: &[ProcMacro] = &[
|
|
|
|
// ProcMacro::custom_derive($name_trait1, &[], ::$name1);
|
|
|
|
// ProcMacro::custom_derive($name_trait2, &["attribute_name"], ::$name2);
|
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-08-22 17:07:11 -07:00
|
|
|
// // ...
|
2018-03-16 01:09:22 +02:00
|
|
|
// ];
|
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-08-22 17:07:11 -07:00
|
|
|
// }
|
2020-02-03 18:34:36 -05:00
|
|
|
fn mk_decls(
|
|
|
|
ast_krate: &mut ast::Crate,
|
|
|
|
cx: &mut ExtCtxt<'_>,
|
|
|
|
macros: &[ProcMacro],
|
|
|
|
) -> P<ast::Item> {
|
|
|
|
// We're the ones filling in this Vec,
|
|
|
|
// so it should be empty to start with
|
|
|
|
assert!(ast_krate.proc_macros.is_empty());
|
|
|
|
|
2019-08-28 12:41:29 +03:00
|
|
|
let expn_id = cx.resolver.expansion_for_ast_pass(
|
2019-08-25 21:03:24 +01:00
|
|
|
DUMMY_SP,
|
|
|
|
AstPass::ProcMacroHarness,
|
|
|
|
&[sym::rustc_attrs, sym::proc_macro_internals],
|
|
|
|
None,
|
|
|
|
);
|
2021-06-25 20:43:04 +02:00
|
|
|
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
|
2019-08-25 21:03:24 +01:00
|
|
|
|
|
|
|
let proc_macro = Ident::new(sym::proc_macro, span);
|
2019-12-22 17:42:04 -05:00
|
|
|
let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None));
|
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-08-22 17:07:11 -07:00
|
|
|
|
2020-07-14 15:05:26 +10:00
|
|
|
let bridge = Ident::new(sym::bridge, span);
|
|
|
|
let client = Ident::new(sym::client, span);
|
|
|
|
let proc_macro_ty = Ident::new(sym::ProcMacro, span);
|
|
|
|
let custom_derive = Ident::new(sym::custom_derive, span);
|
|
|
|
let attr = Ident::new(sym::attr, span);
|
|
|
|
let bang = Ident::new(sym::bang, span);
|
2018-03-16 01:09:22 +02:00
|
|
|
|
2020-02-03 18:34:36 -05:00
|
|
|
let krate_ref = RefCell::new(ast_krate);
|
|
|
|
|
|
|
|
// We add NodeIds to 'krate.proc_macros' in the order
|
|
|
|
// that we generate expressions. The position of each NodeId
|
|
|
|
// in the 'proc_macros' Vec corresponds to its position
|
|
|
|
// in the static array that will be generated
|
2018-03-16 01:09:22 +02:00
|
|
|
let decls = {
|
2019-12-22 17:42:04 -05:00
|
|
|
let local_path =
|
|
|
|
|sp: Span, name| cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name]));
|
|
|
|
let proc_macro_ty_method_path = |method| {
|
|
|
|
cx.expr_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty, method]))
|
2018-03-16 01:09:22 +02:00
|
|
|
};
|
2019-12-22 17:42:04 -05:00
|
|
|
macros
|
|
|
|
.iter()
|
|
|
|
.map(|m| match m {
|
2020-02-03 18:34:36 -05:00
|
|
|
ProcMacro::Derive(cd) => {
|
|
|
|
krate_ref.borrow_mut().proc_macros.push(cd.id);
|
|
|
|
cx.expr_call(
|
|
|
|
span,
|
|
|
|
proc_macro_ty_method_path(custom_derive),
|
|
|
|
vec![
|
|
|
|
cx.expr_str(cd.span, cd.trait_name),
|
|
|
|
cx.expr_vec_slice(
|
|
|
|
span,
|
|
|
|
cd.attrs
|
|
|
|
.iter()
|
|
|
|
.map(|&s| cx.expr_str(cd.span, s))
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
),
|
|
|
|
local_path(cd.span, cd.function_name),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
}
|
2019-09-17 19:07:35 -04:00
|
|
|
ProcMacro::Def(ca) => {
|
2020-02-03 18:34:36 -05:00
|
|
|
krate_ref.borrow_mut().proc_macros.push(ca.id);
|
2019-09-17 19:07:35 -04:00
|
|
|
let ident = match ca.def_type {
|
|
|
|
ProcMacroDefType::Attr => attr,
|
2019-12-22 17:42:04 -05:00
|
|
|
ProcMacroDefType::Bang => bang,
|
2019-09-17 19:07:35 -04:00
|
|
|
};
|
|
|
|
|
2019-12-22 17:42:04 -05:00
|
|
|
cx.expr_call(
|
|
|
|
span,
|
|
|
|
proc_macro_ty_method_path(ident),
|
|
|
|
vec![
|
|
|
|
cx.expr_str(ca.span, ca.function_name.name),
|
|
|
|
local_path(ca.span, ca.function_name),
|
|
|
|
],
|
|
|
|
)
|
2019-09-17 19:07:35 -04:00
|
|
|
}
|
2019-12-22 17:42:04 -05:00
|
|
|
})
|
|
|
|
.collect()
|
2018-07-12 14:04:24 -07:00
|
|
|
};
|
2017-01-09 01:31:14 -08:00
|
|
|
|
2019-12-22 17:42:04 -05:00
|
|
|
let decls_static = cx
|
|
|
|
.item_static(
|
|
|
|
span,
|
2020-07-14 15:05:26 +10:00
|
|
|
Ident::new(sym::_DECLS, span),
|
2019-12-22 17:42:04 -05:00
|
|
|
cx.ty_rptr(
|
|
|
|
span,
|
|
|
|
cx.ty(
|
|
|
|
span,
|
|
|
|
ast::TyKind::Slice(
|
|
|
|
cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
None,
|
|
|
|
ast::Mutability::Not,
|
|
|
|
),
|
|
|
|
ast::Mutability::Not,
|
|
|
|
cx.expr_vec_slice(span, decls),
|
|
|
|
)
|
|
|
|
.map(|mut i| {
|
|
|
|
let attr = cx.meta_word(span, sym::rustc_proc_macro_decls);
|
|
|
|
i.attrs.push(cx.attribute(attr));
|
|
|
|
|
|
|
|
let deprecated_attr = attr::mk_nested_word_item(Ident::new(sym::deprecated, span));
|
|
|
|
let allow_deprecated_attr =
|
|
|
|
attr::mk_list_item(Ident::new(sym::allow, span), vec![deprecated_attr]);
|
|
|
|
i.attrs.push(cx.attribute(allow_deprecated_attr));
|
|
|
|
|
|
|
|
i
|
|
|
|
});
|
|
|
|
|
|
|
|
let block = cx.expr_block(
|
|
|
|
cx.block(span, vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
|
|
|
|
);
|
2016-09-06 07:52:09 +00:00
|
|
|
|
2019-08-25 21:03:24 +01:00
|
|
|
let anon_constant = cx.item_const(
|
|
|
|
span,
|
2020-04-19 13:00:18 +02:00
|
|
|
Ident::new(kw::Underscore, span),
|
2019-09-05 15:05:58 +01:00
|
|
|
cx.ty(span, ast::TyKind::Tup(Vec::new())),
|
2019-08-25 21:03:24 +01:00
|
|
|
block,
|
|
|
|
);
|
|
|
|
|
2019-09-05 15:05:58 +01:00
|
|
|
// Integrate the new item into existing module structures.
|
2019-08-25 21:03:24 +01:00
|
|
|
let items = AstFragment::Items(smallvec![anon_constant]);
|
|
|
|
cx.monotonic_expander().fully_expand_fragment(items).make_items().pop().unwrap()
|
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-08-22 17:07:11 -07:00
|
|
|
}
|