Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #22860 from Veykril/lukaswirth/push-uxlsstlnnszp
internal: Pack `ExprOrPatId` when stored, shrink `ScopeData`
| -rw-r--r-- | crates/hir-def/src/expr_store.rs | 28 | ||||
| -rw-r--r-- | crates/hir-def/src/expr_store/scope.rs | 70 | ||||
| -rw-r--r-- | crates/hir-def/src/hir.rs | 86 | ||||
| -rw-r--r-- | crates/hir-def/src/resolver.rs | 9 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 63 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/closure/analysis.rs | 6 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs | 26 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/diagnostics.rs | 13 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/expr.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/pat.rs | 6 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/path.rs | 19 | ||||
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/mir/lower.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests.rs | 2 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/closure_captures.rs | 2 | ||||
| -rw-r--r-- | crates/hir/src/diagnostics.rs | 16 | ||||
| -rw-r--r-- | crates/hir/src/lib.rs | 4 | ||||
| -rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 6 |
18 files changed, 241 insertions, 133 deletions
diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs index dec911f716..fdb3296b17 100644 --- a/crates/hir-def/src/expr_store.rs +++ b/crates/hir-def/src/expr_store.rs @@ -30,9 +30,9 @@ use crate::{ AdtId, BlockId, ExpressionStoreOwnerId, GenericDefId, SyntheticSyntax, expr_store::path::{AssociatedTypeBinding, GenericArg, GenericArgs, NormalPath, Path}, hir::{ - Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, InlineAsm, Label, - LabelId, MatchArm, OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, RecordSpread, - Statement, + Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, ExprOrPatIdPacked, + InlineAsm, Label, LabelId, MatchArm, OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, + RecordSpread, Statement, }, nameres::{DefMap, block_def_map}, signatures::VariantFields, @@ -127,7 +127,7 @@ struct ExpressionOnlyStore { /// /// Expressions (and destructuing patterns) that can be recorded here are single segment path, although not all single segments path refer /// to variables and have hygiene (some refer to items, we don't know at this stage). - ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, + ident_hygiene: FxHashMap<ExprOrPatIdPacked, HygieneId>, /// Maps expression roots to their origin. /// @@ -171,10 +171,10 @@ pub struct ExpressionStore { struct ExpressionOnlySourceMap { // 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). - expr_map: FxHashMap<ExprSource, ExprOrPatId>, + expr_map: FxHashMap<ExprSource, ExprOrPatIdPacked>, expr_map_back: ArenaMap<ExprId, ExprOrPatSource>, - pat_map: FxHashMap<PatSource, ExprOrPatId>, + pat_map: FxHashMap<PatSource, ExprOrPatIdPacked>, pat_map_back: ArenaMap<PatId, ExprOrPatSource>, label_map: FxHashMap<LabelSource, LabelId>, @@ -270,15 +270,15 @@ pub struct ExpressionStoreBuilder { pub binding_owners: FxHashMap<BindingId, ExprId>, pub types: Arena<TypeRef>, block_scopes: Vec<BlockId>, - ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>, + ident_hygiene: FxHashMap<ExprOrPatIdPacked, HygieneId>, inference_roots: Option<SmallVec<[ExprRoot; 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). - expr_map: FxHashMap<ExprSource, ExprOrPatId>, + expr_map: FxHashMap<ExprSource, ExprOrPatIdPacked>, expr_map_back: ArenaMap<ExprId, ExprOrPatSource>, - pat_map: FxHashMap<PatSource, ExprOrPatId>, + pat_map: FxHashMap<PatSource, ExprOrPatIdPacked>, pat_map_back: ArenaMap<PatId, ExprOrPatSource>, label_map: FxHashMap<LabelSource, LabelId>, @@ -1175,7 +1175,7 @@ impl ExpressionStoreSourceMap { pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprOrPatId> { let src = node.map(AstPtr::new); - self.expr_only()?.expr_map.get(&src).cloned() + self.expr_only()?.expr_map.get(&src).cloned().map(ExprOrPatIdPacked::unpack) } pub fn node_macro_file(&self, node: InFile<&ast::MacroCall>) -> Option<MacroCallId> { @@ -1192,7 +1192,11 @@ impl ExpressionStoreSourceMap { } pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<ExprOrPatId> { - self.expr_only()?.pat_map.get(&node.map(AstPtr::new)).cloned() + self.expr_only()? + .pat_map + .get(&node.map(AstPtr::new)) + .cloned() + .map(ExprOrPatIdPacked::unpack) } pub fn type_syntax(&self, id: TypeRefId) -> Result<TypeSource, SyntheticSyntax> { @@ -1226,7 +1230,7 @@ impl ExpressionStoreSourceMap { pub fn macro_expansion_expr(&self, node: InFile<&ast::MacroExpr>) -> Option<ExprOrPatId> { let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::MacroExpr>).map(AstPtr::upcast); - self.expr_only()?.expr_map.get(&src).copied() + self.expr_only()?.expr_map.get(&src).copied().map(ExprOrPatIdPacked::unpack) } pub fn expansions(&self) -> impl Iterator<Item = (&InFile<MacroCallPtr>, &MacroCallId)> { diff --git a/crates/hir-def/src/expr_store/scope.rs b/crates/hir-def/src/expr_store/scope.rs index c881a961b1..3ce0ed44da 100644 --- a/crates/hir-def/src/expr_store/scope.rs +++ b/crates/hir-def/src/expr_store/scope.rs @@ -46,13 +46,18 @@ impl ScopeEntry { #[derive(Debug, PartialEq, Eq)] pub struct ScopeData { parent: Option<ScopeId>, - block: Option<BlockId>, - label: Option<(LabelId, Name)>, - // FIXME: We can compress this with an enum for this and `label`/`block` if memory usage matters. - macro_def: Option<Box<MacroDefId>>, + kind: ScopeKind, entries: IdxRange<ScopeEntry>, } +#[derive(Debug, PartialEq, Eq)] +enum ScopeKind { + None, + Block { id: BlockId, label: Option<LabelId> }, + Label(LabelId), + MacroDef(Box<MacroDefId>), +} + #[salsa::tracked] impl ExprScopes { #[salsa::tracked(returns(ref))] @@ -100,18 +105,28 @@ impl ExprScopes { /// If `scope` refers to a block expression scope, returns the corresponding `BlockId`. pub fn block(&self, scope: ScopeId) -> Option<BlockId> { - self.scopes[scope].block + match self.scopes[scope].kind { + ScopeKind::Block { id, label: _ } => Some(id), + ScopeKind::None | ScopeKind::Label(_) | ScopeKind::MacroDef(_) => None, + } } /// If `scope` refers to a macro def scope, returns the corresponding `MacroId`. #[allow(clippy::borrowed_box)] // If we return `&MacroDefId` we need to move it, this way we just clone the `Box`. pub fn macro_def(&self, scope: ScopeId) -> Option<&Box<MacroDefId>> { - self.scopes[scope].macro_def.as_ref() + match &self.scopes[scope].kind { + ScopeKind::MacroDef(macro_def) => Some(macro_def), + ScopeKind::None | ScopeKind::Block { id: _, label: _ } | ScopeKind::Label(_) => None, + } } /// If `scope` refers to a labeled expression scope, returns the corresponding `Label`. - pub fn label(&self, scope: ScopeId) -> Option<(LabelId, Name)> { - self.scopes[scope].label.clone() + pub fn label(&self, scope: ScopeId) -> Option<LabelId> { + match &self.scopes[scope].kind { + &ScopeKind::Block { id: _, label } => label, + &ScopeKind::Label(label) => Some(label), + ScopeKind::None | ScopeKind::MacroDef(_) => None, + } } /// Returns the scopes in ascending order. @@ -174,9 +189,7 @@ impl ExprScopes { fn root_scope(&mut self) -> ScopeId { self.scopes.alloc(ScopeData { parent: None, - block: None, - label: None, - macro_def: None, + kind: ScopeKind::None, entries: empty_entries(self.scope_entries.len()), }) } @@ -184,19 +197,19 @@ impl ExprScopes { fn new_scope(&mut self, parent: ScopeId) -> ScopeId { self.scopes.alloc(ScopeData { parent: Some(parent), - block: None, - label: None, - macro_def: None, + kind: ScopeKind::None, entries: empty_entries(self.scope_entries.len()), }) } - fn new_labeled_scope(&mut self, parent: ScopeId, label: Option<(LabelId, Name)>) -> ScopeId { + fn new_labeled_scope(&mut self, parent: ScopeId, label: Option<LabelId>) -> ScopeId { + let kind = match label { + Some(label) => ScopeKind::Label(label), + None => ScopeKind::None, + }; self.scopes.alloc(ScopeData { parent: Some(parent), - block: None, - label, - macro_def: None, + kind, entries: empty_entries(self.scope_entries.len()), }) } @@ -205,13 +218,16 @@ impl ExprScopes { &mut self, parent: ScopeId, block: Option<BlockId>, - label: Option<(LabelId, Name)>, + label: Option<LabelId>, ) -> ScopeId { + let kind = match (block, label) { + (Some(id), label) => ScopeKind::Block { id, label }, + (None, Some(label)) => ScopeKind::Label(label), + (None, None) => ScopeKind::None, + }; self.scopes.alloc(ScopeData { parent: Some(parent), - block, - label, - macro_def: None, + kind, entries: empty_entries(self.scope_entries.len()), }) } @@ -219,9 +235,7 @@ impl ExprScopes { fn new_macro_def_scope(&mut self, parent: ScopeId, macro_id: Box<MacroDefId>) -> ScopeId { self.scopes.alloc(ScopeData { parent: Some(parent), - block: None, - label: None, - macro_def: Some(macro_id), + kind: ScopeKind::MacroDef(macro_id), entries: empty_entries(self.scope_entries.len()), }) } @@ -303,8 +317,6 @@ fn compute_expr_scopes( scope: &mut ScopeId, const_scope: &mut ScopeId, ) { - let make_label = |label: Option<LabelId>| label.map(|label| (label, store[label].name.clone())); - let compute_expr_scopes = |scopes: &mut ExprScopes, expr: ExprId, scope: &mut ScopeId, const_scope: &mut ScopeId| { compute_expr_scopes(expr, store, scopes, scope, const_scope) @@ -316,7 +328,7 @@ fn compute_expr_scopes( scopes: &mut ExprScopes, scope: &mut ScopeId, const_scope: &mut ScopeId| { - let mut scope = scopes.new_block_scope(*scope, id, make_label(label)); + let mut scope = scopes.new_block_scope(*scope, id, label); let mut const_scope = if id.is_some() { scopes.new_block_scope(*const_scope, id, None) } else { @@ -347,7 +359,7 @@ fn compute_expr_scopes( handle_block(*id, statements, *tail, None, scopes, scope, const_scope); } Expr::Loop { body: body_expr, label, source: _ } => { - let mut scope = scopes.new_labeled_scope(*scope, make_label(*label)); + let mut scope = scopes.new_labeled_scope(*scope, *label); compute_expr_scopes(scopes, *body_expr, &mut scope, const_scope); } Expr::Closure { args, body: body_expr, .. } => { diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs index a800569044..dcb2227d9f 100644 --- a/crates/hir-def/src/hir.rs +++ b/crates/hir-def/src/hir.rs @@ -16,11 +16,11 @@ pub mod format_args; pub mod generics; pub mod type_ref; -use std::fmt; +use std::{fmt, mem}; use hir_expand::{MacroDefId, name::Name}; use intern::Symbol; -use la_arena::Idx; +use la_arena::{Idx, RawIdx}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use syntax::ast; use type_ref::TypeRefId; @@ -43,9 +43,7 @@ pub type ExprId = Idx<Expr>; pub type PatId = Idx<Pat>; -// FIXME: Encode this as a single u32, we won't ever reach all 32 bits especially given these counts -// are local to the body. -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, salsa::Update)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum ExprOrPatId { ExprId(ExprId), PatId(PatId), @@ -74,7 +72,83 @@ impl ExprOrPatId { matches!(self, Self::PatId(_)) } } -stdx::impl_from!(ExprId, PatId for ExprOrPatId); + +#[derive(Copy, Clone, Hash, PartialEq, Eq, salsa::Update)] +pub struct ExprOrPatIdPacked(u32); + +const _: () = assert!(mem::size_of::<ExprOrPatIdPacked>() == mem::size_of::<u32>()); + +impl ExprOrPatIdPacked { + const PAT_BIT: u32 = 1 << (u32::BITS - 1); + const INDEX_MASK: u32 = !Self::PAT_BIT; + + pub fn unpack(self) -> ExprOrPatId { + match self.is_expr() { + true => ExprOrPatId::ExprId(ExprId::from_raw(RawIdx::from_u32(self.0))), + false => { + ExprOrPatId::PatId(PatId::from_raw(RawIdx::from_u32(self.0 & Self::INDEX_MASK))) + } + } + } + + #[inline] + pub fn as_expr(self) -> Option<ExprId> { + self.is_expr().then(|| ExprId::from_raw(RawIdx::from_u32(self.0))) + } + + #[inline] + pub fn is_expr(&self) -> bool { + self.0 & Self::PAT_BIT == 0 + } + + #[inline] + pub fn as_pat(self) -> Option<PatId> { + self.is_pat().then(|| PatId::from_raw(RawIdx::from_u32(self.0 & Self::INDEX_MASK))) + } + + #[inline] + pub fn is_pat(&self) -> bool { + self.0 & Self::PAT_BIT != 0 + } +} + +impl fmt::Debug for ExprOrPatIdPacked { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.unpack() { + ExprOrPatId::ExprId(id) => f.debug_tuple("ExprId").field(&id).finish(), + ExprOrPatId::PatId(id) => f.debug_tuple("PatId").field(&id).finish(), + } + } +} + +impl From<ExprId> for ExprOrPatIdPacked { + fn from(value: ExprId) -> Self { + let value = value.into_raw().into_u32(); + // virtually impossible to have IDs that high + debug_assert_eq!(value & Self::PAT_BIT, 0); + Self(value) + } +} + +impl From<PatId> for ExprOrPatId { + fn from(value: PatId) -> Self { + ExprOrPatId::PatId(value) + } +} +impl From<ExprId> for ExprOrPatId { + fn from(value: ExprId) -> Self { + ExprOrPatId::ExprId(value) + } +} + +impl From<PatId> for ExprOrPatIdPacked { + fn from(value: PatId) -> Self { + let value = value.into_raw().into_u32(); + // virtually impossible to have IDs that high + debug_assert_eq!(value & Self::PAT_BIT, 0); + Self(value | Self::PAT_BIT) + } +} #[derive(Debug, Clone, Eq, PartialEq)] pub struct Label { diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index fc639133d4..724926f824 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -22,7 +22,7 @@ use crate::{ TypeOrConstParamId, TypeParamId, UseId, VariantId, builtin_type::BuiltinType, expr_store::{ - HygieneId, + ExpressionStore, HygieneId, path::Path, scope::{ExprScopes, ScopeId}, }, @@ -1071,8 +1071,11 @@ impl<'db> Scope<'db> { } } Scope::ExprScope(scope) => { - if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) { - acc.add(&name, ScopeDef::Label(label)) + if let Some(label) = scope.expr_scopes.label(scope.scope_id) { + acc.add( + &ExpressionStore::of(db, scope.owner)[label].name, + ScopeDef::Label(label), + ) } scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { acc.add_local(e.name(), e.binding()); diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 64d0e2a864..3b9e168d54 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs @@ -47,7 +47,7 @@ use hir_def::{ TupleFieldId, TupleId, VariantId, attrs::AttrFlags, expr_store::{Body, ExpressionStore, HygieneId, body::Param, path::Path}, - hir::{BindingId, ExprId, ExprOrPatId, LabelId, PatId}, + hir::{BindingId, ExprId, ExprOrPatId, ExprOrPatIdPacked, LabelId, PatId}, lang_item::LangItems, layout::Integer, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, @@ -289,7 +289,7 @@ pub enum InferenceTyDiagnosticSource { pub enum InferenceDiagnostic { NoSuchField { #[type_visitable(ignore)] - field: ExprOrPatId, + field: ExprOrPatIdPacked, #[type_visitable(ignore)] private: Option<LocalFieldId>, #[type_visitable(ignore)] @@ -320,7 +320,7 @@ pub enum InferenceDiagnostic { }, DuplicateField { #[type_visitable(ignore)] - field: ExprOrPatId, + field: ExprOrPatIdPacked, #[type_visitable(ignore)] variant: VariantId, }, @@ -332,7 +332,7 @@ pub enum InferenceDiagnostic { }, PrivateAssocItem { #[type_visitable(ignore)] - id: ExprOrPatId, + id: ExprOrPatIdPacked, #[type_visitable(ignore)] item: AssocItemId, }, @@ -358,11 +358,11 @@ pub enum InferenceDiagnostic { }, UnresolvedAssocItem { #[type_visitable(ignore)] - id: ExprOrPatId, + id: ExprOrPatIdPacked, }, UnresolvedIdent { #[type_visitable(ignore)] - id: ExprOrPatId, + id: ExprOrPatIdPacked, }, // FIXME: This should be emitted in body lowering BreakOutsideOfLoop { @@ -461,7 +461,7 @@ pub enum InferenceDiagnostic { }, PathDiagnostic { #[type_visitable(ignore)] - node: ExprOrPatId, + node: ExprOrPatIdPacked, #[type_visitable(ignore)] diag: PathLoweringDiagnostic, }, @@ -507,7 +507,7 @@ pub enum InferenceDiagnostic { }, TypeMismatch { #[type_visitable(ignore)] - node: ExprOrPatId, + node: ExprOrPatIdPacked, expected: StoredTy, found: StoredTy, }, @@ -541,7 +541,7 @@ pub enum ReturnKind { #[derive(Debug, PartialEq, Eq, Clone)] pub enum ExplicitDropMethodUseKind { MethodCall(ExprId), - Path(ExprOrPatId), + Path(ExprOrPatIdPacked), } /// Represents coercing a value to a different type of value. @@ -743,9 +743,9 @@ pub struct InferenceResult { /// For each field access expr, records the field it resolves to. field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>, /// For each struct literal or pattern, records the variant it resolves to. - variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, + variant_resolutions: FxHashMap<ExprOrPatIdPacked, VariantId>, /// For each associated item record what it resolves to - assoc_resolutions: FxHashMap<ExprOrPatId, (CandidateId, StoredGenericArgs)>, + assoc_resolutions: FxHashMap<ExprOrPatIdPacked, (CandidateId, StoredGenericArgs)>, /// Whenever a tuple field expression access a tuple field, we allocate a tuple id in /// [`InferenceContext`] and store the tuples substitution there. This map is the reverse of /// that which allows us to resolve a [`TupleFieldId`]s type. @@ -769,7 +769,7 @@ pub struct InferenceResult { /// During inference this field is empty and [`InferenceContext::diagnostics`] is filled instead. diagnostics: ThinVec<InferenceDiagnostic>, // FIXME: Remove this, change it to be in `InferenceContext`: - nodes_with_type_mismatches: Option<Box<FxHashSet<ExprOrPatId>>>, + nodes_with_type_mismatches: Option<Box<FxHashSet<ExprOrPatIdPacked>>>, /// Interned `Error` type to return references to. // FIXME: Remove this. @@ -897,9 +897,9 @@ pub struct CaptureSourceStack(CaptureSourceStackRepr); #[derive(Clone)] enum CaptureSourceStackRepr { - One(ExprOrPatId), - Two([ExprOrPatId; 2]), - Many(ThinVec<ExprOrPatId>), + One(ExprOrPatIdPacked), + Two([ExprOrPatIdPacked; 2]), + Many(ThinVec<ExprOrPatIdPacked>), } impl PartialEq for CaptureSourceStack { @@ -916,10 +916,11 @@ impl std::hash::Hash for CaptureSourceStack { } } +#[cfg(target_pointer_width = "64")] const _: () = assert!(size_of::<CaptureSourceStack>() == 16); impl Deref for CaptureSourceStack { - type Target = [ExprOrPatId]; + type Target = [ExprOrPatIdPacked]; #[inline] fn deref(&self) -> &Self::Target { @@ -948,16 +949,16 @@ impl CaptureSourceStack { } #[inline] - pub(crate) fn from_single(id: ExprOrPatId) -> Self { + pub(crate) fn from_single(id: ExprOrPatIdPacked) -> Self { Self(CaptureSourceStackRepr::One(id)) } #[inline] - pub fn final_source(&self) -> ExprOrPatId { + pub fn final_source(&self) -> ExprOrPatIdPacked { *self.last().expect("should always have a final source") } - pub fn push(&mut self, new_id: ExprOrPatId) { + pub fn push(&mut self, new_id: ExprOrPatIdPacked) { match &mut self.0 { CaptureSourceStackRepr::One(old_id) => { self.0 = CaptureSourceStackRepr::Two([*old_id, new_id]) @@ -1113,7 +1114,7 @@ impl InferenceResult { ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id), } } - pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatId) -> bool { + pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatIdPacked) -> bool { self.nodes_with_type_mismatches.as_ref().is_some_and(|it| it.contains(&node)) } pub fn expr_has_type_mismatch(&self, expr: ExprId) -> bool { @@ -1878,13 +1879,13 @@ impl<'body, 'db> InferenceContext<'body, 'db> { self.result.method_resolutions.insert(expr, (func, subst.store())); } - fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) { + fn write_variant_resolution(&mut self, id: ExprOrPatIdPacked, variant: VariantId) { self.result.variant_resolutions.insert(id, variant); } fn write_assoc_resolution( &mut self, - id: ExprOrPatId, + id: ExprOrPatIdPacked, item: CandidateId, subs: GenericArgs<'db>, ) { @@ -2140,14 +2141,18 @@ impl<'body, 'db> InferenceContext<'body, 'db> { self.table.resolve_vars_if_possible(t) } - pub(crate) fn structurally_resolve_type(&mut self, node: ExprOrPatId, ty: Ty<'db>) -> Ty<'db> { + pub(crate) fn structurally_resolve_type( + &mut self, + node: ExprOrPatIdPacked, + ty: Ty<'db>, + ) -> Ty<'db> { let result = self.table.try_structurally_resolve_type(node.into(), ty); if result.is_ty_var() { self.type_must_be_known_at_this_point(node, ty) } else { result } } pub(crate) fn emit_type_mismatch( &mut self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, expected: Ty<'db>, found: Ty<'db>, ) { @@ -2162,7 +2167,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { fn demand_eqtype( &mut self, - id: ExprOrPatId, + id: ExprOrPatIdPacked, expected: Ty<'db>, actual: Ty<'db>, ) -> Result<(), ()> { @@ -2192,7 +2197,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { fn demand_suptype( &mut self, - id: ExprOrPatId, + id: ExprOrPatIdPacked, expected: Ty<'db>, actual: Ty<'db>, ) -> Result<(), ()> { @@ -2224,7 +2229,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { pub(crate) fn type_must_be_known_at_this_point( &mut self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, ty: Ty<'db>, ) -> Ty<'db> { if self.vars_emitted_type_must_be_known_for.insert(ty.into()) { @@ -2260,7 +2265,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { fn resolve_variant( &mut self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, path: &Path, value_ns: bool, ) -> (Ty<'db>, Option<VariantId>) { @@ -2570,7 +2575,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> { fn resolve_variant_on_alias( &mut self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, ty: Ty<'db>, unresolved: Option<usize>, path: &ModPath, diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs index 5ea43bc03c..9dce343cae 100644 --- a/crates/hir-ty/src/infer/closure/analysis.rs +++ b/crates/hir-ty/src/infer/closure/analysis.rs @@ -35,8 +35,8 @@ use std::{iter, mem}; use hir_def::{ expr_store::ExpressionStore, hir::{ - BindingAnnotation, BindingId, CaptureBy, CoroutineSource, Expr, ExprId, ExprOrPatId, Pat, - PatId, Statement, + BindingAnnotation, BindingId, CaptureBy, CoroutineSource, Expr, ExprId, ExprOrPatIdPacked, + Pat, PatId, Statement, }, resolver::ValueNs, }; @@ -1461,7 +1461,7 @@ fn determine_capture_info(capture_info_a: &mut CaptureInfo, capture_info_b: &mut fn determine_capture_sources( capture_info_a: &mut CaptureInfo, capture_info_b: &mut CaptureInfo, - dedup_sources_scratch: &mut FxHashMap<ExprOrPatId, CaptureSourceStack>, + dedup_sources_scratch: &mut FxHashMap<ExprOrPatIdPacked, CaptureSourceStack>, ) -> SmallVec<[CaptureSourceStack; 2]> { dedup_sources_scratch.clear(); dedup_sources_scratch.extend( diff --git a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs index d8a8cceee6..f02a85c293 100644 --- a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs +++ b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs @@ -9,8 +9,8 @@ use hir_def::{ AdtId, HasModule, VariantId, attrs::AttrFlags, hir::{ - Array, AsmOperand, BindingId, Expr, ExprId, ExprOrPatId, MatchArm, Pat, PatId, - RecordLitField, RecordSpread, Statement, + Array, AsmOperand, BindingId, Expr, ExprId, ExprOrPatId, ExprOrPatIdPacked, MatchArm, Pat, + PatId, RecordLitField, RecordSpread, Statement, }, resolver::ValueNs, }; @@ -144,7 +144,7 @@ pub(crate) struct PlaceWithOrigin { impl PlaceWithOrigin { fn new_no_projections<'db>( - origin: impl Into<ExprOrPatId>, + origin: impl Into<ExprOrPatIdPacked>, base_ty: Ty<'db>, base: PlaceBase, ) -> PlaceWithOrigin { @@ -166,7 +166,7 @@ impl PlaceWithOrigin { PlaceWithOrigin { origins, place: Place { base_ty: base_ty.store(), base, projections } } } - fn push_projection(&mut self, projection: Projection, origin: ExprOrPatId) { + fn push_projection(&mut self, projection: Projection, origin: ExprOrPatIdPacked) { self.place.projections.push(projection); for origin_stack in &mut self.origins { origin_stack.push(origin); @@ -1392,7 +1392,7 @@ impl<'db, D: Delegate<'db>> ExprUseVisitor<'_, '_, 'db, D> { fn cat_local( &mut self, - id: ExprOrPatId, + id: ExprOrPatIdPacked, expr_ty: Ty<'db>, var_id: BindingId, ) -> Result<PlaceWithOrigin> { @@ -1408,7 +1408,11 @@ impl<'db, D: Delegate<'db>> ExprUseVisitor<'_, '_, 'db, D> { /// Note: the actual upvar access contains invisible derefs of closure /// environment and upvar reference as appropriate. Only regionck cares /// about these dereferences, so we let it compute them as needed. - fn cat_upvar(&mut self, hir_id: ExprOrPatId, var_id: BindingId) -> Result<PlaceWithOrigin> { + fn cat_upvar( + &mut self, + hir_id: ExprOrPatIdPacked, + var_id: BindingId, + ) -> Result<PlaceWithOrigin> { let var_ty = self.expect_and_resolve_type( self.cx.result.type_of_binding.get(var_id).map(|it| it.as_ref()), )?; @@ -1420,13 +1424,13 @@ impl<'db, D: Delegate<'db>> ExprUseVisitor<'_, '_, 'db, D> { )) } - fn cat_rvalue(&self, hir_id: ExprOrPatId, expr_ty: Ty<'db>) -> PlaceWithOrigin { + fn cat_rvalue(&self, hir_id: ExprOrPatIdPacked, expr_ty: Ty<'db>) -> PlaceWithOrigin { PlaceWithOrigin::new_no_projections(hir_id, expr_ty, PlaceBase::Rvalue) } fn cat_projection( &self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, mut base_place: PlaceWithOrigin, ty: Ty<'db>, kind: ProjectionKind, @@ -1455,7 +1459,7 @@ impl<'db, D: Delegate<'db>> ExprUseVisitor<'_, '_, 'db, D> { fn cat_deref( &mut self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, mut base_place: PlaceWithOrigin, ) -> Result<PlaceWithOrigin> { let base_curr_ty = base_place.place.ty(); @@ -1712,7 +1716,7 @@ impl<'db, D: Delegate<'db>> ExprUseVisitor<'_, '_, 'db, D> { /// Represents the place matched on by a deref pattern's interior. fn pat_deref_place( &mut self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, base_place: PlaceWithOrigin, inner: PatId, target_ty: Ty<'db>, @@ -1746,7 +1750,7 @@ impl<'db, D: Delegate<'db>> ExprUseVisitor<'_, '_, 'db, D> { /// FIXME(never_patterns): update this comment once the aforementioned MIR builder /// code is changed to be insensitive to inhhabitedness. #[instrument(skip(self), level = "debug")] - fn is_multivariant_adt(&mut self, node: ExprOrPatId, ty: Ty<'db>) -> bool { + fn is_multivariant_adt(&mut self, node: ExprOrPatIdPacked, ty: Ty<'db>) -> bool { if let TyKind::Adt(def, _) = self.cx.structurally_resolve_type(node, ty).kind() { // Note that if a non-exhaustive SingleVariant is defined in another crate, we need // to assume that more cases will be added to the variant in the future. This mean diff --git a/crates/hir-ty/src/infer/diagnostics.rs b/crates/hir-ty/src/infer/diagnostics.rs index e871edd265..481a5e9cfc 100644 --- a/crates/hir-ty/src/infer/diagnostics.rs +++ b/crates/hir-ty/src/infer/diagnostics.rs @@ -9,8 +9,11 @@ use either::Either; use hir_def::expr_store::path::Path; use hir_def::{ExpressionStoreOwnerId, GenericDefId}; use hir_def::{expr_store::ExpressionStore, type_ref::TypeRefId}; -use hir_def::{hir::ExprOrPatId, resolver::Resolver}; -use la_arena::{Idx, RawIdx}; +use hir_def::{ + hir::{ExprId, ExprOrPatIdPacked}, + resolver::Resolver, +}; +use la_arena::RawIdx; use rustc_hash::FxHashMap; use thin_vec::ThinVec; @@ -55,7 +58,7 @@ impl Diagnostics { } pub(crate) struct PathDiagnosticCallbackData<'a> { - node: ExprOrPatId, + node: ExprOrPatIdPacked, diagnostics: &'a Diagnostics, } @@ -131,7 +134,7 @@ impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> { pub(super) fn at_path<'b>( &'b mut self, path: &'b Path, - node: ExprOrPatId, + node: ExprOrPatIdPacked, ) -> PathLoweringContext<'b, 'a, 'db> { let on_diagnostic = PathDiagnosticCallback { data: Either::Right(PathDiagnosticCallbackData { diagnostics: self.diagnostics, node }), @@ -152,7 +155,7 @@ impl<'db, 'a> InferenceTyLoweringContext<'db, 'a> { let on_diagnostic = PathDiagnosticCallback { data: Either::Right(PathDiagnosticCallbackData { diagnostics: self.diagnostics, - node: ExprOrPatId::ExprId(Idx::from_raw(RawIdx::from_u32(0))), + node: ExprOrPatIdPacked::from(ExprId::from_raw(RawIdx::from_u32(0))), }), callback: |_data, _, _diag| {}, }; diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 40465e3952..d265e1ed77 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -7,9 +7,9 @@ use hir_def::{ AdtId, FieldId, TupleFieldId, TupleId, VariantId, expr_store::path::{GenericArgs as HirGenericArgs, Path}, hir::{ - Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, ExprOrPatId, - InlineAsmKind, LabelId, LoopSource, Pat, PatId, RecordLitField, RecordSpread, Statement, - UnaryOp, + Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, + ExprOrPatIdPacked, InlineAsmKind, LabelId, LoopSource, Pat, PatId, RecordLitField, + RecordSpread, Statement, UnaryOp, }, resolver::ValueNs, signatures::VariantFields, @@ -1274,7 +1274,7 @@ impl<'db> InferenceContext<'_, 'db> { } } - fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatId, scope_id: ExprId) -> Ty<'db> { + fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatIdPacked, scope_id: ExprId) -> Ty<'db> { let g = self.resolver.update_to_inner_scope(self.db, self.store_owner, scope_id); let ty = match self.infer_path(path, id) { Some((_, ty)) => ty, diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index 1e539d24c1..7654ad77cd 100644 --- a/crates/hir-ty/src/infer/pat.rs +++ b/crates/hir-ty/src/infer/pat.rs @@ -10,7 +10,7 @@ use hir_def::{ AdtId, LocalFieldId, VariantId, expr_store::path::Path, hir::{ - BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId, + BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatIdPacked, Literal, Pat, PatId, RecordFieldPat, }, resolver::ValueNs, @@ -853,7 +853,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { // Subtyping doesn't matter here, as the value is some kind of scalar. let mut demand_eqtype = |x: &mut _| { if let Some((_, x_ty, x_expr)) = *x { - _ = self.demand_eqtype(ExprOrPatId::from(x_expr), expected, x_ty); + _ = self.demand_eqtype(ExprOrPatIdPacked::from(x_expr), expected, x_ty); } }; demand_eqtype(&mut lhs); @@ -868,7 +868,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> { // We require types to be resolved here so that we emit inference failure // rather than "_ is not a char or numeric". let ty = self.structurally_resolve_type( - lhs_expr.or(rhs_expr).map(ExprOrPatId::ExprId).unwrap_or(pat.into()), + lhs_expr.or(rhs_expr).map(ExprOrPatIdPacked::from).unwrap_or(pat.into()), expected, ); if !(ty.is_numeric() || ty.is_char() || ty.references_error()) { diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs index ecc81f9de0..1b1d0e1ff6 100644 --- a/crates/hir-ty/src/infer/path.rs +++ b/crates/hir-ty/src/infer/path.rs @@ -3,6 +3,7 @@ use hir_def::{ AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup, expr_store::path::{Path, PathSegment}, + hir::ExprOrPatIdPacked, resolver::{ResolveValueResult, TypeNs, ValueNs}, signatures::{ConstSignature, FunctionSignature}, }; @@ -23,13 +24,13 @@ use crate::{ }, }; -use super::{ExprOrPatId, InferenceContext, InferenceTyDiagnosticSource}; +use super::{InferenceContext, InferenceTyDiagnosticSource}; impl<'db> InferenceContext<'_, 'db> { pub(super) fn infer_path( &mut self, path: &Path, - id: ExprOrPatId, + id: ExprOrPatIdPacked, ) -> Option<(ValueNs, Ty<'db>)> { let (value, self_subst) = self.resolve_value_path_inner(path, id, false)?; @@ -60,7 +61,7 @@ impl<'db> InferenceContext<'_, 'db> { fn resolve_value_path( &mut self, path: &Path, - id: ExprOrPatId, + id: ExprOrPatIdPacked, value: ValueNs, self_subst: Option<GenericArgs<'db>>, ) -> Option<ValuePathResolution<'db>> { @@ -145,7 +146,7 @@ impl<'db> InferenceContext<'_, 'db> { pub(super) fn resolve_value_path_inner( &mut self, path: &Path, - id: ExprOrPatId, + id: ExprOrPatIdPacked, no_diagnostics: bool, ) -> Option<(ValueNs, Option<GenericArgs<'db>>)> { // Don't use `self.make_ty()` here as we need `orig_ns`. @@ -185,7 +186,7 @@ impl<'db> InferenceContext<'_, 'db> { let ty = self.table.process_user_written_ty(ty); self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))? } else { - let hygiene = self.store.expr_or_pat_path_hygiene(id); + let hygiene = self.store.expr_or_pat_path_hygiene(id.unpack()); // FIXME: report error, unresolved first path segment let value_or_partial = path_ctx.resolve_path_in_value_ns(hygiene)?; @@ -273,7 +274,7 @@ impl<'db> InferenceContext<'_, 'db> { pub(super) fn add_required_obligations_for_value_path( &mut self, - node: ExprOrPatId, + node: ExprOrPatIdPacked, def: GenericDefId, subst: GenericArgs<'db>, ) { @@ -293,7 +294,7 @@ impl<'db> InferenceContext<'_, 'db> { &mut self, trait_ref: TraitRef<'db>, segment: PathSegment<'_>, - id: ExprOrPatId, + id: ExprOrPatIdPacked, ) -> Option<(ValueNs, GenericArgs<'db>)> { let trait_ = trait_ref.def_id.0; let item = @@ -330,7 +331,7 @@ impl<'db> InferenceContext<'_, 'db> { &mut self, ty: Ty<'db>, name: &Name, - id: ExprOrPatId, + id: ExprOrPatIdPacked, ) -> Option<(ValueNs, GenericArgs<'db>)> { if ty.is_ty_error() { return None; @@ -399,7 +400,7 @@ impl<'db> InferenceContext<'_, 'db> { &mut self, ty: Ty<'db>, name: &Name, - id: ExprOrPatId, + id: ExprOrPatIdPacked, ) -> Option<(ValueNs, GenericArgs<'db>)> { let ty = self.table.try_structurally_resolve_type(id.into(), ty); let (enum_id, subst) = match ty.as_adt() { diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs index 120c265fdc..b6cf47fe62 100644 --- a/crates/hir-ty/src/lib.rs +++ b/crates/hir-ty/src/lib.rs @@ -67,7 +67,7 @@ use hir_def::{ GenericDefId, HasModule, LifetimeParamId, ModuleId, StaticId, TypeAliasId, TypeOrConstParamId, TypeParamId, expr_store::{Body, ExpressionStore}, - hir::{BindingId, ExprId, ExprOrPatId, PatId}, + hir::{BindingId, ExprId, ExprOrPatId, ExprOrPatIdPacked, PatId}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{Rawness, TypeRefId}, }; @@ -531,9 +531,9 @@ pub enum Span { } impl_from!(ExprId, PatId, BindingId, TypeRefId for Span); -impl From<ExprOrPatId> for Span { - fn from(value: ExprOrPatId) -> Self { - match value { +impl From<ExprOrPatIdPacked> for Span { + fn from(value: ExprOrPatIdPacked) -> Self { + match value.unpack() { ExprOrPatId::ExprId(idx) => idx.into(), ExprOrPatId::PatId(idx) => idx.into(), } diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs index 8cc59ecd0c..8292ea2cf7 100644 --- a/crates/hir-ty/src/mir/lower.rs +++ b/crates/hir-ty/src/mir/lower.rs @@ -1253,7 +1253,7 @@ impl<'a, 'db> MirLowerCtx<'a, 'db> { let span = |sources: &[CaptureSourceStack]| match sources .first() - .map(|it| it.final_source()) + .map(|it| it.final_source().unpack()) { Some(ExprOrPatId::ExprId(it)) => it.into(), Some(ExprOrPatId::PatId(it)) => it.into(), diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs index febd2a833a..70099945b5 100644 --- a/crates/hir-ty/src/tests.rs +++ b/crates/hir-ty/src/tests.rs @@ -204,7 +204,7 @@ fn check_impl( _ => None, }); for (expr_or_pat, expected, actual) in type_mismatches { - let Some(node) = (match expr_or_pat { + let Some(node) = (match expr_or_pat.unpack() { hir_def::hir::ExprOrPatId::ExprId(expr) => { expr_node(body_source_map, expr, &db) } diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs index 1fc556d04d..c951a5481c 100644 --- a/crates/hir-ty/src/tests/closure_captures.rs +++ b/crates/hir-ty/src/tests/closure_captures.rs @@ -125,7 +125,7 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec .info .sources .iter() - .flat_map(|span| match span.final_source() { + .flat_map(|span| match span.final_source().unpack() { ExprOrPatId::ExprId(expr) => { vec![text_range(db, source_map.expr_syntax(expr).unwrap())] } diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index b921a5eef1..422b37c67a 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs @@ -847,7 +847,7 @@ impl<'db> AnyDiagnostic<'db> { let span_syntax = |span| Self::span_syntax(span, source_map); Some(match d { &InferenceDiagnostic::NoSuchField { field: expr, private, variant } => { - let expr_or_pat = match expr { + let expr_or_pat = match expr.unpack() { ExprOrPatId::ExprId(expr) => { source_map.field_syntax(expr).map(AstPtr::wrap_left) } @@ -877,7 +877,7 @@ impl<'db> AnyDiagnostic<'db> { InvalidRangePatType { pat }.into() } &InferenceDiagnostic::DuplicateField { field: expr, variant } => { - let expr_or_pat = match expr { + let expr_or_pat = match expr.unpack() { ExprOrPatId::ExprId(expr) => { source_map.field_syntax(expr).map(AstPtr::wrap_left) } @@ -894,7 +894,7 @@ impl<'db> AnyDiagnostic<'db> { PrivateField { expr, field }.into() } &InferenceDiagnostic::PrivateAssocItem { id, item } => { - let expr_or_pat = expr_or_pat_syntax(id)?; + let expr_or_pat = expr_or_pat_syntax(id.unpack())?; let item = item.into(); PrivateAssocItem { expr_or_pat, item }.into() } @@ -937,11 +937,11 @@ impl<'db> AnyDiagnostic<'db> { .into() } &InferenceDiagnostic::UnresolvedAssocItem { id } => { - let expr_or_pat = expr_or_pat_syntax(id)?; + let expr_or_pat = expr_or_pat_syntax(id.unpack())?; UnresolvedAssocItem { expr_or_pat }.into() } &InferenceDiagnostic::UnresolvedIdent { id } => { - let node = match id { + let node = match id.unpack() { ExprOrPatId::ExprId(id) => match source_map.expr_syntax(id) { Ok(syntax) => syntax.map(|it| (it, None)), Err(SyntheticSyntax) => source_map @@ -1019,7 +1019,7 @@ impl<'db> AnyDiagnostic<'db> { Self::ty_diagnostic(diag, source_map, db)? } InferenceDiagnostic::PathDiagnostic { node, diag } => { - let source = expr_or_pat_syntax(*node)?; + let source = expr_or_pat_syntax(node.unpack())?; let syntax = source.value.to_node(&source.file_id.parse_or_expand(db)); let path = match_ast! { match (syntax.syntax()) { @@ -1100,7 +1100,7 @@ impl<'db> AnyDiagnostic<'db> { UnionExprMustHaveExactlyOneField { expr }.into() } InferenceDiagnostic::TypeMismatch { node, expected, found } => { - let expr_or_pat = expr_or_pat_syntax(*node)?; + let expr_or_pat = expr_or_pat_syntax(node.unpack())?; TypeMismatch { expr_or_pat, expected: Type { owner: type_owner, ty: EarlyBinder::bind(expected.as_ref()) }, @@ -1120,7 +1120,7 @@ impl<'db> AnyDiagnostic<'db> { Either::Left(expr) } ExplicitDropMethodUseKind::Path(path_expr_id) => { - let syntax = expr_or_pat_syntax(*path_expr_id)?; + let syntax = expr_or_pat_syntax(path_expr_id.unpack())?; let file_id = syntax.file_id; let syntax = syntax.with_value(syntax.value.cast::<ast::PathExpr>()?).to_node(db); diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 1ba73c180c..951728617d 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -5210,8 +5210,8 @@ impl CaptureUsages<'_> { let mut result = Vec::with_capacity(self.sources.len()); for source in self.sources { let source = source.final_source(); - let is_ref = Self::is_ref(store, source); - match source { + let is_ref = Self::is_ref(store, source.unpack()); + match source.unpack() { ExprOrPatId::ExprId(expr) => { if let Ok(expr) = source_map.expr_syntax(expr) { result.push(CaptureUsageSource { is_ref, source: expr }) diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index f7528d3db1..084b5d77d6 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -354,8 +354,10 @@ impl SourceToDefCtx<'_, '_> { let src = src.cloned().map(ast::Pat::from); let pat_id = source_map.node_pat(src.as_ref())?; // the pattern could resolve to a constant, verify that this is not the case - if let crate::Pat::Bind { id, .. } = store[pat_id.as_pat()?] { - let parent_infer = semantics.infer_body_for_expr_or_pat(container, store, pat_id)?; + let pat_id = pat_id.as_pat()?; + if let crate::Pat::Bind { id, .. } = store[pat_id] { + let parent_infer = + semantics.infer_body_for_expr_or_pat(container, store, pat_id.into())?; Some(crate::Local { parent: container, parent_infer, binding_id: id }) } else { None |