Skip to content

Commit

Permalink
Rollup merge of #111571 - jhpratt:proc-macro-span, r=m-ou-se
Browse files Browse the repository at this point in the history
Implement proposed API for `proc_macro_span`

As proposed in [#54725 (comment)](#54725 (comment)). I have omitted the byte-level API as it's already available as [`Span::byte_range`](https://doc.rust-lang.org/nightly/proc_macro/struct.Span.html#method.byte_range).

`@rustbot` label +A-proc-macros

r? `@m-ou-se`
  • Loading branch information
Dylan-DPC authored Jun 28, 2023
2 parents 8882507 + 6159075 commit fa56e01
Show file tree
Hide file tree
Showing 16 changed files with 68 additions and 123 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2580,9 +2580,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"

[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
23 changes: 11 additions & 12 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::base::ExtCtxt;
use pm::bridge::{
server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
};
use pm::{Delimiter, Level, LineColumn};
use pm::{Delimiter, Level};
use rustc_ast as ast;
use rustc_ast::token;
use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
Expand Down Expand Up @@ -648,23 +648,22 @@ impl server::Span for Rustc<'_, '_> {

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() }
fn start(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo()
}

fn end(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.hi());
LineColumn { line: loc.line, column: loc.col.to_usize() }
fn end(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_hi()
}

fn before(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo()
fn line(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.line
}

fn after(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_hi()
fn column(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.col.to_usize() + 1
}

fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
Expand Down
12 changes: 5 additions & 7 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#![deny(unsafe_code)]

use crate::{Delimiter, Level, LineColumn, Spacing};
use crate::{Delimiter, Level, Spacing};
use std::fmt;
use std::hash::Hash;
use std::marker;
Expand Down Expand Up @@ -95,10 +95,10 @@ macro_rules! with_api {
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;
fn after($self: $S::Span) -> $S::Span;
fn start($self: $S::Span) -> $S::Span;
fn end($self: $S::Span) -> $S::Span;
fn line($self: $S::Span) -> usize;
fn column($self: $S::Span) -> usize;
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;
Expand Down Expand Up @@ -299,7 +299,6 @@ mark_noop! {
Delimiter,
LitKind,
Level,
LineColumn,
Spacing,
}

Expand All @@ -319,7 +318,6 @@ rpc_encode_decode!(
Help,
}
);
rpc_encode_decode!(struct LineColumn { line, column });
rpc_encode_decode!(
enum Spacing {
Alone,
Expand Down
71 changes: 18 additions & 53 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ mod diagnostic;
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub use diagnostic::{Diagnostic, Level, MultiSpan};

use std::cmp::Ordering;
use std::ops::{Range, RangeBounds};
use std::path::PathBuf;
use std::str::FromStr;
Expand Down Expand Up @@ -494,28 +493,32 @@ impl Span {
self.0.byte_range()
}

/// Gets the starting line/column in the source file for this span.
/// Creates an empty span pointing to directly before this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn start(&self) -> LineColumn {
self.0.start().add_1_to_column()
pub fn start(&self) -> Span {
Span(self.0.start())
}

/// Gets the ending line/column in the source file for this span.
/// Creates an empty span pointing to directly after this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn end(&self) -> LineColumn {
self.0.end().add_1_to_column()
pub fn end(&self) -> Span {
Span(self.0.end())
}

/// Creates an empty span pointing to directly before this span.
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
pub fn before(&self) -> Span {
Span(self.0.before())
/// The one-indexed line of the source file where the span starts.
///
/// To obtain the line of the span's end, use `span.end().line()`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn line(&self) -> usize {
self.0.line()
}

/// Creates an empty span pointing to directly after this span.
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")]
pub fn after(&self) -> Span {
Span(self.0.after())
/// The one-indexed column of the source file where the span starts.
///
/// To obtain the column of the span's end, use `span.end().column()`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn column(&self) -> usize {
self.0.column()
}

/// Creates a new span encompassing `self` and `other`.
Expand Down Expand Up @@ -586,44 +589,6 @@ impl fmt::Debug for Span {
}
}

/// A line-column pair representing the start or end of a `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct LineColumn {
/// The 1-indexed line in the source file on which the span starts or ends (inclusive).
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub line: usize,
/// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
/// file on which the span starts or ends (inclusive).
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub column: usize,
}

impl LineColumn {
fn add_1_to_column(self) -> Self {
LineColumn { line: self.line, column: self.column + 1 }
}
}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Send for LineColumn {}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Sync for LineColumn {}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl Ord for LineColumn {
fn cmp(&self, other: &Self) -> Ordering {
self.line.cmp(&other.line).then(self.column.cmp(&other.column))
}
}

#[unstable(feature = "proc_macro_span", issue = "54725")]
impl PartialOrd for LineColumn {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}

/// The source file of a given `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Clone)]
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -527,9 +527,9 @@ dependencies = [

[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -529,9 +529,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"

[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/cargo-miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"

[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/test-cargo-miri/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ version = "0.1.0"

[[package]]
name = "proc-macro2"
version = "1.0.49"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/test_dependencies/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"

[[package]]
name = "proc-macro2"
version = "1.0.49"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
4 changes: 2 additions & 2 deletions src/tools/rust-analyzer/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1304,9 +1304,9 @@ version = "0.0.0"

[[package]]
name = "proc-macro2"
version = "1.0.56"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [
"unicode-ident",
]
Expand Down
27 changes: 13 additions & 14 deletions src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
//!
//! FIXME: No span and source file information is implemented yet

use proc_macro::{
bridge::{self, server},
LineColumn,
};
use proc_macro::bridge::{self, server};

mod token_stream;
pub use token_stream::TokenStream;
Expand Down Expand Up @@ -304,14 +301,6 @@ impl server::Span for RustAnalyzer {
// FIXME handle span
Range { start: 0, end: 0 }
}
fn start(&mut self, _span: Self::Span) -> LineColumn {
// FIXME handle span
LineColumn { line: 0, column: 0 }
}
fn end(&mut self, _span: Self::Span) -> LineColumn {
// FIXME handle span
LineColumn { line: 0, column: 0 }
}
fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
// Just return the first span again, because some macros will unwrap the result.
Some(first)
Expand All @@ -330,13 +319,23 @@ impl server::Span for RustAnalyzer {
tt::TokenId::unspecified()
}

fn after(&mut self, _self_: Self::Span) -> Self::Span {
fn end(&mut self, _self_: Self::Span) -> Self::Span {
tt::TokenId::unspecified()
}

fn before(&mut self, _self_: Self::Span) -> Self::Span {
fn start(&mut self, _self_: Self::Span) -> Self::Span {
tt::TokenId::unspecified()
}

fn line(&mut self, _span: Self::Span) -> usize {
// FIXME handle line
0
}

fn column(&mut self, _span: Self::Span) -> usize {
// FIXME handle column
0
}
}

impl server::Symbol for RustAnalyzer {
Expand Down
5 changes: 0 additions & 5 deletions tests/ui/macros/auxiliary/proc_macro_sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ extern crate proc_macro;

use proc_macro::{quote, Span, TokenStream, TokenTree};

fn assert_same_span(a: Span, b: Span) {
assert_eq!(a.start(), b.start());
assert_eq!(a.end(), b.end());
}

// This macro generates a macro with the same macro definition as `manual_foo` in
// `same-sequence-span.rs` but with the same span for all sequences.
#[proc_macro]
Expand Down
7 changes: 3 additions & 4 deletions tests/ui/macros/same-sequence-span.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ LL | $(= $z:tt)*
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
--> $DIR/same-sequence-span.rs:19:1
|
LL | | }
| |_________________________________^ not allowed after `expr` fragments
LL |
LL | proc_macro_sequence::make_foo!();
| ^-------------------------------
| |
| _in this macro invocation
| |
LL | |
LL | |
LL | | fn main() {}
| |_________________________________^ not allowed after `expr` fragments
|
= note: allowed there are: `=>`, `,` or `;`
= note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Expand Down
11 changes: 1 addition & 10 deletions tests/ui/proc-macro/auxiliary/api/cmp.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
use proc_macro::{LineColumn, Punct, Spacing};
use proc_macro::{Punct, Spacing};

pub fn test() {
test_line_column_ord();
test_punct_eq();
}

fn test_line_column_ord() {
let line0_column0 = LineColumn { line: 0, column: 0 };
let line0_column1 = LineColumn { line: 0, column: 1 };
let line1_column0 = LineColumn { line: 1, column: 0 };
assert!(line0_column0 < line0_column1);
assert!(line0_column1 < line1_column0);
}

fn test_punct_eq() {
let colon_alone = Punct::new(':', Spacing::Alone);
assert_eq!(colon_alone, ':');
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/proc-macro/auxiliary/assert-span-pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ pub fn assert_span_pos(input: TokenStream) -> TokenStream {
let line: usize = str1.parse().unwrap();
let col: usize = str2.parse().unwrap();

let sp1s = sp1.start();
if (line, col) != (sp1s.line, sp1s.column) {
if (line, col) != (sp1.line(), sp1.column()) {
let msg = format!("line/column mismatch: ({}, {}) != ({}, {})", line, col,
sp1s.line, sp1s.column);
sp1.line(), sp1.column());
sp1.error(msg).emit();
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/proc-macro/auxiliary/macro-only-syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter {

fn check_useful_span(token: TokenTree, expected_filename: &str) {
let span = token.span();
assert!(span.start().column < span.end().column);
assert!(span.column() < span.end().column());

let source_path = span.source_file().path();
let filename = source_path.components().last().unwrap();
Expand Down

0 comments on commit fa56e01

Please sign in to comment.