Skip to content

Commit

Permalink
derive(SmartPointer): register helper attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Aug 11, 2024
1 parent 899eb03 commit 02638a3
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 24 deletions.
15 changes: 12 additions & 3 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern crate proc_macro;
use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
use rustc_expand::proc_macro::BangProcMacro;
use rustc_span::symbol::sym;
use smallvec::smallvec;

use crate::deriving::*;

Expand Down Expand Up @@ -66,8 +67,16 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
macro register_attr($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
}
macro register_derive($($name:ident: $f:expr,)*) {
$(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
macro_rules! register_derive {
($name:ident: $f:expr, $($rest:tt)*) => {
register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f)), smallvec![]));
register_derive!($($rest)*);
};
($name:ident(attrs = [$($attr:ident),+]): $f:expr, $($rest:tt)*) => {
register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f)), smallvec![$(sym::$attr),*]));
register_derive!($($rest)*);
};
() => {};
}

register_bang! {
Expand Down Expand Up @@ -128,7 +137,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
PartialOrd: partial_ord::expand_deriving_partial_ord,
RustcDecodable: decodable::expand_deriving_rustc_decodable,
RustcEncodable: encodable::expand_deriving_rustc_encodable,
SmartPointer: smart_ptr::expand_deriving_smart_ptr,
SmartPointer(attrs = [pointee]): smart_ptr::expand_deriving_smart_ptr,
}

let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,8 @@ pub enum SyntaxExtensionKind {
/// An expander with signature AST -> AST.
/// The produced AST fragment is appended to the input AST fragment.
Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
/// Helper attributes
SmallVec<[Symbol; 1]>,
),

/// A glob delegation.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
},
InvocationKind::Derive { path, item, is_const } => match ext {
SyntaxExtensionKind::Derive(expander)
| SyntaxExtensionKind::LegacyDerive(expander) => {
| SyntaxExtensionKind::LegacyDerive(expander, _) => {
if let SyntaxExtensionKind::Derive(..) = ext {
self.gate_proc_macro_input(&item);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,14 +366,14 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>(
//
// Holy self-referential!

/// Converts a macro item into a syntax extension.
/// Converts a macro item `def` into a syntax extension.
#[instrument(level = "debug", skip(sess, features))]
pub fn compile_declarative_macro(
sess: &Session,
features: &Features,
def: &ast::Item,
edition: Edition,
) -> (SyntaxExtension, Vec<(usize, Span)>) {
debug!("compile_declarative_macro: {:?}", def);
let mk_syn_ext = |expander| {
SyntaxExtension::new(
sess,
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,12 +578,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::No, coroutines, experimental!(coroutines)
),

// `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro
gated!(
pointee, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee)
),

// RFC 3543
// `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
gated!(
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use rustc_span::edition::Edition;
use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use tracing::instrument;

use crate::errors::{
self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
Expand Down Expand Up @@ -1117,6 +1118,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Compile the macro into a `SyntaxExtension` and its rule spans.
///
/// Possibly replace its expander to a pre-defined one for built-in macros.
#[instrument(level = "debug", skip(self))]
pub(crate) fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> MacroData {
let (mut ext, mut rule_spans) =
compile_declarative_macro(self.tcx.sess, self.tcx.features(), item, edition);
Expand All @@ -1129,6 +1131,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(item.span)) {
BuiltinMacroState::NotYetSeen(builtin_ext) => {
if let SyntaxExtensionKind::LegacyDerive(_expander, helper_attrs) =
&builtin_ext
{
ext.helper_attrs.extend(helper_attrs.iter().copied());
}
ext.kind = builtin_ext;
rule_spans = Vec::new();
}
Expand Down
32 changes: 32 additions & 0 deletions tests/ui/deriving/auxiliary/another-proc-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//@ force-host
//@ no-prefer-dynamic

#![crate_type = "proc-macro"]
#![feature(proc_macro_quote)]

extern crate proc_macro;

use proc_macro::{quote, TokenStream};

#[proc_macro_derive(AnotherMacro, attributes(pointee))]
pub fn derive(_input: TokenStream) -> TokenStream {
quote! {
const _: () = {
const ANOTHER_MACRO_DERIVED: () = ();
};
}
.into()
}

#[proc_macro_attribute]
pub fn pointee(
_attr: proc_macro::TokenStream,
_item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
quote! {
const _: () = {
const ANOTHER_MACRO_ATTR_DERIVED: () = ();
};
}
.into()
}
25 changes: 25 additions & 0 deletions tests/ui/deriving/built-in-proc-macro-scope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ check-pass
//@ aux-build: another-proc-macro.rs
//@ compile-flags: -Zunpretty=expanded

#![feature(derive_smart_pointer)]

#[macro_use]
extern crate another_proc_macro;

use another_proc_macro::{pointee, AnotherMacro};

#[derive(core::marker::SmartPointer)]
#[repr(transparent)]
pub struct Ptr<'a, #[pointee] T: ?Sized> {
data: &'a mut T,
}

#[pointee]
fn f() {}

#[derive(AnotherMacro)]
#[pointee]
struct MyStruct;

fn main() {}
43 changes: 43 additions & 0 deletions tests/ui/deriving/built-in-proc-macro-scope.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#![feature(prelude_import)]
#![no_std]
//@ check-pass
//@ aux-build: another-proc-macro.rs
//@ compile-flags: -Zunpretty=expanded

#![feature(derive_smart_pointer)]
#[prelude_import]
use ::std::prelude::rust_2015::*;
#[macro_use]
extern crate std;

#[macro_use]
extern crate another_proc_macro;

use another_proc_macro::{pointee, AnotherMacro};

#[repr(transparent)]
pub struct Ptr<'a, #[pointee] T: ?Sized> {
data: &'a mut T,
}
#[automatically_derived]
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
}
#[automatically_derived]
impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
::core::ops::CoerceUnsized<Ptr<'a, __S>> for Ptr<'a, T> {
}



const _: () =
{
const ANOTHER_MACRO_ATTR_DERIVED: () = ();
};
#[pointee]
struct MyStruct;
const _: () =
{
const ANOTHER_MACRO_DERIVED: () = ();
};
fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive
#[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer'
#[repr(transparent)]
struct MyPointer<'a, #[pointee] T: ?Sized> {
//~^ ERROR the `#[pointee]` attribute is an experimental feature
ptr: &'a T,
}

Expand Down
12 changes: 1 addition & 11 deletions tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@ LL | #[derive(SmartPointer)]
= help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: the `#[pointee]` attribute is an experimental feature
--> $DIR/feature-gate-derive-smart-pointer.rs:5:22
|
LL | struct MyPointer<'a, #[pointee] T: ?Sized> {
| ^^^^^^^^^^
|
= note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
= help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: use of unstable library feature 'derive_smart_pointer'
--> $DIR/feature-gate-derive-smart-pointer.rs:1:5
|
Expand All @@ -28,6 +18,6 @@ LL | use std::marker::SmartPointer;
= help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

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

0 comments on commit 02638a3

Please sign in to comment.