Change:
This issue probably needs a better title, perhaps someone more familiar with the compiler's handling of macros can suggest a better one. Some kind of error message, at least. panic with exit code :
Simplified: Same ICE will happen if is changed to ///. Update: Panic happens at this line: has keys and , but the is .

Discussion:
use syntax::visit; use syntax::symbol::keywords; use syntax::symbol::Symbol; <ins> use syntax::parse::token::{self, Token}; </ins> use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE};

_ => visit::walk_stmt(self, stmt), } } <ins> fn visit_token(&mut self, t: Token) { if let Token::Interpolated(nt) = t { match nt.0 { token::NtExpr(ref expr) => { if let ExprKind::Mac(..) = expr.node { self.visit_macro_invoc(expr.id, false); } } _ => {} } } } </ins> }

use syntax::ext::base::Determinacy::Undetermined; use syntax::ext::hygiene::Mark; use syntax::ext::tt::macro_rules; <del> use syntax::parse::token; </del> <ins> use syntax::parse::token::{self, Token}; </ins> use syntax::symbol::keywords; use syntax::symbol::Symbol; use syntax::visit::{self, Visitor};

visit::walk_trait_item(self, item); self.resolver.current_module = parent; } <ins> fn visit_token(&mut self, t: Token) { if let Token::Interpolated(nt) = t { match nt.0 { token::NtExpr(ref expr) => { if let ast::ExprKind::Mac(..) = expr.node { self.visit_invoc(expr.id); } } _ => {} } } } </ins> }

use ast::*; use syntax_pos::Span; use codemap::Spanned; <ins> use parse::token::Token; use tokenstream::{TokenTree, TokenStream}; </ins> #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> {

fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) { walk_assoc_type_binding(self, type_binding) } <del> fn visit_attribute(&mut self, _attr: &'ast Attribute) {} </del> <ins> fn visit_attribute(&mut self, attr: &'ast Attribute) { walk_attribute(self, attr) } fn visit_tt(&mut self, tt: TokenTree) { walk_tt(self, tt) } fn visit_tts(&mut self, tts: TokenStream) { walk_tts(self, tts) } fn visit_token(&mut self, _t: Token) {} // FIXME: add `visit_interpolated` and `walk_interpolated` </ins> fn visit_vis(&mut self, vis: &'ast Visibility) { walk_vis(self, vis) }

visitor.visit_path(path, id); } } <ins> pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) { visitor.visit_tts(attr.tokens.clone()); } pub fn walk_tt<'a, V: Visitor<'a>>(visitor: &mut V, tt: TokenTree) { match tt { TokenTree::Token(_, tok) => visitor.visit_token(tok), TokenTree::Delimited(_, delimed) => visitor.visit_tts(delimed.stream()), } } pub fn walk_tts<'a, V: Visitor<'a>>(visitor: &mut V, tts: TokenStream) { for tt in tts.trees() { visitor.visit_tt(tt); } } </ins>

<ins> // Copyright 2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. macro_rules! a { () => { "a" } } macro_rules! b { ($doc:expr) => { #[doc = $doc] pub struct B; } } b!(a!()); fn main() {} </ins>