Skip to content

Commit d163541

Browse files
committed
Add test for precise-capturing from an external macro
1 parent 76fd471 commit d163541

File tree

4 files changed

+167
-0
lines changed

4 files changed

+167
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// A macro_rules macro in 2015 that has an RPIT without `use<>` that would
2+
// cause a problem with 2024 capturing rules.
3+
4+
#[macro_export]
5+
macro_rules! macro_rpit {
6+
() => {
7+
fn test_mbe(x: &Vec<i32>) -> impl std::fmt::Display {
8+
x[0]
9+
}
10+
11+
pub fn from_mbe() {
12+
let mut x = vec![];
13+
x.push(1);
14+
15+
let element = test_mbe(&x);
16+
x.push(2);
17+
println!("{element}");
18+
}
19+
};
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// A proc-macro in 2015 that has an RPIT without `use<>` that would cause a
2+
// problem with 2024 capturing rules.
3+
4+
//@ force-host
5+
//@ no-prefer-dynamic
6+
7+
#![crate_type = "proc-macro"]
8+
9+
extern crate proc_macro;
10+
use proc_macro::TokenStream;
11+
12+
#[proc_macro]
13+
pub fn pm_rpit(input: TokenStream) -> TokenStream {
14+
"fn test_pm(x: &Vec<i32>) -> impl std::fmt::Display {
15+
x[0]
16+
}
17+
18+
pub fn from_pm() {
19+
let mut x = vec![];
20+
x.push(1);
21+
22+
let element = test_pm(&x);
23+
x.push(2);
24+
println!(\"{element}\");
25+
}
26+
"
27+
.parse()
28+
.unwrap()
29+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Tests that code generated from an external macro (MBE and proc-macro) that
2+
// has an RPIT will not fail when the call-site is 2024.
3+
// https://github.com/rust-lang/rust/issues/132917
4+
5+
//@ aux-crate: no_use_pm=no-use-pm.rs
6+
//@ aux-crate: no_use_macro=no-use-macro.rs
7+
//@ edition: 2024
8+
//@ compile-flags:-Z unstable-options
9+
10+
no_use_pm::pm_rpit!{}
11+
//~^ ERROR: cannot borrow `x` as mutable
12+
13+
no_use_macro::macro_rpit!{}
14+
//~^ ERROR: cannot borrow `x` as mutable
15+
16+
fn main() {
17+
let mut x = vec![];
18+
x.push(1);
19+
20+
let element = test_pm(&x);
21+
x.push(2);
22+
//~^ ERROR: cannot borrow `x` as mutable
23+
println!("{element}");
24+
25+
let element = test_mbe(&x);
26+
x.push(2);
27+
//~^ ERROR: cannot borrow `x` as mutable
28+
println!("{element}");
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
2+
--> $DIR/external-macro.rs:10:1
3+
|
4+
LL | no_use_pm::pm_rpit!{}
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| mutable borrow occurs here
8+
| immutable borrow occurs here
9+
| immutable borrow later used here
10+
|
11+
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
12+
--> $DIR/external-macro.rs:10:1
13+
|
14+
LL | no_use_pm::pm_rpit!{}
15+
| ^^^^^^^^^^^^^^^^^^^^^
16+
= note: this error originates in the macro `no_use_pm::pm_rpit` (in Nightly builds, run with -Z macro-backtrace for more info)
17+
help: use the precise capturing `use<...>` syntax to make the captures explicit
18+
|
19+
LL | no_use_pm::pm_rpit!{} + use<>
20+
| +++++++
21+
22+
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
23+
--> $DIR/external-macro.rs:13:1
24+
|
25+
LL | no_use_macro::macro_rpit!{}
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
| |
28+
| mutable borrow occurs here
29+
| immutable borrow occurs here
30+
| immutable borrow later used here
31+
|
32+
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
33+
--> $DIR/external-macro.rs:13:1
34+
|
35+
LL | no_use_macro::macro_rpit!{}
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
= note: this error originates in the macro `no_use_macro::macro_rpit` (in Nightly builds, run with -Z macro-backtrace for more info)
38+
help: use the precise capturing `use<...>` syntax to make the captures explicit
39+
--> $DIR/auxiliary/no-use-macro.rs:7:60
40+
|
41+
LL | fn test_mbe(x: &Vec<i32>) -> impl std::fmt::Display + use<> {
42+
| +++++++
43+
44+
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
45+
--> $DIR/external-macro.rs:21:5
46+
|
47+
LL | let element = test_pm(&x);
48+
| -- immutable borrow occurs here
49+
LL | x.push(2);
50+
| ^^^^^^^^^ mutable borrow occurs here
51+
LL |
52+
LL | println!("{element}");
53+
| --------- immutable borrow later used here
54+
|
55+
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
56+
--> $DIR/external-macro.rs:20:19
57+
|
58+
LL | let element = test_pm(&x);
59+
| ^^^^^^^^^^^
60+
help: use the precise capturing `use<...>` syntax to make the captures explicit
61+
|
62+
LL | no_use_pm::pm_rpit!{} + use<>
63+
| +++++++
64+
65+
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
66+
--> $DIR/external-macro.rs:26:5
67+
|
68+
LL | let element = test_pm(&x);
69+
| -- immutable borrow occurs here
70+
...
71+
LL | x.push(2);
72+
| ^^^^^^^^^ mutable borrow occurs here
73+
...
74+
LL | }
75+
| - immutable borrow might be used here, when `element` is dropped and runs the destructor for type `impl std::fmt::Display`
76+
|
77+
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
78+
--> $DIR/external-macro.rs:20:19
79+
|
80+
LL | let element = test_pm(&x);
81+
| ^^^^^^^^^^^
82+
help: use the precise capturing `use<...>` syntax to make the captures explicit
83+
|
84+
LL | no_use_pm::pm_rpit!{} + use<>
85+
| +++++++
86+
87+
error: aborting due to 4 previous errors
88+
89+
For more information about this error, try `rustc --explain E0502`.

0 commit comments

Comments
 (0)