diff options
| author | Josh Driver <keeperofdakeys@gmail.com> | 2017-02-06 22:14:38 +1030 |
|---|---|---|
| committer | Josh Driver <keeperofdakeys@gmail.com> | 2017-02-16 22:03:15 +1030 |
| commit | 2d91e7aab8e91410d504ebfa48d16fca36b04614 (patch) | |
| tree | a0f9403ccd17cd8dd24f47712c42f6af6e39b4df /src/libsyntax/ext | |
| parent | 05a7f25cc42d08aa541f50876915489bdc0eb4bb (diff) | |
| download | rust-2d91e7aab8e91410d504ebfa48d16fca36b04614.tar.gz rust-2d91e7aab8e91410d504ebfa48d16fca36b04614.zip | |
Refactor macro resolution errors + add derive macro suggestions
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 44 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 14 |
2 files changed, 42 insertions, 16 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b5afd0c453a..b61ab74687b 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -474,6 +474,17 @@ impl MacResult for DummyResult { pub type BuiltinDeriveFn = for<'cx> fn(&'cx mut ExtCtxt, Span, &MetaItem, &Annotatable, &mut FnMut(Annotatable)); +/// Represents different kinds of macro invocations that can be resolved. +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum MacroKind { + /// A bang macro - foo!() + Bang, + /// An attribute macro - #[foo] + Attr, + /// A derive attribute macro - #[derive(Foo)] + Derive, +} + /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { /// A syntax extension that is attached to an item and creates new items @@ -520,6 +531,25 @@ pub enum SyntaxExtension { BuiltinDerive(BuiltinDeriveFn), } +impl SyntaxExtension { + /// Return which kind of macro calls this syntax extension. + pub fn kind(&self) -> MacroKind { + match *self { + SyntaxExtension::NormalTT(..) | + SyntaxExtension::IdentTT(..) | + SyntaxExtension::ProcMacro(..) => + MacroKind::Bang, + SyntaxExtension::MultiDecorator(..) | + SyntaxExtension::MultiModifier(..) | + SyntaxExtension::AttrProcMacro(..) => + MacroKind::Attr, + SyntaxExtension::ProcMacroDerive(..) | + SyntaxExtension::BuiltinDerive(..) => + MacroKind::Derive, + } + } +} + pub type NamedSyntaxExtension = (Name, SyntaxExtension); pub trait Resolver { @@ -535,10 +565,8 @@ pub trait Resolver { fn resolve_imports(&mut self); // Resolves attribute and derive legacy macros from `#![plugin(..)]`. fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<Attribute>) -> Option<Attribute>; - fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool) - -> Result<Rc<SyntaxExtension>, Determinacy>; - fn resolve_derive_macro(&mut self, scope: Mark, path: &ast::Path, force: bool) - -> Result<Rc<SyntaxExtension>, Determinacy>; + fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, + force: bool) -> Result<Rc<SyntaxExtension>, Determinacy>; } #[derive(Copy, Clone, Debug)] @@ -561,12 +589,8 @@ impl Resolver for DummyResolver { fn resolve_imports(&mut self) {} fn find_legacy_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>) -> Option<Attribute> { None } - fn resolve_macro(&mut self, _scope: Mark, _path: &ast::Path, _force: bool) - -> Result<Rc<SyntaxExtension>, Determinacy> { - Err(Determinacy::Determined) - } - fn resolve_derive_macro(&mut self, _scope: Mark, _path: &ast::Path, _force: bool) - -> Result<Rc<SyntaxExtension>, Determinacy> { + fn resolve_macro(&mut self, _scope: Mark, _path: &ast::Path, _kind: MacroKind, + _force: bool) -> Result<Rc<SyntaxExtension>, Determinacy> { Err(Determinacy::Determined) } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d011d7c2a1c..38494378f72 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -282,8 +282,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let mark = Mark::fresh(); derives.push(mark); let path = ast::Path::from_ident(span, Ident::with_empty_ctxt(name)); - let item = match self.cx.resolver - .resolve_macro(Mark::root(), &path, false) { + let item = match self.cx.resolver.resolve_macro( + Mark::root(), &path, MacroKind::Derive, false) { Ok(ext) => match *ext { SyntaxExtension::BuiltinDerive(..) => item_with_markers.clone(), _ => item.clone(), @@ -369,12 +369,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> { -> Result<Option<Rc<SyntaxExtension>>, Determinacy> { let (attr, traits, item) = match invoc.kind { InvocationKind::Bang { ref mac, .. } => { - return self.cx.resolver.resolve_macro(scope, &mac.node.path, force).map(Some); + return self.cx.resolver.resolve_macro(scope, &mac.node.path, + MacroKind::Bang, force).map(Some); } InvocationKind::Attr { attr: None, .. } => return Ok(None), InvocationKind::Derive { name, span, .. } => { let path = ast::Path::from_ident(span, Ident::with_empty_ctxt(name)); - return self.cx.resolver.resolve_derive_macro(scope, &path, force).map(Some); + return self.cx.resolver.resolve_macro(scope, &path, + MacroKind::Derive, force).map(Some) } InvocationKind::Attr { ref mut attr, ref traits, ref mut item } => (attr, traits, item), }; @@ -385,7 +387,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let mut determined = true; - match self.cx.resolver.resolve_macro(scope, &path, force) { + match self.cx.resolver.resolve_macro(scope, &path, MacroKind::Attr, force) { Ok(ext) => return Ok(Some(ext)), Err(Determinacy::Undetermined) => determined = false, Err(Determinacy::Determined) if force => return Err(Determinacy::Determined), @@ -394,7 +396,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { for &(name, span) in traits { let path = ast::Path::from_ident(span, Ident::with_empty_ctxt(name)); - match self.cx.resolver.resolve_macro(scope, &path, force) { + match self.cx.resolver.resolve_macro(scope, &path, MacroKind::Derive, force) { Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs) = *ext { if inert_attrs.contains(&attr_name) { // FIXME(jseyfried) Avoid `mem::replace` here. |
