Rollup merge of #111571 - jhpratt:proc-macro-span, r=m-ou-se

Implement proposed API for `proc_macro_span`

As proposed in [#54725 (comment)](https://github.com/rust-lang/rust/issues/54725#issuecomment-1546918161). 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`
This commit is contained in:
Dylan DPC 2023-06-28 18:28:46 +05:30 committed by GitHub
commit fa56e01b35
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 74 additions and 129 deletions

View file

@ -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",
]

View file

@ -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};
@ -648,25 +648,24 @@ 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 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 before(&mut self, span: Self::Span) -> Self::Span {
fn start(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo()
}
fn after(&mut self, span: Self::Span) -> Self::Span {
fn end(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_hi()
}
fn line(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.line
}
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> {
let self_loc = self.sess().source_map().lookup_char_pos(first.lo());
let other_loc = self.sess().source_map().lookup_char_pos(second.lo());

View file

@ -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;
@ -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;
@ -299,7 +299,6 @@ mark_noop! {
Delimiter,
LitKind,
Level,
LineColumn,
Spacing,
}
@ -319,7 +318,6 @@ rpc_encode_decode!(
Help,
}
);
rpc_encode_decode!(struct LineColumn { line, column });
rpc_encode_decode!(
enum Spacing {
Alone,

View file

@ -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;
@ -494,28 +493,32 @@ impl Span {
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 {
self.0.start().add_1_to_column()
}
/// Gets the ending line/column in the source file for this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn end(&self) -> LineColumn {
self.0.end().add_1_to_column()
}
/// 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())
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn start(&self) -> Span {
Span(self.0.start())
}
/// 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())
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn end(&self) -> Span {
Span(self.0.end())
}
/// 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()
}
/// 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`.
@ -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)]

View file

@ -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",
]

View file

@ -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",
]

View file

@ -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",
]

View file

@ -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",
]

View file

@ -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",
]

View file

@ -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",
]

View file

@ -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;
@ -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)
@ -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 {

View file

@ -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]

View file

@ -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)

View file

@ -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, ':');

View file

@ -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();
}

View file

@ -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();