about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-28 00:41:37 +0000
committerbors <bors@rust-lang.org>2023-06-28 00:41:37 +0000
commitbb95b7dcd6a247df0f4a6762a673a2910a81de9c (patch)
tree4fdb876467eeeb9a0f3edf14bdefe9ea3e6f7f79 /tests
parent6b46c996e1d3a07dd73beb2873d74a8a0458d05f (diff)
parent46973c9c8a775faa92eb10c478490c9b69f2eab6 (diff)
downloadrust-bb95b7dcd6a247df0f4a6762a673a2910a81de9c.tar.gz
rust-bb95b7dcd6a247df0f4a6762a673a2910a81de9c.zip
Auto merge of #112307 - lcnr:operand-ref, r=compiler-errors
mir opt + codegen: handle subtyping

fixes #107205

the same issue was caused in multiple places:
- mir opts: both copy and destination propagation
- codegen: assigning operands to locals (which also propagates values)

I changed codegen to always update the type in the operands used for locals which should guard against any new occurrences of this bug going forward. I don't know how to make mir optimizations more resilient here. Hopefully the added tests will be enough to detect any trivially wrong optimizations going forward.
Diffstat (limited to 'tests')
-rw-r--r--tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir2
-rw-r--r--tests/ui/codegen/subtyping-impacts-selection-1.rs44
-rw-r--r--tests/ui/codegen/subtyping-impacts-selection-2.rs12
3 files changed, 57 insertions, 1 deletions
diff --git a/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir b/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
index b15a634256f..5fddfd494ea 100644
--- a/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
+++ b/tests/mir-opt/fn_ptr_shim.core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
@@ -1,6 +1,6 @@
 // MIR for `std::ops::Fn::call` before AddMovesForPackedDrops
 
-fn std::ops::Fn::call(_1: *const fn(), _2: ()) -> <fn() as FnOnce<()>>::Output {
+fn std::ops::Fn::call(_1: &fn(), _2: ()) -> <fn() as FnOnce<()>>::Output {
     let mut _0: <fn() as std::ops::FnOnce<()>>::Output;
 
     bb0: {
diff --git a/tests/ui/codegen/subtyping-impacts-selection-1.rs b/tests/ui/codegen/subtyping-impacts-selection-1.rs
new file mode 100644
index 00000000000..09e06f6d684
--- /dev/null
+++ b/tests/ui/codegen/subtyping-impacts-selection-1.rs
@@ -0,0 +1,44 @@
+// run-pass
+// revisions: mir codegen
+//[mir] compile-flags: -Zmir-opt-level=3
+//[codegen] compile-flags: -Zmir-opt-level=0
+
+// A regression test for #107205
+#![allow(coherence_leak_check)]
+struct Foo<T: 'static>(T);
+
+fn useful<'a>(_: &'a u8) {}
+
+trait GetInner {
+    type Assoc;
+    fn muahaha(&mut self) -> Self::Assoc;
+}
+
+impl GetInner for Foo<fn(&'static u8)> {
+    type Assoc = String;
+    fn muahaha(&mut self) -> String {
+        String::from("I am a string")
+    }
+}
+
+impl GetInner for Foo<for<'a> fn(&'a u8)> {
+    type Assoc = [usize; 3];
+    fn muahaha(&mut self) -> [usize; 3] {
+        [100; 3]
+    }
+}
+
+fn break_me(hr_fnptr: Box<Foo::<for<'a> fn(&'a u8)>>) -> Box<dyn GetInner<Assoc = String>> {
+    let lr_fnptr = hr_fnptr as Box<Foo<fn(&'static u8)>>;
+    lr_fnptr as Box<dyn GetInner<Assoc = String>>
+}
+
+fn main() {
+    drop(Box::new(Foo(useful as fn(&'static u8))) as Box<dyn GetInner<Assoc = String>>);
+    drop(Box::new(Foo(useful as fn(&u8))) as Box<dyn GetInner<Assoc = [usize; 3]>>);
+
+    let mut any = break_me(Box::new(Foo(useful)));
+
+    let evil_string = any.muahaha();
+    assert_eq!(evil_string, "I am a string");
+}
diff --git a/tests/ui/codegen/subtyping-impacts-selection-2.rs b/tests/ui/codegen/subtyping-impacts-selection-2.rs
new file mode 100644
index 00000000000..921136775b7
--- /dev/null
+++ b/tests/ui/codegen/subtyping-impacts-selection-2.rs
@@ -0,0 +1,12 @@
+// run-pass
+// revisions: mir codegen
+//[mir] compile-flags: -Zmir-opt-level=3
+//[codegen] compile-flags: -Zmir-opt-level=0
+
+// A regression test for #107205
+
+const X: for<'b> fn(&'b ()) = |&()| ();
+fn main() {
+    let dyn_debug = Box::new(X) as Box<fn(&'static ())> as Box<dyn Send>;
+    drop(dyn_debug)
+}