Skip to content

Commit daccddb

Browse files
committed
Implement Literal::subspan
1 parent c1cf0f8 commit daccddb

File tree

5 files changed

+66
-3
lines changed

5 files changed

+66
-3
lines changed

build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ fn main() {
7272
println!("cargo:rustc-cfg=no_libprocmacro_unwind_safe");
7373
}
7474

75+
if version.minor < 34 {
76+
println!("cargo:rustc-cfg=no_try_from");
77+
}
78+
7579
if version.minor < 39 {
7680
println!("cargo:rustc-cfg=no_bind_by_move_pattern_guard");
7781
}

src/convert.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pub(crate) fn usize_to_u32(u: usize) -> Option<u32> {
2+
#[cfg(not(no_try_from))]
3+
{
4+
use core::convert::TryFrom;
5+
6+
u32::try_from(u).ok()
7+
}
8+
9+
#[cfg(no_try_from)]
10+
{
11+
use core::mem;
12+
13+
if mem::size_of::<usize>() <= mem::size_of::<u32>() || u <= u32::max_value() as usize {
14+
Some(u as u32)
15+
} else {
16+
None
17+
}
18+
}
19+
}

src/fallback.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,8 +1012,46 @@ impl Literal {
10121012
self.span = span;
10131013
}
10141014

1015-
pub fn subspan<R: RangeBounds<usize>>(&self, _range: R) -> Option<Span> {
1016-
None
1015+
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
1016+
#[cfg(not(span_locations))]
1017+
{
1018+
let _ = range;
1019+
None
1020+
}
1021+
1022+
#[cfg(span_locations)]
1023+
{
1024+
use crate::convert::usize_to_u32;
1025+
use core::ops::Bound;
1026+
1027+
let lo = match range.start_bound() {
1028+
Bound::Included(start) => {
1029+
let start = usize_to_u32(*start)?;
1030+
self.span.lo.checked_add(start)?
1031+
}
1032+
Bound::Excluded(start) => {
1033+
let start = usize_to_u32(*start)?;
1034+
self.span.lo.checked_add(start)?.checked_add(1)?
1035+
}
1036+
Bound::Unbounded => self.span.lo,
1037+
};
1038+
let hi = match range.end_bound() {
1039+
Bound::Included(end) => {
1040+
let end = usize_to_u32(*end)?;
1041+
self.span.lo.checked_add(end)?.checked_add(1)?
1042+
}
1043+
Bound::Excluded(end) => {
1044+
let end = usize_to_u32(*end)?;
1045+
self.span.lo.checked_add(end)?
1046+
}
1047+
Bound::Unbounded => self.span.hi,
1048+
};
1049+
if lo <= hi && hi <= self.span.hi {
1050+
Some(Span { lo, hi })
1051+
} else {
1052+
None
1053+
}
1054+
}
10171055
}
10181056
}
10191057

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ use crate::fallback as imp;
142142
#[cfg(wrap_proc_macro)]
143143
mod imp;
144144

145+
#[cfg(span_locations)]
146+
mod convert;
145147
#[cfg(span_locations)]
146148
mod location;
147149

tests/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ fn literal_span() {
282282
assert_eq!(positive.span().end().column, 3);
283283
assert_eq!(negative.span().start().column, 0);
284284
assert_eq!(negative.span().end().column, 4);
285-
assert_eq!(subspan.unwrap().source_text().unwrap(), "."); // FIXME
285+
assert_eq!(subspan.unwrap().source_text().unwrap(), ".");
286286
}
287287

288288
assert!(positive.subspan(1..4).is_none());

0 commit comments

Comments
 (0)