@@ -4,6 +4,7 @@ use std::{
4
4
ops:: { Bound , Range } ,
5
5
} ;
6
6
7
+ use :: tt:: { TextRange , TextSize } ;
7
8
use proc_macro:: bridge:: { self , server} ;
8
9
use span:: Span ;
9
10
@@ -241,11 +242,11 @@ impl server::Span for RaSpanServer {
241
242
SourceFile { }
242
243
}
243
244
fn save_span ( & mut self , _span : Self :: Span ) -> usize {
244
- // FIXME stub
245
+ // FIXME stub, requires builtin quote! implementation
245
246
0
246
247
}
247
248
fn recover_proc_macro_span ( & mut self , _id : usize ) -> Self :: Span {
248
- // FIXME stub
249
+ // FIXME stub, requires builtin quote! implementation
249
250
self . call_site
250
251
}
251
252
/// Recent feature, not yet in the proc_macro
@@ -289,32 +290,64 @@ impl server::Span for RaSpanServer {
289
290
fn subspan (
290
291
& mut self ,
291
292
span : Self :: Span ,
292
- _start : Bound < usize > ,
293
- _end : Bound < usize > ,
293
+ start : Bound < usize > ,
294
+ end : Bound < usize > ,
294
295
) -> 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
+ } )
297
330
}
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 }
301
334
}
302
335
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 }
305
338
}
306
339
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 }
309
342
}
310
343
311
344
fn line ( & mut self , _span : Self :: Span ) -> usize {
312
- // FIXME handle line
345
+ // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
313
346
0
314
347
}
315
348
316
349
fn column ( & mut self , _span : Self :: Span ) -> usize {
317
- // FIXME handle column
350
+ // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL
318
351
0
319
352
}
320
353
}
0 commit comments