Skip to content

Commit e839486

Browse files
jseyfriedalexcrichton
authored andcommitted
Move resolve_invoc from syntax to resolve.
1 parent 212b6c2 commit e839486

File tree

3 files changed

+78
-72
lines changed

3 files changed

+78
-72
lines changed

src/librustc_resolve/macros.rs

+67-9
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex}
1717
use rustc::hir::def::{Def, Export};
1818
use rustc::hir::map::{self, DefCollector};
1919
use rustc::ty;
20-
use std::cell::Cell;
21-
use std::rc::Rc;
2220
use syntax::ast::{self, Name, Ident};
23-
use syntax::attr;
21+
use syntax::attr::{self, HasAttrs};
2422
use syntax::errors::DiagnosticBuilder;
25-
use syntax::ext::base::{self, Determinacy, MultiModifier, MultiDecorator};
26-
use syntax::ext::base::{Resolver as SyntaxResolver, SyntaxExtension};
27-
use syntax::ext::base::MacroKind;
28-
use syntax::ext::expand::Expansion;
23+
use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
24+
use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
25+
use syntax::ext::expand::{Expansion, ExpansionKind, Invocation, InvocationKind, find_attr_invoc};
2926
use syntax::ext::hygiene::Mark;
27+
use syntax::ext::placeholders::placeholder;
3028
use syntax::ext::tt::macro_rules;
3129
use syntax::feature_gate::{self, emit_feature_err, GateIssue};
3230
use syntax::fold::{self, Folder};
@@ -35,6 +33,10 @@ use syntax::symbol::{Symbol, keywords};
3533
use syntax::util::lev_distance::find_best_match_for_name;
3634
use syntax_pos::{Span, DUMMY_SP};
3735

36+
use std::cell::Cell;
37+
use std::mem;
38+
use std::rc::Rc;
39+
3840
#[derive(Clone)]
3941
pub struct InvocationData<'a> {
4042
pub module: Cell<Module<'a>>,
@@ -235,8 +237,64 @@ impl<'a> base::Resolver for Resolver<'a> {
235237
None
236238
}
237239

238-
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind,
239-
force: bool) -> Result<Rc<SyntaxExtension>, Determinacy> {
240+
fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
241+
-> Result<Option<Rc<SyntaxExtension>>, Determinacy> {
242+
let (attr, traits, item) = match invoc.kind {
243+
InvocationKind::Attr { attr: None, .. } => return Ok(None),
244+
InvocationKind::Attr { ref mut attr, ref traits, ref mut item } => (attr, traits, item),
245+
InvocationKind::Bang { ref mac, .. } => {
246+
return self.resolve_macro(scope, &mac.node.path, MacroKind::Bang, force).map(Some);
247+
}
248+
InvocationKind::Derive { name, span, .. } => {
249+
let path = ast::Path::from_ident(span, Ident::with_empty_ctxt(name));
250+
return self.resolve_macro(scope, &path, MacroKind::Derive, force).map(Some);
251+
}
252+
};
253+
254+
let (attr_name, path) = {
255+
let attr = attr.as_ref().unwrap();
256+
(attr.name(), ast::Path::from_ident(attr.span, Ident::with_empty_ctxt(attr.name())))
257+
};
258+
259+
let mut determined = true;
260+
match self.resolve_macro(scope, &path, MacroKind::Attr, force) {
261+
Ok(ext) => return Ok(Some(ext)),
262+
Err(Determinacy::Undetermined) => determined = false,
263+
Err(Determinacy::Determined) if force => return Err(Determinacy::Determined),
264+
Err(Determinacy::Determined) => {}
265+
}
266+
267+
for &(name, span) in traits {
268+
let path = ast::Path::from_ident(span, Ident::with_empty_ctxt(name));
269+
match self.resolve_macro(scope, &path, MacroKind::Derive, force) {
270+
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs) = *ext {
271+
if inert_attrs.contains(&attr_name) {
272+
// FIXME(jseyfried) Avoid `mem::replace` here.
273+
let dummy_item = placeholder(ExpansionKind::Items, ast::DUMMY_NODE_ID)
274+
.make_items().pop().unwrap();
275+
let dummy_item = Annotatable::Item(dummy_item);
276+
*item = mem::replace(item, dummy_item).map_attrs(|mut attrs| {
277+
let inert_attr = attr.take().unwrap();
278+
attr::mark_known(&inert_attr);
279+
if self.proc_macro_enabled {
280+
*attr = find_attr_invoc(&mut attrs);
281+
}
282+
attrs.push(inert_attr);
283+
attrs
284+
});
285+
}
286+
return Err(Determinacy::Undetermined);
287+
},
288+
Err(Determinacy::Undetermined) => determined = false,
289+
Err(Determinacy::Determined) => {}
290+
}
291+
}
292+
293+
Err(if determined { Determinacy::Determined } else { Determinacy::Undetermined })
294+
}
295+
296+
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
297+
-> Result<Rc<SyntaxExtension>, Determinacy> {
240298
let ast::Path { ref segments, span } = *path;
241299
if segments.iter().any(|segment| segment.parameters.is_some()) {
242300
let kind =

src/libsyntax/ext/base.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use attr::HasAttrs;
1515
use codemap::{self, CodeMap, ExpnInfo, Spanned, respan};
1616
use syntax_pos::{Span, ExpnId, NO_EXPANSION};
1717
use errors::{DiagnosticBuilder, FatalError};
18-
use ext::expand::{self, Expansion};
18+
use ext::expand::{self, Expansion, Invocation};
1919
use ext::hygiene::Mark;
2020
use fold::{self, Folder};
2121
use parse::{self, parser, DirectoryOwnership};
@@ -557,8 +557,10 @@ pub trait Resolver {
557557
fn resolve_imports(&mut self);
558558
// Resolves attribute and derive legacy macros from `#![plugin(..)]`.
559559
fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<Attribute>) -> Option<Attribute>;
560-
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind,
561-
force: bool) -> Result<Rc<SyntaxExtension>, Determinacy>;
560+
fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
561+
-> Result<Option<Rc<SyntaxExtension>>, Determinacy>;
562+
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
563+
-> Result<Rc<SyntaxExtension>, Determinacy>;
562564
}
563565

564566
#[derive(Copy, Clone, Debug)]
@@ -580,6 +582,10 @@ impl Resolver for DummyResolver {
580582

581583
fn resolve_imports(&mut self) {}
582584
fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>) -> Option<Attribute> { None }
585+
fn resolve_invoc(&mut self, _invoc: &mut Invocation, _scope: Mark, _force: bool)
586+
-> Result<Option<Rc<SyntaxExtension>>, Determinacy> {
587+
Err(Determinacy::Determined)
588+
}
583589
fn resolve_macro(&mut self, _scope: Mark, _path: &ast::Path, _kind: MacroKind,
584590
_force: bool) -> Result<Rc<SyntaxExtension>, Determinacy> {
585591
Err(Determinacy::Determined)

src/libsyntax/ext/expand.rs

+2-60
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
251251

252252
let scope =
253253
if self.monotonic { invoc.expansion_data.mark } else { orig_expansion_data.mark };
254-
let ext = match self.resolve_invoc(&mut invoc, scope, force) {
254+
let ext = match self.cx.resolver.resolve_invoc(&mut invoc, scope, force) {
255255
Ok(ext) => Some(ext),
256256
Err(Determinacy::Determined) => None,
257257
Err(Determinacy::Undetermined) => {
@@ -364,64 +364,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
364364
result
365365
}
366366

367-
fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
368-
-> Result<Option<Rc<SyntaxExtension>>, Determinacy> {
369-
let (attr, traits, item) = match invoc.kind {
370-
InvocationKind::Bang { ref mac, .. } => {
371-
return self.cx.resolver.resolve_macro(scope, &mac.node.path,
372-
MacroKind::Bang, force).map(Some);
373-
}
374-
InvocationKind::Attr { attr: None, .. } => return Ok(None),
375-
InvocationKind::Derive { name, span, .. } => {
376-
let path = ast::Path::from_ident(span, Ident::with_empty_ctxt(name));
377-
return self.cx.resolver.resolve_macro(scope, &path,
378-
MacroKind::Derive, force).map(Some)
379-
}
380-
InvocationKind::Attr { ref mut attr, ref traits, ref mut item } => (attr, traits, item),
381-
};
382-
383-
let (attr_name, path) = {
384-
let attr = attr.as_ref().unwrap();
385-
(attr.name(), ast::Path::from_ident(attr.span, Ident::with_empty_ctxt(attr.name())))
386-
};
387-
388-
let mut determined = true;
389-
match self.cx.resolver.resolve_macro(scope, &path, MacroKind::Attr, force) {
390-
Ok(ext) => return Ok(Some(ext)),
391-
Err(Determinacy::Undetermined) => determined = false,
392-
Err(Determinacy::Determined) if force => return Err(Determinacy::Determined),
393-
_ => {}
394-
}
395-
396-
for &(name, span) in traits {
397-
let path = ast::Path::from_ident(span, Ident::with_empty_ctxt(name));
398-
match self.cx.resolver.resolve_macro(scope, &path, MacroKind::Derive, force) {
399-
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs) = *ext {
400-
if inert_attrs.contains(&attr_name) {
401-
// FIXME(jseyfried) Avoid `mem::replace` here.
402-
let dummy_item = placeholder(ExpansionKind::Items, ast::DUMMY_NODE_ID)
403-
.make_items().pop().unwrap();
404-
*item = mem::replace(item, Annotatable::Item(dummy_item))
405-
.map_attrs(|mut attrs| {
406-
let inert_attr = attr.take().unwrap();
407-
attr::mark_known(&inert_attr);
408-
if self.cx.ecfg.proc_macro_enabled() {
409-
*attr = find_attr_invoc(&mut attrs);
410-
}
411-
attrs.push(inert_attr);
412-
attrs
413-
});
414-
}
415-
return Err(Determinacy::Undetermined);
416-
},
417-
Err(Determinacy::Undetermined) => determined = false,
418-
Err(Determinacy::Determined) => {}
419-
}
420-
}
421-
422-
Err(if determined { Determinacy::Determined } else { Determinacy::Undetermined })
423-
}
424-
425367
fn expand_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> Expansion {
426368
match invoc.kind {
427369
InvocationKind::Bang { .. } => self.expand_bang_invoc(invoc, ext),
@@ -802,7 +744,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
802744
}
803745
}
804746

805-
fn find_attr_invoc(attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
747+
pub fn find_attr_invoc(attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
806748
for i in 0 .. attrs.len() {
807749
if !attr::is_known(&attrs[i]) && !is_builtin_attr(&attrs[i]) {
808750
return Some(attrs.remove(i));

0 commit comments

Comments
 (0)