From 218caa410aa38c29984be31a5229b9fa717560ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:13 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/polymorphization/closure_in_upvar/fn.rs | 29 +++++++++++++++++ .../ui/polymorphization/closure_in_upvar/fnmut.rs | 34 +++++++++++++++++++ .../ui/polymorphization/closure_in_upvar/fnonce.rs | 34 +++++++++++++++++++ .../ui/polymorphization/closure_in_upvar/other.rs | 38 ++++++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 tests/ui/polymorphization/closure_in_upvar/fn.rs create mode 100644 tests/ui/polymorphization/closure_in_upvar/fnmut.rs create mode 100644 tests/ui/polymorphization/closure_in_upvar/fnonce.rs create mode 100644 tests/ui/polymorphization/closure_in_upvar/other.rs (limited to 'tests/ui/polymorphization/closure_in_upvar') diff --git a/tests/ui/polymorphization/closure_in_upvar/fn.rs b/tests/ui/polymorphization/closure_in_upvar/fn.rs new file mode 100644 index 000000000..e10308588 --- /dev/null +++ b/tests/ui/polymorphization/closure_in_upvar/fn.rs @@ -0,0 +1,29 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + let x = |_: ()| (); + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} diff --git a/tests/ui/polymorphization/closure_in_upvar/fnmut.rs b/tests/ui/polymorphization/closure_in_upvar/fnmut.rs new file mode 100644 index 000000000..62164ff94 --- /dev/null +++ b/tests/ui/polymorphization/closure_in_upvar/fnmut.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + // Mutate an upvar from `x` so that it implements `FnMut`. + let mut outer = 3; + let mut x = |_: ()| { + outer = 4; + () + }; + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let mut y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} diff --git a/tests/ui/polymorphization/closure_in_upvar/fnonce.rs b/tests/ui/polymorphization/closure_in_upvar/fnonce.rs new file mode 100644 index 000000000..7a364882f --- /dev/null +++ b/tests/ui/polymorphization/closure_in_upvar/fnonce.rs @@ -0,0 +1,34 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn foo(f: impl Fn()) { + // Move a non-copy type into `x` so that it implements `FnOnce`. + let outer = Vec::::new(); + let x = move |_: ()| { + let inner = outer; + () + }; + + // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to + // `x` that will differ for each instantiation despite polymorphisation of the varying + // argument. + let y = || x(()); + + // Consider `f` used in `foo`. + f(); + // Use `y` so that it is visited in monomorphisation collection. + y(); +} + +fn entry_a() { + foo(|| ()); +} + +fn entry_b() { + foo(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} diff --git a/tests/ui/polymorphization/closure_in_upvar/other.rs b/tests/ui/polymorphization/closure_in_upvar/other.rs new file mode 100644 index 000000000..27d59ec88 --- /dev/null +++ b/tests/ui/polymorphization/closure_in_upvar/other.rs @@ -0,0 +1,38 @@ +// build-pass +// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0 + +fn y_uses_f(f: impl Fn()) { + let x = |_: ()| (); + + let y = || { + f(); + x(()); + }; + + f(); + y(); +} + +fn x_uses_f(f: impl Fn()) { + let x = |_: ()| { f(); }; + + let y = || x(()); + + f(); + y(); +} + +fn entry_a() { + x_uses_f(|| ()); + y_uses_f(|| ()); +} + +fn entry_b() { + x_uses_f(|| ()); + y_uses_f(|| ()); +} + +fn main() { + entry_a(); + entry_b(); +} -- cgit v1.2.3