2023-06-21 19:01:53 +08:00
|
|
|
use crate::errors;
|
2020-02-29 20:37:32 +03:00
|
|
|
use rustc_ast::ptr::P;
|
|
|
|
use rustc_ast::visit::{self, Visitor};
|
2023-03-19 21:32:34 +04:00
|
|
|
use rustc_ast::{self as ast, attr, 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;
|
Avoid more `MetaItem`-to-`Attribute` conversions.
There is code for converting `Attribute` (syntactic) to `MetaItem`
(semantic). There is also code for the reverse direction. The reverse
direction isn't really necessary; it's currently only used when
generating attributes, e.g. in `derive` code.
This commit adds some new functions for creating `Attributes`s directly,
without involving `MetaItem`s: `mk_attr_word`, `mk_attr_name_value_str`,
`mk_attr_nested_word`, and
`ExtCtxt::attr_{word,name_value_str,nested_word}`.
These new methods replace the old functions for creating `Attribute`s:
`mk_attr_inner`, `mk_attr_outer`, and `ExtCtxt::attribute`. Those
functions took `MetaItem`s as input, and relied on many other functions
that created `MetaItems`, which are also removed: `mk_name_value_item`,
`mk_list_item`, `mk_word_item`, `mk_nested_word_item`,
`{MetaItem,MetaItemKind,NestedMetaItem}::token_trees`,
`MetaItemKind::attr_args`, `MetaItemLit::{from_lit_kind,to_token}`,
`ExtCtxt::meta_word`.
Overall this cuts more than 100 lines of code and makes thing simpler.
2022-11-29 18:43:44 +11:00
|
|
|
use std::mem;
|
2022-11-23 11:55:16 +11:00
|
|
|
use thin_vec::{thin_vec, ThinVec};
|
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
|
|
|
}
|
|
|
|
|
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-09-17 19:07:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
enum ProcMacro {
|
|
|
|
Derive(ProcMacroDerive),
|
2022-05-13 11:45:51 +10:00
|
|
|
Attr(ProcMacroDef),
|
|
|
|
Bang(ProcMacroDef),
|
2017-01-09 01:31:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
struct CollectProcMacros<'a> {
|
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-07-18 23:29:57 +03:00
|
|
|
pub fn inject(
|
2023-02-18 16:23:57 +04:00
|
|
|
krate: &mut ast::Crate,
|
2020-07-30 11:27:50 +10:00
|
|
|
sess: &Session,
|
2020-06-27 23:51:28 +03:00
|
|
|
resolver: &mut dyn ResolverExpand,
|
2016-10-03 09:49:39 -07:00
|
|
|
is_proc_macro_crate: bool,
|
2019-01-17 07:28:39 +01:00
|
|
|
has_proc_macro_decls: bool,
|
2016-11-17 22:06:36 +10:30
|
|
|
is_test_crate: bool,
|
2020-01-09 11:18:47 +01:00
|
|
|
handler: &rustc_errors::Handler,
|
2023-02-18 16:23:57 +04:00
|
|
|
) {
|
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 {
|
|
|
|
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 {
|
2023-02-18 16:23:57 +04:00
|
|
|
visit::walk_crate(&mut collect, krate);
|
2019-09-17 19:07:35 -04:00
|
|
|
}
|
|
|
|
let macros = collect.macros;
|
|
|
|
|
2016-10-03 09:49:39 -07:00
|
|
|
if !is_proc_macro_crate {
|
2023-02-18 16:23:57 +04:00
|
|
|
return;
|
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 {
|
2023-02-18 16:23:57 +04:00
|
|
|
return;
|
2016-11-22 00:02:58 +10:30
|
|
|
}
|
|
|
|
|
2021-07-16 22:22:08 +02:00
|
|
|
let decls = mk_decls(&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-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() {
|
2023-06-21 19:01:53 +08:00
|
|
|
self.handler.emit_err(errors::ProcMacro { span: sp });
|
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) {
|
2022-02-19 00:48:49 +01:00
|
|
|
let Some((trait_name, proc_attrs)) =
|
|
|
|
parse_macro_name_and_helper_attrs(self.handler, attr, "derive")
|
|
|
|
else {
|
|
|
|
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() {
|
2022-05-13 11:45:51 +10:00
|
|
|
self.macros.push(ProcMacro::Attr(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-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() {
|
2022-05-13 11:45:51 +10:00
|
|
|
self.macros.push(ProcMacro::Bang(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-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 {
|
2023-03-19 21:32:34 +04:00
|
|
|
if self.is_proc_macro_crate && attr::contains_name(&item.attrs, sym::macro_export) {
|
2023-06-21 19:01:53 +08:00
|
|
|
self.handler.emit_err(errors::ExportMacroRules {
|
|
|
|
span: self.source_map.guess_head_span(item.span),
|
|
|
|
});
|
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 {
|
2023-03-19 21:32:34 +04:00
|
|
|
if attr.is_proc_macro_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);
|
|
|
|
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!(
|
2023-07-25 22:00:13 +02:00
|
|
|
"only one `#[{path_str}]` attribute is allowed on any given function",
|
2019-10-08 22:17:46 +02:00
|
|
|
)
|
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-03-03 20:56:24 +03:00
|
|
|
self.handler
|
Restrict `From<S>` for `{D,Subd}iagnosticMessage`.
Currently a `{D,Subd}iagnosticMessage` can be created from any type that
impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static,
str>`, which are reasonable. It also includes `&String`, which is pretty
weird, and results in many places making unnecessary allocations for
patterns like this:
```
self.fatal(&format!(...))
```
This creates a string with `format!`, takes a reference, passes the
reference to `fatal`, which does an `into()`, which clones the
reference, doing a second allocation. Two allocations for a single
string, bleh.
This commit changes the `From` impls so that you can only create a
`{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static,
str>`. This requires changing all the places that currently create one
from a `&String`. Most of these are of the `&format!(...)` form
described above; each one removes an unnecessary static `&`, plus an
allocation when executed. There are also a few places where the existing
use of `&String` was more reasonable; these now just use `clone()` at
the call site.
As well as making the code nicer and more efficient, this is a step
towards possibly using `Cow<'static, str>` in
`{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing
the `From<&'a str>` impls to `From<&'static str>`, which is doable, but
I'm not yet sure if it's worthwhile.
2023-04-20 13:26:58 +10:00
|
|
|
.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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-19 00:48:49 +01:00
|
|
|
let Some(attr) = found_attr else {
|
|
|
|
self.check_not_pub_in_root(&item.vis, self.source_map.guess_head_span(item.span));
|
|
|
|
let prev_in_root = mem::replace(&mut self.in_root, false);
|
|
|
|
visit::walk_item(self, item);
|
|
|
|
self.in_root = prev_in_root;
|
|
|
|
return;
|
2017-01-09 01:31:14 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
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
|
|
|
|
Restrict `From<S>` for `{D,Subd}iagnosticMessage`.
Currently a `{D,Subd}iagnosticMessage` can be created from any type that
impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static,
str>`, which are reasonable. It also includes `&String`, which is pretty
weird, and results in many places making unnecessary allocations for
patterns like this:
```
self.fatal(&format!(...))
```
This creates a string with `format!`, takes a reference, passes the
reference to `fatal`, which does an `into()`, which clones the
reference, doing a second allocation. Two allocations for a single
string, bleh.
This commit changes the `From` impls so that you can only create a
`{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static,
str>`. This requires changing all the places that currently create one
from a `&String`. Most of these are of the `&format!(...)` form
described above; each one removes an unnecessary static `&`, plus an
allocation when executed. There are also a few places where the existing
use of `&String` was more reasonable; these now just use `clone()` at
the call site.
As well as making the code nicer and more efficient, this is a step
towards possibly using `Cow<'static, str>` in
`{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing
the `From<&'a str>` impls to `From<&'static str>`, which is doable, but
I'm not yet sure if it's worthwhile.
2023-04-20 13:26:58 +10: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
|
|
|
|
Restrict `From<S>` for `{D,Subd}iagnosticMessage`.
Currently a `{D,Subd}iagnosticMessage` can be created from any type that
impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static,
str>`, which are reasonable. It also includes `&String`, which is pretty
weird, and results in many places making unnecessary allocations for
patterns like this:
```
self.fatal(&format!(...))
```
This creates a string with `format!`, takes a reference, passes the
reference to `fatal`, which does an `into()`, which clones the
reference, doing a second allocation. Two allocations for a single
string, bleh.
This commit changes the `From` impls so that you can only create a
`{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static,
str>`. This requires changing all the places that currently create one
from a `&String`. Most of these are of the `&format!(...)` form
described above; each one removes an unnecessary static `&`, plus an
allocation when executed. There are also a few places where the existing
use of `&String` was more reasonable; these now just use `clone()` at
the call site.
As well as making the code nicer and more efficient, this is a step
towards possibly using `Cow<'static, str>` in
`{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing
the `From<&'a str>` impls to `From<&'static str>`, which is doable, but
I'm not yet sure if it's worthwhile.
2023-04-20 13:26:58 +10: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]
|
2022-12-22 11:16:29 -06:00
|
|
|
// #[used]
|
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
|
|
|
// }
|
2021-07-16 22:22:08 +02:00
|
|
|
fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
|
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);
|
2022-08-17 12:34:33 +10:00
|
|
|
let krate = cx.item(span, proc_macro, ast::AttrVec::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
|
|
|
|
2021-07-16 22:22:08 +02:00
|
|
|
// We add NodeIds to 'resolver.proc_macros' in the order
|
2020-02-03 18:34:36 -05:00
|
|
|
// 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
|
2022-05-27 17:38:58 +00:00
|
|
|
let decls = macros
|
|
|
|
.iter()
|
|
|
|
.map(|m| {
|
|
|
|
let harness_span = span;
|
|
|
|
let span = match m {
|
|
|
|
ProcMacro::Derive(m) => m.span,
|
|
|
|
ProcMacro::Attr(m) | ProcMacro::Bang(m) => m.span,
|
|
|
|
};
|
|
|
|
let local_path = |cx: &ExtCtxt<'_>, name| cx.expr_path(cx.path(span, vec![name]));
|
|
|
|
let proc_macro_ty_method_path = |cx: &ExtCtxt<'_>, method| {
|
|
|
|
cx.expr_path(cx.path(
|
|
|
|
span.with_ctxt(harness_span.ctxt()),
|
|
|
|
vec![proc_macro, bridge, client, proc_macro_ty, method],
|
|
|
|
))
|
|
|
|
};
|
|
|
|
match m {
|
2020-02-03 18:34:36 -05:00
|
|
|
ProcMacro::Derive(cd) => {
|
2021-07-16 22:22:08 +02:00
|
|
|
cx.resolver.declare_proc_macro(cd.id);
|
2020-02-03 18:34:36 -05:00
|
|
|
cx.expr_call(
|
|
|
|
span,
|
2021-07-16 22:22:08 +02:00
|
|
|
proc_macro_ty_method_path(cx, custom_derive),
|
2022-11-23 11:55:16 +11:00
|
|
|
thin_vec![
|
2022-05-27 17:38:58 +00:00
|
|
|
cx.expr_str(span, cd.trait_name),
|
2022-06-22 08:38:24 +10:00
|
|
|
cx.expr_array_ref(
|
2020-02-03 18:34:36 -05:00
|
|
|
span,
|
2022-11-23 11:55:16 +11:00
|
|
|
cd.attrs
|
|
|
|
.iter()
|
|
|
|
.map(|&s| cx.expr_str(span, s))
|
|
|
|
.collect::<ThinVec<_>>(),
|
2020-02-03 18:34:36 -05:00
|
|
|
),
|
2022-05-27 17:38:58 +00:00
|
|
|
local_path(cx, cd.function_name),
|
2020-02-03 18:34:36 -05:00
|
|
|
],
|
|
|
|
)
|
|
|
|
}
|
2022-05-27 17:38:58 +00:00
|
|
|
ProcMacro::Attr(ca) | ProcMacro::Bang(ca) => {
|
|
|
|
cx.resolver.declare_proc_macro(ca.id);
|
|
|
|
let ident = match m {
|
|
|
|
ProcMacro::Attr(_) => attr,
|
|
|
|
ProcMacro::Bang(_) => bang,
|
|
|
|
ProcMacro::Derive(_) => unreachable!(),
|
|
|
|
};
|
|
|
|
|
|
|
|
cx.expr_call(
|
|
|
|
span,
|
|
|
|
proc_macro_ty_method_path(cx, ident),
|
2022-11-23 11:55:16 +11:00
|
|
|
thin_vec![
|
2022-05-27 17:38:58 +00:00
|
|
|
cx.expr_str(span, ca.function_name.name),
|
|
|
|
local_path(cx, ca.function_name),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect();
|
2017-01-09 01:31:14 -08:00
|
|
|
|
2018-03-16 01:09:22 +02:00
|
|
|
let decls_static = cx
|
|
|
|
.item_static(
|
|
|
|
span,
|
2020-07-14 15:05:26 +10:00
|
|
|
Ident::new(sym::_DECLS, span),
|
2022-12-28 18:06:11 +01:00
|
|
|
cx.ty_ref(
|
2018-03-16 01:09:22 +02:00
|
|
|
span,
|
|
|
|
cx.ty(
|
2019-12-22 17:42:04 -05:00
|
|
|
span,
|
2018-03-16 01:09:22 +02:00
|
|
|
ast::TyKind::Slice(
|
|
|
|
cx.ty_path(cx.path(span, vec![proc_macro, bridge, client, proc_macro_ty])),
|
2019-12-16 17:28:40 +01:00
|
|
|
),
|
2019-12-22 17:42:04 -05:00
|
|
|
),
|
2019-12-16 17:28:40 +01:00
|
|
|
None,
|
|
|
|
ast::Mutability::Not,
|
2019-12-22 17:42:04 -05:00
|
|
|
),
|
2019-12-16 17:28:40 +01:00
|
|
|
ast::Mutability::Not,
|
2022-06-22 08:38:24 +10:00
|
|
|
cx.expr_array_ref(span, decls),
|
2018-03-16 01:09:22 +02:00
|
|
|
)
|
|
|
|
.map(|mut i| {
|
Avoid more `MetaItem`-to-`Attribute` conversions.
There is code for converting `Attribute` (syntactic) to `MetaItem`
(semantic). There is also code for the reverse direction. The reverse
direction isn't really necessary; it's currently only used when
generating attributes, e.g. in `derive` code.
This commit adds some new functions for creating `Attributes`s directly,
without involving `MetaItem`s: `mk_attr_word`, `mk_attr_name_value_str`,
`mk_attr_nested_word`, and
`ExtCtxt::attr_{word,name_value_str,nested_word}`.
These new methods replace the old functions for creating `Attribute`s:
`mk_attr_inner`, `mk_attr_outer`, and `ExtCtxt::attribute`. Those
functions took `MetaItem`s as input, and relied on many other functions
that created `MetaItems`, which are also removed: `mk_name_value_item`,
`mk_list_item`, `mk_word_item`, `mk_nested_word_item`,
`{MetaItem,MetaItemKind,NestedMetaItem}::token_trees`,
`MetaItemKind::attr_args`, `MetaItemLit::{from_lit_kind,to_token}`,
`ExtCtxt::meta_word`.
Overall this cuts more than 100 lines of code and makes thing simpler.
2022-11-29 18:43:44 +11:00
|
|
|
i.attrs.push(cx.attr_word(sym::rustc_proc_macro_decls, span));
|
2022-12-22 11:16:29 -06:00
|
|
|
i.attrs.push(cx.attr_word(sym::used, span));
|
Avoid more `MetaItem`-to-`Attribute` conversions.
There is code for converting `Attribute` (syntactic) to `MetaItem`
(semantic). There is also code for the reverse direction. The reverse
direction isn't really necessary; it's currently only used when
generating attributes, e.g. in `derive` code.
This commit adds some new functions for creating `Attributes`s directly,
without involving `MetaItem`s: `mk_attr_word`, `mk_attr_name_value_str`,
`mk_attr_nested_word`, and
`ExtCtxt::attr_{word,name_value_str,nested_word}`.
These new methods replace the old functions for creating `Attribute`s:
`mk_attr_inner`, `mk_attr_outer`, and `ExtCtxt::attribute`. Those
functions took `MetaItem`s as input, and relied on many other functions
that created `MetaItems`, which are also removed: `mk_name_value_item`,
`mk_list_item`, `mk_word_item`, `mk_nested_word_item`,
`{MetaItem,MetaItemKind,NestedMetaItem}::token_trees`,
`MetaItemKind::attr_args`, `MetaItemLit::{from_lit_kind,to_token}`,
`ExtCtxt::meta_word`.
Overall this cuts more than 100 lines of code and makes thing simpler.
2022-11-29 18:43:44 +11:00
|
|
|
i.attrs.push(cx.attr_nested_word(sym::allow, sym::deprecated, span));
|
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
|
|
|
i
|
|
|
|
});
|
2019-12-22 17:42:04 -05:00
|
|
|
|
2019-09-05 15:05:58 +01:00
|
|
|
let block = cx.expr_block(
|
2023-01-30 14:13:27 +11:00
|
|
|
cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]),
|
2019-09-05 15:05:58 +01:00
|
|
|
);
|
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),
|
2022-11-23 11:55:16 +11:00
|
|
|
cx.ty(span, ast::TyKind::Tup(ThinVec::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
|
|
|
}
|