Skip to content

Commit ddf483a

Browse files
committed
Move some compile_fail doctests to UI tests
1 parent b4cbe20 commit ddf483a

21 files changed

+389
-85
lines changed

objc2-foundation/src/array.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,6 @@ unsafe impl<T: Sync + Send> Send for NSArray<T, Shared> {}
4141
unsafe impl<T: Sync> Sync for NSArray<T, Owned> {}
4242
unsafe impl<T: Send> Send for NSArray<T, Owned> {}
4343

44-
/// ```compile_fail
45-
/// use objc2::rc::Shared;
46-
/// use objc2::runtime::Object;
47-
/// use objc2_foundation::NSArray;
48-
/// fn needs_send_sync<T: Send + Sync>() {}
49-
/// needs_send_sync::<NSArray<Object, Shared>>();
50-
/// ```
51-
#[cfg(doctest)]
52-
pub struct NSArrayWithObjectNotSendSync;
53-
5444
object! {
5545
// TODO: Ensure that this deref to NSArray is safe!
5646
unsafe pub struct NSMutableArray<T, O: Ownership>: NSArray<T, O> {

objc2-foundation/src/object.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,6 @@ object! {
1010
unsafe pub struct NSObject: Object;
1111
}
1212

13-
/// ```compile_fail
14-
/// use objc2_foundation::NSObject;
15-
/// fn needs_sync<T: Sync>() {}
16-
/// needs_sync::<NSObject>();
17-
/// ```
18-
/// ```compile_fail
19-
/// use objc2_foundation::NSObject;
20-
/// fn needs_send<T: Send>() {}
21-
/// needs_send::<NSObject>();
22-
/// ```
23-
#[cfg(doctest)]
24-
pub struct NSObjectNotSendNorSync;
25-
2613
impl NSObject {
2714
unsafe_def_fn!(pub fn new -> Owned);
2815

objc2-foundation/src/string.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,6 @@ impl NSString {
4343
}
4444

4545
/// TODO
46-
///
47-
/// ```compile_fail
48-
/// # use objc2::rc::autoreleasepool;
49-
/// # use objc2_foundation::NSString;
50-
/// autoreleasepool(|pool| {
51-
/// let ns_string = NSString::new();
52-
/// let s = ns_string.as_str(pool);
53-
/// drop(ns_string);
54-
/// println!("{}", s);
55-
/// });
56-
/// ```
57-
///
58-
/// ```compile_fail
59-
/// # use objc2::rc::autoreleasepool;
60-
/// # use objc2_foundation::NSString;
61-
/// let ns_string = NSString::new();
62-
/// let s = autoreleasepool(|pool| ns_string.as_str(pool));
63-
/// ```
6446
pub fn as_str<'r, 's: 'r, 'p: 'r>(&'s self, pool: &'p AutoreleasePool) -> &'r str {
6547
// This is necessary until `auto` types stabilizes.
6648
pool.__verify_is_inner();

objc2-foundation/src/value.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,6 @@ impl<T: 'static + Copy + Encode + fmt::Display> fmt::Display for NSValue<T> {
110110
}
111111
}
112112

113-
/// ```compile_fail
114-
/// use objc2_foundation::NSValue;
115-
/// fn needs_eq<T: Eq>() {}
116-
/// needs_eq::<NSValue<f32>>();
117-
/// ```
118-
#[cfg(doctest)]
119-
pub struct NSValueFloatNotEq;
120-
121113
#[cfg(test)]
122114
mod tests {
123115
use alloc::format;

objc2/src/rc/autorelease.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,6 @@ pub struct AutoreleasePool {
2525
p: PhantomData<*mut UnsafeCell<c_void>>,
2626
}
2727

28-
/// ```
29-
/// use objc2::rc::AutoreleasePool;
30-
/// fn needs_nothing<T>() {}
31-
/// needs_nothing::<AutoreleasePool>();
32-
/// ```
33-
/// ```compile_fail
34-
/// use objc2::rc::AutoreleasePool;
35-
/// fn needs_sync<T: Sync>() {}
36-
/// needs_sync::<AutoreleasePool>();
37-
/// ```
38-
/// ```compile_fail
39-
/// use objc2::rc::AutoreleasePool;
40-
/// fn needs_send<T: Send>() {}
41-
/// needs_send::<AutoreleasePool>();
42-
/// ```
43-
#[cfg(doctest)]
44-
pub struct AutoreleasePoolNotSendNorSync;
45-
4628
#[cfg(all(debug_assertions, not(feature = "unstable_autoreleasesafe")))]
4729
thread_local! {
4830
/// We track the thread's pools to verify that object lifetimes are only

objc2/src/runtime.rs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -613,24 +613,6 @@ impl Object {
613613
// objc_removeAssociatedObjects
614614
}
615615

616-
/// ```
617-
/// use objc2::runtime::Object;
618-
/// fn needs_nothing<T: ?Sized>() {}
619-
/// needs_nothing::<Object>();
620-
/// ```
621-
/// ```compile_fail
622-
/// use objc2::runtime::Object;
623-
/// fn needs_sync<T: ?Sized + Sync>() {}
624-
/// needs_sync::<Object>();
625-
/// ```
626-
/// ```compile_fail
627-
/// use objc2::runtime::Object;
628-
/// fn needs_send<T: ?Sized + Send>() {}
629-
/// needs_send::<Object>();
630-
/// ```
631-
#[cfg(doctest)]
632-
pub struct ObjectNotSendNorSync;
633-
634616
unsafe impl RefEncode for Object {
635617
const ENCODING_REF: Encoding<'static> = Encoding::Object;
636618
}

tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ block-sys = { path = "../block-sys" }
2525
objc-sys = { path = "../objc-sys" }
2626
objc2 = { path = "../objc2" }
2727
objc2-encode = { path = "../objc2-encode" }
28+
objc2-foundation = { path = "../objc2-foundation" }
2829

2930
# Put here instead of dev-dependencies because we want to make it optional
3031
trybuild = { version = "1.0", optional = true }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Test that AutoreleasePool is not Send and Sync, because it internally
2+
//! works with thread locals.
3+
4+
use objc2::rc::AutoreleasePool;
5+
6+
fn needs_sync<T: ?Sized + Sync>() {}
7+
fn needs_send<T: ?Sized + Send>() {}
8+
9+
fn main() {
10+
needs_sync::<AutoreleasePool>();
11+
needs_send::<AutoreleasePool>();
12+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
error[E0277]: `*mut c_void` cannot be shared between threads safely
2+
--> ui/autoreleasepool_not_send_sync.rs:10:5
3+
|
4+
10 | needs_sync::<AutoreleasePool>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut c_void` cannot be shared between threads safely
6+
|
7+
= help: within `AutoreleasePool`, the trait `Sync` is not implemented for `*mut c_void`
8+
= note: required because it appears within the type `AutoreleasePool`
9+
note: required by a bound in `needs_sync`
10+
--> ui/autoreleasepool_not_send_sync.rs:6:27
11+
|
12+
6 | fn needs_sync<T: ?Sized + Sync>() {}
13+
| ^^^^ required by this bound in `needs_sync`
14+
15+
error[E0277]: `*mut UnsafeCell<c_void>` cannot be shared between threads safely
16+
--> ui/autoreleasepool_not_send_sync.rs:10:5
17+
|
18+
10 | needs_sync::<AutoreleasePool>();
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut UnsafeCell<c_void>` cannot be shared between threads safely
20+
|
21+
= help: within `AutoreleasePool`, the trait `Sync` is not implemented for `*mut UnsafeCell<c_void>`
22+
= note: required because it appears within the type `PhantomData<*mut UnsafeCell<c_void>>`
23+
= note: required because it appears within the type `AutoreleasePool`
24+
note: required by a bound in `needs_sync`
25+
--> ui/autoreleasepool_not_send_sync.rs:6:27
26+
|
27+
6 | fn needs_sync<T: ?Sized + Sync>() {}
28+
| ^^^^ required by this bound in `needs_sync`
29+
30+
error[E0277]: `*mut c_void` cannot be sent between threads safely
31+
--> ui/autoreleasepool_not_send_sync.rs:11:5
32+
|
33+
11 | needs_send::<AutoreleasePool>();
34+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut c_void` cannot be sent between threads safely
35+
|
36+
= help: within `AutoreleasePool`, the trait `Send` is not implemented for `*mut c_void`
37+
= note: required because it appears within the type `AutoreleasePool`
38+
note: required by a bound in `needs_send`
39+
--> ui/autoreleasepool_not_send_sync.rs:7:27
40+
|
41+
7 | fn needs_send<T: ?Sized + Send>() {}
42+
| ^^^^ required by this bound in `needs_send`
43+
44+
error[E0277]: `*mut UnsafeCell<c_void>` cannot be sent between threads safely
45+
--> ui/autoreleasepool_not_send_sync.rs:11:5
46+
|
47+
11 | needs_send::<AutoreleasePool>();
48+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut UnsafeCell<c_void>` cannot be sent between threads safely
49+
|
50+
= help: within `AutoreleasePool`, the trait `Send` is not implemented for `*mut UnsafeCell<c_void>`
51+
= note: required because it appears within the type `PhantomData<*mut UnsafeCell<c_void>>`
52+
= note: required because it appears within the type `AutoreleasePool`
53+
note: required by a bound in `needs_send`
54+
--> ui/autoreleasepool_not_send_sync.rs:7:27
55+
|
56+
7 | fn needs_send<T: ?Sized + Send>() {}
57+
| ^^^^ required by this bound in `needs_send`

tests/ui/global_block_not_encode.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use block2::global_block;
2+
3+
global_block! {
4+
pub static BLOCK = |_b: Box<i32>| {};
5+
}
6+
7+
fn main() {}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the trait bound `Box<i32>: objc2_encode::encode::Encode` is not satisfied
2+
--> ui/global_block_not_encode.rs:3:1
3+
|
4+
3 | / global_block! {
5+
4 | | pub static BLOCK = |_b: Box<i32>| {};
6+
5 | | }
7+
| |_^ the trait `objc2_encode::encode::Encode` is not implemented for `Box<i32>`
8+
|
9+
= note: required because of the requirements on the impl of `objc2_encode::encode::EncodeArguments` for `(Box<i32>,)`
10+
= note: required because of the requirements on the impl of `Sync` for `GlobalBlock<(Box<i32>,)>`
11+
= note: shared static variables must have a type that implements `Sync`
12+
= note: this error originates in the macro `global_block` (in Nightly builds, run with -Z macro-backtrace for more info)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use objc2::rc::Shared;
2+
use objc2::runtime::Object;
3+
use objc2_foundation::NSArray;
4+
5+
fn needs_sync<T: ?Sized + Sync>() {}
6+
fn needs_send<T: ?Sized + Send>() {}
7+
8+
fn main() {
9+
needs_sync::<NSArray<Object, Shared>>();
10+
needs_send::<NSArray<Object, Shared>>();
11+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
error[E0277]: `UnsafeCell<()>` cannot be shared between threads safely
2+
--> ui/nsarray_bound_not_send_sync.rs:9:5
3+
|
4+
9 | needs_sync::<NSArray<Object, Shared>>();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<()>` cannot be shared between threads safely
6+
|
7+
= help: within `objc2::runtime::Object`, the trait `Sync` is not implemented for `UnsafeCell<()>`
8+
= note: required because it appears within the type `(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)`
9+
= note: required because it appears within the type `PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>`
10+
= note: required because it appears within the type `objc_object`
11+
= note: required because it appears within the type `objc2::runtime::Object`
12+
= note: required because of the requirements on the impl of `Sync` for `NSArray<objc2::runtime::Object, Shared>`
13+
note: required by a bound in `needs_sync`
14+
--> ui/nsarray_bound_not_send_sync.rs:5:27
15+
|
16+
5 | fn needs_sync<T: ?Sized + Sync>() {}
17+
| ^^^^ required by this bound in `needs_sync`
18+
19+
error[E0277]: `*const UnsafeCell<()>` cannot be shared between threads safely
20+
--> ui/nsarray_bound_not_send_sync.rs:9:5
21+
|
22+
9 | needs_sync::<NSArray<Object, Shared>>();
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const UnsafeCell<()>` cannot be shared between threads safely
24+
|
25+
= help: within `objc2::runtime::Object`, the trait `Sync` is not implemented for `*const UnsafeCell<()>`
26+
= note: required because it appears within the type `(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)`
27+
= note: required because it appears within the type `PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>`
28+
= note: required because it appears within the type `objc_object`
29+
= note: required because it appears within the type `objc2::runtime::Object`
30+
= note: required because of the requirements on the impl of `Sync` for `NSArray<objc2::runtime::Object, Shared>`
31+
note: required by a bound in `needs_sync`
32+
--> ui/nsarray_bound_not_send_sync.rs:5:27
33+
|
34+
5 | fn needs_sync<T: ?Sized + Sync>() {}
35+
| ^^^^ required by this bound in `needs_sync`
36+
37+
error[E0277]: `*const UnsafeCell<()>` cannot be sent between threads safely
38+
--> ui/nsarray_bound_not_send_sync.rs:9:5
39+
|
40+
9 | needs_sync::<NSArray<Object, Shared>>();
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const UnsafeCell<()>` cannot be sent between threads safely
42+
|
43+
= help: within `objc2::runtime::Object`, the trait `Send` is not implemented for `*const UnsafeCell<()>`
44+
= note: required because it appears within the type `(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)`
45+
= note: required because it appears within the type `PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>`
46+
= note: required because it appears within the type `objc_object`
47+
= note: required because it appears within the type `objc2::runtime::Object`
48+
= note: required because of the requirements on the impl of `Sync` for `NSArray<objc2::runtime::Object, Shared>`
49+
note: required by a bound in `needs_sync`
50+
--> ui/nsarray_bound_not_send_sync.rs:5:27
51+
|
52+
5 | fn needs_sync<T: ?Sized + Sync>() {}
53+
| ^^^^ required by this bound in `needs_sync`
54+
55+
error[E0277]: `UnsafeCell<()>` cannot be shared between threads safely
56+
--> ui/nsarray_bound_not_send_sync.rs:10:5
57+
|
58+
10 | needs_send::<NSArray<Object, Shared>>();
59+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<()>` cannot be shared between threads safely
60+
|
61+
= help: within `objc2::runtime::Object`, the trait `Sync` is not implemented for `UnsafeCell<()>`
62+
= note: required because it appears within the type `(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)`
63+
= note: required because it appears within the type `PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>`
64+
= note: required because it appears within the type `objc_object`
65+
= note: required because it appears within the type `objc2::runtime::Object`
66+
= note: required because of the requirements on the impl of `Send` for `NSArray<objc2::runtime::Object, Shared>`
67+
note: required by a bound in `needs_send`
68+
--> ui/nsarray_bound_not_send_sync.rs:6:27
69+
|
70+
6 | fn needs_send<T: ?Sized + Send>() {}
71+
| ^^^^ required by this bound in `needs_send`
72+
73+
error[E0277]: `*const UnsafeCell<()>` cannot be shared between threads safely
74+
--> ui/nsarray_bound_not_send_sync.rs:10:5
75+
|
76+
10 | needs_send::<NSArray<Object, Shared>>();
77+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const UnsafeCell<()>` cannot be shared between threads safely
78+
|
79+
= help: within `objc2::runtime::Object`, the trait `Sync` is not implemented for `*const UnsafeCell<()>`
80+
= note: required because it appears within the type `(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)`
81+
= note: required because it appears within the type `PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>`
82+
= note: required because it appears within the type `objc_object`
83+
= note: required because it appears within the type `objc2::runtime::Object`
84+
= note: required because of the requirements on the impl of `Send` for `NSArray<objc2::runtime::Object, Shared>`
85+
note: required by a bound in `needs_send`
86+
--> ui/nsarray_bound_not_send_sync.rs:6:27
87+
|
88+
6 | fn needs_send<T: ?Sized + Send>() {}
89+
| ^^^^ required by this bound in `needs_send`
90+
91+
error[E0277]: `*const UnsafeCell<()>` cannot be sent between threads safely
92+
--> ui/nsarray_bound_not_send_sync.rs:10:5
93+
|
94+
10 | needs_send::<NSArray<Object, Shared>>();
95+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const UnsafeCell<()>` cannot be sent between threads safely
96+
|
97+
= help: within `objc2::runtime::Object`, the trait `Send` is not implemented for `*const UnsafeCell<()>`
98+
= note: required because it appears within the type `(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)`
99+
= note: required because it appears within the type `PhantomData<(UnsafeCell<()>, *const UnsafeCell<()>, PhantomPinned)>`
100+
= note: required because it appears within the type `objc_object`
101+
= note: required because it appears within the type `objc2::runtime::Object`
102+
= note: required because of the requirements on the impl of `Send` for `NSArray<objc2::runtime::Object, Shared>`
103+
note: required by a bound in `needs_send`
104+
--> ui/nsarray_bound_not_send_sync.rs:6:27
105+
|
106+
6 | fn needs_send<T: ?Sized + Send>() {}
107+
| ^^^^ required by this bound in `needs_send`
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//! Test that the lifetime of `NSString::as_str` is bound to the string.
2+
3+
use objc2::rc::autoreleasepool;
4+
use objc2_foundation::NSString;
5+
6+
fn main() {
7+
autoreleasepool(|pool| {
8+
let ns_string = NSString::new();
9+
let s = ns_string.as_str(pool);
10+
drop(ns_string);
11+
println!("{}", s);
12+
});
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0505]: cannot move out of `ns_string` because it is borrowed
2+
--> ui/nsstring_as_str_use_after_release.rs:10:14
3+
|
4+
9 | let s = ns_string.as_str(pool);
5+
| ---------------------- borrow of `ns_string` occurs here
6+
10 | drop(ns_string);
7+
| ^^^^^^^^^ move out of `ns_string` occurs here
8+
11 | println!("{}", s);
9+
| - borrow later used here
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//! Test that the lifetime of `NSString::as_str` is bound to the pool.
2+
3+
use objc2::rc::autoreleasepool;
4+
use objc2_foundation::NSString;
5+
6+
fn main() {
7+
let ns_string = NSString::new();
8+
let _s = autoreleasepool(|pool| ns_string.as_str(pool));
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: lifetime may not live long enough
2+
--> ui/nsstring_as_str_use_outside_pool.rs:8:37
3+
|
4+
8 | let _s = autoreleasepool(|pool| ns_string.as_str(pool));
5+
| ----- ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
6+
| | |
7+
| | return type of closure is &'2 str
8+
| has type `&'1 AutoreleasePool`

0 commit comments

Comments
 (0)