diff options
| author | Giacomo Stevanato <giaco.stevanato@gmail.com> | 2021-09-21 15:36:52 +0200 |
|---|---|---|
| committer | Giacomo Stevanato <giaco.stevanato@gmail.com> | 2021-09-27 16:59:25 +0200 |
| commit | 0d49da5e1845a3f1c3aff5d65239b08d8315f529 (patch) | |
| tree | 41b8c21bc31c398b5dbe91758f1b9bb179cb1253 | |
| parent | 5347c3ab5989a968b8e942104bdb3b55fb7e7d6f (diff) | |
| download | rust-0d49da5e1845a3f1c3aff5d65239b08d8315f529.tar.gz rust-0d49da5e1845a3f1c3aff5d65239b08d8315f529.zip | |
Move `GenericParams`'s handling of `impl Trait` into `GenericParams::generic_params_query`
| -rw-r--r-- | crates/hir_def/src/generics.rs | 50 | ||||
| -rw-r--r-- | crates/hir_def/src/item_tree.rs | 2 | ||||
| -rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 17 | ||||
| -rw-r--r-- | crates/hir_def/src/item_tree/pretty.rs | 6 |
4 files changed, 50 insertions, 25 deletions
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 0921ecea6fc..8c5313fa458 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs @@ -7,13 +7,15 @@ use base_db::FileId; use either::Either; use hir_expand::{ name::{AsName, Name}, - HirFileId, InFile, + ExpandResult, HirFileId, InFile, }; use la_arena::{Arena, ArenaMap}; +use once_cell::unsync::Lazy; +use std::ops::DerefMut; use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds}; use crate::{ - body::LowerCtx, + body::{Expander, LowerCtx}, child_by_source::ChildBySource, db::DefDatabase, dyn_map::DynMap, @@ -21,8 +23,8 @@ use crate::{ keys, src::{HasChildSource, HasSource}, type_ref::{LifetimeRef, TypeBound, TypeRef}, - AdtId, ConstParamId, GenericDefId, LifetimeParamId, LocalConstParamId, LocalLifetimeParamId, - LocalTypeParamId, Lookup, TypeParamId, + AdtId, ConstParamId, GenericDefId, HasModule, LifetimeParamId, LocalConstParamId, + LocalLifetimeParamId, LocalTypeParamId, Lookup, TypeParamId, }; /// Data about a generic type parameter (to a function, struct, impl, ...). @@ -99,10 +101,23 @@ impl GenericParams { match def { GenericDefId::FunctionId(id) => { - let id = id.lookup(db).id; - let tree = id.item_tree(db); - let item = &tree[id.value]; - item.generic_params.clone() + let loc = id.lookup(db); + let tree = loc.id.item_tree(db); + let item = &tree[loc.id.value]; + + let mut generic_params = GenericParams::clone(&item.explicit_generic_params); + + let module = loc.container.module(db); + let func_data = db.function_data(id); + + // Don't create an `Expander` nor call `loc.source(db)` if not needed since this + // causes a reparse after the `ItemTree` has been created. + let mut expander = Lazy::new(|| Expander::new(db, loc.source(db).file_id, module)); + for param in &func_data.params { + generic_params.fill_implicit_impl_trait_args(db, &mut expander, param); + } + + Interned::new(generic_params) } GenericDefId::AdtId(AdtId::StructId(id)) => { let id = id.lookup(db).id; @@ -259,7 +274,12 @@ impl GenericParams { self.where_predicates.push(predicate); } - pub(crate) fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { + pub(crate) fn fill_implicit_impl_trait_args( + &mut self, + db: &dyn DefDatabase, + expander: &mut impl DerefMut<Target = Expander>, + type_ref: &TypeRef, + ) { type_ref.walk(&mut |type_ref| { if let TypeRef::ImplTrait(bounds) = type_ref { let param = TypeParamData { @@ -275,6 +295,18 @@ impl GenericParams { }); } } + if let TypeRef::Macro(mc) = type_ref { + let macro_call = mc.to_node(db.upcast()); + match expander.enter_expand::<ast::Type>(db, macro_call) { + Ok(ExpandResult { value: Some((mark, expanded)), .. }) => { + let ctx = LowerCtx::new(db, mc.file_id); + let type_ref = TypeRef::from_ast(&ctx, expanded); + self.fill_implicit_impl_trait_args(db, expander, &type_ref); + expander.exit(db, mark); + } + _ => {} + } + } }); } diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index df46ceeaeed..3900e7e97cc 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -605,7 +605,7 @@ pub struct ExternBlock { pub struct Function { pub name: Name, pub visibility: RawVisibilityId, - pub generic_params: Interned<GenericParams>, + pub explicit_generic_params: Interned<GenericParams>, pub abi: Option<Interned<str>>, pub params: IdRange<Param>, pub ret_type: Interned<TypeRef>, diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 6d34556b3ea..9c278f5ac6b 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -401,7 +401,7 @@ impl<'a> Ctx<'a> { let mut res = Function { name, visibility, - generic_params: Interned::new(GenericParams::default()), + explicit_generic_params: Interned::new(GenericParams::default()), abi, params, ret_type: Interned::new(ret_type), @@ -409,7 +409,8 @@ impl<'a> Ctx<'a> { ast_id, flags, }; - res.generic_params = self.lower_generic_params(GenericsOwner::Function(&res), func); + res.explicit_generic_params = + self.lower_generic_params(GenericsOwner::Function(&res), func); Some(id(self.data().functions.alloc(res))) } @@ -664,16 +665,8 @@ impl<'a> Ctx<'a> { ) -> Interned<GenericParams> { let mut generics = GenericParams::default(); match owner { - GenericsOwner::Function(func) => { - generics.fill(&self.body_ctx, node); - // lower `impl Trait` in arguments - for id in func.params.clone() { - if let Param::Normal(ty) = &self.data().params[id] { - generics.fill_implicit_impl_trait_args(ty); - } - } - } - GenericsOwner::Struct + GenericsOwner::Function(_) + | GenericsOwner::Struct | GenericsOwner::Enum | GenericsOwner::Union | GenericsOwner::TypeAlias => { diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs index 3e33b0c46c2..49dc1eef18b 100644 --- a/crates/hir_def/src/item_tree/pretty.rs +++ b/crates/hir_def/src/item_tree/pretty.rs @@ -234,7 +234,7 @@ impl<'a> Printer<'a> { let Function { name, visibility, - generic_params, + explicit_generic_params, abi, params, ret_type, @@ -250,7 +250,7 @@ impl<'a> Printer<'a> { w!(self, "extern \"{}\" ", abi); } w!(self, "fn {}", name); - self.print_generic_params(generic_params); + self.print_generic_params(explicit_generic_params); w!(self, "("); if !params.is_empty() { self.indented(|this| { @@ -271,7 +271,7 @@ impl<'a> Printer<'a> { } w!(self, ") -> "); self.print_type_ref(ret_type); - self.print_where_clause(generic_params); + self.print_where_clause(explicit_generic_params); wln!(self, ";"); } ModItem::Struct(it) => { |
