diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 622c836d12..3b262e3bd8 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -3,7 +3,7 @@ mod lower; use std::{ops::Index, sync::Arc}; -use hir_expand::{either::Either, HirFileId, MacroDefId, Source}; +use hir_expand::{either::Either, hygiene::Hygiene, HirFileId, MacroDefId, Source}; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstPtr}; use rustc_hash::FxHashMap; @@ -20,13 +20,34 @@ pub struct Expander { crate_def_map: Arc, original_file_id: HirFileId, current_file_id: HirFileId, + hygiene: Hygiene, module: ModuleId, } impl Expander { pub fn new(db: &impl DefDatabase2, current_file_id: HirFileId, module: ModuleId) -> Expander { let crate_def_map = db.crate_def_map(module.krate); - Expander { crate_def_map, original_file_id: current_file_id, current_file_id, module } + let hygiene = Hygiene::new(db, current_file_id); + Expander { + crate_def_map, + original_file_id: current_file_id, + current_file_id, + hygiene, + module, + } + } + + fn enter(&mut self, db: &impl DefDatabase2, file_id: HirFileId) -> Mark { + let mark = Mark { file_id: self.current_file_id }; + self.hygiene = Hygiene::new(db, file_id); + self.current_file_id = file_id; + mark + } + + fn exit(&mut self, db: &impl DefDatabase2, mark: Mark) { + self.hygiene = Hygiene::new(db, mark.file_id); + self.current_file_id = mark.file_id; + std::mem::forget(mark); } // FIXME: remove this. @@ -43,6 +64,18 @@ impl Expander { } } +struct Mark { + file_id: HirFileId, +} + +impl Drop for Mark { + fn drop(&mut self) { + if !std::thread::panicking() { + panic!("dropped mark") + } + } +} + /// The body of an item (function, const etc.). #[derive(Debug, Eq, PartialEq)] pub struct Body { diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 1ea8ce249c..5c291421a1 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -2,7 +2,6 @@ use hir_expand::{ either::Either, - hygiene::Hygiene, name::{self, AsName, Name}, AstId, MacroCallLoc, MacroFileKind, }; @@ -447,10 +446,9 @@ where if let Some(node) = self.db.parse_or_expand(file_id) { if let Some(expr) = ast::Expr::cast(node) { log::debug!("macro expansion {:#?}", expr.syntax()); - let old_file_id = - std::mem::replace(&mut self.expander.current_file_id, file_id); + let mark = self.expander.enter(self.db, file_id); let id = self.collect_expr(expr); - self.expander.current_file_id = old_file_id; + self.expander.exit(self.db, mark); return id; } } @@ -572,8 +570,7 @@ where } fn parse_path(&mut self, path: ast::Path) -> Option { - let hygiene = Hygiene::new(self.db, self.expander.current_file_id); - Path::from_src(path, &hygiene) + Path::from_src(path, &self.expander.hygiene) } }