Skip to content

Commit

Permalink
Merge pull request #379 from dtolnay/subspan
Browse files Browse the repository at this point in the history
Implement Literal::subspan
  • Loading branch information
dtolnay authored Apr 1, 2023
2 parents e163e79 + daccddb commit 3310787
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 3 deletions.
4 changes: 4 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ fn main() {
println!("cargo:rustc-cfg=no_libprocmacro_unwind_safe");
}

if version.minor < 34 {
println!("cargo:rustc-cfg=no_try_from");
}

if version.minor < 39 {
println!("cargo:rustc-cfg=no_bind_by_move_pattern_guard");
}
Expand Down
19 changes: 19 additions & 0 deletions src/convert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pub(crate) fn usize_to_u32(u: usize) -> Option<u32> {
#[cfg(not(no_try_from))]
{
use core::convert::TryFrom;

u32::try_from(u).ok()
}

#[cfg(no_try_from)]
{
use core::mem;

if mem::size_of::<usize>() <= mem::size_of::<u32>() || u <= u32::max_value() as usize {
Some(u as u32)
} else {
None
}
}
}
42 changes: 40 additions & 2 deletions src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1012,8 +1012,46 @@ impl Literal {
self.span = span;
}

pub fn subspan<R: RangeBounds<usize>>(&self, _range: R) -> Option<Span> {
None
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
#[cfg(not(span_locations))]
{
let _ = range;
None
}

#[cfg(span_locations)]
{
use crate::convert::usize_to_u32;
use core::ops::Bound;

let lo = match range.start_bound() {
Bound::Included(start) => {
let start = usize_to_u32(*start)?;
self.span.lo.checked_add(start)?
}
Bound::Excluded(start) => {
let start = usize_to_u32(*start)?;
self.span.lo.checked_add(start)?.checked_add(1)?
}
Bound::Unbounded => self.span.lo,
};
let hi = match range.end_bound() {
Bound::Included(end) => {
let end = usize_to_u32(*end)?;
self.span.lo.checked_add(end)?.checked_add(1)?
}
Bound::Excluded(end) => {
let end = usize_to_u32(*end)?;
self.span.lo.checked_add(end)?
}
Bound::Unbounded => self.span.hi,
};
if lo <= hi && hi <= self.span.hi {
Some(Span { lo, hi })
} else {
None
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ use crate::fallback as imp;
#[cfg(wrap_proc_macro)]
mod imp;

#[cfg(span_locations)]
mod convert;
#[cfg(span_locations)]
mod location;

Expand Down
6 changes: 5 additions & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,12 @@ fn literal_parse() {
fn literal_span() {
let positive = "0.1".parse::<Literal>().unwrap();
let negative = "-0.1".parse::<Literal>().unwrap();
let subspan = positive.subspan(1..2);

#[cfg(not(span_locations))]
{
let _ = positive;
let _ = negative;
assert!(subspan.is_none());
}

#[cfg(span_locations)]
Expand All @@ -281,7 +282,10 @@ fn literal_span() {
assert_eq!(positive.span().end().column, 3);
assert_eq!(negative.span().start().column, 0);
assert_eq!(negative.span().end().column, 4);
assert_eq!(subspan.unwrap().source_text().unwrap(), ".");
}

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

#[test]
Expand Down

0 comments on commit 3310787

Please sign in to comment.