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:
commit
fa56e01b35
16 changed files with 74 additions and 129 deletions
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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, ':');
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue