Skip to content

Fix dangling definitions after document deletion#710

Merged
st0012 merged 1 commit intomainfrom
fix-dangling-definitions
Apr 1, 2026
Merged

Fix dangling definitions after document deletion#710
st0012 merged 1 commit intomainfrom
fix-dangling-definitions

Conversation

@st0012
Copy link
Copy Markdown
Member

@st0012 st0012 commented Mar 31, 2026

Summary

Found by the incremental consistency testing tool.

  • When remove_document_data removes definitions from the definitions map, declarations still reference them via their definition_ids list. The resolver later panics when trying to access the removed definition.
  • After detaching definitions handled by pending_detachments, scan for the remainder that definition_to_declaration_id can't resolve (e.g. methods inside class << self when the singleton name was unresolved, instance variables in class body owned by the singleton, or definitions whose enclosing namespace name chain is broken) and detach those by sweeping declarations.

@st0012 st0012 force-pushed the fix-dangling-definitions branch from 1a6553a to e5e956a Compare March 31, 2026 20:56
@st0012 st0012 marked this pull request as ready for review March 31, 2026 20:58
@st0012 st0012 requested a review from a team as a code owner March 31, 2026 20:58
@st0012 st0012 self-assigned this Mar 31, 2026
Copy link
Copy Markdown
Member

@vinistock vinistock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall PR looks good, but let's please avoid exposing mutable state in a generic way

Comment thread rust/rubydex/src/model/graph.rs Outdated
Comment on lines +969 to +979
// Build a set of definition IDs being removed so we can detach them from declarations.
let removed_def_ids: IdentityHashSet<DefinitionId> = document.definitions().iter().copied().collect();

// Detach removed definitions from their declarations. We iterate all declarations
// rather than trying to map definitions → declarations (which is lossy for methods,
// instance variables, etc. that `definition_to_declaration_id` can't always resolve).
for declaration in self.declarations.values_mut() {
declaration
.definitions_mut()
.retain(|def_id| !removed_def_ids.contains(def_id));
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of exposing generic mutable APIs from our structs. Would it be possible to do this (especially since this API already exists)?

// May need to copy due to borrow checks
for def_id in document.definitions() {
  declaration.remove_definition(def_id);
}

@st0012 st0012 force-pushed the fix-dangling-definitions branch 3 times, most recently from 363f9f0 to ebbaf7f Compare April 1, 2026 16:12
When remove_document_data removes definitions from self.definitions,
declarations still reference them via their definition_ids list. The
resolver later panics when trying to access the removed definition.

Add retain_definitions sweep in remove_document_data to detach
definitions from ALL declarations before removing them from the
definitions map.
@st0012 st0012 force-pushed the fix-dangling-definitions branch from ebbaf7f to 4473183 Compare April 1, 2026 16:39
@st0012 st0012 merged commit 1355c53 into main Apr 1, 2026
36 checks passed
@st0012 st0012 deleted the fix-dangling-definitions branch April 1, 2026 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants