Skip to content

Commit 02638a3

Browse files
derive(SmartPointer): register helper attributes
1 parent 899eb03 commit 02638a3

File tree

11 files changed

+125
-24
lines changed

11 files changed

+125
-24
lines changed

compiler/rustc_builtin_macros/src/lib.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ extern crate proc_macro;
2323
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
2424
use rustc_expand::proc_macro::BangProcMacro;
2525
use rustc_span::symbol::sym;
26+
use smallvec::smallvec;
2627

2728
use crate::deriving::*;
2829

@@ -66,8 +67,16 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
6667
macro register_attr($($name:ident: $f:expr,)*) {
6768
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
6869
}
69-
macro register_derive($($name:ident: $f:expr,)*) {
70-
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
70+
macro_rules! register_derive {
71+
($name:ident: $f:expr, $($rest:tt)*) => {
72+
register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f)), smallvec![]));
73+
register_derive!($($rest)*);
74+
};
75+
($name:ident(attrs = [$($attr:ident),+]): $f:expr, $($rest:tt)*) => {
76+
register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f)), smallvec![$(sym::$attr),*]));
77+
register_derive!($($rest)*);
78+
};
79+
() => {};
7180
}
7281

7382
register_bang! {
@@ -128,7 +137,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
128137
PartialOrd: partial_ord::expand_deriving_partial_ord,
129138
RustcDecodable: decodable::expand_deriving_rustc_decodable,
130139
RustcEncodable: encodable::expand_deriving_rustc_encodable,
131-
SmartPointer: smart_ptr::expand_deriving_smart_ptr,
140+
SmartPointer(attrs = [pointee]): smart_ptr::expand_deriving_smart_ptr,
132141
}
133142

134143
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);

compiler/rustc_expand/src/base.rs

+2
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,8 @@ pub enum SyntaxExtensionKind {
714714
/// An expander with signature AST -> AST.
715715
/// The produced AST fragment is appended to the input AST fragment.
716716
Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
717+
/// Helper attributes
718+
SmallVec<[Symbol; 1]>,
717719
),
718720

719721
/// A glob delegation.

compiler/rustc_expand/src/expand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
781781
},
782782
InvocationKind::Derive { path, item, is_const } => match ext {
783783
SyntaxExtensionKind::Derive(expander)
784-
| SyntaxExtensionKind::LegacyDerive(expander) => {
784+
| SyntaxExtensionKind::LegacyDerive(expander, _) => {
785785
if let SyntaxExtensionKind::Derive(..) = ext {
786786
self.gate_proc_macro_input(&item);
787787
}

compiler/rustc_expand/src/mbe/macro_rules.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,14 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
366366
//
367367
// Holy self-referential!
368368

369-
/// Converts a macro item into a syntax extension.
369+
/// Converts a macro item `def` into a syntax extension.
370+
#[instrument(level = "debug", skip(sess, features))]
370371
pub fn compile_declarative_macro(
371372
sess: &Session,
372373
features: &Features,
373374
def: &ast::Item,
374375
edition: Edition,
375376
) -> (SyntaxExtension, Vec<(usize, Span)>) {
376-
debug!("compile_declarative_macro: {:?}", def);
377377
let mk_syn_ext = |expander| {
378378
SyntaxExtension::new(
379379
sess,

compiler/rustc_feature/src/builtin_attrs.rs

-6
Original file line numberDiff line numberDiff line change
@@ -578,12 +578,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
578578
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
579579
),
580580

581-
// `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro
582-
gated!(
583-
pointee, Normal, template!(Word), ErrorFollowing,
584-
EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee)
585-
),
586-
587581
// RFC 3543
588582
// `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
589583
gated!(

compiler/rustc_resolve/src/macros.rs

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use rustc_span::edition::Edition;
3434
use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
3535
use rustc_span::symbol::{kw, sym, Ident, Symbol};
3636
use rustc_span::{Span, DUMMY_SP};
37+
use tracing::instrument;
3738

3839
use crate::errors::{
3940
self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
@@ -1117,6 +1118,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11171118
/// Compile the macro into a `SyntaxExtension` and its rule spans.
11181119
///
11191120
/// Possibly replace its expander to a pre-defined one for built-in macros.
1121+
#[instrument(level = "debug", skip(self))]
11201122
pub(crate) fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> MacroData {
11211123
let (mut ext, mut rule_spans) =
11221124
compile_declarative_macro(self.tcx.sess, self.tcx.features(), item, edition);
@@ -1129,6 +1131,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11291131
// If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
11301132
match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
11311133
BuiltinMacroState::NotYetSeen(builtin_ext) => {
1134+
if let SyntaxExtensionKind::LegacyDerive(_expander, helper_attrs) =
1135+
&builtin_ext
1136+
{
1137+
ext.helper_attrs.extend(helper_attrs.iter().copied());
1138+
}
11321139
ext.kind = builtin_ext;
11331140
rule_spans = Vec::new();
11341141
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@ force-host
2+
//@ no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
#![feature(proc_macro_quote)]
6+
7+
extern crate proc_macro;
8+
9+
use proc_macro::{quote, TokenStream};
10+
11+
#[proc_macro_derive(AnotherMacro, attributes(pointee))]
12+
pub fn derive(_input: TokenStream) -> TokenStream {
13+
quote! {
14+
const _: () = {
15+
const ANOTHER_MACRO_DERIVED: () = ();
16+
};
17+
}
18+
.into()
19+
}
20+
21+
#[proc_macro_attribute]
22+
pub fn pointee(
23+
_attr: proc_macro::TokenStream,
24+
_item: proc_macro::TokenStream,
25+
) -> proc_macro::TokenStream {
26+
quote! {
27+
const _: () = {
28+
const ANOTHER_MACRO_ATTR_DERIVED: () = ();
29+
};
30+
}
31+
.into()
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//@ check-pass
2+
//@ aux-build: another-proc-macro.rs
3+
//@ compile-flags: -Zunpretty=expanded
4+
5+
#![feature(derive_smart_pointer)]
6+
7+
#[macro_use]
8+
extern crate another_proc_macro;
9+
10+
use another_proc_macro::{pointee, AnotherMacro};
11+
12+
#[derive(core::marker::SmartPointer)]
13+
#[repr(transparent)]
14+
pub struct Ptr<'a, #[pointee] T: ?Sized> {
15+
data: &'a mut T,
16+
}
17+
18+
#[pointee]
19+
fn f() {}
20+
21+
#[derive(AnotherMacro)]
22+
#[pointee]
23+
struct MyStruct;
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#![feature(prelude_import)]
2+
#![no_std]
3+
//@ check-pass
4+
//@ aux-build: another-proc-macro.rs
5+
//@ compile-flags: -Zunpretty=expanded
6+
7+
#![feature(derive_smart_pointer)]
8+
#[prelude_import]
9+
use ::std::prelude::rust_2015::*;
10+
#[macro_use]
11+
extern crate std;
12+
13+
#[macro_use]
14+
extern crate another_proc_macro;
15+
16+
use another_proc_macro::{pointee, AnotherMacro};
17+
18+
#[repr(transparent)]
19+
pub struct Ptr<'a, #[pointee] T: ?Sized> {
20+
data: &'a mut T,
21+
}
22+
#[automatically_derived]
23+
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
24+
::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
25+
}
26+
#[automatically_derived]
27+
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
28+
::core::ops::CoerceUnsized<Ptr<'a, __S>> for Ptr<'a, T> {
29+
}
30+
31+
32+
33+
const _: () =
34+
{
35+
const ANOTHER_MACRO_ATTR_DERIVED: () = ();
36+
};
37+
#[pointee]
38+
struct MyStruct;
39+
const _: () =
40+
{
41+
const ANOTHER_MACRO_DERIVED: () = ();
42+
};
43+
fn main() {}

tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive
33
#[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer'
44
#[repr(transparent)]
55
struct MyPointer<'a, #[pointee] T: ?Sized> {
6-
//~^ ERROR the `#[pointee]` attribute is an experimental feature
76
ptr: &'a T,
87
}
98

tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr

+1-11
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@ LL | #[derive(SmartPointer)]
88
= help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
99
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1010

11-
error[E0658]: the `#[pointee]` attribute is an experimental feature
12-
--> $DIR/feature-gate-derive-smart-pointer.rs:5:22
13-
|
14-
LL | struct MyPointer<'a, #[pointee] T: ?Sized> {
15-
| ^^^^^^^^^^
16-
|
17-
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
18-
= help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
19-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
20-
2111
error[E0658]: use of unstable library feature 'derive_smart_pointer'
2212
--> $DIR/feature-gate-derive-smart-pointer.rs:1:5
2313
|
@@ -28,6 +18,6 @@ LL | use std::marker::SmartPointer;
2818
= help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
2919
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3020

31-
error: aborting due to 3 previous errors
21+
error: aborting due to 2 previous errors
3222

3323
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)