about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/proc_macro/src/lib.rs14
-rw-r--r--src/test/ui/proc-macro/auxiliary/assert-span-pos.rs37
-rw-r--r--src/test/ui/proc-macro/span-absolute-posititions.rs24
-rw-r--r--src/test/ui/proc-macro/span-absolute-posititions.stderr14
4 files changed, 85 insertions, 4 deletions
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 46f564199d0..f25e257bf31 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -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`.
@@ -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")]
diff --git a/src/test/ui/proc-macro/auxiliary/assert-span-pos.rs b/src/test/ui/proc-macro/auxiliary/assert-span-pos.rs
new file mode 100644
index 00000000000..455c5c7c380
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/assert-span-pos.rs
@@ -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()
+}
diff --git a/src/test/ui/proc-macro/span-absolute-posititions.rs b/src/test/ui/proc-macro/span-absolute-posititions.rs
new file mode 100644
index 00000000000..6d70fe611c4
--- /dev/null
+++ b/src/test/ui/proc-macro/span-absolute-posititions.rs
@@ -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() {}
diff --git a/src/test/ui/proc-macro/span-absolute-posititions.stderr b/src/test/ui/proc-macro/span-absolute-posititions.stderr
new file mode 100644
index 00000000000..6aca44a6b57
--- /dev/null
+++ b/src/test/ui/proc-macro/span-absolute-posititions.stderr
@@ -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
+