1
Fork 0

Rollup merge of #102049 - fee1-dead-contrib:derive_const, r=oli-obk

Add the `#[derive_const]` attribute

Closes #102371. This is a minimal patchset for the attribute to work. There are no restrictions on what traits this attribute applies to.

r? `````@oli-obk`````
This commit is contained in:
Dylan DPC 2022-11-12 12:02:50 +05:30 committed by GitHub
commit 4b0b89827d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 163 additions and 30 deletions

View file

@ -250,6 +250,7 @@ pub trait MultiItemModifier {
span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
is_derive_const: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable>;
}
@ -263,6 +264,7 @@ where
span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
_is_derive_const: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
ExpandResult::Ready(self(ecx, span, meta_item, item))
}
@ -873,7 +875,7 @@ impl SyntaxExtension {
/// Error type that denotes indeterminacy.
pub struct Indeterminate;
pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>)>;
pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>, bool)>;
pub trait ResolverExpand {
fn next_node_id(&mut self) -> NodeId;

View file

@ -337,6 +337,7 @@ pub enum InvocationKind {
},
Derive {
path: ast::Path,
is_const: bool,
item: Annotatable,
},
}
@ -478,13 +479,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
derive_invocations.reserve(derives.len());
derives
.into_iter()
.map(|(path, item, _exts)| {
.map(|(path, item, _exts, is_const)| {
// FIXME: Consider using the derive resolutions (`_exts`)
// instead of enqueuing the derives to be resolved again later.
let expn_id = LocalExpnId::fresh_empty();
derive_invocations.push((
Invocation {
kind: InvocationKind::Derive { path, item },
kind: InvocationKind::Derive { path, item, is_const },
fragment_kind,
expansion_data: ExpansionData {
id: expn_id,
@ -717,7 +718,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
SyntaxExtensionKind::LegacyAttr(expander) => {
match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) {
Ok(meta) => {
let items = match expander.expand(self.cx, span, &meta, item) {
let items = match expander.expand(self.cx, span, &meta, item, false) {
ExpandResult::Ready(items) => items,
ExpandResult::Retry(item) => {
// Reassemble the original invocation for retrying.
@ -749,19 +750,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
_ => unreachable!(),
},
InvocationKind::Derive { path, item } => match ext {
InvocationKind::Derive { path, item, is_const } => match ext {
SyntaxExtensionKind::Derive(expander)
| SyntaxExtensionKind::LegacyDerive(expander) => {
if let SyntaxExtensionKind::Derive(..) = ext {
self.gate_proc_macro_input(&item);
}
let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path };
let items = match expander.expand(self.cx, span, &meta, item) {
let items = match expander.expand(self.cx, span, &meta, item, is_const) {
ExpandResult::Ready(items) => items,
ExpandResult::Retry(item) => {
// Reassemble the original invocation for retrying.
return ExpandResult::Retry(Invocation {
kind: InvocationKind::Derive { path: meta.path, item },
kind: InvocationKind::Derive { path: meta.path, item, is_const },
..invoc
});
}

View file

@ -112,6 +112,7 @@ impl MultiItemModifier for DeriveProcMacro {
span: Span,
_meta_item: &ast::MetaItem,
item: Annotatable,
_is_derive_const: bool,
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
// We need special handling for statement items
// (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)