Skip to content

Commit 13ce62d

Browse files
authored
slint macro: Do not rely on the debug of Span to know if token are adjacent
We need to know if two Span are adjacent to distinguish between `foo-bar` and `foo - bar` (one identifier, or a minus expression) From Rust 1.88 it is possible to use the line and column information from Span. The eventual goal is also to address #685 unfortunately, rust-analyzer still do not implement these in their macro server
1 parent 241964d commit 13ce62d

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

api/rs/macros/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,26 @@ use std::path::PathBuf;
1919
/// it was written like so in the source code: `foo-` but not when written like so `foo -`
2020
///
2121
/// Returns None if we couldn't detect whether they are touching (eg, our heuristics don't work with rust-analyzer)
22+
#[rustversion::since(1.88)]
23+
fn are_token_touching(token1: proc_macro::Span, token2: proc_macro::Span) -> Option<bool> {
24+
let t1 = token1.end();
25+
let t2 = token2.start();
26+
let t1_column = t1.column();
27+
if t1_column == 1 && t1.line() == 1 && t2.end().line() == 1 && t2.end().column() == 1 {
28+
// If everything is 1, this means that Span::line and Span::column are not working properly
29+
// (eg, rust-analyzer)
30+
return None;
31+
}
32+
Some(t1.line() == t2.line() && t1_column == t2.column())
33+
}
34+
#[rustversion::before(1.88)]
2235
fn are_token_touching(token1: proc_macro::Span, token2: proc_macro::Span) -> Option<bool> {
2336
// There is no way with stable API to find out if the token are touching, so do it by
2437
// extracting the range from the debug representation of the span
2538
are_token_touching_impl(&format!("{token1:?}"), &format!("{token2:?}"))
2639
}
2740

41+
#[rustversion::before(1.88)]
2842
fn are_token_touching_impl(token1_debug: &str, token2_debug: &str) -> Option<bool> {
2943
// The debug representation of a span look like this: "#0 bytes(6662789..6662794)"
3044
// we just have to find out if the first number of the range of second span
@@ -47,6 +61,7 @@ fn are_token_touching_impl(token1_debug: &str, token2_debug: &str) -> Option<boo
4761
(!begin_of_token2.is_empty()).then_some(end_of_token1 == begin_of_token2)
4862
}
4963

64+
#[rustversion::before(1.88)]
5065
#[test]
5166
fn are_token_touching_impl_test() {
5267
assert!(are_token_touching_impl("#0 bytes(6662788..6662789)", "#0 bytes(6662789..6662794)")

0 commit comments

Comments
 (0)