Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21900 from Veykril/push-ylmpryvvpsym
Fully implement `VariantFields `expression support
76 files changed, 740 insertions, 457 deletions
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs index 2f2889ec66..5d5d435398 100644 --- a/crates/hir-def/src/db.rs +++ b/crates/hir-def/src/db.rs @@ -4,16 +4,15 @@ use hir_expand::{ EditionedFileId, HirFileId, InFile, Lookup, MacroCallId, MacroDefId, MacroDefKind, db::ExpandDatabase, }; -use la_arena::ArenaMap; use triomphe::Arc; use crate::{ AnonConstId, AnonConstLoc, AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, - ExternCrateLoc, FunctionId, FunctionLoc, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, - MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, - ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, - TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, + ExternCrateLoc, FunctionId, FunctionLoc, ImplId, ImplLoc, Macro2Id, Macro2Loc, MacroExpander, + MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, + StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, + UnionLoc, UseId, UseLoc, attrs::AttrFlags, item_tree::{ItemTree, file_item_tree_query}, nameres::crate_def_map, @@ -98,9 +97,6 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase { // region:visibilities - #[salsa::invoke(visibility::field_visibilities_query)] - fn field_visibilities(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Visibility>>; - #[salsa::invoke(visibility::assoc_visibility_query)] fn assoc_visibility(&self, def: AssocItemId) -> Visibility; diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs index 1ae89e170d..ca523622ec 100644 --- a/crates/hir-def/src/expr_store.rs +++ b/crates/hir-def/src/expr_store.rs @@ -31,6 +31,7 @@ use crate::{ PatId, RecordFieldPat, RecordSpread, Statement, }, nameres::{DefMap, block_def_map}, + signatures::VariantFields, type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId}, }; @@ -95,7 +96,7 @@ pub type LifetimeSource = InFile<LifetimePtr>; /// Used by signature/body inference to determine the expected type for each /// const expression root. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum ConstExprOrigin { +pub enum RootExprOrigin { /// Array length expression: `[T; <expr>]` — expected type is `usize`. ArrayLength, /// Const parameter default value: `const N: usize = <expr>`. @@ -103,6 +104,8 @@ pub enum ConstExprOrigin { /// Const generic argument in a path: `SomeType::<{ <expr> }>` or `some_fn::<{ <expr> }>()`. /// Determining the expected type requires path resolution, so it is deferred. GenericArgsPath, + /// The root expression of a body. + BodyRoot, } // We split the store into types-only and expressions, because most stores (e.g. generics) @@ -125,11 +128,8 @@ struct ExpressionOnlyStore { /// to variables and have hygiene (some refer to items, we don't know at this stage). ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, - /// Maps const expression roots to their origin. - /// - /// Populated during lowering. Used by signature inference to determine expected types, - /// and by `signature_const_expr_roots()` to enumerate roots for scope computation. - const_expr_origins: ThinVec<(ExprId, ConstExprOrigin)>, + /// Maps expression roots to their origin. + expr_roots: SmallVec<[(ExprId, RootExprOrigin); 1]>, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -243,7 +243,7 @@ pub struct ExpressionStoreBuilder { pub types: Arena<TypeRef>, block_scopes: Vec<BlockId>, ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, - pub const_expr_origins: Option<ThinVec<(ExprId, ConstExprOrigin)>>, + pub inference_roots: Option<SmallVec<[(ExprId, RootExprOrigin); 1]>>, // AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map // to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected). @@ -315,7 +315,7 @@ impl ExpressionStoreBuilder { mut bindings, mut binding_owners, mut ident_hygiene, - mut const_expr_origins, + inference_roots: mut expr_roots, mut types, mut lifetimes, @@ -375,7 +375,7 @@ impl ExpressionStoreBuilder { let store = { let expr_only = if has_exprs { - if let Some(const_expr_origins) = &mut const_expr_origins { + if let Some(const_expr_origins) = &mut expr_roots { const_expr_origins.shrink_to_fit(); } Some(Box::new(ExpressionOnlyStore { @@ -386,7 +386,7 @@ impl ExpressionStoreBuilder { binding_owners, block_scopes: block_scopes.into_boxed_slice(), ident_hygiene, - const_expr_origins: const_expr_origins.unwrap_or_default(), + expr_roots: expr_roots.unwrap_or_default(), })) } else { None @@ -448,6 +448,9 @@ impl ExpressionStore { } } ExpressionStoreOwnerId::Body(body) => &Body::of(db, body).store, + ExpressionStoreOwnerId::VariantFields(variant_id) => { + &VariantFields::of(db, variant_id).store + } } } @@ -505,30 +508,27 @@ impl ExpressionStore { let (store, sm) = Body::with_source_map(db, body); (&store.store, &sm.store) } + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let (store, sm) = VariantFields::with_source_map(db, variant_id); + (&store.store, sm) + } } } - /// Returns all const expression root `ExprId`s found in this store. - /// - /// Used to compute expression scopes for signature stores. - pub fn signature_const_expr_roots(&self) -> impl Iterator<Item = ExprId> { + /// Returns all expression root `ExprId`s found in this store. + pub fn expr_roots(&self) -> impl Iterator<Item = ExprId> { self.const_expr_origins().iter().map(|&(id, _)| id) } /// Like [`Self::signature_const_expr_roots`], but also returns the origin - /// of each const expression. - /// - /// This is used by signature inference to determine the expected type for - /// each root expression. - pub fn signature_const_expr_roots_with_origins( - &self, - ) -> impl Iterator<Item = (ExprId, ConstExprOrigin)> { + /// of each expression. + pub fn expr_roots_with_origins(&self) -> impl Iterator<Item = (ExprId, RootExprOrigin)> { self.const_expr_origins().iter().map(|&(id, origin)| (id, origin)) } /// Returns the map of const expression roots to their origins. - pub fn const_expr_origins(&self) -> &[(ExprId, ConstExprOrigin)] { - self.expr_only.as_ref().map_or(&[], |it| &it.const_expr_origins) + pub fn const_expr_origins(&self) -> &[(ExprId, RootExprOrigin)] { + self.expr_only.as_ref().map_or(&[], |it| &it.expr_roots) } /// Returns an iterator over all block expressions in this store that define inner items. diff --git a/crates/hir-def/src/expr_store/body.rs b/crates/hir-def/src/expr_store/body.rs index 60aaba5b84..0c8320369f 100644 --- a/crates/hir-def/src/expr_store/body.rs +++ b/crates/hir-def/src/expr_store/body.rs @@ -29,8 +29,6 @@ pub struct Body { /// empty. pub params: Box<[PatId]>, pub self_param: Option<BindingId>, - /// The `ExprId` of the actual body expression. - pub body_expr: ExprId, } impl ops::Deref for Body { @@ -115,6 +113,10 @@ impl Body { } impl Body { + pub fn root_expr(&self) -> ExprId { + self.store.expr_roots().next().unwrap() + } + pub fn pretty_print( &self, db: &dyn DefDatabase, diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index afa1c7fcfd..74006c6037 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -18,6 +18,7 @@ use hir_expand::{ }; use intern::{Symbol, sym}; use rustc_hash::FxHashMap; +use smallvec::smallvec; use stdx::never; use syntax::{ AstNode, AstPtr, SyntaxNodePtr, @@ -36,9 +37,9 @@ use crate::{ attrs::AttrFlags, db::DefDatabase, expr_store::{ - Body, BodySourceMap, ConstExprOrigin, ExprPtr, ExpressionStore, ExpressionStoreBuilder, + Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder, ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, LifetimePtr, - PatPtr, TypePtr, + PatPtr, RootExprOrigin, TypePtr, expander::Expander, lower::generics::ImplTraitLowerFn, path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path}, @@ -117,9 +118,10 @@ pub(super) fn lower_body( params = (0..count).map(|_| collector.missing_pat()).collect(); }; let body_expr = collector.missing_expr(); + collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]); let (store, source_map) = collector.store.finish(); return ( - Body { store, params: params.into_boxed_slice(), self_param, body_expr }, + Body { store, params: params.into_boxed_slice(), self_param }, BodySourceMap { self_param: source_map_self_param, store: source_map }, ); } @@ -173,10 +175,11 @@ pub(super) fn lower_body( } }, ); + collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]); let (store, source_map) = collector.store.finish(); ( - Body { store, params: params.into_boxed_slice(), self_param, body_expr }, + Body { store, params: params.into_boxed_slice(), self_param }, BodySourceMap { self_param: source_map_self_param, store: source_map }, ) } @@ -535,7 +538,7 @@ impl<'db> ExprCollector<'db> { current_file_id: HirFileId, ) -> ExprCollector<'_> { let mut this = Self::body(db, module, current_file_id); - this.store.const_expr_origins = Some(Default::default()); + this.store.inference_roots = Some(Default::default()); this } @@ -635,8 +638,8 @@ impl<'db> ExprCollector<'db> { } ast::Type::ArrayType(inner) => { let len = self.lower_const_arg_opt(inner.const_arg()); - if let Some(const_expr_origins) = &mut self.store.const_expr_origins { - const_expr_origins.push((len.expr, ConstExprOrigin::ArrayLength)); + if let Some(const_expr_origins) = &mut self.store.inference_roots { + const_expr_origins.push((len.expr, RootExprOrigin::ArrayLength)); } TypeRef::Array(ArrayType { ty: self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn), @@ -922,8 +925,8 @@ impl<'db> ExprCollector<'db> { } ast::GenericArg::ConstArg(arg) => { let arg = self.lower_const_arg(arg); - if let Some(const_expr_origins) = &mut self.store.const_expr_origins { - const_expr_origins.push((arg.expr, ConstExprOrigin::GenericArgsPath)); + if let Some(const_expr_origins) = &mut self.store.inference_roots { + const_expr_origins.push((arg.expr, RootExprOrigin::GenericArgsPath)); } args.push(GenericArg::Const(arg)) } @@ -1065,16 +1068,16 @@ impl<'db> ExprCollector<'db> { } fn lower_const_arg_opt(&mut self, arg: Option<ast::ConstArg>) -> ConstRef { - let const_expr_origins = self.store.const_expr_origins.take(); + let const_expr_origins = self.store.inference_roots.take(); let r = ConstRef { expr: self.collect_expr_opt(arg.and_then(|it| it.expr())) }; - self.store.const_expr_origins = const_expr_origins; + self.store.inference_roots = const_expr_origins; r } pub fn lower_const_arg(&mut self, arg: ast::ConstArg) -> ConstRef { - let const_expr_origins = self.store.const_expr_origins.take(); + let const_expr_origins = self.store.inference_roots.take(); let r = ConstRef { expr: self.collect_expr_opt(arg.expr()) }; - self.store.const_expr_origins = const_expr_origins; + self.store.inference_roots = const_expr_origins; r } diff --git a/crates/hir-def/src/expr_store/lower/generics.rs b/crates/hir-def/src/expr_store/lower/generics.rs index 7c7b697164..5ffc4f5851 100644 --- a/crates/hir-def/src/expr_store/lower/generics.rs +++ b/crates/hir-def/src/expr_store/lower/generics.rs @@ -130,11 +130,11 @@ impl GenericParamsCollector { let param = ConstParamData { name, ty, default }; let idx = self.type_or_consts.alloc(param.into()); if let Some(default) = default - && let Some(const_expr_origins) = &mut ec.store.const_expr_origins + && let Some(const_expr_origins) = &mut ec.store.inference_roots { const_expr_origins.push(( default.expr, - crate::expr_store::ConstExprOrigin::ConstParam(idx), + crate::expr_store::RootExprOrigin::ConstParam(idx), )); } } diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 39e0153ded..9c9c4db3b2 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -105,7 +105,7 @@ pub fn print_body_hir( p.buf.push(')'); p.buf.push(' '); } - p.print_expr(body.body_expr); + p.print_expr(body.root_expr()); if matches!(owner, DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_)) { p.buf.push(';'); } diff --git a/crates/hir-def/src/expr_store/scope.rs b/crates/hir-def/src/expr_store/scope.rs index 22a3a7b079..40ae0b7de4 100644 --- a/crates/hir-def/src/expr_store/scope.rs +++ b/crates/hir-def/src/expr_store/scope.rs @@ -3,13 +3,14 @@ use hir_expand::{MacroDefId, name::Name}; use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx}; use crate::{ - BlockId, DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, + BlockId, DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, VariantId, db::DefDatabase, expr_store::{Body, ExpressionStore, HygieneId}, hir::{ Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement, generics::GenericParams, }, + signatures::VariantFields, }; pub type ScopeId = Idx<ScopeData>; @@ -65,11 +66,20 @@ impl ExprScopes { #[salsa::tracked(returns(ref))] pub fn sig_expr_scopes(db: &dyn DefDatabase, def: GenericDefId) -> ExprScopes { let (_, store) = GenericParams::with_store(db, def); - let roots = store.signature_const_expr_roots(); + let roots = store.expr_roots(); let mut scopes = ExprScopes::new_store(store, roots); scopes.shrink_to_fit(); scopes } + + #[salsa::tracked(returns(ref))] + pub fn variant_scopes(db: &dyn DefDatabase, def: VariantId) -> ExprScopes { + let fields = VariantFields::of(db, def); + let roots = fields.store.expr_roots(); + let mut scopes = ExprScopes::new_store(&fields.store, roots); + scopes.shrink_to_fit(); + scopes + } } impl ExprScopes { @@ -78,6 +88,9 @@ impl ExprScopes { match def.into() { ExpressionStoreOwnerId::Body(def) => Self::body_expr_scopes(db, def), ExpressionStoreOwnerId::Signature(def) => Self::sig_expr_scopes(db, def), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + Self::variant_scopes(db, variant_id) + } } } @@ -138,7 +151,7 @@ impl ExprScopes { scopes.add_bindings(body, root, self_param, body.binding_hygiene(self_param)); } scopes.add_params_bindings(body, root, &body.params); - compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root); + compute_expr_scopes(body.root_expr(), body, &mut scopes, &mut root); scopes } diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index 4387ef055f..9a7fbc812f 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -259,7 +259,7 @@ impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); impl StructId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self.into()) + VariantFields::of(db, self.into()) } pub fn fields_with_source_map( @@ -276,7 +276,7 @@ impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); impl UnionId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self.into()) + VariantFields::of(db, self.into()) } pub fn fields_with_source_map( @@ -396,7 +396,7 @@ impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId); impl EnumVariantId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self.into()) + VariantFields::of(db, self.into()) } pub fn fields_with_source_map( @@ -756,19 +756,17 @@ impl GeneralConstId { } } -/// The defs which have a body (have root expressions for type inference). +/// The defs which have a body. #[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)] pub enum DefWithBodyId { + /// A function body. FunctionId(FunctionId), + /// A static item initializer. StaticId(StaticId), + /// A const item initializer ConstId(ConstId), + /// An enum variant discrimiant VariantId(EnumVariantId), - // /// All fields of a variant are inference roots - // VariantId(VariantId), - // /// The signature can contain inference roots in a bunch of places - // /// like const parameters or const arguments in paths - // This should likely be kept on its own with a separate query - // GenericDefId(GenericDefId), } impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId); @@ -840,10 +838,15 @@ impl_from!( /// Owner of an expression store - either a body or a signature. /// This is used for queries that operate on expression stores generically, /// such as `expr_scopes`. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +// NOTE: This type cannot be `salsa::Supertype` as its variants are overlapping. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord /* !salsa::Supertype */)] pub enum ExpressionStoreOwnerId { Signature(GenericDefId), + /// A body, something with a root expression. + /// + /// An enum variant's body is considered its discriminant initializer. Body(DefWithBodyId), + VariantFields(VariantId), } impl ExpressionStoreOwnerId { @@ -861,6 +864,11 @@ impl ExpressionStoreOwnerId { DefWithBodyId::ConstId(id) => GenericDefId::ConstId(id), DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(), }, + ExpressionStoreOwnerId::VariantFields(variant_id) => match variant_id { + VariantId::EnumVariantId(it) => it.lookup(db).parent.into(), + VariantId::StructId(it) => it.into(), + VariantId::UnionId(it) => it.into(), + }, } } } @@ -877,6 +885,12 @@ impl From<DefWithBodyId> for ExpressionStoreOwnerId { } } +impl From<VariantId> for ExpressionStoreOwnerId { + fn from(id: VariantId) -> Self { + ExpressionStoreOwnerId::VariantFields(id) + } +} + impl GenericDefId { pub fn file_id_and_params_of( self, @@ -1017,7 +1031,9 @@ impl From<VariantId> for AttrDefId { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype, salsa::Update)] +#[derive( + Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa_macros::Supertype, salsa::Update, +)] pub enum VariantId { EnumVariantId(EnumVariantId), StructId(StructId), @@ -1027,7 +1043,7 @@ impl_from!(EnumVariantId, StructId, UnionId for VariantId); impl VariantId { pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields { - VariantFields::firewall(db, self) + VariantFields::of(db, self) } pub fn fields_with_source_map( @@ -1241,6 +1257,7 @@ impl HasModule for ExpressionStoreOwnerId { match self { ExpressionStoreOwnerId::Signature(def) => def.module(db), ExpressionStoreOwnerId::Body(def) => def.module(db), + ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.module(db), } } } diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index dee7800e84..bb292ac1a6 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -1419,6 +1419,7 @@ impl HasResolver for ExpressionStoreOwnerId { match self { ExpressionStoreOwnerId::Signature(def) => def.resolver(db), ExpressionStoreOwnerId::Body(def) => def.resolver(db), + ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.resolver(db), } } } diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs index c16ca6d0b4..6d704274f4 100644 --- a/crates/hir-def/src/signatures.rs +++ b/crates/hir-def/src/signatures.rs @@ -848,7 +848,7 @@ pub struct VariantFields { #[salsa::tracked] impl VariantFields { #[salsa::tracked(returns(ref))] - pub(crate) fn with_source_map( + pub fn with_source_map( db: &dyn DefDatabase, id: VariantId, ) -> (Arc<Self>, ExpressionStoreSourceMap) { @@ -906,7 +906,7 @@ impl VariantFields { } #[salsa::tracked(returns(deref))] - pub(crate) fn firewall(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> { + pub fn of(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> { Self::with_source_map(db, id).0.clone() } } @@ -1101,7 +1101,7 @@ impl EnumVariants { if !matches!(variant.shape, FieldsShape::Unit) { let body = Body::of(db, v.into()); // A variant with explicit discriminant - if !matches!(body[body.body_expr], crate::hir::Expr::Missing) { + if !matches!(body[body.root_expr()], crate::hir::Expr::Missing) { return false; } } diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs index cb5eed1b8b..81a61ec20f 100644 --- a/crates/hir-def/src/visibility.rs +++ b/crates/hir-def/src/visibility.rs @@ -6,11 +6,11 @@ use base_db::Crate; use hir_expand::{InFile, Lookup}; use la_arena::ArenaMap; use syntax::ast::{self, HasVisibility}; -use triomphe::Arc; use crate::{ AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, VariantId, - db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, + db::DefDatabase, nameres::DefMap, resolver::HasResolver, signatures::VariantFields, + src::HasSource, }; pub use crate::item_tree::{RawVisibility, VisibilityExplicitness}; @@ -277,23 +277,26 @@ impl Visibility { } } -/// Resolve visibility of all specific fields of a struct or union variant. -pub(crate) fn field_visibilities_query( - db: &dyn DefDatabase, - variant_id: VariantId, -) -> Arc<ArenaMap<LocalFieldId, Visibility>> { - let variant_fields = variant_id.fields(db); - let fields = variant_fields.fields(); - if fields.is_empty() { - return Arc::default(); - } - let resolver = variant_id.module(db).resolver(db); - let mut res = ArenaMap::default(); - for (field_id, field_data) in fields.iter() { - res.insert(field_id, Visibility::resolve(db, &resolver, &field_data.visibility)); +#[salsa::tracked] +impl VariantFields { + /// Resolve visibility of all specific fields of a struct or union variant. + #[salsa::tracked(returns(ref))] + pub fn field_visibilities( + db: &dyn DefDatabase, + variant_id: VariantId, + ) -> ArenaMap<LocalFieldId, Visibility> { + let variant_fields = variant_id.fields(db); + let fields = variant_fields.fields(); + if fields.is_empty() { + return ArenaMap::default(); + } + let resolver = variant_id.module(db).resolver(db); + let mut res = ArenaMap::with_capacity(fields.len()); + for (field_id, field_data) in fields.iter() { + res.insert(field_id, Visibility::resolve(db, &resolver, &field_data.visibility)); + } + res } - res.shrink_to_fit(); - Arc::new(res) } pub fn visibility_from_ast( diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index 673d00d956..928396c63a 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -276,7 +276,7 @@ pub(crate) fn const_eval_discriminant_variant( let def = variant_id.into(); let body = Body::of(db, def); let loc = variant_id.lookup(db); - if matches!(body[body.body_expr], Expr::Missing) { + if matches!(body[body.root_expr()], Expr::Missing) { let prev_idx = loc.index.checked_sub(1); let value = match prev_idx { Some(prev_idx) => { diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs index e227be6995..33d9dd538d 100644 --- a/crates/hir-ty/src/diagnostics/expr.rs +++ b/crates/hir-ty/src/diagnostics/expr.rs @@ -119,7 +119,7 @@ impl<'db> ExprValidator<'db> { let body = self.body; if matches!(self.owner, DefWithBodyId::FunctionId(_)) { - self.check_for_trailing_return(body.body_expr, body); + self.check_for_trailing_return(body.root_expr(), body); } for (id, expr) in body.exprs() { diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs index eda7e7e249..bc3d9bbec6 100644 --- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs +++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs @@ -4,6 +4,7 @@ use std::{cell::LazyCell, fmt}; use hir_def::{ EnumId, EnumVariantId, HasModule, LocalFieldId, ModuleId, VariantId, attrs::AttrFlags, + signatures::VariantFields, }; use intern::sym; use rustc_pattern_analysis::{ @@ -363,7 +364,8 @@ impl<'a, 'db> PatCx for MatchCheckCtx<'a, 'db> { let adt = adt_def.def_id().0; let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap(); - let visibilities = LazyCell::new(|| self.db.field_visibilities(variant)); + let visibilities = + LazyCell::new(|| VariantFields::field_visibilities(self.db, variant)); self.list_variant_fields(*ty, variant) .map(move |(fid, ty)| { diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs index ba9b7416b7..09c648139c 100644 --- a/crates/hir-ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs @@ -5,8 +5,9 @@ use std::mem; use either::Either; use hir_def::{ - AdtId, CallableDefId, DefWithBodyId, FieldId, FunctionId, VariantId, - expr_store::{Body, path::Path}, + AdtId, CallableDefId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId, GenericDefId, + VariantId, + expr_store::{Body, ExpressionStore, path::Path}, hir::{AsmOperand, Expr, ExprId, ExprOrPatId, InlineAsmKind, Pat, PatId, Statement, UnaryOp}, resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs}, signatures::{FunctionSignature, StaticFlags, StaticSignature}, @@ -55,8 +56,8 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe } } }; - let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut callback); - visitor.walk_expr(body.body_expr); + let mut visitor = UnsafeVisitor::new(db, infer, body, def.into(), &mut callback); + visitor.walk_expr(body.root_expr()); if !is_unsafe { // Unsafety in function parameter patterns (that can only be union destructuring) @@ -109,8 +110,8 @@ pub fn unsafe_operations_for_body( callback(node); } }; - let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut visitor_callback); - visitor.walk_expr(body.body_expr); + let mut visitor = UnsafeVisitor::new(db, infer, body, def.into(), &mut visitor_callback); + visitor.walk_expr(body.root_expr()); for ¶m in &body.params { visitor.walk_pat(param); } @@ -119,8 +120,8 @@ pub fn unsafe_operations_for_body( pub fn unsafe_operations( db: &dyn HirDatabase, infer: &InferenceResult, - def: DefWithBodyId, - body: &Body, + def: ExpressionStoreOwnerId, + body: &ExpressionStore, current: ExprId, callback: &mut dyn FnMut(ExprOrPatId, InsideUnsafeBlock), ) { @@ -137,9 +138,9 @@ pub fn unsafe_operations( struct UnsafeVisitor<'db> { db: &'db dyn HirDatabase, infer: &'db InferenceResult, - body: &'db Body, + body: &'db ExpressionStore, resolver: Resolver<'db>, - def: DefWithBodyId, + def: ExpressionStoreOwnerId, inside_unsafe_block: InsideUnsafeBlock, inside_assignment: bool, inside_union_destructure: bool, @@ -156,13 +157,16 @@ impl<'db> UnsafeVisitor<'db> { fn new( db: &'db dyn HirDatabase, infer: &'db InferenceResult, - body: &'db Body, - def: DefWithBodyId, + body: &'db ExpressionStore, + def: ExpressionStoreOwnerId, unsafe_expr_cb: &'db mut dyn FnMut(UnsafeDiagnostic), ) -> Self { let resolver = def.resolver(db); let def_target_features = match def { - DefWithBodyId::FunctionId(func) => TargetFeatures::from_fn(db, func), + ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(func)) + | ExpressionStoreOwnerId::Signature(GenericDefId::FunctionId(func)) => { + TargetFeatures::from_fn(db, func) + } _ => TargetFeatures::default(), }; let krate = resolver.krate(); diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 52edbc899f..d14e9d6526 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -36,7 +36,7 @@ use hir_def::{ AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId, GenericDefId, GenericParamId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, TypeOrConstParamId, VariantId, - expr_store::{Body, ConstExprOrigin, ExpressionStore, HygieneId, path::Path}, + expr_store::{Body, ExpressionStore, HygieneId, RootExprOrigin, path::Path}, hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId}, lang_item::LangItems, layout::Integer, @@ -143,9 +143,9 @@ pub fn infer_query_with_inspect<'db>( } } - ctx.infer_body(body.body_expr); + ctx.infer_body(body.root_expr()); - ctx.infer_mut_body(body.body_expr); + ctx.infer_mut_body(body.root_expr()); infer_finalize(ctx) } @@ -166,7 +166,7 @@ fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> I fn infer_signature_query(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult { let _p = tracing::info_span!("infer_signature_query").entered(); let store = ExpressionStore::of(db, def.into()); - let mut roots = store.signature_const_expr_roots_with_origins().peekable(); + let mut roots = store.expr_roots_with_origins().peekable(); let Some(_) = roots.peek() else { return InferenceResult::new(crate::next_solver::default_types(db).types.error); }; @@ -179,15 +179,47 @@ fn infer_signature_query(db: &dyn HirDatabase, def: GenericDefId) -> InferenceRe for (root_expr, origin) in roots { let expected = match origin { // Array lengths are always `usize`. - ConstExprOrigin::ArrayLength => Expectation::has_type(ctx.types.types.usize), + RootExprOrigin::ArrayLength => Expectation::has_type(ctx.types.types.usize), // Const parameter default: look up the param's declared type. - ConstExprOrigin::ConstParam(local_id) => Expectation::has_type(db.const_param_ty_ns( + RootExprOrigin::ConstParam(local_id) => Expectation::has_type(db.const_param_ty_ns( ConstParamId::from_unchecked(TypeOrConstParamId { parent: def, local_id }), )), // Path const generic args: determining the expected type requires // path resolution. // FIXME - ConstExprOrigin::GenericArgsPath => Expectation::None, + RootExprOrigin::GenericArgsPath => Expectation::None, + RootExprOrigin::BodyRoot => Expectation::None, + }; + ctx.infer_expr(root_expr, &expected, ExprIsRead::Yes); + } + + infer_finalize(ctx) +} + +fn infer_variant_fields_query(db: &dyn HirDatabase, def: VariantId) -> InferenceResult { + let _p = tracing::info_span!("infer_variant_fields_query").entered(); + let store = ExpressionStore::of(db, def.into()); + let mut roots = store.expr_roots_with_origins().peekable(); + let Some(_) = roots.peek() else { + return InferenceResult::new(crate::next_solver::default_types(db).types.error); + }; + + let resolver = def.resolver(db); + let owner = ExpressionStoreOwnerId::VariantFields(def); + + let mut ctx = InferenceContext::new(db, owner, store, resolver); + + for (root_expr, origin) in roots { + let expected = match origin { + // Array lengths are always `usize`. + RootExprOrigin::ArrayLength => Expectation::has_type(ctx.types.types.usize), + // unreachable + RootExprOrigin::ConstParam(_) => Expectation::None, + // Path const generic args: determining the expected type requires + // path resolution. + // FIXME + RootExprOrigin::GenericArgsPath => Expectation::None, + RootExprOrigin::BodyRoot => Expectation::None, }; ctx.infer_expr(root_expr, &expected, ExprIsRead::Yes); } @@ -206,6 +238,17 @@ fn infer_signature_cycle_result( } } +fn infer_variant_fields_cycle_result( + db: &dyn HirDatabase, + _: salsa::Id, + _: VariantId, +) -> InferenceResult { + InferenceResult { + has_errors: true, + ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed)) + } +} + fn infer_finalize(mut ctx: InferenceContext<'_, '_>) -> InferenceResult { ctx.handle_opaque_type_uses(); @@ -617,6 +660,11 @@ impl InferenceResult { fn for_signature(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult { infer_signature_query(db, def) } + + #[salsa::tracked(returns(ref), cycle_result = infer_variant_fields_cycle_result)] + fn for_variant_fields(db: &dyn HirDatabase, def: VariantId) -> InferenceResult { + infer_variant_fields_query(db, def) + } } impl InferenceResult { @@ -626,6 +674,9 @@ impl InferenceResult { Self::for_signature(db, generic_def_id) } ExpressionStoreOwnerId::Body(def_with_body_id) => Self::for_body(db, def_with_body_id), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + Self::for_variant_fields(db, variant_id) + } } } @@ -937,6 +988,9 @@ impl<'body, 'db> InferenceContext<'body, 'db> { ExpressionStoreOwnerId::Body(def_with_body_id) => { db.trait_environment(ExpressionStoreOwnerId::Body(def_with_body_id)) } + ExpressionStoreOwnerId::VariantFields(variant_id) => { + db.trait_environment(ExpressionStoreOwnerId::VariantFields(variant_id)) + } }; let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), Some(owner)); let types = crate::next_solver::default_types(db); diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs index d720295d93..ce0ccfe82f 100644 --- a/crates/hir-ty/src/infer/closure/analysis.rs +++ b/crates/hir-ty/src/infer/closure/analysis.rs @@ -12,6 +12,7 @@ use hir_def::{ }, item_tree::FieldsShape, resolver::ValueNs, + signatures::VariantFields, }; use rustc_ast_ir::Mutability; use rustc_hash::{FxHashMap, FxHashSet}; @@ -194,6 +195,10 @@ impl CapturedItem { .name .display(db, edition) .to_string(), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let fields = VariantFields::of(db, variant_id); + fields.store[self.place.local].name.display(db, edition).to_string() + } }; for proj in &self.place.projections { match proj { @@ -245,6 +250,10 @@ impl CapturedItem { .name .display(db, edition) .to_string(), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let fields = VariantFields::of(db, variant_id); + fields.store[self.place.local].name.display(db, edition).to_string() + } }; for proj in &self.place.projections { match proj { @@ -301,6 +310,10 @@ impl CapturedItem { .name .display(db, edition) .to_string(), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + let fields = VariantFields::of(db, variant_id); + fields.store[self.place.local].name.display(db, edition).to_string() + } }; let mut field_need_paren = false; for proj in &self.place.projections { diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index c4c217b010..dc57b1d1c2 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -11,7 +11,7 @@ use hir_def::{ InlineAsmKind, LabelId, Literal, Pat, PatId, RecordSpread, Statement, UnaryOp, }, resolver::ValueNs, - signatures::FunctionSignature, + signatures::{FunctionSignature, VariantFields}, }; use hir_def::{FunctionId, hir::ClosureKind}; use hir_expand::name::Name; @@ -609,7 +609,7 @@ impl<'db> InferenceContext<'_, 'db> { Some(def) => { let field_types = self.db.field_types(def); let variant_data = def.fields(self.db); - let visibilities = self.db.field_visibilities(def); + let visibilities = VariantFields::field_visibilities(self.db, def); for field in fields.iter() { let field_def = { match variant_data.field(&field.name) { @@ -1625,7 +1625,8 @@ impl<'db> InferenceContext<'_, 'db> { }, _ => return None, }; - let is_visible = self.db.field_visibilities(field_id.parent)[field_id.local_id] + let is_visible = VariantFields::field_visibilities(self.db, field_id.parent) + [field_id.local_id] .is_visible_from(self.db, self.resolver.module()); if !is_visible { if private_field.is_none() { diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index 0b6c9977f0..8033680dcc 100644 --- a/crates/hir-ty/src/infer/pat.rs +++ b/crates/hir-ty/src/infer/pat.rs @@ -6,6 +6,7 @@ use hir_def::{ HasModule as _, expr_store::{ExpressionStore, path::Path}, hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId}, + signatures::VariantFields, }; use hir_expand::name::Name; use rustc_ast_ir::Mutability; @@ -60,7 +61,7 @@ impl<'db> InferenceContext<'_, 'db> { Some(def) => { let field_types = self.db.field_types(def); let variant_data = def.fields(self.db); - let visibilities = self.db.field_visibilities(def); + let visibilities = VariantFields::field_visibilities(self.db, def); let (pre, post) = match ellipsis { Some(idx) => subs.split_at(idx as usize), @@ -129,7 +130,7 @@ impl<'db> InferenceContext<'_, 'db> { Some(def) => { let field_types = self.db.field_types(def); let variant_data = def.fields(self.db); - let visibilities = self.db.field_visibilities(def); + let visibilities = VariantFields::field_visibilities(self.db, def); let substs = ty.as_adt().map(TupleExt::tail); diff --git a/crates/hir-ty/src/inhabitedness.rs b/crates/hir-ty/src/inhabitedness.rs index 402e9ce969..74d66123ea 100644 --- a/crates/hir-ty/src/inhabitedness.rs +++ b/crates/hir-ty/src/inhabitedness.rs @@ -1,7 +1,9 @@ //! Type inhabitedness logic. use std::ops::ControlFlow::{self, Break, Continue}; -use hir_def::{AdtId, EnumVariantId, ModuleId, VariantId, visibility::Visibility}; +use hir_def::{ + AdtId, EnumVariantId, ModuleId, VariantId, signatures::VariantFields, visibility::Visibility, +}; use rustc_hash::FxHashSet; use rustc_type_ir::{ TypeSuperVisitable, TypeVisitable, TypeVisitor, @@ -151,7 +153,11 @@ impl<'a, 'db> UninhabitedFrom<'a, 'db> { let is_enum = matches!(variant, VariantId::EnumVariantId(..)); let field_tys = self.db().field_types(variant); - let field_vis = if is_enum { None } else { Some(self.db().field_visibilities(variant)) }; + let field_vis = if is_enum { + None + } else { + Some(VariantFields::field_visibilities(self.db(), variant)) + }; for (fid, _) in fields.iter() { self.visit_field(field_vis.as_ref().map(|it| it[fid]), &field_tys[fid].get(), subst)?; diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 5eee025f2c..7259099107 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -2156,13 +2156,7 @@ pub(crate) fn trait_environment<'db>( db: &'db dyn HirDatabase, def: ExpressionStoreOwnerId, ) -> ParamEnv<'db> { - let def = match def { - ExpressionStoreOwnerId::Signature(def) => def, - ExpressionStoreOwnerId::Body(def) => match def.as_generic_def_id(db) { - Some(def) => def, - None => return ParamEnv::empty(), - }, - }; + let def = def.generic_def(db); return ParamEnv { clauses: trait_environment_query(db, def).as_ref() }; diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index c013e78d81..505db1776f 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -900,7 +900,7 @@ impl<'db> Evaluator<'db> { OperandKind::Constant { konst: _, ty } => ty.as_ref(), &OperandKind::Static(s) => { let ty = InferenceResult::of(self.db, DefWithBodyId::from(s)) - .expr_ty(Body::of(self.db, s.into()).body_expr); + .expr_ty(Body::of(self.db, s.into()).root_expr()); Ty::new_ref( self.interner(), Region::new_static(self.interner()), @@ -2835,7 +2835,7 @@ impl<'db> Evaluator<'db> { self.allocate_const_in_heap(locals, konst)? } else { let ty = InferenceResult::of(self.db, DefWithBodyId::from(st)) - .expr_ty(Body::of(self.db, st.into()).body_expr); + .expr_ty(Body::of(self.db, st.into()).root_expr()); let Some((size, align)) = self.size_align_of(ty, locals)? else { not_supported!("unsized extern static"); }; diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 675fc371c6..44785d948a 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -2251,7 +2251,7 @@ pub fn mir_body_query<'db>( let _p = tracing::info_span!("mir_body_query", ?detail).entered(); let body = Body::of(db, def); let infer = InferenceResult::of(db, def); - let mut result = lower_body_to_mir(db, def, body, infer, body.body_expr)?; + let mut result = lower_body_to_mir(db, def, body, infer, body.root_expr())?; result.shrink_to_fit(); Ok(Arc::new(result)) } @@ -2275,7 +2275,7 @@ pub fn lower_body_to_mir<'db>( // but this is currently also used for `X` in `[(); X]` which live in the same expression store root_expr: ExprId, ) -> Result<'db, MirBody> { - let is_root = root_expr == body.body_expr; + let is_root = root_expr == body.root_expr(); // Extract params and self_param only when lowering the body's root expression for a function. if is_root && let DefWithBodyId::FunctionId(fid) = owner { let callable_sig = diff --git a/crates/hir-ty/src/next_solver/def_id.rs b/crates/hir-ty/src/next_solver/def_id.rs index 5d122ce446..00161d6d08 100644 --- a/crates/hir-ty/src/next_solver/def_id.rs +++ b/crates/hir-ty/src/next_solver/def_id.rs @@ -3,7 +3,7 @@ use hir_def::{ AdtId, AnonConstId, AttrDefId, BuiltinDeriveImplId, CallableDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, ExpressionStoreOwnerId, FunctionId, GeneralConstId, GenericDefId, - ImplId, StaticId, StructId, TraitId, TypeAliasId, UnionId, + ImplId, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, signatures::{ ConstSignature, EnumSignature, FunctionSignature, StaticSignature, StructSignature, TraitSignature, TypeAliasSignature, UnionSignature, @@ -166,12 +166,24 @@ impl From<DefWithBodyId> for SolverDefId { } } +impl From<VariantId> for SolverDefId { + #[inline] + fn from(value: VariantId) -> Self { + match value { + VariantId::EnumVariantId(id) => id.into(), + VariantId::StructId(id) => id.into(), + VariantId::UnionId(id) => id.into(), + } + } +} + impl From<ExpressionStoreOwnerId> for SolverDefId { #[inline] fn from(value: ExpressionStoreOwnerId) -> Self { match value { ExpressionStoreOwnerId::Body(body_id) => body_id.into(), ExpressionStoreOwnerId::Signature(sig_id) => sig_id.into(), + ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.into(), } } } diff --git a/crates/hir-ty/src/upvars.rs b/crates/hir-ty/src/upvars.rs index d19fbbc187..489895fe3c 100644 --- a/crates/hir-ty/src/upvars.rs +++ b/crates/hir-ty/src/upvars.rs @@ -47,7 +47,7 @@ pub fn upvars_mentioned( let body = Body::of(db, owner); let mut resolver = owner.resolver(db); let mut result = FxHashMap::default(); - handle_expr_outside_closure(db, &mut resolver, owner, body, body.body_expr, &mut result); + handle_expr_outside_closure(db, &mut resolver, owner, body, body.root_expr(), &mut result); return if result.is_empty() { None } else { diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 4efb7fcb6f..27e7985146 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -27,9 +27,9 @@ use intern::Symbol; use stdx::never; use crate::{ - Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl, - Field, Function, GenericParam, HasCrate, Impl, LangItem, LifetimeParam, Macro, Module, - ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, + Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, EnumVariant, + ExternCrateDecl, Field, Function, GenericParam, HasCrate, Impl, LangItem, LifetimeParam, Macro, + Module, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, }; #[derive(Debug, Clone, Copy)] @@ -200,7 +200,7 @@ macro_rules! impl_has_attrs { } impl_has_attrs![ - (Variant, EnumVariantId), + (EnumVariant, EnumVariantId), (Static, StaticId), (Const, ConstId), (Trait, TraitId), @@ -407,7 +407,7 @@ fn resolve_assoc_or_field( TypeNs::AdtId(id) | TypeNs::AdtSelfType(id) => Adt::from(id).ty(db), TypeNs::EnumVariantId(id) => { // Enum variants don't have path candidates. - let variant = Variant::from(id); + let variant = EnumVariant::from(id); return resolve_field(db, variant.into(), name, ns); } TypeNs::TypeAliasId(id) => { @@ -444,7 +444,7 @@ fn resolve_assoc_or_field( .id .enum_variants(db) .variant(&name) - .map(|variant| DocLinkDef::ModuleDef(ModuleDef::Variant(variant.into()))); + .map(|variant| DocLinkDef::ModuleDef(ModuleDef::EnumVariant(variant.into()))); } }; resolve_field(db, variant_def, name, ns) @@ -506,7 +506,7 @@ fn resolve_impl_trait_item<'db>( fn resolve_field( db: &dyn HirDatabase, - def: VariantDef, + def: Variant, name: Name, ns: Option<Namespace>, ) -> Option<DocLinkDef> { diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index ef885f0be8..4bfdd239f9 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -29,9 +29,9 @@ use rustc_type_ir::inherent::IntoKind; use crate::{ Adt, AnyFunctionId, AsAssocItem, AssocItem, AssocItemContainer, Const, ConstParam, Crate, Enum, - ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, LifetimeParam, - Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, TupleField, Type, - TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, Variant, + EnumVariant, ExternCrateDecl, Field, Function, GenericParam, HasCrate, HasVisibility, Impl, + LifetimeParam, Macro, Module, SelfParam, Static, Struct, StructKind, Trait, TraitRef, + TupleField, Type, TypeAlias, TypeNs, TypeOrConstParam, TypeParam, Union, }; fn write_builtin_derive_impl_method<'db>( @@ -443,7 +443,7 @@ fn write_fields<'db>( } fn write_variants<'db>( - variants: &[Variant], + variants: &[EnumVariant], has_where_clause: bool, limit: usize, f: &mut HirFormatter<'_, 'db>, @@ -497,7 +497,7 @@ impl<'db> HirDisplay<'db> for TupleField { } } -impl<'db> HirDisplay<'db> for Variant { +impl<'db> HirDisplay<'db> for EnumVariant { fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result { write!(f, "{}", self.name(f.db).display(f.db, f.edition()))?; let data = self.id.fields(f.db); diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs index 1aeed874af..0a48be5473 100644 --- a/crates/hir/src/from_id.rs +++ b/crates/hir/src/from_id.rs @@ -5,14 +5,14 @@ use hir_def::{ AdtId, AssocItemId, BuiltinDeriveImplId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, - FieldId, GenericDefId, GenericParamId, ModuleDefId, VariantId, + FieldId, FunctionId, GenericDefId, GenericParamId, ImplId, ModuleDefId, VariantId, hir::{BindingId, LabelId}, }; use hir_ty::next_solver::AnyImplId; use crate::{ - Adt, AnyFunctionId, AssocItem, BuiltinType, DefWithBody, Field, GenericDef, GenericParam, - ItemInNs, Label, Local, ModuleDef, Variant, VariantDef, + Adt, AnyFunctionId, AssocItem, BuiltinType, DefWithBody, EnumVariant, ExpressionStoreOwner, + Field, Function, GenericDef, GenericParam, Impl, ItemInNs, Label, Local, ModuleDef, Variant, }; macro_rules! from_id { @@ -71,6 +71,15 @@ impl From<Adt> for AdtId { } } +impl From<VariantId> for Variant { + fn from(v: VariantId) -> Self { + match v { + VariantId::EnumVariantId(it) => Variant::EnumVariant(it.into()), + VariantId::StructId(it) => Variant::Struct(it.into()), + VariantId::UnionId(it) => Variant::Union(it.into()), + } + } +} impl From<GenericParamId> for GenericParam { fn from(id: GenericParamId) -> Self { match id { @@ -91,14 +100,14 @@ impl From<GenericParam> for GenericParamId { } } -impl From<EnumVariantId> for Variant { +impl From<EnumVariantId> for EnumVariant { fn from(id: EnumVariantId) -> Self { - Variant { id } + EnumVariant { id } } } -impl From<Variant> for EnumVariantId { - fn from(def: Variant) -> Self { +impl From<EnumVariant> for EnumVariantId { + fn from(def: EnumVariant) -> Self { def.id } } @@ -109,7 +118,7 @@ impl From<ModuleDefId> for ModuleDef { ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()), ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()), ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()), - ModuleDefId::EnumVariantId(it) => ModuleDef::Variant(it.into()), + ModuleDefId::EnumVariantId(it) => ModuleDef::EnumVariant(it.into()), ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()), ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()), ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()), @@ -130,7 +139,7 @@ impl TryFrom<ModuleDef> for ModuleDefId { AnyFunctionId::BuiltinDeriveImplMethod { .. } => return Err(()), }, ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()), - ModuleDef::Variant(it) => ModuleDefId::EnumVariantId(it.into()), + ModuleDef::EnumVariant(it) => ModuleDefId::EnumVariantId(it.into()), ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()), ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()), ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()), @@ -151,7 +160,7 @@ impl TryFrom<DefWithBody> for DefWithBodyId { }, DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id), DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id), - DefWithBody::Variant(it) => DefWithBodyId::VariantId(it.into()), + DefWithBody::EnumVariant(it) => DefWithBodyId::VariantId(it.into()), }) } } @@ -162,7 +171,7 @@ impl From<DefWithBodyId> for DefWithBody { DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()), DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()), DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()), - DefWithBodyId::VariantId(it) => DefWithBody::Variant(it.into()), + DefWithBodyId::VariantId(it) => DefWithBody::EnumVariant(it.into()), } } } @@ -209,22 +218,12 @@ impl From<Adt> for GenericDefId { } } -impl From<VariantId> for VariantDef { - fn from(def: VariantId) -> Self { - match def { - VariantId::StructId(it) => VariantDef::Struct(it.into()), - VariantId::EnumVariantId(it) => VariantDef::Variant(it.into()), - VariantId::UnionId(it) => VariantDef::Union(it.into()), - } - } -} - -impl From<VariantDef> for VariantId { - fn from(def: VariantDef) -> Self { +impl From<Variant> for VariantId { + fn from(def: Variant) -> Self { match def { - VariantDef::Struct(it) => VariantId::StructId(it.id), - VariantDef::Variant(it) => VariantId::EnumVariantId(it.into()), - VariantDef::Union(it) => VariantId::UnionId(it.id), + Variant::Struct(it) => VariantId::StructId(it.id), + Variant::EnumVariant(it) => VariantId::EnumVariantId(it.into()), + Variant::Union(it) => VariantId::UnionId(it.id), } } } @@ -322,3 +321,43 @@ impl From<hir_def::FunctionId> for crate::Function { crate::Function { id: AnyFunctionId::FunctionId(value) } } } + +impl TryFrom<ExpressionStoreOwner> for ExpressionStoreOwnerId { + type Error = (); + + fn try_from(v: ExpressionStoreOwner) -> Result<Self, Self::Error> { + match v { + ExpressionStoreOwner::Signature(generic_def_id) => { + Ok(Self::Signature(generic_def_id.try_into()?)) + } + ExpressionStoreOwner::Body(def_with_body_id) => { + Ok(Self::Body(def_with_body_id.try_into()?)) + } + ExpressionStoreOwner::VariantFields(variant_id) => { + Ok(Self::VariantFields(variant_id.into())) + } + } + } +} + +impl TryFrom<Function> for FunctionId { + type Error = (); + + fn try_from(v: Function) -> Result<Self, Self::Error> { + match v.id { + AnyFunctionId::FunctionId(id) => Ok(id), + _ => Err(()), + } + } +} + +impl TryFrom<Impl> for ImplId { + type Error = (); + + fn try_from(v: Impl) -> Result<Self, Self::Error> { + match v.id { + AnyImplId::ImplId(id) => Ok(id), + _ => Err(()), + } + } +} diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 752c4f3173..f9badc0b79 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs @@ -13,9 +13,9 @@ use syntax::{AstNode, ast}; use tt::TextRange; use crate::{ - Adt, AnyFunctionId, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl, - InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static, - Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant, VariantDef, db::HirDatabase, + Adt, AnyFunctionId, Callee, Const, Enum, EnumVariant, ExternCrateDecl, Field, FieldSource, + Function, Impl, InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, + SelfParam, Static, Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant, db::HirDatabase, }; pub trait HasSource: Sized { @@ -124,13 +124,13 @@ impl HasSource for Adt { } } } -impl HasSource for VariantDef { +impl HasSource for Variant { type Ast = ast::VariantDef; fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> { match self { - VariantDef::Struct(s) => Some(s.source(db)?.map(ast::VariantDef::Struct)), - VariantDef::Union(u) => Some(u.source(db)?.map(ast::VariantDef::Union)), - VariantDef::Variant(v) => Some(v.source(db)?.map(ast::VariantDef::Variant)), + Variant::Struct(s) => Some(s.source(db)?.map(ast::VariantDef::Struct)), + Variant::Union(u) => Some(u.source(db)?.map(ast::VariantDef::Union)), + Variant::EnumVariant(v) => Some(v.source(db)?.map(ast::VariantDef::Variant)), } } } @@ -152,7 +152,7 @@ impl HasSource for Enum { Some(self.id.lookup(db).source(db)) } } -impl HasSource for Variant { +impl HasSource for EnumVariant { type Ast = ast::Variant; fn source(self, db: &dyn HirDatabase) -> Option<InFile<ast::Variant>> { Some(self.id.lookup(db).source(db)) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 67527150bd..bc5e164830 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -356,8 +356,7 @@ pub enum ModuleDef { Function(Function), Adt(Adt), // Can't be directly declared, but can be imported. - // FIXME: Rename to `EnumVariant` - Variant(Variant), + EnumVariant(EnumVariant), Const(Const), Static(Static), Trait(Trait), @@ -369,7 +368,7 @@ impl_from!( Module, Function, Adt(Struct, Enum, Union), - Variant, + EnumVariant, Const, Static, Trait, @@ -379,12 +378,12 @@ impl_from!( for ModuleDef ); -impl From<VariantDef> for ModuleDef { - fn from(var: VariantDef) -> Self { +impl From<Variant> for ModuleDef { + fn from(var: Variant) -> Self { match var { - VariantDef::Struct(t) => Adt::from(t).into(), - VariantDef::Union(t) => Adt::from(t).into(), - VariantDef::Variant(t) => t.into(), + Variant::Struct(t) => Adt::from(t).into(), + Variant::Union(t) => Adt::from(t).into(), + Variant::EnumVariant(t) => t.into(), } } } @@ -395,7 +394,7 @@ impl ModuleDef { ModuleDef::Module(it) => it.parent(db), ModuleDef::Function(it) => Some(it.module(db)), ModuleDef::Adt(it) => Some(it.module(db)), - ModuleDef::Variant(it) => Some(it.module(db)), + ModuleDef::EnumVariant(it) => Some(it.module(db)), ModuleDef::Const(it) => Some(it.module(db)), ModuleDef::Static(it) => Some(it.module(db)), ModuleDef::Trait(it) => Some(it.module(db)), @@ -428,7 +427,7 @@ impl ModuleDef { ModuleDef::Adt(it) => it.name(db), ModuleDef::Trait(it) => it.name(db), ModuleDef::Function(it) => it.name(db), - ModuleDef::Variant(it) => it.name(db), + ModuleDef::EnumVariant(it) => it.name(db), ModuleDef::TypeAlias(it) => it.name(db), ModuleDef::Static(it) => it.name(db), ModuleDef::Macro(it) => it.name(db), @@ -457,7 +456,7 @@ impl ModuleDef { ModuleDef::Module(it) => it.id.into(), ModuleDef::Const(it) => it.id.into(), ModuleDef::Static(it) => it.id.into(), - ModuleDef::Variant(it) => it.id.into(), + ModuleDef::EnumVariant(it) => it.id.into(), ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(), }; @@ -486,7 +485,7 @@ impl ModuleDef { ModuleDef::Function(it) => Some(it.into()), ModuleDef::Const(it) => Some(it.into()), ModuleDef::Static(it) => Some(it.into()), - ModuleDef::Variant(it) => Some(it.into()), + ModuleDef::EnumVariant(it) => Some(it.into()), ModuleDef::Module(_) | ModuleDef::Adt(_) @@ -505,7 +504,7 @@ impl ModuleDef { ModuleDef::Trait(it) => Some(it.into()), ModuleDef::TypeAlias(it) => Some(it.into()), ModuleDef::Module(_) - | ModuleDef::Variant(_) + | ModuleDef::EnumVariant(_) | ModuleDef::Static(_) | ModuleDef::Const(_) | ModuleDef::BuiltinType(_) @@ -521,7 +520,7 @@ impl ModuleDef { ModuleDef::TypeAlias(it) => Some(it.into()), ModuleDef::Static(it) => Some(it.into()), ModuleDef::Const(it) => Some(it.into()), - ModuleDef::Variant(_) + ModuleDef::EnumVariant(_) | ModuleDef::Module(_) | ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => None, @@ -533,7 +532,7 @@ impl ModuleDef { ModuleDef::Module(it) => it.attrs(db), ModuleDef::Function(it) => HasAttrs::attrs(*it, db), ModuleDef::Adt(it) => it.attrs(db), - ModuleDef::Variant(it) => it.attrs(db), + ModuleDef::EnumVariant(it) => it.attrs(db), ModuleDef::Const(it) => it.attrs(db), ModuleDef::Static(it) => it.attrs(db), ModuleDef::Trait(it) => it.attrs(db), @@ -563,7 +562,7 @@ impl HasVisibility for ModuleDef { ModuleDef::Static(it) => it.visibility(db), ModuleDef::Trait(it) => it.visibility(db), ModuleDef::TypeAlias(it) => it.visibility(db), - ModuleDef::Variant(it) => it.visibility(db), + ModuleDef::EnumVariant(it) => it.visibility(db), ModuleDef::Macro(it) => it.visibility(db), ModuleDef::BuiltinType(_) => Visibility::Public, } @@ -1300,7 +1299,7 @@ impl HasVisibility for Module { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Field { - pub(crate) parent: VariantDef, + pub(crate) parent: Variant, pub(crate) id: LocalFieldId, } @@ -1324,7 +1323,7 @@ impl<'db> InstantiatedField<'db> { #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] pub struct TupleField { - pub owner: DefWithBodyId, + pub owner: ExpressionStoreOwnerId, pub tuple: TupleId, pub index: u32, } @@ -1406,9 +1405,9 @@ impl Field { ) -> Type<'db> { let var_id = self.parent.into(); let def_id: AdtId = match self.parent { - VariantDef::Struct(it) => it.id.into(), - VariantDef::Union(it) => it.id.into(), - VariantDef::Variant(it) => it.parent_enum(db).id.into(), + Variant::Struct(it) => it.id.into(), + Variant::Union(it) => it.id.into(), + Variant::EnumVariant(it) => it.parent_enum(db).id.into(), }; let interner = DbInterner::new_no_crate(db); let args = generic_args_from_tys(interner, def_id.into(), generics.map(|ty| ty.ty)); @@ -1434,7 +1433,7 @@ impl Field { .map(|layout| Layout(layout, db.target_data_layout(self.krate(db).into()).unwrap())) } - pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef { + pub fn parent_def(&self, _db: &dyn HirDatabase) -> Variant { self.parent } } @@ -1615,8 +1614,8 @@ impl Enum { EnumSignature::of(db, self.id).name.clone() } - pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> { - self.id.enum_variants(db).variants.iter().map(|&(id, _, _)| Variant { id }).collect() + pub fn variants(self, db: &dyn HirDatabase) -> Vec<EnumVariant> { + self.id.enum_variants(db).variants.iter().map(|&(id, _, _)| EnumVariant { id }).collect() } pub fn num_variants(self, db: &dyn HirDatabase) -> usize { @@ -1708,19 +1707,18 @@ impl<'db> InstantiatedEnum<'db> { } } -impl From<&Variant> for DefWithBodyId { - fn from(&v: &Variant) -> Self { +impl From<&EnumVariant> for DefWithBodyId { + fn from(&v: &EnumVariant) -> Self { DefWithBodyId::VariantId(v.into()) } } -// FIXME: Rename to `EnumVariant` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Variant { +pub struct EnumVariant { pub(crate) id: EnumVariantId, } -impl Variant { +impl EnumVariant { pub fn module(self, db: &dyn HirDatabase) -> Module { Module { id: self.id.module(db) } } @@ -1794,7 +1792,7 @@ impl Variant { // FIXME: Rename to `EnumVariant` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct InstantiatedVariant<'db> { - pub(crate) inner: Variant, + pub(crate) inner: EnumVariant, pub(crate) args: GenericArgs<'db>, } @@ -1825,7 +1823,7 @@ pub enum StructKind { } /// Variants inherit visibility from the parent enum. -impl HasVisibility for Variant { +impl HasVisibility for EnumVariant { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { self.parent_enum(db).visibility(db) } @@ -1934,35 +1932,35 @@ impl HasVisibility for Adt { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum VariantDef { +pub enum Variant { Struct(Struct), Union(Union), - Variant(Variant), + EnumVariant(EnumVariant), } -impl_from!(Struct, Union, Variant for VariantDef); +impl_from!(Struct, Union, EnumVariant for Variant); -impl VariantDef { +impl Variant { pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> { match self { - VariantDef::Struct(it) => it.fields(db), - VariantDef::Union(it) => it.fields(db), - VariantDef::Variant(it) => it.fields(db), + Variant::Struct(it) => it.fields(db), + Variant::Union(it) => it.fields(db), + Variant::EnumVariant(it) => it.fields(db), } } pub fn module(self, db: &dyn HirDatabase) -> Module { match self { - VariantDef::Struct(it) => it.module(db), - VariantDef::Union(it) => it.module(db), - VariantDef::Variant(it) => it.module(db), + Variant::Struct(it) => it.module(db), + Variant::Union(it) => it.module(db), + Variant::EnumVariant(it) => it.module(db), } } pub fn name(&self, db: &dyn HirDatabase) -> Name { match self { - VariantDef::Struct(s) => (*s).name(db), - VariantDef::Union(u) => (*u).name(db), - VariantDef::Variant(e) => (*e).name(db), + Variant::Struct(s) => (*s).name(db), + Variant::Union(u) => (*u).name(db), + Variant::EnumVariant(e) => (*e).name(db), } } } @@ -1971,6 +1969,7 @@ impl VariantDef { pub enum ExpressionStoreOwner { Body(DefWithBody), Signature(GenericDef), + VariantFields(Variant), } impl From<GenericDef> for ExpressionStoreOwner { @@ -1992,6 +1991,9 @@ impl From<ExpressionStoreOwnerId> for ExpressionStoreOwner { Self::Signature(generic_def_id.into()) } ExpressionStoreOwnerId::Body(def_with_body_id) => Self::Body(def_with_body_id.into()), + ExpressionStoreOwnerId::VariantFields(variant_id) => { + Self::VariantFields(variant_id.into()) + } } } } @@ -2001,6 +2003,7 @@ impl ExpressionStoreOwner { match self { Self::Body(body) => body.module(db), Self::Signature(generic_def) => generic_def.module(db), + Self::VariantFields(variant) => variant.module(db), } } } @@ -2011,9 +2014,9 @@ pub enum DefWithBody { Function(Function), Static(Static), Const(Const), - Variant(Variant), + EnumVariant(EnumVariant), } -impl_from!(Function, Const, Static, Variant for DefWithBody); +impl_from!(Function, Const, Static, EnumVariant for DefWithBody); impl DefWithBody { pub fn module(self, db: &dyn HirDatabase) -> Module { @@ -2021,7 +2024,7 @@ impl DefWithBody { DefWithBody::Const(c) => c.module(db), DefWithBody::Function(f) => f.module(db), DefWithBody::Static(s) => s.module(db), - DefWithBody::Variant(v) => v.module(db), + DefWithBody::EnumVariant(v) => v.module(db), } } @@ -2030,7 +2033,7 @@ impl DefWithBody { DefWithBody::Function(f) => Some(f.name(db)), DefWithBody::Static(s) => Some(s.name(db)), DefWithBody::Const(c) => c.name(db), - DefWithBody::Variant(v) => Some(v.name(db)), + DefWithBody::EnumVariant(v) => Some(v.name(db)), } } @@ -2040,7 +2043,7 @@ impl DefWithBody { DefWithBody::Function(it) => it.ret_type(db), DefWithBody::Static(it) => it.ty(db), DefWithBody::Const(it) => it.ty(db), - DefWithBody::Variant(it) => it.parent_enum(db).variant_body_ty(db), + DefWithBody::EnumVariant(it) => it.parent_enum(db).variant_body_ty(db), } } @@ -2052,7 +2055,7 @@ impl DefWithBody { }, DefWithBody::Static(it) => it.id.into(), DefWithBody::Const(it) => it.id.into(), - DefWithBody::Variant(it) => it.into(), + DefWithBody::EnumVariant(it) => it.into(), }) } @@ -2096,7 +2099,7 @@ impl DefWithBody { }, DefWithBody::Static(id) => &StaticSignature::with_source_map(db, id.into()).1, DefWithBody::Const(id) => &ConstSignature::with_source_map(db, id.into()).1, - DefWithBody::Variant(variant) => { + DefWithBody::EnumVariant(variant) => { let enum_id = variant.parent_enum(db).id; &EnumSignature::with_source_map(db, enum_id).1 } @@ -3785,7 +3788,7 @@ impl AsAssocItem for DefWithBody { match self { DefWithBody::Function(it) => it.as_assoc_item(db), DefWithBody::Const(it) => it.as_assoc_item(db), - DefWithBody::Static(_) | DefWithBody::Variant(_) => None, + DefWithBody::Static(_) | DefWithBody::EnumVariant(_) => None, } } } @@ -4369,11 +4372,9 @@ impl Local { /// All definitions for this local. Example: `let (a$0, _) | (_, a$0) = it;` pub fn sources(self, db: &dyn HirDatabase) -> Vec<LocalSource> { let b; - let s; let (_, source_map) = match self.parent { ExpressionStoreOwnerId::Signature(generic_def_id) => { - s = ExpressionStore::with_source_map(db, generic_def_id.into()); - (s.0, s.1) + ExpressionStore::with_source_map(db, generic_def_id.into()) } ExpressionStoreOwnerId::Body(def_with_body_id) => { b = Body::with_source_map(db, def_with_body_id); @@ -4388,6 +4389,9 @@ impl Local { } (&b.0.store, &b.1.store) } + ExpressionStoreOwnerId::VariantFields(def) => { + ExpressionStore::with_source_map(db, def.into()) + } }; source_map .patterns_for_binding(self.binding_id) @@ -4409,11 +4413,9 @@ impl Local { /// The leftmost definition for this local. Example: `let (a$0, _) | (_, a) = it;` pub fn primary_source(self, db: &dyn HirDatabase) -> LocalSource { let b; - let s; let (_, source_map) = match self.parent { ExpressionStoreOwnerId::Signature(generic_def_id) => { - s = ExpressionStore::with_source_map(db, generic_def_id.into()); - (s.0, s.1) + ExpressionStore::with_source_map(db, generic_def_id.into()) } ExpressionStoreOwnerId::Body(def_with_body_id) => { b = Body::with_source_map(db, def_with_body_id); @@ -4428,6 +4430,9 @@ impl Local { } (&b.0.store, &b.1.store) } + ExpressionStoreOwnerId::VariantFields(def) => { + ExpressionStore::with_source_map(db, def.into()) + } }; source_map .patterns_for_binding(self.binding_id) @@ -6519,7 +6524,7 @@ enum Callee<'db> { pub enum CallableKind<'db> { Function(Function), TupleStruct(Struct), - TupleEnumVariant(Variant), + TupleEnumVariant(EnumVariant), Closure(Closure<'db>), FnPtr, FnImpl(FnTrait), @@ -6869,7 +6874,7 @@ impl HasCrate for Field { } } -impl HasCrate for Variant { +impl HasCrate for EnumVariant { fn krate(&self, db: &dyn HirDatabase) -> Crate { self.module(db).krate(db) } @@ -7038,9 +7043,9 @@ impl_has_name!( Struct, Union, Enum, - Variant, + EnumVariant, Adt, - VariantDef, + Variant, DefWithBody, Function, ExternCrateDecl, @@ -7264,9 +7269,9 @@ fn param_env_from_has_crate<'db>( fn body_param_env_from_has_crate<'db>( db: &'db dyn HirDatabase, - id: impl hir_def::HasModule + Into<DefWithBodyId> + Copy, + id: impl hir_def::HasModule + Into<ExpressionStoreOwnerId> + Copy, ) -> ParamEnvAndCrate<'db> { - ParamEnvAndCrate { param_env: db.trait_environment(id.into().into()), krate: id.krate(db) } + ParamEnvAndCrate { param_env: db.trait_environment(id.into()), krate: id.krate(db) } } fn empty_param_env<'db>(krate: base_db::Crate) -> ParamEnvAndCrate<'db> { diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index f1aabb5933..4e9e3c44be 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -16,7 +16,7 @@ use hir_def::{ BuiltinDeriveImplId, DefWithBodyId, ExpressionStoreOwnerId, HasModule, MacroId, StructId, TraitId, VariantId, attrs::parse_extra_crate_attrs, - expr_store::{Body, ExprOrPatSource, HygieneId, path::Path}, + expr_store::{Body, ExprOrPatSource, ExpressionStore, HygieneId, path::Path}, hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat}, nameres::{ModuleOrigin, crate_def_map}, resolver::{self, HasResolver, Resolver, TypeNs, ValueNs}, @@ -32,7 +32,7 @@ use hir_expand::{ }; use hir_ty::{ InferenceResult, - diagnostics::{unsafe_operations, unsafe_operations_for_body}, + diagnostics::unsafe_operations, infer_query_with_inspect, next_solver::{ AnyImplId, DbInterner, Span, @@ -55,10 +55,10 @@ use syntax::{ use crate::{ Adjust, Adjustment, Adt, AnyFunctionId, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const, - ConstParam, Crate, DefWithBody, DeriveHelper, Enum, ExpressionStoreOwner, Field, Function, + ConstParam, Crate, DeriveHelper, Enum, EnumVariant, ExpressionStoreOwner, Field, Function, GenericSubstitution, HasSource, Impl, InFile, InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, OverloadedDeref, ScopeDef, Static, Struct, ToolModule, - Trait, TupleField, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, + Trait, TupleField, Type, TypeAlias, TypeParam, Union, Variant, db::HirDatabase, semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, source_analyzer::{SourceAnalyzer, resolve_hir_path}, @@ -91,7 +91,7 @@ impl PathResolution { } PathResolution::Def( ModuleDef::Const(_) - | ModuleDef::Variant(_) + | ModuleDef::EnumVariant(_) | ModuleDef::Macro(_) | ModuleDef::Function(_) | ModuleDef::Module(_) @@ -368,8 +368,8 @@ impl<DB: HirDatabase + ?Sized> Semantics<'_, DB> { self.imp.resolve_try_expr(try_expr) } - pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantDef> { - self.imp.resolve_variant(record_lit).map(VariantDef::from) + pub fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<Variant> { + self.imp.resolve_variant(record_lit).map(Variant::from) } pub fn file_to_module_def(&self, file: impl Into<FileId>) -> Option<Module> { @@ -410,7 +410,7 @@ impl<DB: HirDatabase + ?Sized> Semantics<'_, DB> { self.imp.to_def(e) } - pub fn to_enum_variant_def(&self, v: &ast::Variant) -> Option<Variant> { + pub fn to_enum_variant_def(&self, v: &ast::Variant) -> Option<EnumVariant> { self.imp.to_def(v) } @@ -792,7 +792,8 @@ impl<'db> SemanticsImpl<'db> { }; let body = Body::of(self.db, def); let resolver = to_be_renamed.parent.resolver(self.db); - let starting_expr = body.binding_owner(to_be_renamed.binding_id).unwrap_or(body.body_expr); + let starting_expr = + body.binding_owner(to_be_renamed.binding_id).unwrap_or(body.root_expr()); let mut visitor = RenameConflictsVisitor { body, conflicts: FxHashSet::default(), @@ -1918,36 +1919,32 @@ impl<'db> SemanticsImpl<'db> { self.db.parse_macro_expansion(file_id).value.1.matched_arm } - pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet<ExprOrPatSource> { - let Ok(def) = DefWithBodyId::try_from(def) else { - return FxHashSet::default(); - }; - let (body, source_map) = Body::with_source_map(self.db, def); + pub fn get_unsafe_ops(&self, def: ExpressionStoreOwner) -> FxHashSet<ExprOrPatSource> { + let Ok(def) = ExpressionStoreOwnerId::try_from(def) else { return Default::default() }; + let (body, source_map) = ExpressionStore::with_source_map(self.db, def); let infer = InferenceResult::of(self.db, def); let mut res = FxHashSet::default(); - unsafe_operations_for_body(self.db, infer, def, body, &mut |node| { - if let Ok(node) = source_map.expr_or_pat_syntax(node) { - res.insert(node); - } - }); + for root in body.expr_roots() { + unsafe_operations(self.db, infer, def, body, root, &mut |node, _| { + if let Ok(node) = source_map.expr_or_pat_syntax(node) { + res.insert(node); + } + }); + } res } pub fn get_unsafe_ops_for_unsafe_block(&self, block: ast::BlockExpr) -> Vec<ExprOrPatSource> { always!(block.unsafe_token().is_some()); + let Some(sa) = self.analyze(block.syntax()) else { return vec![] }; + let Some((def, store, sm, Some(infer))) = sa.def() else { return vec![] }; let block = self.wrap_node_infile(ast::Expr::from(block)); - let Some(def) = self.body_for(block.syntax()) else { return Vec::new() }; - let Ok(def) = def.try_into() else { - return Vec::new(); - }; - let (body, source_map) = Body::with_source_map(self.db, def); - let infer = InferenceResult::of(self.db, def); - let Some(ExprOrPatId::ExprId(block)) = source_map.node_expr(block.as_ref()) else { + let Some(ExprOrPatId::ExprId(block)) = sm.node_expr(block.as_ref()) else { return Vec::new(); }; let mut res = Vec::default(); - unsafe_operations(self.db, infer, def, body, block, &mut |node, _| { - if let Ok(node) = source_map.expr_or_pat_syntax(node) { + unsafe_operations(self.db, infer, def, store, block, &mut |node, _| { + if let Ok(node) = sm.expr_or_pat_syntax(node) { res.push(node); } }); @@ -1999,7 +1996,7 @@ impl<'db> SemanticsImpl<'db> { pub fn resolve_offset_of_field( &self, name_ref: &ast::NameRef, - ) -> Option<(Either<Variant, Field>, GenericSubstitution<'db>)> { + ) -> Option<(Either<EnumVariant, Field>, GenericSubstitution<'db>)> { self.analyze_no_infer(name_ref.syntax())?.resolve_offset_of_field(self.db, name_ref) } @@ -2119,13 +2116,9 @@ impl<'db> SemanticsImpl<'db> { Some(res) } - pub fn body_for(&self, node: InFile<&SyntaxNode>) -> Option<DefWithBody> { + pub fn store_owner_for(&self, node: InFile<&SyntaxNode>) -> Option<ExpressionStoreOwner> { let container = self.with_ctx(|ctx| ctx.find_container(node))?; - - match container { - ChildContainer::DefWithBodyId(def) => Some(def.into()), - _ => None, - } + container.as_expression_store_owner().map(|id| id.into()) } /// Returns none if the file of the node is not part of a crate. @@ -2169,7 +2162,7 @@ impl<'db> SemanticsImpl<'db> { }); } ChildContainer::VariantId(def) => { - return Some(SourceAnalyzer::new_variant_body(self.db, def, node, offset)); + return Some(SourceAnalyzer::new_variant_body(self.db, def, node, offset, infer)); } ChildContainer::TraitId(it) => { return Some(if infer { @@ -2522,7 +2515,7 @@ to_def_impls![ (crate::Function, ast::Fn, fn_to_def), (crate::Field, ast::RecordField, record_field_to_def), (crate::Field, ast::TupleField, tuple_field_to_def), - (crate::Variant, ast::Variant, enum_variant_to_def), + (crate::EnumVariant, ast::Variant, enum_variant_to_def), (crate::TypeParam, ast::TypeParam, type_param_to_def), (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), (crate::ConstParam, ast::ConstParam, const_param_to_def), diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 8c398728b0..a9a779a287 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -738,7 +738,7 @@ impl ChildContainer { } } - fn as_expression_store_owner(self) -> Option<ExpressionStoreOwnerId> { + pub(crate) fn as_expression_store_owner(self) -> Option<ExpressionStoreOwnerId> { match self { ChildContainer::DefWithBodyId(it) => Some(it.into()), ChildContainer::ModuleId(_) => None, diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 1b41c78892..1a34fa9134 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -20,7 +20,7 @@ use hir_def::{ hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat, PatId, generics::GenericParams}, lang_item::LangItems, nameres::MacroSubNs, - resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope}, + resolver::{Resolver, TypeNs, ValueNs, resolver_for_scope}, type_ref::{Mutability, TypeRef, TypeRefId}, }; use hir_expand::{ @@ -58,8 +58,8 @@ use syntax::{ use crate::{ Adt, AnyFunctionId, AssocItem, BindingMode, BuiltinAttr, BuiltinType, Callable, Const, - DeriveHelper, Field, Function, GenericSubstitution, Local, Macro, ModuleDef, Static, Struct, - ToolModule, Trait, TupleField, Type, TypeAlias, Variant, + DeriveHelper, EnumVariant, Field, Function, GenericSubstitution, Local, Macro, ModuleDef, + Static, Struct, ToolModule, Trait, TupleField, Type, TypeAlias, db::HirDatabase, semantics::{PathResolution, PathResolutionPerNs}, }; @@ -81,11 +81,11 @@ pub(crate) enum BodyOrSig<'db> { source_map: &'db BodySourceMap, infer: Option<&'db InferenceResult>, }, - // To be folded into body once it is considered one VariantFields { def: VariantId, store: &'db ExpressionStore, source_map: &'db ExpressionStoreSourceMap, + infer: Option<&'db InferenceResult>, }, Sig { def: GenericDefId, @@ -196,14 +196,34 @@ impl<'db> SourceAnalyzer<'db> { pub(crate) fn new_variant_body( db: &'db dyn HirDatabase, def: VariantId, - InFile { file_id, .. }: InFile<&SyntaxNode>, - _offset: Option<TextSize>, + node @ InFile { file_id, .. }: InFile<&SyntaxNode>, + offset: Option<TextSize>, + infer: bool, ) -> SourceAnalyzer<'db> { let (fields, source_map) = def.fields_with_source_map(db); - let resolver = def.resolver(db); + let scopes = ExprScopes::of(db, def); + let scope = match offset { + None => scope_for(db, scopes, source_map, node), + Some(offset) => { + debug_assert!( + node.text_range().contains_inclusive(offset), + "{:?} not in {:?}", + offset, + node.text_range() + ); + scope_for_offset(db, scopes, source_map, node.file_id, offset) + } + }; + let resolver = resolver_for_scope(db, def, scope); + let infer = if infer { Some(InferenceResult::of(db, def)) } else { None }; SourceAnalyzer { resolver, - body_or_sig: Some(BodyOrSig::VariantFields { def, store: &fields.store, source_map }), + body_or_sig: Some(BodyOrSig::VariantFields { + def, + store: &fields.store, + source_map, + infer, + }), file_id, } } @@ -215,31 +235,39 @@ impl<'db> SourceAnalyzer<'db> { SourceAnalyzer { resolver, body_or_sig: None, file_id: node.file_id } } - // FIXME: Remove this - fn body_(&self) -> Option<(DefWithBodyId, &Body, &BodySourceMap, Option<&InferenceResult>)> { - self.body_or_sig.as_ref().and_then(|it| match it { - BodyOrSig::Body { def, body, source_map, infer } => { - Some((*def, &**body, &**source_map, infer.as_deref())) - } - _ => None, + fn owner(&self) -> Option<ExpressionStoreOwnerId> { + self.body_or_sig.as_ref().map(|it| match *it { + BodyOrSig::VariantFields { def, .. } => def.into(), + BodyOrSig::Sig { def, .. } => def.into(), + BodyOrSig::Body { def, .. } => def.into(), }) } fn infer(&self) -> Option<&InferenceResult> { self.body_or_sig.as_ref().and_then(|it| match it { - BodyOrSig::VariantFields { .. } => None, - BodyOrSig::Sig { infer, .. } | BodyOrSig::Body { infer, .. } => infer.as_deref(), + BodyOrSig::VariantFields { infer, .. } + | BodyOrSig::Sig { infer, .. } + | BodyOrSig::Body { infer, .. } => infer.as_deref(), }) } pub(crate) fn def( &self, - ) -> Option<(ExpressionStoreOwnerId, &ExpressionStore, &ExpressionStoreSourceMap)> { - self.body_or_sig.as_ref().and_then(|it| match it { - BodyOrSig::VariantFields { .. } => None, - &BodyOrSig::Sig { def, store, source_map, .. } => Some((def.into(), store, source_map)), - BodyOrSig::Body { def, body, source_map, .. } => { - Some(((*def).into(), &body.store, source_map)) + ) -> Option<( + ExpressionStoreOwnerId, + &ExpressionStore, + &ExpressionStoreSourceMap, + Option<&InferenceResult>, + )> { + self.body_or_sig.as_ref().map(|it| match *it { + BodyOrSig::VariantFields { def, store, source_map, infer, .. } => { + (def.into(), store, source_map, infer) + } + BodyOrSig::Sig { def, store, source_map, infer, .. } => { + (def.into(), store, source_map, infer) + } + BodyOrSig::Body { def, body, source_map, infer, .. } => { + (def.into(), &body.store, &source_map.store, infer) } }) } @@ -268,7 +296,7 @@ impl<'db> SourceAnalyzer<'db> { self.param_and(self.body_or_sig.as_ref().map_or_else(ParamEnv::empty, |body_or_sig| { match *body_or_sig { BodyOrSig::Body { def, .. } => db.trait_environment(def.into()), - BodyOrSig::VariantFields { .. } => ParamEnv::empty(), + BodyOrSig::VariantFields { def, .. } => db.trait_environment(def.into()), BodyOrSig::Sig { def, .. } => db.trait_environment(def.into()), } })) @@ -510,7 +538,7 @@ impl<'db> SourceAnalyzer<'db> { &self, field: &ast::FieldExpr, ) -> Option<Either<Field, TupleField>> { - let (def, ..) = self.body_()?; + let def = self.owner()?; let expr_id = self.expr_id(field.clone().into())?.as_expr()?; self.infer()?.field_resolution(expr_id).map(|it| { it.map_either(Into::into, |f| TupleField { owner: def, tuple: f.tuple, index: f.index }) @@ -537,7 +565,7 @@ impl<'db> SourceAnalyzer<'db> { field: &ast::FieldExpr, ) -> Option<(Either<Either<Field, TupleField>, Function>, Option<GenericSubstitution<'db>>)> { - let (def, ..) = self.body_()?; + let def = self.owner()?; let expr_id = self.expr_id(field.clone().into())?.as_expr()?; let inference_result = self.infer()?; match inference_result.field_resolution(expr_id) { @@ -889,7 +917,7 @@ impl<'db> SourceAnalyzer<'db> { &self, db: &'db dyn HirDatabase, name_ref: &ast::NameRef, - ) -> Option<(Either<crate::Variant, crate::Field>, GenericSubstitution<'db>)> { + ) -> Option<(Either<crate::EnumVariant, crate::Field>, GenericSubstitution<'db>)> { let offset_of_expr = ast::OffsetOfExpr::cast(name_ref.syntax().parent()?)?; let container = offset_of_expr.ty()?; let container = self.type_of_type(db, &container)?; @@ -940,7 +968,7 @@ impl<'db> SourceAnalyzer<'db> { let variants = id.enum_variants(db); let variant = variants.variant(&field_name.as_name())?; container = Either::Left((variant, subst)); - (Either::Left(Variant { id: variant }), id.into(), subst) + (Either::Left(EnumVariant { id: variant }), id.into(), subst) } }, _ => return None, @@ -1020,7 +1048,10 @@ impl<'db> SourceAnalyzer<'db> { if let Some(VariantId::EnumVariantId(variant)) = infer.variant_resolution_for_expr_or_pat(expr_id) { - return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None)); + return Some(( + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), + None, + )); } prefer_value_ns = true; } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) { @@ -1052,14 +1083,20 @@ impl<'db> SourceAnalyzer<'db> { if let Some(VariantId::EnumVariantId(variant)) = infer.variant_resolution_for_expr_or_pat(expr_or_pat_id) { - return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None)); + return Some(( + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), + None, + )); } } else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) { let expr_id = self.expr_id(rec_lit.into())?; if let Some(VariantId::EnumVariantId(variant)) = infer.variant_resolution_for_expr_or_pat(expr_id) { - return Some((PathResolution::Def(ModuleDef::Variant(variant.into())), None)); + return Some(( + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), + None, + )); } } else { let record_pat = parent().and_then(ast::RecordPat::cast).map(ast::Pat::from); @@ -1070,7 +1107,7 @@ impl<'db> SourceAnalyzer<'db> { let variant_res_for_pat = infer.variant_resolution_for_pat(pat_id.as_pat()?); if let Some(VariantId::EnumVariantId(variant)) = variant_res_for_pat { return Some(( - PathResolution::Def(ModuleDef::Variant(variant.into())), + PathResolution::Def(ModuleDef::EnumVariant(variant.into())), None, )); } @@ -1404,7 +1441,7 @@ impl<'db> SourceAnalyzer<'db> { db: &'db dyn HirDatabase, macro_expr: InFile<&ast::MacroExpr>, ) -> bool { - if let Some((def, body, sm, Some(infer))) = self.body_() + if let Some((def, body, sm, Some(infer))) = self.def() && let Some(expanded_expr) = sm.macro_expansion_expr(macro_expr) { let mut is_unsafe = false; @@ -1455,7 +1492,7 @@ impl<'db> SourceAnalyzer<'db> { line: usize, offset: TextSize, ) -> Option<(ExpressionStoreOwnerId, (ExprId, TextRange, usize))> { - let (def, _, sm) = self.def()?; + let (def, _, sm, _) = self.def()?; let (expr, args) = sm.asm_template_args(asm)?; Some(def).zip( args.get(line)? @@ -1492,7 +1529,7 @@ impl<'db> SourceAnalyzer<'db> { &self, asm: InFile<&ast::AsmExpr>, ) -> Option<(ExpressionStoreOwnerId, (ExprId, &[Vec<(TextRange, usize)>]))> { - let (def, _, sm) = self.def()?; + let (def, _, sm, _) = self.def()?; Some(def).zip(sm.asm_template_args(asm)) } @@ -1722,7 +1759,7 @@ fn resolve_hir_path_( TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { PathResolution::Def(Adt::from(it).into()) } - TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), + TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), @@ -1806,7 +1843,7 @@ fn resolve_hir_value_path( ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), - ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), + ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), ValueNs::GenericParam(id) => PathResolution::ConstParam(id.into()), }; @@ -1871,7 +1908,7 @@ fn resolve_hir_path_qualifier( TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { PathResolution::Def(Adt::from(it).into()) } - TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()), + TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), diff --git a/crates/hir/src/term_search/expr.rs b/crates/hir/src/term_search/expr.rs index e56f9e91e3..e3d0121e49 100644 --- a/crates/hir/src/term_search/expr.rs +++ b/crates/hir/src/term_search/expr.rs @@ -10,8 +10,8 @@ use itertools::Itertools; use span::Edition; use crate::{ - Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Field, Function, Local, ModuleDef, - SemanticsScope, Static, Struct, StructKind, Trait, Type, Variant, + Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, EnumVariant, Field, Function, Local, + ModuleDef, SemanticsScope, Static, Struct, StructKind, Trait, Type, }; /// Helper function to get path to `ModuleDef` @@ -80,7 +80,7 @@ pub enum Expr<'db> { params: Vec<Expr<'db>>, }, /// Enum variant construction - Variant { variant: Variant, generics: Vec<Type<'db>>, params: Vec<Expr<'db>> }, + Variant { variant: EnumVariant, generics: Vec<Type<'db>>, params: Vec<Expr<'db>> }, /// Struct construction Struct { strukt: Struct, generics: Vec<Type<'db>>, params: Vec<Expr<'db>> }, /// Tuple construction @@ -222,7 +222,7 @@ impl<'db> Expr<'db> { StructKind::Unit => String::new(), }; - let prefix = mod_item_path_str(sema_scope, &ModuleDef::Variant(*variant))?; + let prefix = mod_item_path_str(sema_scope, &ModuleDef::EnumVariant(*variant))?; Ok(format!("{prefix}{inner}")) } Expr::Struct { strukt, params, .. } => { diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs index 3c3f71aea6..b063e5ffce 100644 --- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs +++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs @@ -86,6 +86,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>) def_with_body.as_assoc_item(ctx.db()) } hir::ExpressionStoreOwner::Signature(def) => def.as_assoc_item(ctx.db()), + hir::ExpressionStoreOwner::VariantFields(_) => None, }? .implementing_ty(ctx.db()) }) @@ -477,7 +478,7 @@ enum ExtendedEnum { enum ExtendedVariant { True, False, - Variant { variant: hir::Variant, use_self: bool }, + Variant { variant: hir::EnumVariant, use_self: bool }, } impl ExtendedVariant { diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs index da5c123957..de5dfdf4d9 100644 --- a/crates/ide-assists/src/handlers/auto_import.rs +++ b/crates/ide-assists/src/handlers/auto_import.rs @@ -268,7 +268,7 @@ pub(crate) fn relevance_score( hir::Adt::Union(it) => it.ty(ctx.db()), hir::Adt::Enum(it) => it.ty(ctx.db()), }), - hir::ModuleDef::Variant(variant) => Some(variant.constructor_ty(ctx.db())), + hir::ModuleDef::EnumVariant(variant) => Some(variant.constructor_ty(ctx.db())), hir::ModuleDef::Const(it) => Some(it.ty(ctx.db())), hir::ModuleDef::Static(it) => Some(it.ty(ctx.db())), hir::ModuleDef::TypeAlias(it) => Some(it.ty(ctx.db())), diff --git a/crates/ide-assists/src/handlers/convert_bool_then.rs b/crates/ide-assists/src/handlers/convert_bool_then.rs index 236436989e..b3bfe5b8c4 100644 --- a/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -237,7 +237,7 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> fn option_variants( sema: &Semantics<'_, RootDatabase>, expr: &SyntaxNode, -) -> Option<(hir::Variant, hir::Variant)> { +) -> Option<(hir::EnumVariant, hir::EnumVariant)> { let fam = FamousDefs(sema, sema.scope(expr)?.krate()); let option_variants = fam.core_option_Option()?.variants(sema.db); match &*option_variants { @@ -254,7 +254,7 @@ fn option_variants( /// If any of these conditions are met it is impossible to rewrite this as a `bool::then` call. fn is_invalid_body( sema: &Semantics<'_, RootDatabase>, - some_variant: hir::Variant, + some_variant: hir::EnumVariant, expr: &ast::Expr, ) -> bool { let mut invalid = false; @@ -277,7 +277,7 @@ fn is_invalid_body( && let Some(ast::Expr::PathExpr(p)) = call.expr() { let res = p.path().and_then(|p| sema.resolve_path(&p)); - if let Some(hir::PathResolution::Def(hir::ModuleDef::Variant(v))) = res { + if let Some(hir::PathResolution::Def(hir::ModuleDef::EnumVariant(v))) = res { return invalid |= v != some_variant; } } @@ -290,11 +290,11 @@ fn is_invalid_body( fn block_is_none_variant( sema: &Semantics<'_, RootDatabase>, block: &ast::BlockExpr, - none_variant: hir::Variant, + none_variant: hir::EnumVariant, ) -> bool { block_as_lone_tail(block).and_then(|e| match e { ast::Expr::PathExpr(pat) => match sema.resolve_path(&pat.path()?)? { - hir::PathResolution::Def(hir::ModuleDef::Variant(v)) => Some(v), + hir::PathResolution::Def(hir::ModuleDef::EnumVariant(v)) => Some(v), _ => None, }, _ => None, diff --git a/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs index 4dd2036c02..aaf727058c 100644 --- a/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs +++ b/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs @@ -158,11 +158,11 @@ fn edit_struct_def( fn edit_struct_references( ctx: &AssistContext<'_>, builder: &mut SourceChangeBuilder, - strukt: Either<hir::Struct, hir::Variant>, + strukt: Either<hir::Struct, hir::EnumVariant>, ) { let strukt_def = match strukt { Either::Left(s) => Definition::Adt(hir::Adt::Struct(s)), - Either::Right(v) => Definition::Variant(v), + Either::Right(v) => Definition::EnumVariant(v), }; let usages = strukt_def.usages(&ctx.sema).include_self_refs().all(); diff --git a/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs index 270467b14f..ae41e6c015 100644 --- a/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs +++ b/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs @@ -142,12 +142,12 @@ fn edit_struct_def( fn edit_struct_references( ctx: &AssistContext<'_>, edit: &mut SourceChangeBuilder, - strukt: Either<hir::Struct, hir::Variant>, + strukt: Either<hir::Struct, hir::EnumVariant>, names: &[ast::Name], ) { let strukt_def = match strukt { Either::Left(s) => Definition::Adt(hir::Adt::Struct(s)), - Either::Right(v) => Definition::Variant(v), + Either::Right(v) => Definition::EnumVariant(v), }; let usages = strukt_def.usages(&ctx.sema).include_self_refs().all(); diff --git a/crates/ide-assists/src/handlers/expand_glob_import.rs b/crates/ide-assists/src/handlers/expand_glob_import.rs index 7eca4d3f2a..6c5c21bfc9 100644 --- a/crates/ide-assists/src/handlers/expand_glob_import.rs +++ b/crates/ide-assists/src/handlers/expand_glob_import.rs @@ -317,7 +317,7 @@ fn find_refs_in_mod( .into_iter() .map(|v| Ref { visible_name: v.name(ctx.db()), - def: Definition::Variant(v), + def: Definition::EnumVariant(v), is_pub: true, }) .collect(), @@ -379,7 +379,7 @@ fn find_imported_defs(ctx: &AssistContext<'_>, use_item: Use) -> Vec<Definition> | Definition::Module(_) | Definition::Function(_) | Definition::Adt(_) - | Definition::Variant(_) + | Definition::EnumVariant(_) | Definition::Const(_) | Definition::Static(_) | Definition::Trait(_) diff --git a/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/crates/ide-assists/src/handlers/expand_rest_pattern.rs index 867ac48518..a7e78dfc9c 100644 --- a/crates/ide-assists/src/handlers/expand_rest_pattern.rs +++ b/crates/ide-assists/src/handlers/expand_rest_pattern.rs @@ -102,7 +102,7 @@ fn expand_tuple_struct_rest_pattern( let fields = match ctx.sema.type_of_pat(&pat.clone().into())?.original.as_adt()? { hir::Adt::Struct(s) if s.kind(ctx.sema.db) == StructKind::Tuple => s.fields(ctx.sema.db), hir::Adt::Enum(_) => match ctx.sema.resolve_path(&path)? { - PathResolution::Def(hir::ModuleDef::Variant(v)) + PathResolution::Def(hir::ModuleDef::EnumVariant(v)) if v.kind(ctx.sema.db) == StructKind::Tuple => { v.fields(ctx.sema.db) diff --git a/crates/ide-assists/src/handlers/extract_module.rs b/crates/ide-assists/src/handlers/extract_module.rs index a17ae4885e..dcbeaefa21 100644 --- a/crates/ide-assists/src/handlers/extract_module.rs +++ b/crates/ide-assists/src/handlers/extract_module.rs @@ -728,7 +728,7 @@ fn check_def_in_mod_and_out_sel( } Definition::Function(x) => check_item!(x), Definition::Adt(x) => check_item!(x), - Definition::Variant(x) => check_item!(x), + Definition::EnumVariant(x) => check_item!(x), Definition::Const(x) => check_item!(x), Definition::Static(x) => check_item!(x), Definition::Trait(x) => check_item!(x), diff --git a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs index cbf4e0ec28..4c46a51bef 100644 --- a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs @@ -1,7 +1,7 @@ use std::iter; use either::Either; -use hir::{HasCrate, Module, ModuleDef, Name, Variant}; +use hir::{EnumVariant, HasCrate, Module, ModuleDef, Name}; use ide_db::{ FxHashSet, RootDatabase, defs::Definition, @@ -61,7 +61,7 @@ pub(crate) fn extract_struct_from_enum_variant( let edition = enum_hir.krate(ctx.db()).edition(ctx.db()); let variant_hir_name = variant_hir.name(ctx.db()); let enum_module_def = ModuleDef::from(enum_hir); - let usages = Definition::Variant(variant_hir).usages(&ctx.sema).all(); + let usages = Definition::EnumVariant(variant_hir).usages(&ctx.sema).all(); let mut visited_modules_set = FxHashSet::default(); let current_module = enum_hir.module(ctx.db()); @@ -161,7 +161,7 @@ fn extract_field_list_if_applicable( } } -fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Variant) -> bool { +fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &EnumVariant) -> bool { variant .parent_enum(db) .module(db) @@ -173,7 +173,7 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Va def, ModuleDef::Module(_) | ModuleDef::Adt(_) - | ModuleDef::Variant(_) + | ModuleDef::EnumVariant(_) | ModuleDef::Trait(_) | ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_) diff --git a/crates/ide-assists/src/handlers/extract_variable.rs b/crates/ide-assists/src/handlers/extract_variable.rs index 7071106970..e5ce02cf53 100644 --- a/crates/ide-assists/src/handlers/extract_variable.rs +++ b/crates/ide-assists/src/handlers/extract_variable.rs @@ -465,7 +465,7 @@ fn like_const_value(ctx: &AssistContext<'_>, path_resolution: hir::PathResolutio match path_resolution { hir::PathResolution::Def(def) => match def { hir::ModuleDef::Adt(adt) => adt_like_const_value(Some(adt)), - hir::ModuleDef::Variant(variant) => variant.kind(db) == hir::StructKind::Unit, + hir::ModuleDef::EnumVariant(variant) => variant.kind(db) == hir::StructKind::Unit, hir::ModuleDef::TypeAlias(ty) => adt_like_const_value(ty.ty(db).as_adt()), hir::ModuleDef::Const(_) | hir::ModuleDef::Static(_) => true, hir::ModuleDef::Trait(_) diff --git a/crates/ide-assists/src/handlers/fix_visibility.rs b/crates/ide-assists/src/handlers/fix_visibility.rs index 5134b98f1b..440f2d5f17 100644 --- a/crates/ide-assists/src/handlers/fix_visibility.rs +++ b/crates/ide-assists/src/handlers/fix_visibility.rs @@ -173,7 +173,7 @@ fn target_data_for_def( // FIXME hir::ModuleDef::Macro(_) => return None, // Enum variants can't be private, we can't modify builtin types - hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None, + hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None, }; Some((offset, target, target_file, target_name)) diff --git a/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs index 009fc077ce..cdf20586ef 100644 --- a/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs @@ -102,7 +102,7 @@ fn target_path(ctx: &AssistContext<'_>, mut original_path: ast::Path) -> Option< } match ctx.sema.resolve_path(&original_path)? { - PathResolution::Def(ModuleDef::Variant(_)) if on_first => original_path.qualifier(), + PathResolution::Def(ModuleDef::EnumVariant(_)) if on_first => original_path.qualifier(), PathResolution::Def(def) if def.as_assoc_item(ctx.db()).is_some() => { on_first.then_some(original_path.qualifier()?) } diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 355687b203..1fb1fd4e57 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -26,7 +26,7 @@ pub(crate) mod vis; use std::iter; -use hir::{HasAttrs, Name, ScopeDef, Variant, sym}; +use hir::{EnumVariant, HasAttrs, Name, ScopeDef, sym}; use ide_db::{RootDatabase, SymbolKind, imports::import_assets::LocatedImport}; use syntax::{SmolStr, ToSmolStr, ast}; @@ -426,7 +426,7 @@ impl Completions { &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx<'_>, - variant: hir::Variant, + variant: hir::EnumVariant, path: hir::ModPath, ) { if !ctx.check_stability_and_hidden(variant) { @@ -443,7 +443,7 @@ impl Completions { &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx<'_>, - variant: hir::Variant, + variant: hir::EnumVariant, local_name: Option<hir::Name>, ) { if !ctx.check_stability_and_hidden(variant) { @@ -569,7 +569,7 @@ impl Completions { ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx<'_>>, - variant: hir::Variant, + variant: hir::EnumVariant, local_name: Option<hir::Name>, ) { if !ctx.check_stability_and_hidden(variant) { @@ -589,7 +589,7 @@ impl Completions { &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, - variant: hir::Variant, + variant: hir::EnumVariant, path: hir::ModPath, ) { if !ctx.check_stability_and_hidden(variant) { @@ -644,9 +644,9 @@ fn enum_variants_with_paths( ctx: &CompletionContext<'_>, enum_: hir::Enum, impl_: Option<&ast::Impl>, - cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath), + cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::EnumVariant, hir::ModPath), ) { - let mut process_variant = |variant: Variant| { + let mut process_variant = |variant: EnumVariant| { let self_path = hir::ModPath::from_segments( hir::PathKind::Plain, iter::once(Name::new_symbol_root(sym::Self_)).chain(iter::once(variant.name(ctx.db))), diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs index 6e9328165d..e7597bf95c 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs @@ -91,7 +91,7 @@ pub(crate) fn complete_pattern( acc.add_struct_pat(ctx, pattern_ctx, strukt, Some(name.clone())); true } - hir::ModuleDef::Variant(variant) + hir::ModuleDef::EnumVariant(variant) if refutable || single_variant_enum(variant.parent_enum(ctx.db)) => { acc.add_variant_pat(ctx, pattern_ctx, None, variant, Some(name.clone())); @@ -190,7 +190,7 @@ pub(crate) fn complete_pattern_path( let add_completion = match res { ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db), ScopeDef::ModuleDef(hir::ModuleDef::Adt(_)) => true, - ScopeDef::ModuleDef(hir::ModuleDef::Variant(_)) => true, + ScopeDef::ModuleDef(hir::ModuleDef::EnumVariant(_)) => true, ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => true, ScopeDef::ImplSelfType(_) => true, _ => false, diff --git a/crates/ide-completion/src/completions/type.rs b/crates/ide-completion/src/completions/type.rs index abcf9fca6f..8ff9c3258e 100644 --- a/crates/ide-completion/src/completions/type.rs +++ b/crates/ide-completion/src/completions/type.rs @@ -23,7 +23,9 @@ pub(crate) fn complete_type_path( ScopeDef::GenericParam(LifetimeParam(_)) => location.complete_lifetimes(), ScopeDef::Label(_) => false, // no values in type places - ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_)) | ScopeDef::Local(_) => false, + ScopeDef::ModuleDef(Function(_) | EnumVariant(_) | Static(_)) | ScopeDef::Local(_) => { + false + } // unless its a constant in a generic arg list position ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => { location.complete_consts() diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index 97afd07b00..4fd0348156 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -288,7 +288,7 @@ pub(crate) struct PatternContext { pub(crate) record_pat: Option<ast::RecordPat>, pub(crate) impl_or_trait: Option<Either<ast::Impl, ast::Trait>>, /// List of missing variants in a match expr - pub(crate) missing_variants: Vec<hir::Variant>, + pub(crate) missing_variants: Vec<hir::EnumVariant>, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -527,7 +527,7 @@ impl CompletionContext<'_> { hir::ModuleDef::Module(it) => self.is_visible(it), hir::ModuleDef::Function(it) => self.is_visible(it), hir::ModuleDef::Adt(it) => self.is_visible(it), - hir::ModuleDef::Variant(it) => self.is_visible(it), + hir::ModuleDef::EnumVariant(it) => self.is_visible(it), hir::ModuleDef::Const(it) => self.is_visible(it), hir::ModuleDef::Static(it) => self.is_visible(it), hir::ModuleDef::Trait(it) => self.is_visible(it), diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index bf899539a2..a3494b964f 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -1,7 +1,7 @@ //! Module responsible for analyzing the code surrounding the cursor for completion. use std::iter; -use hir::{ExpandResult, InFile, Semantics, Type, TypeInfo, Variant}; +use hir::{EnumVariant, ExpandResult, InFile, Semantics, Type, TypeInfo}; use ide_db::{ RootDatabase, active_parameter::ActiveParameter, syntax_helpers::node_ext::find_loops, }; @@ -781,7 +781,7 @@ fn expected_type_and_name<'db>( ast::TupleStructPat(it) => { let fields = it.path().and_then(|path| match sema.resolve_path(&path)? { hir::PathResolution::Def(hir::ModuleDef::Adt(adt)) => Some(adt.as_struct()?.fields(sema.db)), - hir::PathResolution::Def(hir::ModuleDef::Variant(variant)) => Some(variant.fields(sema.db)), + hir::PathResolution::Def(hir::ModuleDef::EnumVariant(variant)) => Some(variant.fields(sema.db)), _ => None, }); let nr = it.fields().take_while(|it| it.syntax().text_range().end() <= token.text_range().start()).count(); @@ -1149,7 +1149,7 @@ fn classify_name_ref<'db>( hir::ModuleDef::Adt(adt) => { sema.source(adt)?.value.generic_param_list() } - hir::ModuleDef::Variant(variant) => { + hir::ModuleDef::EnumVariant(variant) => { sema.source(variant.parent_enum(sema.db))?.value.generic_param_list() } hir::ModuleDef::Trait(trait_) => { @@ -1825,7 +1825,7 @@ fn pattern_context_for( }); (!variant_already_present).then_some(*variant) - }).collect::<Vec<Variant>>()) + }).collect::<Vec<EnumVariant>>()) }); if let Some(missing_variants_) = missing_variants_opt { diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 765304d818..d77e793295 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -408,7 +408,7 @@ fn render_resolution_path( let ctx = ctx.import_to_add(import_to_add); return render_fn(ctx, path_ctx, Some(local_name), func); } - ScopeDef::ModuleDef(Variant(var)) => { + ScopeDef::ModuleDef(EnumVariant(var)) => { let ctx = ctx.clone().import_to_add(import_to_add.clone()); if let Some(item) = render_variant_lit(ctx, path_ctx, Some(local_name.clone()), var, None) @@ -476,7 +476,7 @@ fn render_resolution_path( } // Filtered out above ScopeDef::ModuleDef( - ModuleDef::Function(_) | ModuleDef::Variant(_) | ModuleDef::Macro(_), + ModuleDef::Function(_) | ModuleDef::EnumVariant(_) | ModuleDef::Macro(_), ) => (), ScopeDef::ModuleDef(ModuleDef::Const(konst)) => set_item_relevance(konst.ty(db)), ScopeDef::ModuleDef(ModuleDef::Static(stat)) => set_item_relevance(stat.ty(db)), @@ -528,7 +528,7 @@ fn res_to_kind(resolution: ScopeDef) -> CompletionItemKind { match resolution { ScopeDef::Unknown => CompletionItemKind::UnresolvedReference, ScopeDef::ModuleDef(Function(_)) => CompletionItemKind::SymbolKind(SymbolKind::Function), - ScopeDef::ModuleDef(Variant(_)) => CompletionItemKind::SymbolKind(SymbolKind::Variant), + ScopeDef::ModuleDef(EnumVariant(_)) => CompletionItemKind::SymbolKind(SymbolKind::Variant), ScopeDef::ModuleDef(Macro(_)) => CompletionItemKind::SymbolKind(SymbolKind::Macro), ScopeDef::ModuleDef(Module(..)) => CompletionItemKind::SymbolKind(SymbolKind::Module), ScopeDef::ModuleDef(Adt(adt)) => CompletionItemKind::SymbolKind(match adt { @@ -559,7 +559,7 @@ fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<Documentati match resolution { ScopeDef::ModuleDef(Module(it)) => it.docs(db), ScopeDef::ModuleDef(Adt(it)) => it.docs(db), - ScopeDef::ModuleDef(Variant(it)) => it.docs(db), + ScopeDef::ModuleDef(EnumVariant(it)) => it.docs(db), ScopeDef::ModuleDef(Const(it)) => it.docs(db), ScopeDef::ModuleDef(Static(it)) => it.docs(db), ScopeDef::ModuleDef(Trait(it)) => it.docs(db), diff --git a/crates/ide-completion/src/render/literal.rs b/crates/ide-completion/src/render/literal.rs index 8b14f05b72..6e49af980a 100644 --- a/crates/ide-completion/src/render/literal.rs +++ b/crates/ide-completion/src/render/literal.rs @@ -23,7 +23,7 @@ pub(crate) fn render_variant_lit( ctx: RenderContext<'_>, path_ctx: &PathCompletionCtx<'_>, local_name: Option<hir::Name>, - variant: hir::Variant, + variant: hir::EnumVariant, path: Option<hir::ModPath>, ) -> Option<Builder> { let _p = tracing::info_span!("render_variant_lit").entered(); @@ -150,7 +150,7 @@ fn render( #[derive(Clone, Copy)] enum Variant { Struct(hir::Struct), - EnumVariant(hir::Variant), + EnumVariant(hir::EnumVariant), } impl Variant { diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 60474a31b4..fb35d7b9b6 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -47,7 +47,7 @@ pub(crate) fn render_variant_pat( ctx: RenderContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx<'_>>, - variant: hir::Variant, + variant: hir::EnumVariant, local_name: Option<Name>, path: Option<&hir::ModPath>, ) -> Option<CompletionItem> { diff --git a/crates/ide-db/src/active_parameter.rs b/crates/ide-db/src/active_parameter.rs index f5a5b76c33..8bd4c6c46b 100644 --- a/crates/ide-db/src/active_parameter.rs +++ b/crates/ide-db/src/active_parameter.rs @@ -113,7 +113,7 @@ pub fn generic_def_for_node( sema: &Semantics<'_, RootDatabase>, generic_arg_list: &ast::GenericArgList, token: &SyntaxToken, -) -> Option<(hir::GenericDef, usize, bool, Option<hir::Variant>)> { +) -> Option<(hir::GenericDef, usize, bool, Option<hir::EnumVariant>)> { let parent = generic_arg_list.syntax().parent()?; let mut variant = None; let def = match_ast! { @@ -125,7 +125,7 @@ pub fn generic_def_for_node( hir::PathResolution::Def(hir::ModuleDef::Function(it)) => it.into(), hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(), hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(), - hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => { + hir::PathResolution::Def(hir::ModuleDef::EnumVariant(it)) => { variant = Some(it); it.parent_enum(sema.db).into() }, diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index 6ee4c97c87..82cff37296 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -14,11 +14,11 @@ use arrayvec::ArrayVec; use either::Either; use hir::{ Adt, AsAssocItem, AsExternAssocItem, AssocItem, AttributeTemplate, BuiltinAttr, BuiltinType, - Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, ExpressionStoreOwner, - ExternAssocItem, ExternCrateDecl, Field, Function, GenericDef, GenericParam, - GenericSubstitution, HasContainer, HasVisibility, HirDisplay, Impl, InlineAsmOperand, - ItemContainer, Label, Local, Macro, Module, ModuleDef, Name, PathResolution, Semantics, Static, - StaticLifetime, Struct, ToolModule, Trait, TupleField, TypeAlias, Variant, VariantDef, + Const, Crate, DefWithBody, DeriveHelper, DisplayTarget, DocLinkDef, EnumVariant, + ExpressionStoreOwner, ExternAssocItem, ExternCrateDecl, Field, Function, GenericDef, + GenericParam, GenericSubstitution, HasContainer, HasVisibility, HirDisplay, Impl, + InlineAsmOperand, ItemContainer, Label, Local, Macro, Module, ModuleDef, Name, PathResolution, + Semantics, Static, StaticLifetime, Struct, ToolModule, Trait, TupleField, TypeAlias, Variant, Visibility, }; use span::Edition; @@ -39,7 +39,7 @@ pub enum Definition { Crate(Crate), Function(Function), Adt(Adt), - Variant(Variant), + EnumVariant(EnumVariant), Const(Const), Static(Static), Trait(Trait), @@ -86,7 +86,7 @@ impl Definition { Definition::Static(it) => it.module(db), Definition::Trait(it) => it.module(db), Definition::TypeAlias(it) => it.module(db), - Definition::Variant(it) => it.module(db), + Definition::EnumVariant(it) => it.module(db), Definition::SelfType(it) => it.module(db), Definition::Local(it) => it.module(db), Definition::GenericParam(it) => it.module(db), @@ -124,7 +124,7 @@ impl Definition { Definition::Static(it) => container_to_definition(it.container(db)), Definition::Trait(it) => container_to_definition(it.container(db)), Definition::TypeAlias(it) => container_to_definition(it.container(db)), - Definition::Variant(it) => Some(Adt::Enum(it.parent_enum(db)).into()), + Definition::EnumVariant(it) => Some(Adt::Enum(it.parent_enum(db)).into()), Definition::SelfType(it) => Some(it.module(db).into()), Definition::Local(it) => it.parent(db).try_into().ok(), Definition::GenericParam(it) => Some(it.parent().into()), @@ -152,7 +152,7 @@ impl Definition { Definition::Static(it) => it.visibility(db), Definition::Trait(it) => it.visibility(db), Definition::TypeAlias(it) => it.visibility(db), - Definition::Variant(it) => it.visibility(db), + Definition::EnumVariant(it) => it.visibility(db), Definition::ExternCrateDecl(it) => it.visibility(db), Definition::Macro(it) => it.visibility(db), Definition::BuiltinType(_) | Definition::TupleField(_) => Visibility::Public, @@ -180,7 +180,7 @@ impl Definition { } Definition::Function(it) => it.name(db), Definition::Adt(it) => it.name(db), - Definition::Variant(it) => it.name(db), + Definition::EnumVariant(it) => it.name(db), Definition::Const(it) => it.name(db)?, Definition::Static(it) => it.name(db), Definition::Trait(it) => it.name(db), @@ -228,7 +228,7 @@ impl Definition { Definition::Crate(it) => it.docs_with_rangemap(db), Definition::Function(it) => it.docs_with_rangemap(db), Definition::Adt(it) => it.docs_with_rangemap(db), - Definition::Variant(it) => it.docs_with_rangemap(db), + Definition::EnumVariant(it) => it.docs_with_rangemap(db), Definition::Const(it) => it.docs_with_rangemap(db), Definition::Static(it) => it.docs_with_rangemap(db), Definition::Trait(it) => it.docs_with_rangemap(db), @@ -316,7 +316,7 @@ impl Definition { Definition::Crate(it) => it.display(db, display_target).to_string(), Definition::Function(it) => it.display(db, display_target).to_string(), Definition::Adt(it) => it.display(db, display_target).to_string(), - Definition::Variant(it) => it.display(db, display_target).to_string(), + Definition::EnumVariant(it) => it.display(db, display_target).to_string(), Definition::Const(it) => it.display(db, display_target).to_string(), Definition::Static(it) => it.display(db, display_target).to_string(), Definition::Trait(it) => it.display(db, display_target).to_string(), @@ -557,7 +557,7 @@ impl<'db> NameClass<'db> { ast::Rename(it) => classify_rename(sema, it)?, ast::SelfParam(it) => Definition::Local(sema.to_def(&it)?), ast::RecordField(it) => Definition::Field(sema.to_def(&it)?), - ast::Variant(it) => Definition::Variant(sema.to_def(&it)?), + ast::Variant(it) => Definition::EnumVariant(sema.to_def(&it)?), ast::TypeParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()), ast::ConstParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()), ast::AsmOperandNamed(it) => Definition::InlineAsmOperand(sema.to_def(&it)?), @@ -849,7 +849,7 @@ impl<'db> NameRefClass<'db> { ast::OffsetOfExpr(_) => { let (def, subst) = sema.resolve_offset_of_field(name_ref)?; let def = match def { - Either::Left(variant) => Definition::Variant(variant), + Either::Left(variant) => Definition::EnumVariant(variant), Either::Right(field) => Definition::Field(field), }; Some(NameRefClass::Definition(def, Some(subst))) @@ -892,7 +892,7 @@ impl<'db> NameRefClass<'db> { } impl_from!( - Field, Module, Function, Adt, Variant, Const, Static, Trait, TypeAlias, BuiltinType, Local, + Field, Module, Function, Adt, EnumVariant, Const, Static, Trait, TypeAlias, BuiltinType, Local, GenericParam, Label, Macro, ExternCrateDecl for Definition ); @@ -968,7 +968,7 @@ impl From<ModuleDef> for Definition { ModuleDef::Module(it) => Definition::Module(it), ModuleDef::Function(it) => Definition::Function(it), ModuleDef::Adt(it) => Definition::Adt(it), - ModuleDef::Variant(it) => Definition::Variant(it), + ModuleDef::EnumVariant(it) => Definition::EnumVariant(it), ModuleDef::Const(it) => Definition::Const(it), ModuleDef::Static(it) => Definition::Static(it), ModuleDef::Trait(it) => Definition::Trait(it), @@ -989,8 +989,8 @@ impl From<DocLinkDef> for Definition { } } -impl From<VariantDef> for Definition { - fn from(def: VariantDef) -> Self { +impl From<Variant> for Definition { + fn from(def: Variant) -> Self { ModuleDef::from(def).into() } } @@ -1002,7 +1002,7 @@ impl TryFrom<DefWithBody> for Definition { DefWithBody::Function(it) => Ok(it.into()), DefWithBody::Static(it) => Ok(it.into()), DefWithBody::Const(it) => Ok(it.into()), - DefWithBody::Variant(it) => Ok(it.into()), + DefWithBody::EnumVariant(it) => Ok(it.into()), } } } @@ -1027,6 +1027,7 @@ impl TryFrom<ExpressionStoreOwner> for Definition { match def { ExpressionStoreOwner::Body(def_with_body) => def_with_body.try_into(), ExpressionStoreOwner::Signature(generic_def) => Ok(generic_def.into()), + ExpressionStoreOwner::VariantFields(it) => Ok(it.into()), } } } diff --git a/crates/ide-db/src/documentation.rs b/crates/ide-db/src/documentation.rs index 4c4691cca2..407049f4b3 100644 --- a/crates/ide-db/src/documentation.rs +++ b/crates/ide-db/src/documentation.rs @@ -58,8 +58,22 @@ macro_rules! impl_has_docs { } impl_has_docs![ - Variant, Field, Static, Const, Trait, TypeAlias, Macro, Function, Adt, Module, Impl, Crate, - AssocItem, Struct, Union, Enum, + EnumVariant, + Field, + Static, + Const, + Trait, + TypeAlias, + Macro, + Function, + Adt, + Module, + Impl, + Crate, + AssocItem, + Struct, + Union, + Enum, ]; impl HasDocs for hir::ExternCrateDecl { diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs index 023b32b361..cde0705d8a 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -312,7 +312,7 @@ impl SymbolKind { pub fn from_module_def(db: &dyn HirDatabase, it: hir::ModuleDef) -> Self { match it { hir::ModuleDef::Const(..) => SymbolKind::Const, - hir::ModuleDef::Variant(..) => SymbolKind::Variant, + hir::ModuleDef::EnumVariant(..) => SymbolKind::Variant, hir::ModuleDef::Function(..) => SymbolKind::Function, hir::ModuleDef::Macro(mac) if mac.is_proc_macro() => SymbolKind::ProcMacro, hir::ModuleDef::Macro(..) => SymbolKind::Macro, diff --git a/crates/ide-db/src/path_transform.rs b/crates/ide-db/src/path_transform.rs index 01a326a0dc..508f841340 100644 --- a/crates/ide-db/src/path_transform.rs +++ b/crates/ide-db/src/path_transform.rs @@ -580,7 +580,7 @@ impl Ctx<'_> { } } - if let hir::ModuleDef::Variant(v) = def + if let hir::ModuleDef::EnumVariant(v) = def && v.kind(self.source_scope.db) != hir::StructKind::Unit { return None; diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs index b03a5b6efb..b18ed69d80 100644 --- a/crates/ide-db/src/rename.rs +++ b/crates/ide-db/src/rename.rs @@ -170,7 +170,7 @@ impl Definition { hir::Adt::Union(it) => name_range(it, sema).and_then(syn_ctx_is_root), hir::Adt::Enum(it) => name_range(it, sema).and_then(syn_ctx_is_root), }, - Definition::Variant(it) => name_range(it, sema).and_then(syn_ctx_is_root), + Definition::EnumVariant(it) => name_range(it, sema).and_then(syn_ctx_is_root), Definition::Const(it) => name_range(it, sema).and_then(syn_ctx_is_root), Definition::Static(it) => name_range(it, sema).and_then(syn_ctx_is_root), Definition::Trait(it) => name_range(it, sema).and_then(syn_ctx_is_root), diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index 2cf4627ac8..25acb47f7b 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -314,7 +314,7 @@ impl Definition { DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + DefWithBody::EnumVariant(v) => v.source(db).map(|src| src.syntax().cloned()), }, ExpressionStoreOwner::Signature(def) => match def { hir::GenericDef::Function(it) => it.source(db).map(|src| src.syntax().cloned()), @@ -327,6 +327,9 @@ impl Definition { hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()), hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()), }, + ExpressionStoreOwner::VariantFields(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } }; return match def { Some(def) => SearchScope::file_range( @@ -342,7 +345,7 @@ impl Definition { DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()), DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()), DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()), - DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()), + DefWithBody::EnumVariant(v) => v.source(db).map(|src| src.syntax().cloned()), }, ExpressionStoreOwner::Signature(def) => match def { hir::GenericDef::Function(it) => it.source(db).map(|src| src.syntax().cloned()), @@ -355,6 +358,9 @@ impl Definition { hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()), hir::GenericDef::Static(it) => it.source(db).map(|src| src.syntax().cloned()), }, + ExpressionStoreOwner::VariantFields(it) => { + it.source(db).map(|src| src.syntax().cloned()) + } }; return match def { Some(def) => SearchScope::file_range( diff --git a/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/crates/ide-db/src/test_data/test_symbol_index_collection.txt index 46d938b5a5..02a023038a 100644 --- a/crates/ide-db/src/test_data/test_symbol_index_collection.txt +++ b/crates/ide-db/src/test_data/test_symbol_index_collection.txt @@ -8,8 +8,8 @@ [ FileSymbol { name: "A", - def: Variant( - Variant { + def: EnumVariant( + EnumVariant { id: EnumVariantId( 7c00, ), @@ -80,8 +80,8 @@ }, FileSymbol { name: "B", - def: Variant( - Variant { + def: EnumVariant( + EnumVariant { id: EnumVariantId( 7c01, ), diff --git a/crates/ide-diagnostics/src/handlers/no_such_field.rs b/crates/ide-diagnostics/src/handlers/no_such_field.rs index 619bb2307c..944622bb1d 100644 --- a/crates/ide-diagnostics/src/handlers/no_such_field.rs +++ b/crates/ide-diagnostics/src/handlers/no_such_field.rs @@ -64,20 +64,20 @@ fn missing_record_expr_field_fixes( let module; let def_file_id; let record_fields = match def_id { - hir::VariantDef::Struct(s) => { + hir::Variant::Struct(s) => { module = s.module(sema.db); let source = s.source(sema.db)?; def_file_id = source.file_id; let fields = source.value.field_list()?; record_field_list(fields)? } - hir::VariantDef::Union(u) => { + hir::Variant::Union(u) => { module = u.module(sema.db); let source = u.source(sema.db)?; def_file_id = source.file_id; source.value.record_field_list()? } - hir::VariantDef::Variant(e) => { + hir::Variant::EnumVariant(e) => { module = e.module(sema.db); let source = e.source(sema.db)?; def_file_id = source.file_id; @@ -116,7 +116,7 @@ fn missing_record_expr_field_fixes( let mut new_field = new_field.to_string(); // FIXME: check submodule instead of FileId - if usage_file_id != def_file_id && !matches!(def_id, hir::VariantDef::Variant(_)) { + if usage_file_id != def_file_id && !matches!(def_id, hir::Variant::EnumVariant(_)) { new_field = format!("pub(crate) {new_field}"); } new_field = format!("\n{indent}{new_field}{postfix}"); diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index d854c1c450..33bed9501a 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -219,7 +219,7 @@ pub(crate) fn resolve_doc_path_for_def( Definition::Crate(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Function(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Adt(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), - Definition::Variant(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), + Definition::EnumVariant(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Const(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Static(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), Definition::Trait(it) => it.resolve_doc_path(db, link, ns, is_inner_doc), @@ -678,7 +678,7 @@ fn filename_and_frag_for_def( Definition::Function(f) => { format!("fn.{}.html", f.name(db).as_str()) } - Definition::Variant(ev) => { + Definition::EnumVariant(ev) => { let def = Definition::Adt(ev.parent_enum(db).into()); let (_, file, _) = filename_and_frag_for_def(db, def)?; return Some((def, file, Some(format!("variant.{}", ev.name(db).as_str())))); @@ -703,9 +703,9 @@ fn filename_and_frag_for_def( }, Definition::Field(field) => { let def = match field.parent_def(db) { - hir::VariantDef::Struct(it) => Definition::Adt(it.into()), - hir::VariantDef::Union(it) => Definition::Adt(it.into()), - hir::VariantDef::Variant(it) => Definition::Variant(it), + hir::Variant::Struct(it) => Definition::Adt(it.into()), + hir::Variant::Union(it) => Definition::Adt(it.into()), + hir::Variant::EnumVariant(it) => Definition::EnumVariant(it), }; let (_, file, _) = filename_and_frag_for_def(db, def)?; return Some((def, file, Some(format!("structfield.{}", field.name(db).as_str())))); diff --git a/crates/ide/src/doc_links/tests.rs b/crates/ide/src/doc_links/tests.rs index a61a6c677f..509c55a31e 100644 --- a/crates/ide/src/doc_links/tests.rs +++ b/crates/ide/src/doc_links/tests.rs @@ -113,7 +113,7 @@ fn node_to_def<'db>( ast::Struct(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Struct(def)))), ast::Union(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Union(def)))), ast::Enum(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Adt(hir::Adt::Enum(def)))), - ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Variant(def))), + ast::Variant(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::EnumVariant(def))), ast::Trait(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Trait(def))), ast::Static(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Static(def))), ast::Const(it) => sema.to_def(&it).map(|def| (def.docs_with_rangemap(sema.db), Definition::Const(def))), diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index cf5f137cdd..af78e9a40c 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -5,7 +5,7 @@ use either::Either; use hir::{ Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DisplayTarget, DropGlue, DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError, - MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef, + MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, Variant, db::ExpandDatabase, }; use ide_db::{ @@ -366,14 +366,14 @@ fn definition_owner_name(db: &RootDatabase, def: Definition, edition: Edition) - let parent_name = parent.name(db); let parent_name = parent_name.display(db, edition).to_string(); return match parent { - VariantDef::Variant(variant) => { + Variant::EnumVariant(variant) => { let enum_name = variant.parent_enum(db).name(db); Some(format!("{}::{parent_name}", enum_name.display(db, edition))) } _ => Some(parent_name), }; } - Definition::Variant(e) => Some(e.parent_enum(db).name(db)), + Definition::EnumVariant(e) => Some(e.parent_enum(db).name(db)), Definition::GenericParam(generic_param) => match generic_param.parent() { hir::GenericDef::Adt(it) => Some(it.name(db)), hir::GenericDef::Trait(it) => Some(it.name(db)), @@ -470,7 +470,7 @@ pub(super) fn definition( Definition::Adt(adt @ (Adt::Struct(_) | Adt::Union(_))) => { adt.display_limited(db, config.max_fields_count, display_target).to_string() } - Definition::Variant(variant) => { + Definition::EnumVariant(variant) => { variant.display_limited(db, config.max_fields_count, display_target).to_string() } Definition::Adt(adt @ Adt::Enum(_)) => { @@ -499,7 +499,7 @@ pub(super) fn definition( }; let docs = def.docs_with_rangemap(db, famous_defs, display_target); let value = || match def { - Definition::Variant(it) => { + Definition::EnumVariant(it) => { if !it.parent_enum(db).is_data_carrying(db) { match it.eval(db) { Ok(it) => { @@ -596,7 +596,7 @@ pub(super) fn definition( |_| { let var_def = it.parent_def(db); match var_def { - hir::VariantDef::Struct(s) => { + hir::Variant::Struct(s) => { Adt::from(s).layout(db).ok().and_then(|layout| layout.field_offset(it)) } _ => None, @@ -627,7 +627,7 @@ pub(super) fn definition( |_| None, |_| None, ), - Definition::Variant(it) => render_memory_layout( + Definition::EnumVariant(it) => render_memory_layout( config.memory_layout, || it.layout(db), |_| None, @@ -710,7 +710,7 @@ pub(super) fn definition( has_dtor: Some(enum_drop_glue > fields_drop_glue), } } - Definition::Variant(variant) => { + Definition::EnumVariant(variant) => { let fields_drop_glue = variant .fields(db) .iter() diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs index f1e62a5ab8..08588bbed0 100644 --- a/crates/ide/src/inlay_hints/param_name.rs +++ b/crates/ide/src/inlay_hints/param_name.rs @@ -374,7 +374,7 @@ fn is_adt_constructor_similar_to_param_name( hir::PathResolution::Def(hir::ModuleDef::Adt(_)) => { Some(to_lower_snake_case(&path.segment()?.name_ref()?.text()) == param_name) } - hir::PathResolution::Def(hir::ModuleDef::Function(_) | hir::ModuleDef::Variant(_)) => { + hir::PathResolution::Def(hir::ModuleDef::Function(_) | hir::ModuleDef::EnumVariant(_)) => { if to_lower_snake_case(&path.segment()?.name_ref()?.text()) == param_name { return Some(true); } diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs index 1c1389ca7a..335e1b5b13 100644 --- a/crates/ide/src/moniker.rs +++ b/crates/ide/src/moniker.rs @@ -205,7 +205,7 @@ pub(crate) fn def_to_kind(db: &RootDatabase, def: Definition) -> SymbolInformati Definition::Adt(Adt::Struct(..)) => Struct, Definition::Adt(Adt::Union(..)) => Union, Definition::Adt(Adt::Enum(..)) => Enum, - Definition::Variant(..) => EnumMember, + Definition::EnumVariant(..) => EnumMember, Definition::Const(..) => Constant, Definition::Static(..) => StaticVariable, Definition::Trait(..) => Trait, diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index 185df92e2d..92020321f4 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -276,7 +276,7 @@ impl<'db> TryToNav for FileSymbol<'db> { Some(it.display(db, display_target).to_string()) } hir::ModuleDef::Adt(it) => Some(it.display(db, display_target).to_string()), - hir::ModuleDef::Variant(it) => { + hir::ModuleDef::EnumVariant(it) => { Some(it.display(db, display_target).to_string()) } hir::ModuleDef::Const(it) => { @@ -319,7 +319,7 @@ impl TryToNav for Definition { Definition::GenericParam(it) => it.try_to_nav(sema), Definition::Function(it) => it.try_to_nav(sema), Definition::Adt(it) => it.try_to_nav(sema), - Definition::Variant(it) => it.try_to_nav(sema), + Definition::EnumVariant(it) => it.try_to_nav(sema), Definition::Const(it) => it.try_to_nav(sema), Definition::Static(it) => it.try_to_nav(sema), Definition::Trait(it) => it.try_to_nav(sema), @@ -347,7 +347,7 @@ impl TryToNav for hir::ModuleDef { hir::ModuleDef::Module(it) => Some(it.to_nav(sema.db)), hir::ModuleDef::Function(it) => it.try_to_nav(sema), hir::ModuleDef::Adt(it) => it.try_to_nav(sema), - hir::ModuleDef::Variant(it) => it.try_to_nav(sema), + hir::ModuleDef::EnumVariant(it) => it.try_to_nav(sema), hir::ModuleDef::Const(it) => it.try_to_nav(sema), hir::ModuleDef::Static(it) => it.try_to_nav(sema), hir::ModuleDef::Trait(it) => it.try_to_nav(sema), @@ -406,7 +406,7 @@ impl ToNavFromAst for hir::Enum { container_name(db, self) } } -impl ToNavFromAst for hir::Variant { +impl ToNavFromAst for hir::EnumVariant { const KIND: SymbolKind = SymbolKind::Variant; } impl ToNavFromAst for hir::Union { diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 6464c47716..9392651c17 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -299,7 +299,7 @@ fn retain_adt_literal_usages( }); usages.references.retain(|_, it| !it.is_empty()); } - Definition::Adt(_) | Definition::Variant(_) => { + Definition::Adt(_) | Definition::EnumVariant(_) => { refs.for_each(|it| { it.retain(|reference| reference.name.as_name_ref().is_some_and(is_lit_name_ref)) }); @@ -377,7 +377,7 @@ fn is_enum_lit_name_ref( let path_is_variant_of_enum = |path: ast::Path| { matches!( sema.resolve_path(&path), - Some(PathResolution::Def(hir::ModuleDef::Variant(variant))) + Some(PathResolution::Def(hir::ModuleDef::EnumVariant(variant))) if variant.parent_enum(sema.db) == enum_ ) }; diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 42efa7142b..a0a6a24559 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -494,7 +494,7 @@ fn module_def_doctest(sema: &Semantics<'_, RootDatabase>, def: Definition) -> Op Definition::Module(it) => it.attrs(db), Definition::Function(it) => it.attrs(db), Definition::Adt(it) => it.attrs(db), - Definition::Variant(it) => it.attrs(db), + Definition::EnumVariant(it) => it.attrs(db), Definition::Const(it) => it.attrs(db), Definition::Static(it) => it.attrs(db), Definition::Trait(it) => it.attrs(db), diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs index f86974b4ec..9eb01b12f2 100644 --- a/crates/ide/src/signature_help.rs +++ b/crates/ide/src/signature_help.rs @@ -497,7 +497,7 @@ fn signature_help_for_tuple_struct_pat( }; let db = sema.db; - let fields: Vec<_> = if let PathResolution::Def(ModuleDef::Variant(variant)) = path_res { + let fields: Vec<_> = if let PathResolution::Def(ModuleDef::EnumVariant(variant)) = path_res { let en = variant.parent_enum(db); res.doc = en.docs(db).map(Documentation::into_owned); @@ -623,7 +623,7 @@ fn signature_help_for_record_<'db>( let db = sema.db; let path_res = sema.resolve_path(path)?; - if let PathResolution::Def(ModuleDef::Variant(variant)) = path_res { + if let PathResolution::Def(ModuleDef::EnumVariant(variant)) = path_res { fields = variant.fields(db); let en = variant.parent_enum(db); diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index ce1df6a1e7..217b13b4ef 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -14,7 +14,9 @@ mod tests; use std::ops::ControlFlow; use either::Either; -use hir::{DefWithBody, EditionedFileId, InFile, InRealFile, MacroKind, Semantics}; +use hir::{ + DefWithBody, EditionedFileId, ExpressionStoreOwner, InFile, InRealFile, MacroKind, Semantics, +}; use ide_db::{FxHashMap, FxHashSet, MiniCore, Ranker, RootDatabase, SymbolKind}; use syntax::{ AstNode, AstToken, NodeOrToken, @@ -256,8 +258,8 @@ fn traverse( let mut inside_attribute = false; // FIXME: accommodate range highlighting - let mut body_stack: Vec<Option<DefWithBody>> = vec![]; - let mut per_body_cache: FxHashMap<DefWithBody, FxHashSet<_>> = FxHashMap::default(); + let mut body_stack: Vec<Option<ExpressionStoreOwner>> = vec![]; + let mut per_body_cache: FxHashMap<ExpressionStoreOwner, FxHashSet<_>> = FxHashMap::default(); // Walk all nodes, keeping track of whether we are inside a macro or not. // If in macro, expand it first and highlight the expanded code. @@ -288,19 +290,18 @@ fn traverse( inside_attribute = false } Enter(NodeOrToken::Node(node)) => { + // FIXME: ExpressionStore signatures and variant fields + // Maybe we can re-use child container stuff here if let Some(item) = <Either<ast::Item, ast::Variant>>::cast(node.clone()) { match item { Either::Left(item) => { match &item { - ast::Item::Fn(it) => { - body_stack.push(sema.to_def(it).map(Into::into)) - } - ast::Item::Const(it) => { - body_stack.push(sema.to_def(it).map(Into::into)) - } - ast::Item::Static(it) => { - body_stack.push(sema.to_def(it).map(Into::into)) - } + ast::Item::Fn(it) => body_stack + .push(sema.to_def(it).map(DefWithBody::from).map(Into::into)), + ast::Item::Const(it) => body_stack + .push(sema.to_def(it).map(DefWithBody::from).map(Into::into)), + ast::Item::Static(it) => body_stack + .push(sema.to_def(it).map(DefWithBody::from).map(Into::into)), _ => (), } @@ -329,7 +330,9 @@ fn traverse( } } } - Either::Right(it) => body_stack.push(sema.to_def(&it).map(Into::into)), + Either::Right(it) => { + body_stack.push(sema.to_def(&it).map(DefWithBody::from).map(Into::into)) + } } } } @@ -392,11 +395,11 @@ fn traverse( let descended = descend_token(sema, InRealFile::new(file_id, token)); let body = match &descended.value { NodeOrToken::Node(n) => { - sema.body_for(InFile::new(descended.file_id, n.syntax())) - } - NodeOrToken::Token(t) => { - t.parent().and_then(|it| sema.body_for(InFile::new(descended.file_id, &it))) + sema.store_owner_for(InFile::new(descended.file_id, n.syntax())) } + NodeOrToken::Token(t) => t + .parent() + .and_then(|it| sema.store_owner_for(InFile::new(descended.file_id, &it))), }; (descended, body) } diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index a94bbc9f04..0e101ab235 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -538,7 +538,7 @@ pub(super) fn highlight_def( (Highlight::new(h), Some(adt.attrs(sema.db))) } - Definition::Variant(variant) => { + Definition::EnumVariant(variant) => { (Highlight::new(HlTag::Symbol(SymbolKind::Variant)), Some(variant.attrs(sema.db))) } Definition::Const(konst) => { diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs index 291333f09c..74a8d93dfe 100644 --- a/crates/ide/src/syntax_highlighting/inject.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs @@ -209,7 +209,7 @@ fn module_def_to_hl_tag(db: &dyn HirDatabase, def: Definition) -> HlTag { Definition::Adt(hir::Adt::Struct(_)) => SymbolKind::Struct, Definition::Adt(hir::Adt::Enum(_)) => SymbolKind::Enum, Definition::Adt(hir::Adt::Union(_)) => SymbolKind::Union, - Definition::Variant(_) => SymbolKind::Variant, + Definition::EnumVariant(_) => SymbolKind::Variant, Definition::Const(_) => SymbolKind::Const, Definition::Static(_) => SymbolKind::Static, Definition::Trait(_) => SymbolKind::Trait, diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 7541a41b20..74828cba02 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -11,7 +11,7 @@ use std::{ use cfg::{CfgAtom, CfgDiff}; use hir::{ Adt, AssocItem, Crate, DefWithBody, FindPathConfig, GenericDef, HasCrate, HasSource, - HirDisplay, ModuleDef, Name, crate_lang_items, + HirDisplay, ModuleDef, Name, Variant, VariantId, crate_lang_items, db::{DefDatabase, ExpandDatabase, HirDatabase}, next_solver::{DbInterner, GenericArgs}, }; @@ -230,6 +230,7 @@ impl flags::AnalysisStats { let mut num_decls = 0; let mut bodies = Vec::new(); let mut signatures = Vec::new(); + let mut variants = Vec::new(); let mut adts = Vec::new(); let mut file_ids = Vec::new(); @@ -247,10 +248,15 @@ impl flags::AnalysisStats { match decl { ModuleDef::Function(f) => bodies.push(DefWithBody::from(f)), ModuleDef::Adt(a) => { - if let Adt::Enum(e) = a { - for v in e.variants(db) { - bodies.push(DefWithBody::from(v)); + match a { + Adt::Enum(e) => { + for v in e.variants(db) { + bodies.push(DefWithBody::from(v)); + variants.push(Variant::EnumVariant(v)); + } } + Adt::Struct(it) => variants.push(Variant::Struct(it)), + Adt::Union(it) => variants.push(Variant::Union(it)), } adts.push(a) } @@ -293,7 +299,7 @@ impl flags::AnalysisStats { } } eprintln!( - ", mods: {}, decls: {num_decls}, bodies: {}, adts: {}, consts: {}, signatures: {}", + ", mods: {}, decls: {num_decls}, bodies: {}, adts: {}, consts: {}, signatures: {}, variants: {}", visited_modules.len(), bodies.len(), adts.len(), @@ -302,6 +308,7 @@ impl flags::AnalysisStats { .filter(|it| matches!(it, DefWithBody::Const(_) | DefWithBody::Static(_))) .count(), signatures.len(), + variants.len() ); eprintln!(" Workspace:"); @@ -337,15 +344,15 @@ impl flags::AnalysisStats { } if !self.skip_lowering { - self.run_body_lowering(db, &vfs, &bodies, &signatures, verbosity); + self.run_body_lowering(db, &vfs, &bodies, &signatures, &variants, verbosity); } if !self.skip_inference { - self.run_inference(db, &vfs, &bodies, &signatures, verbosity); + self.run_inference(db, &vfs, &bodies, &signatures, &variants, verbosity); } if !self.skip_mir_stats { - self.run_mir_lowering(db, &bodies, &signatures, verbosity); + self.run_mir_lowering(db, &bodies, &signatures, &variants, verbosity); } if !self.skip_data_layout { @@ -353,7 +360,7 @@ impl flags::AnalysisStats { } if !self.skip_const_eval { - self.run_const_eval(db, &bodies, &signatures, verbosity); + self.run_const_eval(db, &bodies, &signatures, &variants, verbosity); } }); @@ -431,6 +438,7 @@ impl flags::AnalysisStats { db: &RootDatabase, bodies: &[DefWithBody], _signatures: &[GenericDef], + _variants: &[Variant], verbosity: Verbosity, ) { let len = bodies @@ -710,6 +718,7 @@ impl flags::AnalysisStats { db: &RootDatabase, bodies: &[DefWithBody], _signatures: &[GenericDef], + _variants: &[Variant], verbosity: Verbosity, ) { let mut bar = match verbosity { @@ -725,7 +734,7 @@ impl flags::AnalysisStats { format!("mir lowering: {}", full_name(db, || body.name(db), body.module(db))) }); bar.inc(1); - if matches!(body, DefWithBody::Variant(_)) { + if matches!(body, DefWithBody::EnumVariant(_)) { continue; } let module = body.module(db); @@ -768,6 +777,7 @@ impl flags::AnalysisStats { vfs: &Vfs, bodies: &[DefWithBody], signatures: &[GenericDef], + variants: &[Variant], verbosity: Verbosity, ) { let mut bar = match verbosity { @@ -798,6 +808,13 @@ impl flags::AnalysisStats { InferenceResult::of(snap, signatures); }) .count(); + let variants = variants.iter().copied().map(Into::into).collect::<Vec<VariantId>>(); + variants + .par_iter() + .map_with(db.clone(), |snap, &variants| { + InferenceResult::of(snap, variants); + }) + .count(); eprintln!("{:<20} {}", "Parallel Inference:", inference_sw.elapsed()); } @@ -829,7 +846,9 @@ impl flags::AnalysisStats { DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()), - DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()), + DefWithBody::EnumVariant(it) => { + it.source(db).map(|it| it.syntax().cloned()) + } }; if let Some(src) = source { let original_file = src.file_id.original_file(db); @@ -1127,12 +1146,13 @@ impl flags::AnalysisStats { vfs: &Vfs, bodies: &[DefWithBody], signatures: &[GenericDef], + variants: &[Variant], verbosity: Verbosity, ) { let mut bar = match verbosity { Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(), _ if self.output.is_some() => ProgressReport::hidden(), - _ => ProgressReport::new(bodies.len() + signatures.len()), + _ => ProgressReport::new(bodies.len() + signatures.len() + variants.len()), }; let mut sw = self.stop_watch(); @@ -1181,6 +1201,44 @@ impl flags::AnalysisStats { bar.inc(1); } + for &variant in variants { + let variant_id = variant.into(); + let module = variant.module(db); + if !self.should_process(db, || Some(variant.name(db)), module) { + continue; + } + let msg = move || { + if verbosity.is_verbose() { + let source = match variant { + Variant::EnumVariant(it) => it.source(db).map(|it| it.syntax().cloned()), + Variant::Struct(it) => it.source(db).map(|it| it.syntax().cloned()), + Variant::Union(it) => it.source(db).map(|it| it.syntax().cloned()), + }; + if let Some(src) = source { + let original_file = src.file_id.original_file(db); + let path = vfs.file_path(original_file.file_id(db)); + let syntax_range = src.text_range(); + format!( + "processing: {} ({} {:?})", + full_name(db, || Some(variant.name(db)), module), + path, + syntax_range + ) + } else { + format!("processing: {}", full_name(db, || Some(variant.name(db)), module)) + } + } else { + format!("processing: {}", full_name(db, || Some(variant.name(db)), module)) + } + }; + if verbosity.is_spammy() { + bar.println(msg()); + } + bar.set_message(msg); + ExpressionStore::of(db, ExpressionStoreOwnerId::VariantFields(variant_id)); + bar.inc(1); + } + for &body_id in bodies { let Ok(body_def_id) = body_id.try_into() else { continue }; let module = body_id.module(db); @@ -1193,7 +1251,9 @@ impl flags::AnalysisStats { DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()), DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()), - DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()), + DefWithBody::EnumVariant(it) => { + it.source(db).map(|it| it.syntax().cloned()) + } }; if let Some(src) = source { let original_file = src.file_id.original_file(db); |