Skip to content

Commit

Permalink
Add test for precise-capturing from an external macro
Browse files Browse the repository at this point in the history
  • Loading branch information
ehuss committed Nov 15, 2024
1 parent 76fd471 commit d163541
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 0 deletions.
20 changes: 20 additions & 0 deletions tests/ui/impl-trait/precise-capturing/auxiliary/no-use-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// A macro_rules macro in 2015 that has an RPIT without `use<>` that would
// cause a problem with 2024 capturing rules.

#[macro_export]
macro_rules! macro_rpit {
() => {
fn test_mbe(x: &Vec<i32>) -> impl std::fmt::Display {
x[0]
}

pub fn from_mbe() {
let mut x = vec![];
x.push(1);

let element = test_mbe(&x);
x.push(2);
println!("{element}");
}
};
}
29 changes: 29 additions & 0 deletions tests/ui/impl-trait/precise-capturing/auxiliary/no-use-pm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// A proc-macro in 2015 that has an RPIT without `use<>` that would cause a
// problem with 2024 capturing rules.

//@ force-host
//@ no-prefer-dynamic

#![crate_type = "proc-macro"]

extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro]
pub fn pm_rpit(input: TokenStream) -> TokenStream {
"fn test_pm(x: &Vec<i32>) -> impl std::fmt::Display {
x[0]
}
pub fn from_pm() {
let mut x = vec![];
x.push(1);
let element = test_pm(&x);
x.push(2);
println!(\"{element}\");
}
"
.parse()
.unwrap()
}
29 changes: 29 additions & 0 deletions tests/ui/impl-trait/precise-capturing/external-macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Tests that code generated from an external macro (MBE and proc-macro) that
// has an RPIT will not fail when the call-site is 2024.
// https://github.com/rust-lang/rust/issues/132917

//@ aux-crate: no_use_pm=no-use-pm.rs
//@ aux-crate: no_use_macro=no-use-macro.rs
//@ edition: 2024
//@ compile-flags:-Z unstable-options

no_use_pm::pm_rpit!{}
//~^ ERROR: cannot borrow `x` as mutable

no_use_macro::macro_rpit!{}
//~^ ERROR: cannot borrow `x` as mutable

fn main() {
let mut x = vec![];
x.push(1);

let element = test_pm(&x);
x.push(2);
//~^ ERROR: cannot borrow `x` as mutable
println!("{element}");

let element = test_mbe(&x);
x.push(2);
//~^ ERROR: cannot borrow `x` as mutable
println!("{element}");
}
89 changes: 89 additions & 0 deletions tests/ui/impl-trait/precise-capturing/external-macro.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> $DIR/external-macro.rs:10:1
|
LL | no_use_pm::pm_rpit!{}
| ^^^^^^^^^^^^^^^^^^^^^
| |
| mutable borrow occurs here
| immutable borrow occurs here
| immutable borrow later used here
|
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
--> $DIR/external-macro.rs:10:1
|
LL | no_use_pm::pm_rpit!{}
| ^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `no_use_pm::pm_rpit` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use the precise capturing `use<...>` syntax to make the captures explicit
|
LL | no_use_pm::pm_rpit!{} + use<>
| +++++++

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> $DIR/external-macro.rs:13:1
|
LL | no_use_macro::macro_rpit!{}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| mutable borrow occurs here
| immutable borrow occurs here
| immutable borrow later used here
|
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
--> $DIR/external-macro.rs:13:1
|
LL | no_use_macro::macro_rpit!{}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `no_use_macro::macro_rpit` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use the precise capturing `use<...>` syntax to make the captures explicit
--> $DIR/auxiliary/no-use-macro.rs:7:60
|
LL | fn test_mbe(x: &Vec<i32>) -> impl std::fmt::Display + use<> {
| +++++++

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> $DIR/external-macro.rs:21:5
|
LL | let element = test_pm(&x);
| -- immutable borrow occurs here
LL | x.push(2);
| ^^^^^^^^^ mutable borrow occurs here
LL |
LL | println!("{element}");
| --------- immutable borrow later used here
|
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
--> $DIR/external-macro.rs:20:19
|
LL | let element = test_pm(&x);
| ^^^^^^^^^^^
help: use the precise capturing `use<...>` syntax to make the captures explicit
|
LL | no_use_pm::pm_rpit!{} + use<>
| +++++++

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> $DIR/external-macro.rs:26:5
|
LL | let element = test_pm(&x);
| -- immutable borrow occurs here
...
LL | x.push(2);
| ^^^^^^^^^ mutable borrow occurs here
...
LL | }
| - immutable borrow might be used here, when `element` is dropped and runs the destructor for type `impl std::fmt::Display`
|
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
--> $DIR/external-macro.rs:20:19
|
LL | let element = test_pm(&x);
| ^^^^^^^^^^^
help: use the precise capturing `use<...>` syntax to make the captures explicit
|
LL | no_use_pm::pm_rpit!{} + use<>
| +++++++

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0502`.

0 comments on commit d163541

Please sign in to comment.