Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/item_tree/lower.rs')
| -rw-r--r-- | crates/hir-def/src/item_tree/lower.rs | 565 |
1 files changed, 82 insertions, 483 deletions
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 71848845a8..b490e1683c 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -3,42 +3,29 @@ use std::{cell::OnceCell, collections::hash_map::Entry}; use hir_expand::{ - mod_path::path, + HirFileId, + mod_path::PathKind, name::AsName, span_map::{SpanMap, SpanMapRef}, - HirFileId, }; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use la_arena::Arena; -use rustc_hash::FxHashMap; -use span::{AstIdMap, SyntaxContextId}; -use stdx::thin_vec::ThinVec; +use span::{AstIdMap, SyntaxContext}; use syntax::{ - ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString}, AstNode, + ast::{self, HasModuleItem, HasName, IsString}, }; use triomphe::Arc; use crate::{ db::DefDatabase, - generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance}, item_tree::{ - AssocItem, AttrOwner, Const, Either, Enum, ExternBlock, ExternCrate, Field, FieldParent, - FieldsShape, FileItemTreeId, FnFlags, Function, GenericArgs, GenericItemSourceMapBuilder, - GenericModItem, Idx, Impl, ImportAlias, Interned, ItemTree, ItemTreeData, - ItemTreeSourceMaps, ItemTreeSourceMapsBuilder, Macro2, MacroCall, MacroRules, Mod, ModItem, - ModKind, ModPath, Mutability, Name, Param, Path, Range, RawAttrs, RawIdx, RawVisibilityId, - Static, Struct, StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind, - Variant, - }, - lower::LowerCtx, - path::AssociatedTypeBinding, - type_ref::{ - LifetimeRef, PathId, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, - TypesMap, TypesSourceMap, + AssocItem, AttrOwner, Const, Enum, ExternBlock, ExternCrate, Field, FieldParent, + FieldsShape, FileItemTreeId, Function, Idx, Impl, ImportAlias, Interned, ItemTree, + ItemTreeData, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, ModPath, Name, Range, + RawAttrs, RawIdx, RawVisibility, RawVisibilityId, Static, Struct, StructKind, Trait, + TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind, Variant, VisibilityExplicitness, }, - visibility::RawVisibility, - LocalLifetimeParamId, LocalTypeOrConstParamId, }; fn id<N>(index: Idx<N>) -> FileItemTreeId<N> { @@ -49,11 +36,8 @@ pub(super) struct Ctx<'a> { db: &'a dyn DefDatabase, tree: ItemTree, source_ast_id_map: Arc<AstIdMap>, - generic_param_attr_buffer: - FxHashMap<Either<LocalTypeOrConstParamId, LocalLifetimeParamId>, RawAttrs>, span_map: OnceCell<SpanMap>, file: HirFileId, - source_maps: ItemTreeSourceMapsBuilder, } impl<'a> Ctx<'a> { @@ -61,11 +45,9 @@ impl<'a> Ctx<'a> { Self { db, tree: ItemTree::default(), - generic_param_attr_buffer: FxHashMap::default(), source_ast_id_map: db.ast_id_map(file), file, span_map: OnceCell::new(), - source_maps: ItemTreeSourceMapsBuilder::default(), } } @@ -73,39 +55,13 @@ impl<'a> Ctx<'a> { self.span_map.get_or_init(|| self.db.span_map(self.file)).as_ref() } - fn body_ctx<'b, 'c>( - &self, - types_map: &'b mut TypesMap, - types_source_map: &'b mut TypesSourceMap, - ) -> LowerCtx<'c> - where - 'a: 'c, - 'b: 'c, - { - // FIXME: This seems a bit wasteful that if `LowerCtx` will initialize the span map we won't benefit. - LowerCtx::with_span_map_cell( - self.db, - self.file, - self.span_map.clone(), - types_map, - types_source_map, - ) - } - - pub(super) fn lower_module_items( - mut self, - item_owner: &dyn HasModuleItem, - ) -> (ItemTree, ItemTreeSourceMaps) { + pub(super) fn lower_module_items(mut self, item_owner: &dyn HasModuleItem) -> ItemTree { self.tree.top_level = item_owner.items().flat_map(|item| self.lower_mod_item(&item)).collect(); - assert!(self.generic_param_attr_buffer.is_empty()); - (self.tree, self.source_maps.build()) + self.tree } - pub(super) fn lower_macro_stmts( - mut self, - stmts: ast::MacroStmts, - ) -> (ItemTree, ItemTreeSourceMaps) { + pub(super) fn lower_macro_stmts(mut self, stmts: ast::MacroStmts) -> ItemTree { self.tree.top_level = stmts .statements() .filter_map(|stmt| { @@ -135,14 +91,11 @@ impl<'a> Ctx<'a> { } } - assert!(self.generic_param_attr_buffer.is_empty()); - (self.tree, self.source_maps.build()) + self.tree } - pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> (ItemTree, ItemTreeSourceMaps) { - self.tree - .attrs - .insert(AttrOwner::TopLevel, RawAttrs::new(self.db.upcast(), block, self.span_map())); + pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree { + self.tree.attrs.insert(AttrOwner::TopLevel, RawAttrs::new(self.db, block, self.span_map())); self.tree.top_level = block .statements() .filter_map(|stmt| match stmt { @@ -164,8 +117,7 @@ impl<'a> Ctx<'a> { } } - assert!(self.generic_param_attr_buffer.is_empty()); - (self.tree, self.source_maps.build()) + self.tree } fn data(&mut self) -> &mut ItemTreeData { @@ -192,7 +144,7 @@ impl<'a> Ctx<'a> { ast::Item::MacroDef(ast) => self.lower_macro_def(ast)?.into(), ast::Item::ExternBlock(ast) => self.lower_extern_block(ast).into(), }; - let attrs = RawAttrs::new(self.db.upcast(), item, self.span_map()); + let attrs = RawAttrs::new(self.db, item, self.span_map()); self.add_attrs(mod_item.into(), attrs); Some(mod_item) @@ -218,7 +170,7 @@ impl<'a> Ctx<'a> { ast::AssocItem::Const(ast) => Some(self.lower_const(ast).into()), ast::AssocItem::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), }?; - let attrs = RawAttrs::new(self.db.upcast(), item_node, self.span_map()); + let attrs = RawAttrs::new(self.db, item_node, self.span_map()); self.add_attrs( match item { AssocItem::Function(it) => AttrOwner::ModItem(ModItem::Function(it)), @@ -232,31 +184,13 @@ impl<'a> Ctx<'a> { } fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<FileItemTreeId<Struct>> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); let visibility = self.lower_visibility(strukt); let name = strukt.name()?.as_name(); let ast_id = self.source_ast_id_map.ast_id(strukt); - let (fields, kind, attrs) = self.lower_fields(&strukt.kind(), &mut body_ctx); - let (generic_params, generics_source_map) = - self.lower_generic_params(HasImplicitSelf::No, strukt); - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let res = Struct { - name, - visibility, - generic_params, - fields, - shape: kind, - ast_id, - types_map: Arc::new(types_map), - }; + let (fields, kind, attrs) = self.lower_fields(&strukt.kind()); + let res = Struct { name, visibility, fields, shape: kind, ast_id }; let id = id(self.data().structs.alloc(res)); - self.source_maps.structs.push(GenericItemSourceMapBuilder { - item: types_source_map, - generics: generics_source_map, - }); + for (idx, attr) in attrs { self.add_attrs( AttrOwner::Field( @@ -266,14 +200,12 @@ impl<'a> Ctx<'a> { attr, ); } - self.write_generic_params_attributes(id.into()); Some(id) } fn lower_fields( &mut self, strukt_kind: &ast::StructKind, - body_ctx: &mut LowerCtx<'_>, ) -> (Box<[Field]>, FieldsShape, Vec<(usize, RawAttrs)>) { match strukt_kind { ast::StructKind::Record(it) => { @@ -281,9 +213,9 @@ impl<'a> Ctx<'a> { let mut attrs = vec![]; for (i, field) in it.fields().enumerate() { - let data = self.lower_record_field(&field, body_ctx); + let data = self.lower_record_field(&field); fields.push(data); - let attr = RawAttrs::new(self.db.upcast(), &field, self.span_map()); + let attr = RawAttrs::new(self.db, &field, self.span_map()); if !attr.is_empty() { attrs.push((i, attr)) } @@ -295,9 +227,9 @@ impl<'a> Ctx<'a> { let mut attrs = vec![]; for (i, field) in it.fields().enumerate() { - let data = self.lower_tuple_field(i, &field, body_ctx); + let data = self.lower_tuple_field(i, &field); fields.push(data); - let attr = RawAttrs::new(self.db.upcast(), &field, self.span_map()); + let attr = RawAttrs::new(self.db, &field, self.span_map()); if !attr.is_empty() { attrs.push((i, attr)) } @@ -308,63 +240,32 @@ impl<'a> Ctx<'a> { } } - fn lower_record_field( - &mut self, - field: &ast::RecordField, - body_ctx: &mut LowerCtx<'_>, - ) -> Field { + fn lower_record_field(&mut self, field: &ast::RecordField) -> Field { let name = match field.name() { Some(name) => name.as_name(), None => Name::missing(), }; let visibility = self.lower_visibility(field); - let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty()); - Field { name, type_ref, visibility } + Field { name, visibility, is_unsafe: field.unsafe_token().is_some() } } - fn lower_tuple_field( - &mut self, - idx: usize, - field: &ast::TupleField, - body_ctx: &mut LowerCtx<'_>, - ) -> Field { + fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleField) -> Field { let name = Name::new_tuple_field(idx); let visibility = self.lower_visibility(field); - let type_ref = TypeRef::from_ast_opt(body_ctx, field.ty()); - Field { name, type_ref, visibility } + Field { name, visibility, is_unsafe: false } } fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); let visibility = self.lower_visibility(union); let name = union.name()?.as_name(); let ast_id = self.source_ast_id_map.ast_id(union); let (fields, _, attrs) = match union.record_field_list() { - Some(record_field_list) => { - self.lower_fields(&StructKind::Record(record_field_list), &mut body_ctx) - } + Some(record_field_list) => self.lower_fields(&StructKind::Record(record_field_list)), None => (Box::default(), FieldsShape::Record, Vec::default()), }; - let (generic_params, generics_source_map) = - self.lower_generic_params(HasImplicitSelf::No, union); - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let res = Union { - name, - visibility, - generic_params, - fields, - ast_id, - types_map: Arc::new(types_map), - }; + let res = Union { name, visibility, fields, ast_id }; let id = id(self.data().unions.alloc(res)); - self.source_maps.unions.push(GenericItemSourceMapBuilder { - item: types_source_map, - generics: generics_source_map, - }); for (idx, attr) in attrs { self.add_attrs( AttrOwner::Field( @@ -374,7 +275,6 @@ impl<'a> Ctx<'a> { attr, ); } - self.write_generic_params_attributes(id.into()); Some(id) } @@ -388,12 +288,8 @@ impl<'a> Ctx<'a> { FileItemTreeId(self.next_variant_idx())..FileItemTreeId(self.next_variant_idx()) } }; - let (generic_params, generics_source_map) = - self.lower_generic_params(HasImplicitSelf::No, enum_); - let res = Enum { name, visibility, generic_params, variants, ast_id }; + let res = Enum { name, visibility, variants, ast_id }; let id = id(self.data().enums.alloc(res)); - self.source_maps.enum_generics.push(generics_source_map); - self.write_generic_params_attributes(id.into()); Some(id) } @@ -401,34 +297,25 @@ impl<'a> Ctx<'a> { let start = self.next_variant_idx(); for variant in variants.variants() { let idx = self.lower_variant(&variant); - self.add_attrs( - id(idx).into(), - RawAttrs::new(self.db.upcast(), &variant, self.span_map()), - ); + self.add_attrs(id(idx).into(), RawAttrs::new(self.db, &variant, self.span_map())); } let end = self.next_variant_idx(); FileItemTreeId(start)..FileItemTreeId(end) } fn lower_variant(&mut self, variant: &ast::Variant) -> Idx<Variant> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); let name = match variant.name() { Some(name) => name.as_name(), None => Name::missing(), }; - let (fields, kind, attrs) = self.lower_fields(&variant.kind(), &mut body_ctx); + let (fields, kind, attrs) = self.lower_fields(&variant.kind()); let ast_id = self.source_ast_id_map.ast_id(variant); - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let res = Variant { name, fields, shape: kind, ast_id, types_map: Arc::new(types_map) }; + let res = Variant { name, fields, shape: kind, ast_id }; let id = self.data().variants.alloc(res); - self.source_maps.variants.push(types_source_map); for (idx, attr) in attrs { self.add_attrs( AttrOwner::Field( - FieldParent::Variant(FileItemTreeId(id)), + FieldParent::EnumVariant(FileItemTreeId(id)), Idx::from_raw(RawIdx::from_u32(idx as u32)), ), attr, @@ -438,144 +325,14 @@ impl<'a> Ctx<'a> { } fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); - let visibility = self.lower_visibility(func); let name = func.name()?.as_name(); - let mut has_self_param = false; - let mut has_var_args = false; - let mut params = vec![]; - let mut attrs = vec![]; - let mut push_attr = |idx, attr: RawAttrs| { - if !attr.is_empty() { - attrs.push((idx, attr)) - } - }; - if let Some(param_list) = func.param_list() { - if let Some(self_param) = param_list.self_param() { - push_attr( - params.len(), - RawAttrs::new(self.db.upcast(), &self_param, self.span_map()), - ); - let self_type = match self_param.ty() { - Some(type_ref) => TypeRef::from_ast(&mut body_ctx, type_ref), - None => { - let self_type = body_ctx.alloc_type_ref_desugared(TypeRef::Path( - Name::new_symbol_root(sym::Self_.clone()).into(), - )); - match self_param.kind() { - ast::SelfParamKind::Owned => self_type, - ast::SelfParamKind::Ref => body_ctx.alloc_type_ref_desugared( - TypeRef::Reference(Box::new(RefType { - ty: self_type, - lifetime: self_param.lifetime().as_ref().map(LifetimeRef::new), - mutability: Mutability::Shared, - })), - ), - ast::SelfParamKind::MutRef => body_ctx.alloc_type_ref_desugared( - TypeRef::Reference(Box::new(RefType { - ty: self_type, - lifetime: self_param.lifetime().as_ref().map(LifetimeRef::new), - mutability: Mutability::Mut, - })), - ), - } - } - }; - params.push(Param { type_ref: Some(self_type) }); - has_self_param = true; - } - for param in param_list.params() { - push_attr(params.len(), RawAttrs::new(self.db.upcast(), ¶m, self.span_map())); - let param = match param.dotdotdot_token() { - Some(_) => { - has_var_args = true; - Param { type_ref: None } - } - None => { - let type_ref = TypeRef::from_ast_opt(&mut body_ctx, param.ty()); - Param { type_ref: Some(type_ref) } - } - }; - params.push(param); - } - } - - let ret_type = match func.ret_type() { - Some(rt) => match rt.ty() { - Some(type_ref) => TypeRef::from_ast(&mut body_ctx, type_ref), - None if rt.thin_arrow_token().is_some() => body_ctx.alloc_error_type(), - None => body_ctx.alloc_type_ref_desugared(TypeRef::unit()), - }, - None => body_ctx.alloc_type_ref_desugared(TypeRef::unit()), - }; - - let ret_type = if func.async_token().is_some() { - let future_impl = desugar_future_path(&mut body_ctx, ret_type); - let ty_bound = TypeBound::Path(future_impl, TraitBoundModifier::None); - body_ctx.alloc_type_ref_desugared(TypeRef::ImplTrait(ThinVec::from_iter([ty_bound]))) - } else { - ret_type - }; - - let abi = func.abi().map(lower_abi); - let ast_id = self.source_ast_id_map.ast_id(func); - let mut flags = FnFlags::default(); - if func.body().is_some() { - flags |= FnFlags::HAS_BODY; - } - if has_self_param { - flags |= FnFlags::HAS_SELF_PARAM; - } - if func.default_token().is_some() { - flags |= FnFlags::HAS_DEFAULT_KW; - } - if func.const_token().is_some() { - flags |= FnFlags::HAS_CONST_KW; - } - if func.async_token().is_some() { - flags |= FnFlags::HAS_ASYNC_KW; - } - if func.unsafe_token().is_some() { - flags |= FnFlags::HAS_UNSAFE_KW; - } - if func.safe_token().is_some() { - flags |= FnFlags::HAS_SAFE_KW; - } - if has_var_args { - flags |= FnFlags::IS_VARARGS; - } - - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let (generic_params, generics_source_map) = - self.lower_generic_params(HasImplicitSelf::No, func); - let res = Function { - name, - visibility, - explicit_generic_params: generic_params, - abi, - params: params.into_boxed_slice(), - ret_type, - ast_id, - types_map: Arc::new(types_map), - flags, - }; + let res = Function { name, visibility, ast_id }; let id = id(self.data().functions.alloc(res)); - self.source_maps.functions.push(GenericItemSourceMapBuilder { - item: types_source_map, - generics: generics_source_map, - }); - for (idx, attr) in attrs { - self.add_attrs(AttrOwner::Param(id, Idx::from_raw(RawIdx::from_u32(idx as u32))), attr); - } - self.write_generic_params_attributes(id.into()); Some(id) } @@ -583,82 +340,27 @@ impl<'a> Ctx<'a> { &mut self, type_alias: &ast::TypeAlias, ) -> Option<FileItemTreeId<TypeAlias>> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); let name = type_alias.name()?.as_name(); - let type_ref = type_alias.ty().map(|it| TypeRef::from_ast(&mut body_ctx, it)); let visibility = self.lower_visibility(type_alias); - let bounds = self.lower_type_bounds(type_alias, &mut body_ctx); let ast_id = self.source_ast_id_map.ast_id(type_alias); - let (generic_params, generics_source_map) = - self.lower_generic_params(HasImplicitSelf::No, type_alias); - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let res = TypeAlias { - name, - visibility, - bounds, - generic_params, - type_ref, - ast_id, - types_map: Arc::new(types_map), - }; + let res = TypeAlias { name, visibility, ast_id }; let id = id(self.data().type_aliases.alloc(res)); - self.source_maps.type_aliases.push(GenericItemSourceMapBuilder { - item: types_source_map, - generics: generics_source_map, - }); - self.write_generic_params_attributes(id.into()); Some(id) } fn lower_static(&mut self, static_: &ast::Static) -> Option<FileItemTreeId<Static>> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); let name = static_.name()?.as_name(); - let type_ref = TypeRef::from_ast_opt(&mut body_ctx, static_.ty()); let visibility = self.lower_visibility(static_); - let mutable = static_.mut_token().is_some(); - let has_safe_kw = static_.safe_token().is_some(); - let has_unsafe_kw = static_.unsafe_token().is_some(); let ast_id = self.source_ast_id_map.ast_id(static_); - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let res = Static { - name, - visibility, - mutable, - type_ref, - ast_id, - has_safe_kw, - has_unsafe_kw, - types_map: Arc::new(types_map), - }; - self.source_maps.statics.push(types_source_map); + let res = Static { name, visibility, ast_id }; Some(id(self.data().statics.alloc(res))) } fn lower_const(&mut self, konst: &ast::Const) -> FileItemTreeId<Const> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); let name = konst.name().map(|it| it.as_name()); - let type_ref = TypeRef::from_ast_opt(&mut body_ctx, konst.ty()); let visibility = self.lower_visibility(konst); let ast_id = self.source_ast_id_map.ast_id(konst); - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let res = Const { - name, - visibility, - type_ref, - ast_id, - has_body: konst.body().is_some(), - types_map: Arc::new(types_map), - }; - self.source_maps.consts.push(types_source_map); + let res = Const { name, visibility, ast_id }; id(self.data().consts.alloc(res)) } @@ -687,8 +389,6 @@ impl<'a> Ctx<'a> { let name = trait_def.name()?.as_name(); let visibility = self.lower_visibility(trait_def); let ast_id = self.source_ast_id_map.ast_id(trait_def); - let is_auto = trait_def.auto_token().is_some(); - let is_unsafe = trait_def.unsafe_token().is_some(); let items = trait_def .assoc_item_list() @@ -697,12 +397,8 @@ impl<'a> Ctx<'a> { .filter_map(|item_node| self.lower_assoc_item(&item_node)) .collect(); - let (generic_params, generics_source_map) = - self.lower_generic_params(HasImplicitSelf::Yes(trait_def.type_bound_list()), trait_def); - let def = Trait { name, visibility, generic_params, is_auto, is_unsafe, items, ast_id }; + let def = Trait { name, visibility, items, ast_id }; let id = id(self.data().traits.alloc(def)); - self.source_maps.trait_generics.push(generics_source_map); - self.write_generic_params_attributes(id.into()); Some(id) } @@ -713,32 +409,14 @@ impl<'a> Ctx<'a> { let name = trait_alias_def.name()?.as_name(); let visibility = self.lower_visibility(trait_alias_def); let ast_id = self.source_ast_id_map.ast_id(trait_alias_def); - let (generic_params, generics_source_map) = self.lower_generic_params( - HasImplicitSelf::Yes(trait_alias_def.type_bound_list()), - trait_alias_def, - ); - let alias = TraitAlias { name, visibility, generic_params, ast_id }; + let alias = TraitAlias { name, visibility, ast_id }; let id = id(self.data().trait_aliases.alloc(alias)); - self.source_maps.trait_alias_generics.push(generics_source_map); - self.write_generic_params_attributes(id.into()); Some(id) } fn lower_impl(&mut self, impl_def: &ast::Impl) -> FileItemTreeId<Impl> { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); - let ast_id = self.source_ast_id_map.ast_id(impl_def); - // FIXME: If trait lowering fails, due to a non PathType for example, we treat this impl - // as if it was an non-trait impl. Ideally we want to create a unique missing ref that only - // equals itself. - let self_ty = TypeRef::from_ast_opt(&mut body_ctx, impl_def.self_ty()); - let target_trait = impl_def.trait_().and_then(|tr| TraitRef::from_ast(&mut body_ctx, tr)); - let is_negative = impl_def.excl_token().is_some(); - let is_unsafe = impl_def.unsafe_token().is_some(); - // We cannot use `assoc_items()` here as that does not include macro calls. let items = impl_def .assoc_item_list() @@ -748,27 +426,8 @@ impl<'a> Ctx<'a> { .collect(); // Note that trait impls don't get implicit `Self` unlike traits, because here they are a // type alias rather than a type parameter, so this is handled by the resolver. - let (generic_params, generics_source_map) = - self.lower_generic_params(HasImplicitSelf::No, impl_def); - types_map.shrink_to_fit(); - types_source_map.shrink_to_fit(); - let res = Impl { - generic_params, - target_trait, - self_ty, - is_negative, - is_unsafe, - items, - ast_id, - types_map: Arc::new(types_map), - }; - let id = id(self.data().impls.alloc(res)); - self.source_maps.impls.push(GenericItemSourceMapBuilder { - item: types_source_map, - generics: generics_source_map, - }); - self.write_generic_params_attributes(id.into()); - id + let res = Impl { items, ast_id }; + id(self.data().impls.alloc(res)) } fn lower_use(&mut self, use_item: &ast::Use) -> Option<FileItemTreeId<Use>> { @@ -801,7 +460,7 @@ impl<'a> Ctx<'a> { let span_map = self.span_map(); let path = m.path()?; let range = path.syntax().text_range(); - let path = Interned::new(ModPath::from_src(self.db.upcast(), path, &mut |range| { + let path = Interned::new(ModPath::from_src(self.db, path, &mut |range| { span_map.span_for_range(range).ctx })?); let ast_id = self.source_ast_id_map.ast_id(m); @@ -844,7 +503,7 @@ impl<'a> Ctx<'a> { ast::ExternItem::TypeAlias(ty) => self.lower_type_alias(ty)?.into(), ast::ExternItem::MacroCall(call) => self.lower_macro_call(call)?.into(), }; - let attrs = RawAttrs::new(self.db.upcast(), &item, self.span_map()); + let attrs = RawAttrs::new(self.db, &item, self.span_map()); self.add_attrs(mod_item.into(), attrs); Some(mod_item) }) @@ -855,75 +514,8 @@ impl<'a> Ctx<'a> { id(self.data().extern_blocks.alloc(res)) } - fn write_generic_params_attributes(&mut self, parent: GenericModItem) { - self.generic_param_attr_buffer.drain().for_each(|(idx, attrs)| { - self.tree.attrs.insert( - match idx { - Either::Left(id) => AttrOwner::TypeOrConstParamData(parent, id), - Either::Right(id) => AttrOwner::LifetimeParamData(parent, id), - }, - attrs, - ); - }) - } - - fn lower_generic_params( - &mut self, - has_implicit_self: HasImplicitSelf, - node: &dyn ast::HasGenericParams, - ) -> (Arc<GenericParams>, TypesSourceMap) { - let (mut types_map, mut types_source_map) = - (TypesMap::default(), TypesSourceMap::default()); - let mut body_ctx = self.body_ctx(&mut types_map, &mut types_source_map); - debug_assert!(self.generic_param_attr_buffer.is_empty(),); - body_ctx.take_impl_traits_bounds(); - let mut generics = GenericParamsCollector::default(); - - if let HasImplicitSelf::Yes(bounds) = has_implicit_self { - // Traits and trait aliases get the Self type as an implicit first type parameter. - generics.type_or_consts.alloc( - TypeParamData { - name: Some(Name::new_symbol_root(sym::Self_.clone())), - default: None, - provenance: TypeParamProvenance::TraitSelf, - } - .into(), - ); - // add super traits as bounds on Self - // i.e., `trait Foo: Bar` is equivalent to `trait Foo where Self: Bar` - let bound_target = Either::Left(body_ctx.alloc_type_ref_desugared(TypeRef::Path( - Name::new_symbol_root(sym::Self_.clone()).into(), - ))); - generics.fill_bounds(&mut body_ctx, bounds, bound_target); - } - - let span_map = body_ctx.span_map().clone(); - let add_param_attrs = |item: Either<LocalTypeOrConstParamId, LocalLifetimeParamId>, - param| { - let attrs = RawAttrs::new(self.db.upcast(), ¶m, span_map.as_ref()); - debug_assert!(self.generic_param_attr_buffer.insert(item, attrs).is_none()); - }; - generics.fill(&mut body_ctx, node, add_param_attrs); - - let generics = generics.finish(types_map, &mut types_source_map); - (generics, types_source_map) - } - - fn lower_type_bounds( - &mut self, - node: &dyn ast::HasTypeBounds, - body_ctx: &mut LowerCtx<'_>, - ) -> Box<[TypeBound]> { - match node.type_bound_list() { - Some(bound_list) => { - bound_list.bounds().map(|it| TypeBound::from_ast(body_ctx, it)).collect() - } - None => Box::default(), - } - } - fn lower_visibility(&mut self, item: &dyn ast::HasVisibility) -> RawVisibilityId { - let vis = RawVisibility::from_ast(self.db, item.visibility(), &mut |range| { + let vis = visibility_from_ast(self.db, item.visibility(), &mut |range| { self.span_map().span_for_range(range).ctx }); self.data().vis.alloc(vis) @@ -936,33 +528,11 @@ impl<'a> Ctx<'a> { } } -fn desugar_future_path(ctx: &mut LowerCtx<'_>, orig: TypeRefId) -> PathId { - let path = path![core::future::Future]; - let mut generic_args: Vec<_> = - std::iter::repeat(None).take(path.segments().len() - 1).collect(); - let binding = AssociatedTypeBinding { - name: Name::new_symbol_root(sym::Output.clone()), - args: None, - type_ref: Some(orig), - bounds: Box::default(), - }; - generic_args.push(Some(GenericArgs { bindings: Box::new([binding]), ..GenericArgs::empty() })); - - let path = Path::from_known_path(path, generic_args); - PathId::from_type_ref_unchecked(ctx.alloc_type_ref_desugared(TypeRef::Path(path))) -} - -enum HasImplicitSelf { - /// Inner list is a type bound list for the implicit `Self`. - Yes(Option<ast::TypeBoundList>), - No, -} - fn lower_abi(abi: ast::Abi) -> Symbol { match abi.abi_string() { Some(tok) => Symbol::intern(tok.text_without_quotes()), // `extern` default to be `extern "C"`. - _ => sym::C.clone(), + _ => sym::C, } } @@ -975,7 +545,7 @@ impl UseTreeLowering<'_> { fn lower_use_tree( &mut self, tree: ast::UseTree, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> Option<UseTree> { if let Some(use_tree_list) = tree.use_tree_list() { let prefix = match tree.path() { @@ -984,7 +554,7 @@ impl UseTreeLowering<'_> { // E.g. `use something::{inner}` (prefix is `None`, path is `something`) // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) Some(path) => { - match ModPath::from_src(self.db.upcast(), path, span_for_range) { + match ModPath::from_src(self.db, path, span_for_range) { Some(it) => Some(it), None => return None, // FIXME: report errors somewhere } @@ -1005,7 +575,7 @@ impl UseTreeLowering<'_> { } else { let is_glob = tree.star_token().is_some(); let path = match tree.path() { - Some(path) => Some(ModPath::from_src(self.db.upcast(), path, span_for_range)?), + Some(path) => Some(ModPath::from_src(self.db, path, span_for_range)?), None => None, }; let alias = tree.rename().map(|a| { @@ -1042,9 +612,38 @@ impl UseTreeLowering<'_> { pub(crate) fn lower_use_tree( db: &dyn DefDatabase, tree: ast::UseTree, - span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContextId, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, ) -> Option<(UseTree, Arena<ast::UseTree>)> { let mut lowering = UseTreeLowering { db, mapping: Arena::new() }; let tree = lowering.lower_use_tree(tree, span_for_range)?; Some((tree, lowering.mapping)) } + +fn private_vis() -> RawVisibility { + RawVisibility::Module( + Interned::new(ModPath::from_kind(PathKind::SELF)), + VisibilityExplicitness::Implicit, + ) +} + +fn visibility_from_ast( + db: &dyn DefDatabase, + node: Option<ast::Visibility>, + span_for_range: &mut dyn FnMut(::tt::TextRange) -> SyntaxContext, +) -> RawVisibility { + let Some(node) = node else { return private_vis() }; + let path = match node.kind() { + ast::VisibilityKind::In(path) => { + let path = ModPath::from_src(db, path, span_for_range); + match path { + None => return private_vis(), + Some(path) => path, + } + } + ast::VisibilityKind::PubCrate => ModPath::from_kind(PathKind::Crate), + ast::VisibilityKind::PubSuper => ModPath::from_kind(PathKind::Super(1)), + ast::VisibilityKind::PubSelf => ModPath::from_kind(PathKind::SELF), + ast::VisibilityKind::Pub => return RawVisibility::Public, + }; + RawVisibility::Module(Interned::new(path), VisibilityExplicitness::Explicit) +} |