@@ -4,6 +4,7 @@ use std::{
44 ops:: { Bound , Range } ,
55} ;
66
7+ use :: tt:: { TextRange , TextSize } ;
78use proc_macro:: bridge:: { self , server} ;
89use span:: Span ;
910
@@ -241,11 +242,11 @@ impl server::Span for RaSpanServer {
241242 SourceFile { }
242243 }
243244 fn save_span ( & mut self , _span : Self :: Span ) -> usize {
244- // FIXME stub
245+ // FIXME stub, requires builtin quote! implementation
245246 0
246247 }
247248 fn recover_proc_macro_span ( & mut self , _id : usize ) -> Self :: Span {
248- // FIXME stub
249+ // FIXME stub, requires builtin quote! implementation
249250 self . call_site
250251 }
251252 /// Recent feature, not yet in the proc_macro
@@ -289,32 +290,64 @@ impl server::Span for RaSpanServer {
289290 fn subspan (
290291 & mut self ,
291292 span : Self :: Span ,
292- _start : Bound < usize > ,
293- _end : Bound < usize > ,
293+ start : Bound < usize > ,
294+ end : Bound < usize > ,
294295 ) -> Option < Self :: Span > {
295- // Just return the span again, because some macros will unwrap the result.
296- Some ( span)
296+ // FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL as it works on absolute
297+ // ranges
298+ let length = span. range . len ( ) . into ( ) ;
299+
300+ let start: u32 = match start {
301+ Bound :: Included ( lo) => lo,
302+ Bound :: Excluded ( lo) => lo. checked_add ( 1 ) ?,
303+ Bound :: Unbounded => 0 ,
304+ }
305+ . try_into ( )
306+ . ok ( ) ?;
307+
308+ let end: u32 = match end {
309+ Bound :: Included ( hi) => hi. checked_add ( 1 ) ?,
310+ Bound :: Excluded ( hi) => hi,
311+ Bound :: Unbounded => span. range . len ( ) . into ( ) ,
312+ }
313+ . try_into ( )
314+ . ok ( ) ?;
315+
316+ // Bounds check the values, preventing addition overflow and OOB spans.
317+ let span_start = span. range . start ( ) . into ( ) ;
318+ if ( u32:: MAX - start) < span_start
319+ || ( u32:: MAX - end) < span_start
320+ || start >= end
321+ || end > length
322+ {
323+ return None ;
324+ }
325+
326+ Some ( Span {
327+ range : TextRange :: new ( TextSize :: from ( start) , TextSize :: from ( end) ) + span. range . start ( ) ,
328+ ..span
329+ } )
297330 }
298- fn resolved_at ( & mut self , _span : Self :: Span , _at : Self :: Span ) -> Self :: Span {
299- // FIXME handle span
300- self . call_site
331+
332+ fn resolved_at ( & mut self , span : Self :: Span , at : Self :: Span ) -> Self :: Span {
333+ Span { ctx : at . ctx , ..span }
301334 }
302335
303- fn end ( & mut self , _self_ : Self :: Span ) -> Self :: Span {
304- self . call_site
336+ fn end ( & mut self , span : Self :: Span ) -> Self :: Span {
337+ Span { range : TextRange :: empty ( span . range . end ( ) ) , ..span }
305338 }
306339
307- fn start ( & mut self , _self_ : Self :: Span ) -> Self :: Span {
308- self . call_site
340+ fn start ( & mut self , span : Self :: Span ) -> Self :: Span {
341+ Span { range : TextRange :: empty ( span . range . start ( ) ) , ..span }
309342 }
310343
311344 fn line ( & mut self , _span : Self :: Span ) -> usize {
312- // FIXME handle line
345+ // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
313346 0
314347 }
315348
316349 fn column ( & mut self , _span : Self :: Span ) -> usize {
317- // FIXME handle column
350+ // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
318351 0
319352 }
320353}
0 commit comments