Skip to content

Commit 4ad0daa

Browse files
committed
Move proc macro server into libsyntax
1 parent 3eeec1c commit 4ad0daa

File tree

15 files changed

+271
-343
lines changed

15 files changed

+271
-343
lines changed

Cargo.lock

-1
Original file line numberDiff line numberDiff line change
@@ -3008,7 +3008,6 @@ dependencies = [
30083008
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
30093009
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
30103010
"syntax 0.0.0",
3011-
"syntax_ext 0.0.0",
30123011
"syntax_pos 0.0.0",
30133012
]
30143013

src/librustc_metadata/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,4 @@ rustc_target = { path = "../librustc_target" }
2121
rustc_serialize = { path = "../libserialize", package = "serialize" }
2222
stable_deref_trait = "1.0.0"
2323
syntax = { path = "../libsyntax" }
24-
syntax_ext = { path = "../libsyntax_ext" }
2524
syntax_pos = { path = "../libsyntax_pos" }

src/librustc_metadata/creader.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,7 @@ impl<'a> CrateLoader<'a> {
586586
use std::{env, mem};
587587
use crate::dynamic_lib::DynamicLibrary;
588588
use proc_macro::bridge::client::ProcMacro;
589-
use syntax_ext::deriving::custom::ProcMacroDerive;
590-
use syntax_ext::proc_macro_impl::{AttrProcMacro, BangProcMacro};
589+
use syntax::ext::proc_macro::{BangProcMacro, AttrProcMacro, ProcMacroDerive};
591590

592591
let path = match dylib {
593592
Some(dylib) => dylib,

src/librustc_metadata/cstore_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ use syntax::attr;
3131
use syntax::source_map;
3232
use syntax::edition::Edition;
3333
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
34+
use syntax::ext::proc_macro::BangProcMacro;
3435
use syntax::parse::source_file_to_stream;
3536
use syntax::parse::parser::emit_unclosed_delims;
3637
use syntax::symbol::{Symbol, sym};
37-
use syntax_ext::proc_macro_impl::BangProcMacro;
3838
use syntax_pos::{Span, NO_EXPANSION, FileName};
3939
use rustc_data_structures::bit_set::BitSet;
4040

src/libsyntax/ext/derive.rs

-72
This file was deleted.

src/libsyntax/ext/expand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::attr::{self, HasAttrs};
44
use crate::source_map::{dummy_spanned, respan};
55
use crate::config::StripUnconfigured;
66
use crate::ext::base::*;
7-
use crate::ext::derive::{add_derived_markers, collect_derives};
7+
use crate::ext::proc_macro::{add_derived_markers, collect_derives};
88
use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind};
99
use crate::ext::placeholders::{placeholder, PlaceholderExpander};
1010
use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};

src/libsyntax/ext/proc_macro.rs

+244-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,249 @@
1-
use crate::ast::Attribute;
2-
use crate::symbol::sym;
1+
use crate::ast::{self, ItemKind, Attribute, Mac};
2+
use crate::attr::{mark_used, mark_known, HasAttrs};
3+
use crate::errors::{Applicability, FatalError};
4+
use crate::ext::base::{self, *};
5+
use crate::ext::build::AstBuilder;
6+
use crate::ext::proc_macro_server;
7+
use crate::parse::{self, token};
8+
use crate::parse::parser::PathStyle;
9+
use crate::symbol::{sym, Symbol};
10+
use crate::tokenstream::{self, TokenStream};
11+
use crate::visit::Visitor;
12+
13+
use rustc_data_structures::fx::FxHashSet;
14+
use rustc_data_structures::sync::Lrc;
15+
use syntax_pos::hygiene::{ExpnInfo, ExpnKind};
16+
use syntax_pos::{Span, DUMMY_SP};
17+
18+
const EXEC_STRATEGY: proc_macro::bridge::server::SameThread =
19+
proc_macro::bridge::server::SameThread;
20+
21+
pub struct BangProcMacro {
22+
pub client: proc_macro::bridge::client::Client<
23+
fn(proc_macro::TokenStream) -> proc_macro::TokenStream,
24+
>,
25+
}
26+
27+
impl base::ProcMacro for BangProcMacro {
28+
fn expand<'cx>(&self,
29+
ecx: &'cx mut ExtCtxt<'_>,
30+
span: Span,
31+
input: TokenStream)
32+
-> TokenStream {
33+
let server = proc_macro_server::Rustc::new(ecx);
34+
match self.client.run(&EXEC_STRATEGY, server, input) {
35+
Ok(stream) => stream,
36+
Err(e) => {
37+
let msg = "proc macro panicked";
38+
let mut err = ecx.struct_span_fatal(span, msg);
39+
if let Some(s) = e.as_str() {
40+
err.help(&format!("message: {}", s));
41+
}
42+
43+
err.emit();
44+
FatalError.raise();
45+
}
46+
}
47+
}
48+
}
49+
50+
pub struct AttrProcMacro {
51+
pub client: proc_macro::bridge::client::Client<
52+
fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream,
53+
>,
54+
}
55+
56+
impl base::AttrProcMacro for AttrProcMacro {
57+
fn expand<'cx>(&self,
58+
ecx: &'cx mut ExtCtxt<'_>,
59+
span: Span,
60+
annotation: TokenStream,
61+
annotated: TokenStream)
62+
-> TokenStream {
63+
let server = proc_macro_server::Rustc::new(ecx);
64+
match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) {
65+
Ok(stream) => stream,
66+
Err(e) => {
67+
let msg = "custom attribute panicked";
68+
let mut err = ecx.struct_span_fatal(span, msg);
69+
if let Some(s) = e.as_str() {
70+
err.help(&format!("message: {}", s));
71+
}
72+
73+
err.emit();
74+
FatalError.raise();
75+
}
76+
}
77+
}
78+
}
79+
80+
pub struct ProcMacroDerive {
81+
pub client: proc_macro::bridge::client::Client<
82+
fn(proc_macro::TokenStream) -> proc_macro::TokenStream,
83+
>,
84+
pub attrs: Vec<ast::Name>,
85+
}
86+
87+
impl MultiItemModifier for ProcMacroDerive {
88+
fn expand(&self,
89+
ecx: &mut ExtCtxt<'_>,
90+
span: Span,
91+
_meta_item: &ast::MetaItem,
92+
item: Annotatable)
93+
-> Vec<Annotatable> {
94+
let item = match item {
95+
Annotatable::Item(item) => item,
96+
Annotatable::ImplItem(_) |
97+
Annotatable::TraitItem(_) |
98+
Annotatable::ForeignItem(_) |
99+
Annotatable::Stmt(_) |
100+
Annotatable::Expr(_) => {
101+
ecx.span_err(span, "proc-macro derives may only be \
102+
applied to a struct, enum, or union");
103+
return Vec::new()
104+
}
105+
};
106+
match item.node {
107+
ItemKind::Struct(..) |
108+
ItemKind::Enum(..) |
109+
ItemKind::Union(..) => {},
110+
_ => {
111+
ecx.span_err(span, "proc-macro derives may only be \
112+
applied to a struct, enum, or union");
113+
return Vec::new()
114+
}
115+
}
116+
117+
// Mark attributes as known, and used.
118+
MarkAttrs(&self.attrs).visit_item(&item);
119+
120+
let token = token::Interpolated(Lrc::new(token::NtItem(item)));
121+
let input = tokenstream::TokenTree::token(token, DUMMY_SP).into();
122+
123+
let server = proc_macro_server::Rustc::new(ecx);
124+
let stream = match self.client.run(&EXEC_STRATEGY, server, input) {
125+
Ok(stream) => stream,
126+
Err(e) => {
127+
let msg = "proc-macro derive panicked";
128+
let mut err = ecx.struct_span_fatal(span, msg);
129+
if let Some(s) = e.as_str() {
130+
err.help(&format!("message: {}", s));
131+
}
132+
133+
err.emit();
134+
FatalError.raise();
135+
}
136+
};
137+
138+
let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
139+
let msg = "proc-macro derive produced unparseable tokens";
140+
141+
let mut parser = parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
142+
let mut items = vec![];
143+
144+
loop {
145+
match parser.parse_item() {
146+
Ok(None) => break,
147+
Ok(Some(item)) => {
148+
items.push(Annotatable::Item(item))
149+
}
150+
Err(mut err) => {
151+
// FIXME: handle this better
152+
err.cancel();
153+
ecx.struct_span_fatal(span, msg).emit();
154+
FatalError.raise();
155+
}
156+
}
157+
}
158+
159+
160+
// fail if there have been errors emitted
161+
if ecx.parse_sess.span_diagnostic.err_count() > error_count_before {
162+
ecx.struct_span_fatal(span, msg).emit();
163+
FatalError.raise();
164+
}
165+
166+
items
167+
}
168+
}
169+
170+
struct MarkAttrs<'a>(&'a [ast::Name]);
171+
172+
impl<'a> Visitor<'a> for MarkAttrs<'a> {
173+
fn visit_attribute(&mut self, attr: &Attribute) {
174+
if let Some(ident) = attr.ident() {
175+
if self.0.contains(&ident.name) {
176+
mark_used(attr);
177+
mark_known(attr);
178+
}
179+
}
180+
}
181+
182+
fn visit_mac(&mut self, _mac: &Mac) {}
183+
}
3184

4185
pub fn is_proc_macro_attr(attr: &Attribute) -> bool {
5186
[sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
6187
.iter().any(|kind| attr.check_name(*kind))
7188
}
189+
190+
crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
191+
let mut result = Vec::new();
192+
attrs.retain(|attr| {
193+
if attr.path != sym::derive {
194+
return true;
195+
}
196+
if !attr.is_meta_item_list() {
197+
cx.struct_span_err(attr.span, "malformed `derive` attribute input")
198+
.span_suggestion(
199+
attr.span,
200+
"missing traits to be derived",
201+
"#[derive(Trait1, Trait2, ...)]".to_owned(),
202+
Applicability::HasPlaceholders,
203+
).emit();
204+
return false;
205+
}
206+
207+
match attr.parse_list(cx.parse_sess,
208+
|parser| parser.parse_path_allowing_meta(PathStyle::Mod)) {
209+
Ok(traits) => {
210+
result.extend(traits);
211+
true
212+
}
213+
Err(mut e) => {
214+
e.emit();
215+
false
216+
}
217+
}
218+
});
219+
result
220+
}
221+
222+
crate fn add_derived_markers<T: HasAttrs>(
223+
cx: &mut ExtCtxt<'_>, span: Span, traits: &[ast::Path], item: &mut T
224+
) {
225+
let (mut names, mut pretty_name) = (FxHashSet::default(), String::new());
226+
for (i, path) in traits.iter().enumerate() {
227+
if i > 0 {
228+
pretty_name.push_str(", ");
229+
}
230+
pretty_name.push_str(&path.to_string());
231+
names.insert(unwrap_or!(path.segments.get(0), continue).ident.name);
232+
}
233+
234+
let span = span.fresh_expansion(cx.current_expansion.mark, ExpnInfo::allow_unstable(
235+
ExpnKind::Macro(MacroKind::Derive, Symbol::intern(&pretty_name)), span,
236+
cx.parse_sess.edition, cx.allow_derive_markers.clone(),
237+
));
238+
239+
item.visit_attrs(|attrs| {
240+
if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) {
241+
let meta = cx.meta_word(span, sym::structural_match);
242+
attrs.push(cx.attribute(span, meta));
243+
}
244+
if names.contains(&sym::Copy) {
245+
let meta = cx.meta_word(span, sym::rustc_copy_clone_marker);
246+
attrs.push(cx.attribute(span, meta));
247+
}
248+
});
249+
}

0 commit comments

Comments
 (0)