Skip to content

Commit

Permalink
Auto merge of rust-lang#109002 - michaelvanstraten:master, r=petroche…
Browse files Browse the repository at this point in the history
…nkov

Added byte position range for `proc_macro::Span`

Currently, the [`Debug`](https://doc.rust-lang.org/beta/proc_macro/struct.Span.html#impl-Debug-for-Span) implementation for [`proc_macro::Span`](https://doc.rust-lang.org/beta/proc_macro/struct.Span.html#) calls the debug function implemented in the trait implementation of `server::Span` for the type `Rustc` in the `rustc-expand` crate.

The current implementation, of the referenced function, looks something like this:
```rust
fn debug(&mut self, span: Self::Span) -> String {
    if self.ecx.ecfg.span_debug {
        format!("{:?}", span)
    } else {
        format!("{:?} bytes({}..{})", span.ctxt(), span.lo().0, span.hi().0)
    }
}
```

It returns the byte position of the [`Span`](https://doc.rust-lang.org/beta/proc_macro/struct.Span.html#) as an interpolated string.

Because this is currently the only way to get a spans position in the file, I might lead someone, who is interested in this information, to parsing this interpolated string back into a range of bytes, which I think is a very non-rusty way.

The proposed `position()`, method implemented in this PR, gives the ability to directly get this info.
It returns a [`std::ops::Range`](https://doc.rust-lang.org/std/ops/struct.Range.html#) wrapping the lowest and highest byte of the [`Span`](https://doc.rust-lang.org/beta/proc_macro/struct.Span.html#).

I put it behind the `proc_macro_span` feature flag because many of the other functions that have a similar footprint also are annotated with it, I don't actually know if this is right.

It would be great if somebody could take a look at this, thank you very much in advanced.
  • Loading branch information
bors committed Apr 21, 2023
2 parents 1f5768b + 342c5fb commit 1151ea6
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
11 changes: 10 additions & 1 deletion compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_span::def_id::CrateNum;
use rustc_span::symbol::{self, sym, Symbol};
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};
use smallvec::{smallvec, SmallVec};
use std::ops::Bound;
use std::ops::{Bound, Range};

trait FromInternal<T> {
fn from_internal(x: T) -> Self;
Expand Down Expand Up @@ -634,6 +634,15 @@ impl server::Span for Rustc<'_, '_> {
span.source_callsite()
}

fn byte_range(&mut self, span: Self::Span) -> Range<usize> {
let source_map = self.sess().source_map();

let relative_start_pos = source_map.lookup_byte_offset(span.lo()).pos;
let relative_end_pos = source_map.lookup_byte_offset(span.hi()).pos;

Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
}

fn start(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
LineColumn { line: loc.line, column: loc.col.to_usize() }
Expand Down
6 changes: 6 additions & 0 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::hash::Hash;
use std::marker;
use std::mem;
use std::ops::Bound;
use std::ops::Range;
use std::panic;
use std::sync::atomic::AtomicUsize;
use std::sync::Once;
Expand Down Expand Up @@ -93,6 +94,7 @@ macro_rules! with_api {
fn source_file($self: $S::Span) -> $S::SourceFile;
fn parent($self: $S::Span) -> Option<$S::Span>;
fn source($self: $S::Span) -> $S::Span;
fn byte_range($self: $S::Span) -> Range<usize>;
fn start($self: $S::Span) -> LineColumn;
fn end($self: $S::Span) -> LineColumn;
fn before($self: $S::Span) -> $S::Span;
Expand Down Expand Up @@ -519,3 +521,7 @@ pub struct ExpnGlobals<Span> {
compound_traits!(
struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
);

compound_traits!(
struct Range<T> { start, end }
);
8 changes: 7 additions & 1 deletion library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ mod diagnostic;
pub use diagnostic::{Diagnostic, Level, MultiSpan};

use std::cmp::Ordering;
use std::ops::RangeBounds;
use std::ops::{Range, RangeBounds};
use std::path::PathBuf;
use std::str::FromStr;
use std::{error, fmt};
Expand Down Expand Up @@ -488,6 +488,12 @@ impl Span {
Span(self.0.source())
}

/// Returns the span's byte position range in the source file.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn byte_range(&self) -> Range<usize> {
self.0.byte_range()
}

/// Gets the starting line/column in the source file for this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn start(&self) -> LineColumn {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use token_stream::TokenStreamBuilder;
mod symbol;
pub use symbol::*;

use std::ops::Bound;
use std::ops::{Bound, Range};

use crate::tt;

Expand Down Expand Up @@ -298,6 +298,10 @@ impl server::Span for RustAnalyzer {
// FIXME handle span
span
}
fn byte_range(&mut self, _span: Self::Span) -> Range<usize> {
// FIXME handle span
Range { start: 0, end: 0 }
}
fn start(&mut self, _span: Self::Span) -> LineColumn {
// FIXME handle span
LineColumn { line: 0, column: 0 }
Expand Down

0 comments on commit 1151ea6

Please sign in to comment.