about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-04-27 21:34:16 +0200
committerGitHub <noreply@github.com>2023-04-27 21:34:16 +0200
commit1091a7a884b2de331ced19a7a4d1325c74fdaf06 (patch)
treeb458b9356eab7a45c5167c77d881ac8b346d1233
parentd3c43d0a22c70a1ca0f4aadb215ce8fbbe473aa0 (diff)
parentfcf8468efc7cab2f66372baf9bb28131de444f86 (diff)
downloadrust-1091a7a884b2de331ced19a7a4d1325c74fdaf06.tar.gz
rust-1091a7a884b2de331ced19a7a4d1325c74fdaf06.zip
Rollup merge of #110878 - whtahy:105107/known-bug-tests-for-unsound-issues, r=jackh726
Add `known-bug` tests for 4 unsound issues

This PR adds `known-bug` tests for 4 unsound issues as part of #105107
- #40582
- #49682
- #74629
- #105782
-rw-r--r--tests/ui/coherence/coherence-overlap-negative-impls.rs41
-rw-r--r--tests/ui/specialization/issue-40582.rs35
-rw-r--r--tests/ui/specialization/specialization-default-items-drop-coherence.rs30
-rw-r--r--tests/ui/thread-local/thread-local-static-ref-use-after-free.rs46
4 files changed, 152 insertions, 0 deletions
diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.rs b/tests/ui/coherence/coherence-overlap-negative-impls.rs
new file mode 100644
index 00000000000..cd1df53a528
--- /dev/null
+++ b/tests/ui/coherence/coherence-overlap-negative-impls.rs
@@ -0,0 +1,41 @@
+// check-pass
+// known-bug: #74629
+
+// Should fail. The `0` and `1` impls overlap, violating coherence. Eg, with
+// `T = Test, F = ()`, all bounds are true, making both impls applicable.
+// `Test: Fold<Nil>`, `Test: Fold<()>` are true because of `2`.
+// `Is<Test>: NotNil` is true because of `auto trait` and lack of negative impl.
+
+#![feature(negative_impls)]
+#![feature(auto_traits)]
+
+struct Nil;
+struct Cons<H>(H);
+struct Test;
+
+trait Fold<F> {}
+
+impl<T, F> Fold<F> for Cons<T> // 0
+where
+    T: Fold<Nil>,
+{}
+
+impl<T, F> Fold<F> for Cons<T> // 1
+where
+    T: Fold<F>,
+    private::Is<T>: private::NotNil,
+{}
+
+impl<F> Fold<F> for Test {} // 2
+
+mod private {
+    use crate::Nil;
+
+    pub struct Is<T>(T);
+    pub auto trait NotNil {}
+
+    #[allow(suspicious_auto_trait_impls)]
+    impl !NotNil for Is<Nil> {}
+}
+
+fn main() {}
diff --git a/tests/ui/specialization/issue-40582.rs b/tests/ui/specialization/issue-40582.rs
new file mode 100644
index 00000000000..9805933553d
--- /dev/null
+++ b/tests/ui/specialization/issue-40582.rs
@@ -0,0 +1,35 @@
+// check-pass
+// known-bug: #40582
+
+// Should fail. Should not be possible to implement `make_static`.
+
+#![feature(specialization)]
+#![allow(incomplete_features)]
+
+trait FromRef<'a, T: ?Sized> {
+    fn from_ref(r: &'a T) -> Self;
+}
+
+impl<'a, T: ?Sized> FromRef<'a, T> for &'a T {
+    fn from_ref(r: &'a T) -> Self {
+        r
+    }
+}
+
+impl<'a, T: ?Sized, R> FromRef<'a, T> for R {
+    default fn from_ref(_: &'a T) -> Self {
+        unimplemented!()
+    }
+}
+
+fn make_static<T: ?Sized>(data: &T) -> &'static T {
+    fn helper<T: ?Sized, R>(data: &T) -> R {
+        R::from_ref(data)
+    }
+    helper(data)
+}
+
+fn main() {
+    let s = "specialization".to_owned();
+    println!("{:?}", make_static(s.as_str()));
+}
diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
new file mode 100644
index 00000000000..16ad942d5ab
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
@@ -0,0 +1,30 @@
+// check-pass
+// known-bug: #105782
+
+// Should fail. Default items completely drop candidates instead of ambiguity,
+// which is unsound during coherence, since coherence requires completeness.
+
+#![feature(specialization)]
+#![allow(incomplete_features)]
+
+trait Default {
+   type Id;
+}
+
+impl<T> Default for T {
+   default type Id = T;
+}
+
+trait Overlap {
+   type Assoc;
+}
+
+impl Overlap for u32 {
+   type Assoc = usize;
+}
+
+impl Overlap for <u32 as Default>::Id {
+   type Assoc = Box<usize>;
+}
+
+fn main() {}
diff --git a/tests/ui/thread-local/thread-local-static-ref-use-after-free.rs b/tests/ui/thread-local/thread-local-static-ref-use-after-free.rs
new file mode 100644
index 00000000000..c282e2185bc
--- /dev/null
+++ b/tests/ui/thread-local/thread-local-static-ref-use-after-free.rs
@@ -0,0 +1,46 @@
+// check-pass
+// known-bug: #49682
+// edition:2021
+
+// Should fail. Keeping references to thread local statics can result in a
+// use-after-free.
+
+#![feature(thread_local)]
+
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::thread;
+
+#[allow(dead_code)]
+#[thread_local]
+static FOO: AtomicUsize = AtomicUsize::new(0);
+
+#[allow(dead_code)]
+async fn bar() {}
+
+#[allow(dead_code)]
+async fn foo() {
+    let r = &FOO;
+    bar().await;
+    r.load(Ordering::SeqCst);
+}
+
+fn main() {
+    // &FOO = 0x7fd1e9cbf6d0
+    _ = thread::spawn(|| {
+        let g = foo();
+        println!("&FOO = {:p}", &FOO);
+        g
+    })
+    .join()
+    .unwrap();
+
+    // &FOO = 0x7fd1e9cc0f50
+    println!("&FOO = {:p}", &FOO);
+
+    // &FOO = 0x7fd1e9cbf6d0
+    thread::spawn(move || {
+        println!("&FOO = {:p}", &FOO);
+    })
+    .join()
+    .unwrap();
+}