From 7ed42a3a527b2c39826cfeb3626521c11abb25f0 Mon Sep 17 00:00:00 2001 From: cynecx Date: Sat, 17 Apr 2021 17:38:38 +0200 Subject: hir_def: refactor expand_macro_type and cleanups --- crates/hir_def/src/body.rs | 72 +++++++++----------------------------- crates/hir_def/src/type_ref.rs | 78 ++++++++---------------------------------- crates/hir_ty/src/lower.rs | 6 ++-- 3 files changed, 33 insertions(+), 123 deletions(-) (limited to 'crates') diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 44ae13643..8a9b936ea 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs @@ -19,7 +19,7 @@ use hir_expand::{ use la_arena::{Arena, ArenaMap}; use profile::Count; use rustc_hash::FxHashMap; -use syntax::{ast, AstNode, AstPtr, SyntaxNode}; +use syntax::{ast, AstNode, AstPtr}; pub use lower::LowerCtx; @@ -98,14 +98,11 @@ impl Expander { } } - fn enter_expand_intern( + pub(crate) fn enter_expand( &mut self, db: &dyn DefDatabase, macro_call: ast::MacroCall, - ) -> Result< - ExpandResult Mark + '_)>>, - UnresolvedMacro, - > { + ) -> Result>, UnresolvedMacro> { if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT { cov_mark::hit!(your_stack_belongs_to_me); return Ok(ExpandResult::str_err( @@ -150,55 +147,6 @@ impl Expander { } }; - let this = self; - - let advance_state = move |db: &dyn DefDatabase| { - this.recursion_limit += 1; - let mark = Mark { - file_id: this.current_file_id, - ast_id_map: mem::take(&mut this.ast_id_map), - bomb: DropBomb::new("expansion mark dropped"), - }; - this.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id); - this.current_file_id = file_id; - this.ast_id_map = db.ast_id_map(file_id); - mark - }; - - Ok(ExpandResult { value: Some((raw_node, advance_state)), err }) - } - - pub(crate) fn enter_expand_raw( - &mut self, - db: &dyn DefDatabase, - macro_call: ast::MacroCall, - ) -> Result>, UnresolvedMacro> { - let (raw_node, mut advance_state, err) = match self.enter_expand_intern(db, macro_call)? { - ExpandResult { value: Some((raw_node, advance_state)), err } => { - (raw_node, advance_state, err) - } - ExpandResult { value: None, err } => return Ok(ExpandResult { value: None, err }), - }; - - log::debug!("macro expansion {:#?}", raw_node); - - let mark = advance_state(db); - - Ok(ExpandResult { value: Some((mark, raw_node)), err }) - } - - pub(crate) fn enter_expand( - &mut self, - db: &dyn DefDatabase, - macro_call: ast::MacroCall, - ) -> Result>, UnresolvedMacro> { - let (raw_node, mut advance_state, err) = match self.enter_expand_intern(db, macro_call)? { - ExpandResult { value: Some((raw_node, advance_state)), err } => { - (raw_node, advance_state, err) - } - ExpandResult { value: None, err } => return Ok(ExpandResult { value: None, err }), - }; - let node = match T::cast(raw_node) { Some(it) => it, None => { @@ -209,7 +157,15 @@ impl Expander { log::debug!("macro expansion {:#?}", node.syntax()); - let mark = advance_state(db); + self.recursion_limit += 1; + let mark = Mark { + file_id: self.current_file_id, + ast_id_map: mem::take(&mut self.ast_id_map), + bomb: DropBomb::new("expansion mark dropped"), + }; + self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id); + self.current_file_id = file_id; + self.ast_id_map = db.ast_id_map(file_id); Ok(ExpandResult { value: Some((mark, node)), err }) } @@ -234,6 +190,10 @@ impl Expander { &self.cfg_expander.cfg_options } + pub(crate) fn current_file_id(&self) -> HirFileId { + self.current_file_id + } + fn parse_path(&mut self, path: ast::Path) -> Option { let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene); Path::from_src(path, &ctx) diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index 0832371c0..cf8a584ab 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs @@ -1,9 +1,8 @@ //! HIR for references to types. Paths in these are not yet resolved. They can //! be directly created from an ast::TypeRef, without further queries. -use std::borrow::Cow; use hir_expand::{ast_id_map::FileAstId, name::Name, ExpandResult, InFile}; -use syntax::{algo::SyntaxRewriter, ast, AstNode, SyntaxKind, SyntaxNode}; +use syntax::ast; use crate::{ body::{Expander, LowerCtx}, @@ -207,16 +206,6 @@ impl TypeRef { TypeRef::Tuple(Vec::new()) } - pub fn has_macro_calls(&self) -> bool { - let mut has_macro_call = false; - self.walk(&mut |ty_ref| { - if let TypeRef::Macro(_) = ty_ref { - has_macro_call |= true - } - }); - has_macro_call - } - pub fn walk(&self, f: &mut impl FnMut(&TypeRef)) { go(self, f); @@ -315,68 +304,29 @@ impl TypeBound { } } -pub fn expand_type_ref<'a>( +pub fn expand_macro_type( db: &dyn DefDatabase, module_id: ModuleId, - type_ref: &'a TypeRef, -) -> Option> { - let macro_call = match type_ref { + macro_type: &TypeRef, +) -> Option { + let macro_call = match macro_type { TypeRef::Macro(macro_call) => macro_call, - _ => return Some(Cow::Borrowed(type_ref)), + _ => panic!("expected TypeRef::Macro"), }; let file_id = macro_call.file_id; let macro_call = macro_call.to_node(db.upcast()); let mut expander = Expander::new(db, file_id, module_id); - let expanded = expand(db, &mut expander, ¯o_call, true)?; - - let node = ast::Type::cast(expanded)?; - - let ctx = LowerCtx::new(db, file_id); - return Some(Cow::Owned(TypeRef::from_ast(&ctx, node))); - - fn expand( - db: &dyn DefDatabase, - expander: &mut Expander, - macro_call: &ast::MacroCall, - expect_type: bool, - ) -> Option { - let (mark, mut expanded) = match expander.enter_expand_raw(db, macro_call.clone()) { - Ok(ExpandResult { value: Some((mark, expanded)), .. }) => (mark, expanded), - _ => return None, - }; - - if expect_type && !ast::Type::can_cast(expanded.kind()) { + let (file_id, expanded) = match expander.enter_expand::(db, macro_call.clone()) { + Ok(ExpandResult { value: Some((mark, expanded)), .. }) => { + let file_id = expander.current_file_id(); expander.exit(db, mark); - return None; - } - - if ast::MacroType::can_cast(expanded.kind()) { - expanded = expanded.first_child()?; // MACRO_CALL + (file_id, expanded) } + _ => return None, + }; - let mut rewriter = SyntaxRewriter::default(); - - let children = expanded.descendants().filter_map(ast::MacroCall::cast); - for child in children { - if let Some(new_node) = expand(db, expander, &child, false) { - if expanded == *child.syntax() { - expanded = new_node; - } else { - let parent = child.syntax().parent(); - let old_node = match &parent { - Some(node) if node.kind() == SyntaxKind::MACRO_TYPE => node, - _ => child.syntax(), - }; - rewriter.replace(old_node, &new_node) - } - } - } - - expander.exit(db, mark); - - let res = rewriter.rewrite(&expanded); - Some(res) - } + let ctx = LowerCtx::new(db, file_id); + return Some(TypeRef::from_ast(&ctx, expanded)); } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 95ca5bdb0..e01b7aa91 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -15,7 +15,7 @@ use hir_def::{ generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget}, path::{GenericArg, Path, PathSegment, PathSegments}, resolver::{HasResolver, Resolver, TypeNs}, - type_ref::{expand_type_ref, TraitRef as HirTraitRef, TypeBound, TypeRef}, + type_ref::{expand_macro_type, TraitRef as HirTraitRef, TypeBound, TypeRef}, AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, VariantId, @@ -289,8 +289,8 @@ impl<'a> TyLoweringContext<'a> { } mt @ TypeRef::Macro(_) => { if let Some(module_id) = self.resolver.module() { - match expand_type_ref(self.db.upcast(), module_id, mt) { - Some(type_ref) => self.lower_ty(type_ref.as_ref()), + match expand_macro_type(self.db.upcast(), module_id, mt) { + Some(type_ref) => self.lower_ty(&type_ref), None => TyKind::Error.intern(&Interner), } } else { -- cgit v1.2.3