mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
fix: correct extend_to logic in parser
Previously we swapped to events in the buffer, but that might be wrong if there aer `forward_parent` links pointing to the swapped-out node. Let's do the same via parent links instead, keeping the nodes in place
This commit is contained in:
parent
6997adfee7
commit
7dc331faef
2 changed files with 11 additions and 9 deletions
|
@ -93,8 +93,6 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec<Event>) {
|
||||||
|
|
||||||
for i in 0..events.len() {
|
for i in 0..events.len() {
|
||||||
match mem::replace(&mut events[i], Event::tombstone()) {
|
match mem::replace(&mut events[i], Event::tombstone()) {
|
||||||
Event::Start { kind: TOMBSTONE, .. } => (),
|
|
||||||
|
|
||||||
Event::Start { kind, forward_parent } => {
|
Event::Start { kind, forward_parent } => {
|
||||||
// For events[A, B, C], B is A's forward_parent, C is B's forward_parent,
|
// For events[A, B, C], B is A's forward_parent, C is B's forward_parent,
|
||||||
// in the normal control flow, the parent-child relation: `A -> B -> C`,
|
// in the normal control flow, the parent-child relation: `A -> B -> C`,
|
||||||
|
@ -109,9 +107,7 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec<Event>) {
|
||||||
// append `A`'s forward_parent `B`
|
// append `A`'s forward_parent `B`
|
||||||
fp = match mem::replace(&mut events[idx], Event::tombstone()) {
|
fp = match mem::replace(&mut events[idx], Event::tombstone()) {
|
||||||
Event::Start { kind, forward_parent } => {
|
Event::Start { kind, forward_parent } => {
|
||||||
if kind != TOMBSTONE {
|
forward_parents.push(kind);
|
||||||
forward_parents.push(kind);
|
|
||||||
}
|
|
||||||
forward_parent
|
forward_parent
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -120,7 +116,9 @@ pub(super) fn process(sink: &mut dyn TreeSink, mut events: Vec<Event>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for kind in forward_parents.drain(..).rev() {
|
for kind in forward_parents.drain(..).rev() {
|
||||||
sink.start_node(kind);
|
if kind != TOMBSTONE {
|
||||||
|
sink.start_node(kind);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Finish => sink.finish_node(),
|
Event::Finish => sink.finish_node(),
|
||||||
|
|
|
@ -340,10 +340,14 @@ impl CompletedMarker {
|
||||||
|
|
||||||
/// Extends this completed marker *to the left* up to `m`.
|
/// Extends this completed marker *to the left* up to `m`.
|
||||||
pub(crate) fn extend_to(self, p: &mut Parser, mut m: Marker) {
|
pub(crate) fn extend_to(self, p: &mut Parser, mut m: Marker) {
|
||||||
assert!(m.pos <= self.pos);
|
|
||||||
m.bomb.defuse();
|
m.bomb.defuse();
|
||||||
|
let idx = m.pos as usize;
|
||||||
p.events.swap(self.pos as usize, m.pos as usize);
|
match &mut p.events[idx] {
|
||||||
|
Event::Start { forward_parent, .. } => {
|
||||||
|
*forward_parent = Some(self.pos - m.pos);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn kind(&self) -> SyntaxKind {
|
pub(crate) fn kind(&self) -> SyntaxKind {
|
||||||
|
|
Loading…
Reference in a new issue