summaryrefslogtreecommitdiffstats
path: root/src/test/incremental/issue-85197-invalid-span
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/incremental/issue-85197-invalid-span
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/incremental/issue-85197-invalid-span')
-rw-r--r--src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs11
-rw-r--r--src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-mod.rs14
-rw-r--r--src/test/incremental/issue-85197-invalid-span/auxiliary/respan.rs19
-rw-r--r--src/test/incremental/issue-85197-invalid-span/invalid_span_main.rs24
4 files changed, 68 insertions, 0 deletions
diff --git a/src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs b/src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs
new file mode 100644
index 000000000..2453af5b6
--- /dev/null
+++ b/src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-lib.rs
@@ -0,0 +1,11 @@
+// revisions: rpass1 rpass2
+
+extern crate respan;
+
+#[macro_use]
+#[path = "invalid-span-helper-mod.rs"]
+mod invalid_span_helper_mod;
+
+// Invoke a macro from a different file - this
+// allows us to get tokens with spans from different files
+helper!(1);
diff --git a/src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-mod.rs b/src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-mod.rs
new file mode 100644
index 000000000..747174b1e
--- /dev/null
+++ b/src/test/incremental/issue-85197-invalid-span/auxiliary/invalid-span-helper-mod.rs
@@ -0,0 +1,14 @@
+#[macro_export]
+macro_rules! helper {
+ // Use `:tt` instead of `:ident` so that we don't get a `None`-delimited group
+ ($first:tt) => {
+ pub fn foo<T>() {
+ // The span of `$first` comes from another file,
+ // so the expression `1 + $first` ends up with an
+ // 'invalid' span that starts and ends in different files.
+ // We use the `respan!` macro to give all tokens the same
+ // `SyntaxContext`, so that the parser will try to merge the spans.
+ respan::respan!(let a = 1 + $first;);
+ }
+ }
+}
diff --git a/src/test/incremental/issue-85197-invalid-span/auxiliary/respan.rs b/src/test/incremental/issue-85197-invalid-span/auxiliary/respan.rs
new file mode 100644
index 000000000..5088eab62
--- /dev/null
+++ b/src/test/incremental/issue-85197-invalid-span/auxiliary/respan.rs
@@ -0,0 +1,19 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+
+/// Copies the resolution information (the `SyntaxContext`) of the first
+/// token to all other tokens in the stream. Does not recurse into groups.
+#[proc_macro]
+pub fn respan(input: TokenStream) -> TokenStream {
+ let first_span = input.clone().into_iter().next().unwrap().span();
+ input.into_iter().map(|mut tree| {
+ tree.set_span(tree.span().resolved_at(first_span));
+ tree
+ }).collect()
+}
diff --git a/src/test/incremental/issue-85197-invalid-span/invalid_span_main.rs b/src/test/incremental/issue-85197-invalid-span/invalid_span_main.rs
new file mode 100644
index 000000000..f358460b3
--- /dev/null
+++ b/src/test/incremental/issue-85197-invalid-span/invalid_span_main.rs
@@ -0,0 +1,24 @@
+// revisions: rpass1 rpass2
+// aux-build:respan.rs
+// aux-build:invalid-span-helper-lib.rs
+
+// This issue has several different parts. The high level idea is:
+// 1. We create an 'invalid' span with the help of the `respan` proc-macro,
+// The compiler attempts to prevent the creation of invalid spans by
+// refusing to join spans with different `SyntaxContext`s. We work around
+// this by applying the same `SyntaxContext` to the span of every token,
+// using `Span::resolved_at`
+// 2. We using this invalid span in the body of a function, causing it to get
+// encoded into the `optimized_mir`
+// 3. We call the function from a different crate - since the function is generic,
+// monomorphization runs, causing `optimized_mir` to get called.
+// 4. We re-run compilation using our populated incremental cache, but without
+// making any changes. When we recompile the crate containing our generic function
+// (`invalid_span_helper_lib`), we load the span from the incremental cache, and
+// write it into the crate metadata.
+
+extern crate invalid_span_helper_lib;
+
+fn main() {
+ invalid_span_helper_lib::foo::<u8>();
+}