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 0000000000000..cd1df53a52889 --- /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`, `Test: Fold<()>` are true because of `2`. +// `Is: NotNil` is true because of `auto trait` and lack of negative impl. + +#![feature(negative_impls)] +#![feature(auto_traits)] + +struct Nil; +struct Cons(H); +struct Test; + +trait Fold {} + +impl Fold for Cons // 0 +where + T: Fold, +{} + +impl Fold for Cons // 1 +where + T: Fold, + private::Is: private::NotNil, +{} + +impl Fold for Test {} // 2 + +mod private { + use crate::Nil; + + pub struct Is(T); + pub auto trait NotNil {} + + #[allow(suspicious_auto_trait_impls)] + impl !NotNil for Is {} +} + +fn main() {} diff --git a/tests/ui/specialization/issue-40582.rs b/tests/ui/specialization/issue-40582.rs new file mode 100644 index 0000000000000..9805933553dd7 --- /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(data: &T) -> &'static T { + fn helper(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 0000000000000..16ad942d5ab95 --- /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 Default for T { + default type Id = T; +} + +trait Overlap { + type Assoc; +} + +impl Overlap for u32 { + type Assoc = usize; +} + +impl Overlap for ::Id { + type Assoc = Box; +} + +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 0000000000000..c282e2185bca2 --- /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(); +}