Skip to content

Commit

Permalink
Auto merge of rust-lang#87712 - est31:line-column-1-based, r=petroche…
Browse files Browse the repository at this point in the history
…nkov

Proc macro spans: make columns 1 based

This makes proc macro spans consistent with the `column!()` macro as well as `std::panic::Location`, as both are 1-based.

rust-lang#54725 (comment)
  • Loading branch information
bors committed Aug 4, 2021
2 parents bb744e1 + 7d20789 commit 71ff9b4
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 4 deletions.
14 changes: 10 additions & 4 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,13 @@ impl Span {
/// 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()
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()
self.0.end().add_1_to_column()
}

/// Creates a new span encompassing `self` and `other`.
Expand Down Expand Up @@ -432,12 +432,18 @@ 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 0-indexed column (in UTF-8 characters) in the source file on which
/// the span starts or ends (inclusive).
/// 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")]
Expand Down
37 changes: 37 additions & 0 deletions src/test/ui/proc-macro/auxiliary/assert-span-pos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// force-host
// no-prefer-dynamic

#![feature(proc_macro_diagnostic, proc_macro_span)]
#![crate_type = "proc-macro"]

extern crate proc_macro;

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

fn lit_span(tt: TokenTree) -> (Span, String) {
match tt {
TokenTree::Literal(..) |
TokenTree::Group(..) => (tt.span(), tt.to_string().trim().into()),
_ => panic!("expected a literal in token tree, got: {:?}", tt)
}
}

#[proc_macro]
pub fn assert_span_pos(input: TokenStream) -> TokenStream {
let mut tokens = input.into_iter();
let (sp1, str1) = lit_span(tokens.next().expect("first argument"));
let _ = tokens.next();
let (_sp2, str2) = lit_span(tokens.next().expect("second argument"));

let line: usize = str1.parse().unwrap();
let col: usize = str2.parse().unwrap();

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

"".parse().unwrap()
}
24 changes: 24 additions & 0 deletions src/test/ui/proc-macro/span-absolute-posititions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// aux-build:assert-span-pos.rs
// ignore-tidy-tab
extern crate assert_span_pos;

assert_span_pos::assert_span_pos!(5, 35);

// Test space indentation
assert_span_pos::assert_span_pos!(8, 39);
// Test tab indentation
assert_span_pos::assert_span_pos!(10, 36);

// Two tests to ensure the promise of the docs that the column is the number
// of UTF-8 bytes instead of some other number like number of code points.

// Test that multi byte UTF-8 characters indeed count as multiple bytes
/*🌈*/assert_span_pos::assert_span_pos!(16, 40);
// Test with a complete grapheme cluster
/*🏳️‍🌈*/assert_span_pos::assert_span_pos!(18, 43);

// Test that the macro actually emits an error on a mismatch:
assert_span_pos::assert_span_pos!(0, 35); //~ ERROR line/column mismatch: (0, 35) != (21, 35)
assert_span_pos::assert_span_pos!(22, 0); //~ ERROR line/column mismatch: (22, 0) != (22, 35)

fn main() {}
14 changes: 14 additions & 0 deletions src/test/ui/proc-macro/span-absolute-posititions.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: line/column mismatch: (0, 35) != (21, 35)
--> $DIR/span-absolute-posititions.rs:21:35
|
LL | assert_span_pos::assert_span_pos!(0, 35);
| ^

error: line/column mismatch: (22, 0) != (22, 35)
--> $DIR/span-absolute-posititions.rs:22:35
|
LL | assert_span_pos::assert_span_pos!(22, 0);
| ^^

error: aborting due to 2 previous errors

0 comments on commit 71ff9b4

Please sign in to comment.