Change:
I was migrating my library (Mammut) to use reqwest and be async, and the compiler ICEd. I don't know how to reduce it further than this. I tried this code: I expected to see this happen: A successful build or another compile error Instead, this happened: I also tried this on the latest nightly and it emits the same error. : Backtrace:
Reproduced with lastest nighlty: ICE from macro resolving I believe. cc
cc
triage: P-high, removing nomination tag. (instead, going to proritize going through the P-high issues that have accumulated over last two weeks.)
Visiting from triage.. the next step is to reduce the reproducer.
Reduced ():
Further reduced:
Fixed in

Discussion:
use rustc::hir::map::definitions::*; use rustc_ast::ast::*; use rustc_ast::token::{self, Token}; <del> use rustc_ast::visit; </del> <ins> use rustc_ast::visit::{self, FnKind}; </ins> use rustc_expand::expand::AstFragment; use rustc_hir::def_id::DefIndex; use rustc_span::hygiene::ExpnId;

self.parent_def = orig_parent_def; } <del> fn visit_async_fn( &mut self, id: NodeId, name: Name, span: Span, header: &FnHeader, generics: &'a Generics, decl: &'a FnDecl, body: Option<&'a Block>, ) { let (closure_id, return_impl_trait_id) = match header.asyncness { Async::Yes { span: _, closure_id, return_impl_trait_id } => { (closure_id, return_impl_trait_id) } _ => unreachable!(), }; // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. let fn_def_data = DefPathData::ValueNs(name); let fn_def = self.create_def(id, fn_def_data, span); return self.with_parent(fn_def, |this| { this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); visit::walk_generics(this, generics); visit::walk_fn_decl(this, decl); let closure_def = this.create_def(closure_id, DefPathData::ClosureExpr, span); this.with_parent(closure_def, |this| { if let Some(body) = body { visit::walk_block(this, body); } }) }); } </del> fn collect_field(&mut self, field: &'a StructField, index: Option<usize>) { let index = |this: &Self| { index.unwrap_or_else(|| {

| ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), <del> ItemKind::Fn(_, sig, generics, body) if sig.header.asyncness.is_async() => { return self.visit_async_fn( i.id, i.ident.name, i.span, &sig.header, generics, &sig.decl, body.as_deref(), ); } </del> ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => { DefPathData::ValueNs(i.ident.name) }

}); } <ins> fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { if let FnKind::Fn(_, _, sig, _, body) = fn_kind { if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness { self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. Besides that, // we must mirror everything that `visit::walk_fn` below does. self.visit_fn_header(&sig.header); visit::walk_fn_decl(self, &sig.decl); if let Some(body) = body { let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span); self.with_parent(closure_def, |this| this.visit_block(body)); } return; } } visit::walk_fn(self, fn_kind, span); } </ins> fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) { self.create_def(id, DefPathData::Misc, use_tree.span); visit::walk_use_tree(self, use_tree, id);

fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) { let def_data = match &i.kind { <del> AssocItemKind::Fn(_, FnSig { header, decl }, generics, body) if header.asyncness.is_async() => { return self.visit_async_fn( i.id, i.ident.name, i.span, header, generics, decl, body.as_deref(), ); } </del> AssocItemKind::Fn(..) | AssocItemKind::Const(..) => DefPathData::ValueNs(i.ident.name), AssocItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), AssocItemKind::Macro(..) => return self.visit_macro_invoc(i.id),

<ins> // check-pass // edition:2018 macro_rules! with_doc { ($doc: expr) => { #[doc = $doc] async fn f() {} }; } with_doc!(concat!("")); fn main() {} </ins>