]> git.lizzy.rs Git - rust.git/commitdiff
hir_def: refactor expand_macro_type and cleanups
authorcynecx <me@cynecx.net>
Sat, 17 Apr 2021 15:38:38 +0000 (17:38 +0200)
committercynecx <me@cynecx.net>
Sat, 17 Apr 2021 15:38:45 +0000 (17:38 +0200)
crates/hir_def/src/body.rs
crates/hir_def/src/type_ref.rs
crates/hir_ty/src/lower.rs

index 44ae136437fc3d86028be87e9a3e4ca99fe72f3b..8a9b936ea40474b446e4e523222e4c8a735fd2d0 100644 (file)
@@ -19,7 +19,7 @@
 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 @@ pub(crate) fn new(
         }
     }
 
-    fn enter_expand_intern(
+    pub(crate) fn enter_expand<T: ast::AstNode>(
         &mut self,
         db: &dyn DefDatabase,
         macro_call: ast::MacroCall,
-    ) -> Result<
-        ExpandResult<Option<(SyntaxNode, impl FnMut(&dyn DefDatabase) -> Mark + '_)>>,
-        UnresolvedMacro,
-    > {
+    ) -> Result<ExpandResult<Option<(Mark, T)>>, 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 @@ fn enter_expand_intern(
             }
         };
 
-        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<ExpandResult<Option<(Mark, SyntaxNode)>>, 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<T: ast::AstNode>(
-        &mut self,
-        db: &dyn DefDatabase,
-        macro_call: ast::MacroCall,
-    ) -> Result<ExpandResult<Option<(Mark, T)>>, 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 @@ pub(crate) fn enter_expand<T: ast::AstNode>(
 
         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 @@ pub(crate) fn cfg_options(&self) -> &CfgOptions {
         &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<Path> {
         let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene);
         Path::from_src(path, &ctx)
index 0832371c0dcf17fa84744e709540222968e21933..cf8a584ab67732bc14f873f12ca3268b5670984a 100644 (file)
@@ -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 @@ pub(crate) fn unit() -> 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 @@ pub fn as_path(&self) -> Option<&Path> {
     }
 }
 
-pub fn expand_type_ref<'a>(
+pub fn expand_macro_type(
     db: &dyn DefDatabase,
     module_id: ModuleId,
-    type_ref: &'a TypeRef,
-) -> Option<Cow<'a, TypeRef>> {
-    let macro_call = match type_ref {
+    macro_type: &TypeRef,
+) -> Option<TypeRef> {
+    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, &macro_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<SyntaxNode> {
-        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::<ast::Type>(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));
 }
index 95ca5bdb0971d5a7427e9b14480dc08712cc576b..e01b7aa91906d25461e1ea9eabc6f4c021e6e343 100644 (file)
@@ -15,7 +15,7 @@
     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 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
             }
             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 {