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 | 519 |
1 files changed, 65 insertions, 454 deletions
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 4a3deec5ff..25cb95b906 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -4,41 +4,28 @@ use std::{cell::OnceCell, collections::hash_map::Entry}; use hir_expand::{ HirFileId, - mod_path::path, + mod_path::PathKind, name::AsName, span_map::{SpanMap, SpanMapRef}, }; use intern::{Symbol, sym}; use la_arena::Arena; -use rustc_hash::FxHashMap; use span::{AstIdMap, SyntaxContext}; use syntax::{ AstNode, - ast::{self, HasModuleItem, HasName, HasTypeBounds, IsString}, + ast::{self, HasModuleItem, HasName, IsString}, }; -use thin_vec::ThinVec; use triomphe::Arc; use crate::{ - LocalLifetimeParamId, LocalTypeOrConstParamId, db::DefDatabase, - generics::{GenericParams, GenericParamsCollector}, 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, StaticFlags, Struct, StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, - UseTreeKind, Variant, + 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, }, - lower::LowerCtx, - path::AssociatedTypeBinding, - type_ref::{ - LifetimeRef, PathId, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, - TypesMap, TypesSourceMap, - }, - visibility::RawVisibility, }; 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,11 +91,10 @@ 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) { + pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree { self.tree .attrs .insert(AttrOwner::TopLevel, RawAttrs::new(self.db.upcast(), block, self.span_map())); @@ -164,8 +119,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 { @@ -232,31 +186,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 +202,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,7 +215,7 @@ 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()); if !attr.is_empty() { @@ -295,7 +229,7 @@ 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()); if !attr.is_empty() { @@ -308,63 +242,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, is_unsafe: field.unsafe_token().is_some() } + 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, is_unsafe: false } + 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 +277,6 @@ impl<'a> Ctx<'a> { attr, ); } - self.write_generic_params_attributes(id.into()); Some(id) } @@ -388,12 +290,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) } @@ -411,20 +309,14 @@ impl<'a> Ctx<'a> { } 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( @@ -438,144 +330,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,83 +345,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 mut flags = StaticFlags::empty(); - if static_.mut_token().is_some() { - flags |= StaticFlags::MUTABLE; - } - if static_.safe_token().is_some() { - flags |= StaticFlags::HAS_SAFE_KW; - } - if static_.unsafe_token().is_some() { - flags |= StaticFlags::HAS_UNSAFE_KW; - } - 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, type_ref, ast_id, flags, 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)) } @@ -688,8 +394,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() @@ -698,12 +402,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) } @@ -714,32 +414,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() @@ -749,27 +431,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>> { @@ -856,68 +519,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.fill_self_param(); - // 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) @@ -930,27 +533,6 @@ 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_n(None, 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()), @@ -1041,3 +623,32 @@ pub(crate) fn lower_use_tree( 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.upcast(), 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) +} |