mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-26 13:54:06 +00:00
hir_def: refactor expand_macro_type and cleanups
This commit is contained in:
parent
14918a3870
commit
7ed42a3a52
@ -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<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 @@ 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<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 @@ 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<Path> {
|
||||
let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene);
|
||||
Path::from_src(path, &ctx)
|
||||
|
@ -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<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, ¯o_call, true)?;
|
||||
|
||||
let node = ast::Type::cast(expanded)?;
|
||||
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);
|
||||
(file_id, expanded)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
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()) {
|
||||
expander.exit(db, mark);
|
||||
return None;
|
||||
}
|
||||
|
||||
if ast::MacroType::can_cast(expanded.kind()) {
|
||||
expanded = expanded.first_child()?; // MACRO_CALL
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
return Some(TypeRef::from_ast(&ctx, expanded));
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user