diff options
| author | bors <bors@rust-lang.org> | 2023-12-12 21:08:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-12 21:08:52 +0000 |
| commit | 5d7453ccd6e885b688b0bfcc6daca843e1f62c90 (patch) | |
| tree | 7b5a551e35d801e6be819229546d523e111a2c80 | |
| parent | 98a8053143b4f67b8a2c8f5fb8acb1834295c357 (diff) | |
| parent | c209b5f97c35c6d5e9a0f6868edbed1665acbdc7 (diff) | |
| download | rust-5d7453ccd6e885b688b0bfcc6daca843e1f62c90.tar.gz rust-5d7453ccd6e885b688b0bfcc6daca843e1f62c90.zip | |
Auto merge of #16106 - Veykril:fix-lifetime-span-split, r=Veykril
fix: Fix syntax bridge assigning invalid span to lifetime tokens Fixes https://github.com/rust-lang/rust-analyzer/issues/16097 Fixes https://github.com/rust-lang/rust-analyzer/issues/16103
| -rw-r--r-- | crates/hir-expand/src/span.rs | 29 | ||||
| -rw-r--r-- | crates/mbe/src/syntax_bridge.rs | 21 |
2 files changed, 22 insertions, 28 deletions
diff --git a/crates/hir-expand/src/span.rs b/crates/hir-expand/src/span.rs index 0a6c22fe42d..fe476a40feb 100644 --- a/crates/hir-expand/src/span.rs +++ b/crates/hir-expand/src/span.rs @@ -75,27 +75,40 @@ pub struct RealSpanMap { /// Invariant: Sorted vec over TextSize // FIXME: SortedVec<(TextSize, ErasedFileAstId)>? pairs: Box<[(TextSize, ErasedFileAstId)]>, + end: TextSize, } impl RealSpanMap { /// Creates a real file span map that returns absolute ranges (relative ranges to the root ast id). pub fn absolute(file_id: FileId) -> Self { - RealSpanMap { file_id, pairs: Box::from([(TextSize::new(0), ROOT_ERASED_FILE_AST_ID)]) } + RealSpanMap { + file_id, + pairs: Box::from([(TextSize::new(0), ROOT_ERASED_FILE_AST_ID)]), + end: TextSize::new(!0), + } } pub fn from_file(db: &dyn ExpandDatabase, file_id: FileId) -> Self { let mut pairs = vec![(TextSize::new(0), ROOT_ERASED_FILE_AST_ID)]; let ast_id_map = db.ast_id_map(file_id.into()); - pairs.extend( - db.parse(file_id) - .tree() - .items() - .map(|item| (item.syntax().text_range().start(), ast_id_map.ast_id(&item).erase())), - ); - RealSpanMap { file_id, pairs: pairs.into_boxed_slice() } + let tree = db.parse(file_id).tree(); + pairs + .extend(tree.items().map(|item| { + (item.syntax().text_range().start(), ast_id_map.ast_id(&item).erase()) + })); + RealSpanMap { + file_id, + pairs: pairs.into_boxed_slice(), + end: tree.syntax().text_range().end(), + } } pub fn span_for_range(&self, range: TextRange) -> SpanData { + assert!( + range.end() <= self.end, + "range {range:?} goes beyond the end of the file {:?}", + self.end + ); let start = range.start(); let idx = self .pairs diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index 1c46471a383..b89bfd74a6e 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs @@ -311,7 +311,7 @@ where let ident = tt::Leaf::from(tt::Ident { text: SmolStr::new(&token.to_text(conv)[1..]), - span: conv.span_for(TextRange::at( + span: conv.span_for(TextRange::new( abs_range.start() + TextSize::of('\''), abs_range.end(), )), @@ -625,25 +625,6 @@ impl<SpanMap, S> Converter<SpanMap, S> { } fn next_token(&mut self) -> Option<SyntaxToken> { - // while let Some(ev) = self.preorder.next() { - // match ev { - // WalkEvent::Enter(SyntaxElement::Token(t)) => { - // if let Some(leafs) = self.append.remove(&t.clone().into()) { - // self.current_leafs.extend(leafs); - // } - // return Some(t); - // } - // WalkEvent::Enter(SyntaxElement::Node(n)) if self.remove.contains(&n) => { - // self.preorder.skip_subtree(); - // if let Some(leafs) = self.append.remove(&n.into()) { - // self.current_leafs.extend(leafs); - // } - // } - // _ => (), - // } - // } - // None; - while let Some(ev) = self.preorder.next() { match ev { WalkEvent::Enter(SyntaxElement::Token(t)) => return Some(t), |
