Skip to content

Commit

Permalink
proc_macro: Move subspan to be a method on Span in the bridge
Browse files Browse the repository at this point in the history
This method is still only used for Literal::subspan, however the
implementation only depends on the Span component, so it is simpler and
more efficient for now to pass down only the information that is needed.
In the future, if more information about the Literal is required in the
implementation (e.g. to validate that spans line up as expected with
source text), that extra information can be added back with extra
arguments.
  • Loading branch information
mystor committed Jul 18, 2022
1 parent b34c79f commit c4acac6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 44 deletions.
73 changes: 36 additions & 37 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,43 +436,6 @@ impl server::FreeFunctions for Rustc<'_, '_> {
span: self.call_site,
})
}

fn literal_subspan(
&mut self,
literal: Literal<Self::Span, Self::Symbol>,
start: Bound<usize>,
end: Bound<usize>,
) -> Option<Self::Span> {
let span = literal.span;
let length = span.hi().to_usize() - span.lo().to_usize();

let start = match start {
Bound::Included(lo) => lo,
Bound::Excluded(lo) => lo.checked_add(1)?,
Bound::Unbounded => 0,
};

let end = match end {
Bound::Included(hi) => hi.checked_add(1)?,
Bound::Excluded(hi) => hi,
Bound::Unbounded => length,
};

// Bounds check the values, preventing addition overflow and OOB spans.
if start > u32::MAX as usize
|| end > u32::MAX as usize
|| (u32::MAX - start as u32) < span.lo().to_u32()
|| (u32::MAX - end as u32) < span.lo().to_u32()
|| start >= end
|| end > length
{
return None;
}

let new_lo = span.lo() + BytePos::from_usize(start);
let new_hi = span.lo() + BytePos::from_usize(end);
Some(span.with_lo(new_lo).with_hi(new_hi))
}
}

impl server::TokenStream for Rustc<'_, '_> {
Expand Down Expand Up @@ -697,6 +660,42 @@ impl server::Span for Rustc<'_, '_> {
Some(first.to(second))
}

fn subspan(
&mut self,
span: Self::Span,
start: Bound<usize>,
end: Bound<usize>,
) -> Option<Self::Span> {
let length = span.hi().to_usize() - span.lo().to_usize();

let start = match start {
Bound::Included(lo) => lo,
Bound::Excluded(lo) => lo.checked_add(1)?,
Bound::Unbounded => 0,
};

let end = match end {
Bound::Included(hi) => hi.checked_add(1)?,
Bound::Excluded(hi) => hi,
Bound::Unbounded => length,
};

// Bounds check the values, preventing addition overflow and OOB spans.
if start > u32::MAX as usize
|| end > u32::MAX as usize
|| (u32::MAX - start as u32) < span.lo().to_u32()
|| (u32::MAX - end as u32) < span.lo().to_u32()
|| start >= end
|| end > length
{
return None;
}

let new_lo = span.lo() + BytePos::from_usize(start);
let new_hi = span.lo() + BytePos::from_usize(end);
Some(span.with_lo(new_lo).with_hi(new_hi))
}

fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span {
span.with_ctxt(at.ctxt())
}
Expand Down
2 changes: 1 addition & 1 deletion library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ macro_rules! with_api {
fn track_env_var(var: &str, value: Option<&str>);
fn track_path(path: &str);
fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>;
fn literal_subspan(lit: Literal<$S::Span, $S::Symbol>, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
},
TokenStream {
fn drop($self: $S::TokenStream);
Expand Down Expand Up @@ -114,6 +113,7 @@ macro_rules! with_api {
fn before($self: $S::Span) -> $S::Span;
fn after($self: $S::Span) -> $S::Span;
fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
fn source_text($self: $S::Span) -> Option<String>;
fn save_span($self: $S::Span) -> usize;
Expand Down
7 changes: 1 addition & 6 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1379,12 +1379,7 @@ impl Literal {
// was 'c' or whether it was '\u{63}'.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
bridge::client::FreeFunctions::literal_subspan(
self.0.clone(),
range.start_bound().cloned(),
range.end_bound().cloned(),
)
.map(Span)
self.0.span.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
}

fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
Expand Down

0 comments on commit c4acac6

Please sign in to comment.