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::*; |
Lukasz Anforowicz | 40c2eb8 | 2022-01-11 18:22:31 +0000 | [diff] [blame^] | 11 | use elided_lifetimes::*; |
Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 12 | |
| 13 | #[test] |
| 14 | fn test_user_provided_constructors() { |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 15 | assert_impl_all!(StructWithUserProvidedConstructors: Default); |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 16 | let s: StructWithUserProvidedConstructors = Default::default(); |
Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 17 | assert_eq!(42, s.int_field); |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 18 | |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 19 | // TODO(lukasza): Implement and test a user-defined copy constructor / impl |
| 20 | // Clone. |
| 21 | |
| 22 | // Trivial-ABI structs implement the Copy trait, even if they have user-defined |
| 23 | // constructors. |
| 24 | assert_impl_all!(StructWithUserProvidedConstructors: Copy); |
| 25 | |
| 26 | assert_impl_all!(StructWithUserProvidedConstructors: From<i32>); |
Lukasz Anforowicz | 73326af | 2022-01-05 01:13:10 +0000 | [diff] [blame] | 27 | let i: StructWithUserProvidedConstructors = 123.into(); |
| 28 | assert_eq!(123, i.int_field); |
Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 29 | } |
Lukasz Anforowicz | 7470471 | 2021-12-22 15:30:31 +0000 | [diff] [blame] | 30 | |
| 31 | #[test] |
Lukasz Anforowicz | 7b0042d | 2022-01-06 23:00:19 +0000 | [diff] [blame] | 32 | fn test_inline_constructors() { |
| 33 | assert_impl_all!(StructWithInlineConstructors: Default); |
| 34 | let s: StructWithInlineConstructors = Default::default(); |
| 35 | assert_eq!(123, s.int_field); |
| 36 | |
| 37 | // TODO(lukasza): Implement and test a user-defined copy constructor / impl |
| 38 | // Clone. |
| 39 | |
| 40 | // Trivial-ABI structs implement the Copy trait, even if they have user-defined |
| 41 | // constructors. |
| 42 | assert_impl_all!(StructWithUserProvidedConstructors: Copy); |
Lukasz Anforowicz | 40c2eb8 | 2022-01-11 18:22:31 +0000 | [diff] [blame^] | 43 | let s_copy = s; |
| 44 | assert_eq!(123, s_copy.int_field); |
Lukasz Anforowicz | 7b0042d | 2022-01-06 23:00:19 +0000 | [diff] [blame] | 45 | |
| 46 | assert_impl_all!(StructWithInlineConstructors: From<i32>); |
| 47 | let i: StructWithInlineConstructors = 456.into(); |
| 48 | assert_eq!(456, i.int_field); |
| 49 | } |
| 50 | |
| 51 | #[test] |
Lukasz Anforowicz | 0a1b480 | 2021-12-22 15:30:56 +0000 | [diff] [blame] | 52 | fn test_deleted_constructors() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 53 | assert_not_impl_all!(StructWithDeletedConstructors: Clone); |
| 54 | assert_not_impl_all!(StructWithDeletedConstructors: Copy); |
| 55 | assert_not_impl_all!(StructWithDeletedConstructors: Default); |
| 56 | assert_not_impl_all!(StructWithDeletedConstructors: From<i32>); |
Lukasz Anforowicz | 0a1b480 | 2021-12-22 15:30:56 +0000 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | #[test] |
Lukasz Anforowicz | 7470471 | 2021-12-22 15:30:31 +0000 | [diff] [blame] | 60 | fn test_private_constructors() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 61 | assert_not_impl_all!(StructWithPrivateConstructors: Clone); |
| 62 | assert_not_impl_all!(StructWithPrivateConstructors: Copy); |
| 63 | assert_not_impl_all!(StructWithPrivateConstructors: Default); |
| 64 | assert_not_impl_all!(StructWithPrivateConstructors: From<i32>); |
Lukasz Anforowicz | 7470471 | 2021-12-22 15:30:31 +0000 | [diff] [blame] | 65 | } |
Lukasz Anforowicz | e643ec9 | 2021-12-22 15:45:15 +0000 | [diff] [blame] | 66 | |
| 67 | #[test] |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 68 | #[allow(clippy::clone_on_copy)] |
| 69 | fn test_explicitly_defaulted_constructors() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 70 | assert_impl_all!(StructWithExplicitlyDefaultedConstructors: Default); |
| 71 | let s: StructWithExplicitlyDefaultedConstructors = Default::default(); |
Lukasz Anforowicz | bedbdee | 2022-01-05 01:14:52 +0000 | [diff] [blame] | 72 | assert_eq!(0, s.field_with_no_initializer); // Using `MaybeUninit<T>::zeroed()`. |
Lukasz Anforowicz | e643ec9 | 2021-12-22 15:45:15 +0000 | [diff] [blame] | 73 | assert_eq!(123, s.field_with_explicit_initializer); |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 74 | |
| 75 | // In some scenarios the bindings generator may be able to ask Rust to |
| 76 | // `#[derive(Clone)]` (e.g. when the C++ constructor has been |
| 77 | // implicitly or explicitly `=default`-ed + when Rust can mimic how C++ |
| 78 | // would copy/clone all the fields). Therefore, the test assertions |
| 79 | // below may mostly be testing/exercising how Rust derives Clone. This |
| 80 | // should be okay. |
| 81 | assert_impl_all!(StructWithExplicitlyDefaultedConstructors: Clone); |
Lukasz Anforowicz | 40c2eb8 | 2022-01-11 18:22:31 +0000 | [diff] [blame^] | 82 | let s_clone = s.clone(); |
| 83 | assert_eq!(0, s_clone.field_with_no_initializer); |
| 84 | assert_eq!(123, s_clone.field_with_explicit_initializer); |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 85 | |
| 86 | assert_impl_all!(StructWithExplicitlyDefaultedConstructors: Copy); |
Lukasz Anforowicz | e643ec9 | 2021-12-22 15:45:15 +0000 | [diff] [blame] | 87 | } |
Lukasz Anforowicz | 9bab835 | 2021-12-22 17:35:31 +0000 | [diff] [blame] | 88 | |
| 89 | #[test] |
| 90 | fn test_nontrivial_struct() { |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 91 | // Non-trivial types cannot be copied. |
| 92 | assert_not_impl_all!(NonTrivialStructWithConstructors: Copy); |
| 93 | |
| 94 | // Non-trivial types cannot be constructed by-value, despite having default |
| 95 | // constructor, copy constructor, and constructor taking an int. |
| 96 | assert_not_impl_all!(NonTrivialStructWithConstructors: Clone); |
Lukasz Anforowicz | 9bab835 | 2021-12-22 17:35:31 +0000 | [diff] [blame] | 97 | assert_not_impl_all!(NonTrivialStructWithConstructors: Default); |
Lukasz Anforowicz | cd32f06 | 2022-01-05 01:14:07 +0000 | [diff] [blame] | 98 | assert_not_impl_all!(NonTrivialStructWithConstructors: From<i32>); |
| 99 | |
| 100 | // TODO(b/200067242): Support constructing non-trivially-relocatable |
| 101 | // types. See also <internal link>. |
Lukasz Anforowicz | 9bab835 | 2021-12-22 17:35:31 +0000 | [diff] [blame] | 102 | } |
Lukasz Anforowicz | 40c2eb8 | 2022-01-11 18:22:31 +0000 | [diff] [blame^] | 103 | |
| 104 | #[test] |
| 105 | fn test_elided_lifetimes() { |
| 106 | assert_impl_all!(ElidedLifetimes: Default); |
| 107 | let s: ElidedLifetimes = Default::default(); |
| 108 | assert_eq!(456, s.int_field); |
| 109 | |
| 110 | // TODO(lukasza): Implement and test a user-defined copy constructor / impl |
| 111 | // Clone. |
| 112 | |
| 113 | // Trivial-ABI structs implement the Copy trait, even if they have user-defined |
| 114 | // constructors. |
| 115 | assert_impl_all!(ElidedLifetimes: Copy); |
| 116 | let s_copy = s; |
| 117 | assert_eq!(456, s_copy.int_field); |
| 118 | |
| 119 | assert_impl_all!(ElidedLifetimes: From<i32>); |
| 120 | let i: ElidedLifetimes = 123.into(); |
| 121 | assert_eq!(123, i.int_field); |
| 122 | } |
Lukasz Anforowicz | 13cf749 | 2021-12-22 15:29:52 +0000 | [diff] [blame] | 123 | } |