Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 1 | // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| 2 | // Exceptions. See /LICENSE for license information. |
| 3 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 4 | |
| 5 | #[macro_use] |
| 6 | extern crate static_assertions; |
| 7 | |
| 8 | #[cfg(test)] |
| 9 | mod tests { |
| 10 | use constructors::*; |
| 11 | |
| 12 | #[test] |
| 13 | fn test_user_provided_constructors() { |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 14 | assert_impl_all!(StructWithUserProvidedConstructors: Default); |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 15 | let s: StructWithUserProvidedConstructors = Default::default(); |
Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 16 | assert_eq!(42, s.int_field); |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 17 | |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 18 | // TODO(lukasza): Implement and test a user-defined copy constructor / impl |
| 19 | // Clone. |
| 20 | |
| 21 | // Trivial-ABI structs implement the Copy trait, even if they have user-defined |
| 22 | // constructors. |
| 23 | assert_impl_all!(StructWithUserProvidedConstructors: Copy); |
| 24 | |
| 25 | assert_impl_all!(StructWithUserProvidedConstructors: From<i32>); |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 26 | let i: StructWithUserProvidedConstructors = 123.into(); |
| 27 | assert_eq!(123, i.int_field); |
Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 28 | } |
Lukasz Anforowicz | 7470471 | 2021-12-22 15:30:31 +0000 | [diff] [blame] | 29 | |
| 30 | #[test] |
Lukasz Anforowicz | 7b0042d | 2022-01-06 23:00:19 +0000 | [diff] [blame] | 31 | fn test_inline_constructors() { |
| 32 | assert_impl_all!(StructWithInlineConstructors: Default); |
| 33 | let s: StructWithInlineConstructors = Default::default(); |
| 34 | assert_eq!(123, s.int_field); |
| 35 | |
| 36 | // TODO(lukasza): Implement and test a user-defined copy constructor / impl |
| 37 | // Clone. |
| 38 | |
| 39 | // Trivial-ABI structs implement the Copy trait, even if they have user-defined |
| 40 | // constructors. |
| 41 | assert_impl_all!(StructWithUserProvidedConstructors: Copy); |
| 42 | let s3 = s; |
| 43 | assert_eq!(123, s3.int_field); |
| 44 | |
| 45 | assert_impl_all!(StructWithInlineConstructors: From<i32>); |
| 46 | let i: StructWithInlineConstructors = 456.into(); |
| 47 | assert_eq!(456, i.int_field); |
| 48 | } |
| 49 | |
| 50 | #[test] |
Lukasz Anforowicz | 0a1b480 | 2021-12-22 15:30:56 +0000 | [diff] [blame] | 51 | fn test_deleted_constructors() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 52 | assert_not_impl_all!(StructWithDeletedConstructors: Clone); |
| 53 | assert_not_impl_all!(StructWithDeletedConstructors: Copy); |
| 54 | assert_not_impl_all!(StructWithDeletedConstructors: Default); |
| 55 | assert_not_impl_all!(StructWithDeletedConstructors: From<i32>); |
Lukasz Anforowicz | 0a1b480 | 2021-12-22 15:30:56 +0000 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | #[test] |
Lukasz Anforowicz | 7470471 | 2021-12-22 15:30:31 +0000 | [diff] [blame] | 59 | fn test_private_constructors() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 60 | assert_not_impl_all!(StructWithPrivateConstructors: Clone); |
| 61 | assert_not_impl_all!(StructWithPrivateConstructors: Copy); |
| 62 | assert_not_impl_all!(StructWithPrivateConstructors: Default); |
| 63 | assert_not_impl_all!(StructWithPrivateConstructors: From<i32>); |
Lukasz Anforowicz | 7470471 | 2021-12-22 15:30:31 +0000 | [diff] [blame] | 64 | } |
Lukasz Anforowicz | e643ec9 | 2021-12-22 15:45:15 +0000 | [diff] [blame] | 65 | |
| 66 | #[test] |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 67 | #[allow(clippy::clone_on_copy)] |
| 68 | fn test_explicitly_defaulted_constructors() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 69 | assert_impl_all!(StructWithExplicitlyDefaultedConstructors: Default); |
| 70 | let s: StructWithExplicitlyDefaultedConstructors = Default::default(); |
Lukasz Anforowicz | bedbdee | 2022-01-05 01:14:52 +0000 | [diff] [blame] | 71 | assert_eq!(0, s.field_with_no_initializer); // Using `MaybeUninit<T>::zeroed()`. |
Lukasz Anforowicz | e643ec9 | 2021-12-22 15:45:15 +0000 | [diff] [blame] | 72 | assert_eq!(123, s.field_with_explicit_initializer); |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 73 | |
| 74 | // In some scenarios the bindings generator may be able to ask Rust to |
| 75 | // `#[derive(Clone)]` (e.g. when the C++ constructor has been |
| 76 | // implicitly or explicitly `=default`-ed + when Rust can mimic how C++ |
| 77 | // would copy/clone all the fields). Therefore, the test assertions |
| 78 | // below may mostly be testing/exercising how Rust derives Clone. This |
| 79 | // should be okay. |
| 80 | assert_impl_all!(StructWithExplicitlyDefaultedConstructors: Clone); |
| 81 | let s2 = s.clone(); |
| 82 | assert_eq!(0, s2.field_with_no_initializer); |
| 83 | assert_eq!(123, s2.field_with_explicit_initializer); |
| 84 | |
| 85 | assert_impl_all!(StructWithExplicitlyDefaultedConstructors: Copy); |
Lukasz Anforowicz | e643ec9 | 2021-12-22 15:45:15 +0000 | [diff] [blame] | 86 | } |
Lukasz Anforowicz | 9bab835 | 2021-12-22 17:35:31 +0000 | [diff] [blame] | 87 | |
| 88 | #[test] |
| 89 | fn test_nontrivial_struct() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 90 | // Non-trivial types cannot be copied. |
| 91 | assert_not_impl_all!(NonTrivialStructWithConstructors: Copy); |
| 92 | |
| 93 | // Non-trivial types cannot be constructed by-value, despite having default |
| 94 | // constructor, copy constructor, and constructor taking an int. |
| 95 | assert_not_impl_all!(NonTrivialStructWithConstructors: Clone); |
Lukasz Anforowicz | 9bab835 | 2021-12-22 17:35:31 +0000 | [diff] [blame] | 96 | assert_not_impl_all!(NonTrivialStructWithConstructors: Default); |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 97 | assert_not_impl_all!(NonTrivialStructWithConstructors: From<i32>); |
| 98 | |
| 99 | // TODO(b/200067242): Support constructing non-trivially-relocatable |
| 100 | // types. See also <internal link>. |
Lukasz Anforowicz | 9bab835 | 2021-12-22 17:35:31 +0000 | [diff] [blame] | 101 | } |
Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 102 | } |