blob: e3b551355781373a47b0077e74b6918635dd167c [file] [log] [blame]
Lukasz Anforowicz13cf7492021-12-22 15:29:52 +00001// 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]
6extern crate static_assertions;
7
8#[cfg(test)]
9mod tests {
10 use constructors::*;
11
12 #[test]
13 fn test_user_provided_constructors() {
Lukasz Anforowicz73326af2022-01-05 01:13:10 +000014 assert_impl_all!(StructWithUserProvidedConstructors: Default);
Lukasz Anforowicz73326af2022-01-05 01:13:10 +000015 let s: StructWithUserProvidedConstructors = Default::default();
Lukasz Anforowicz13cf7492021-12-22 15:29:52 +000016 assert_eq!(42, s.int_field);
Lukasz Anforowicz73326af2022-01-05 01:13:10 +000017
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000018 // 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 Anforowicz73326af2022-01-05 01:13:10 +000026 let i: StructWithUserProvidedConstructors = 123.into();
27 assert_eq!(123, i.int_field);
Lukasz Anforowicz13cf7492021-12-22 15:29:52 +000028 }
Lukasz Anforowicz74704712021-12-22 15:30:31 +000029
30 #[test]
Lukasz Anforowicz7b0042d2022-01-06 23:00:19 +000031 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 Anforowicz0a1b4802021-12-22 15:30:56 +000051 fn test_deleted_constructors() {
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000052 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 Anforowicz0a1b4802021-12-22 15:30:56 +000056 }
57
58 #[test]
Lukasz Anforowicz74704712021-12-22 15:30:31 +000059 fn test_private_constructors() {
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000060 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 Anforowicz74704712021-12-22 15:30:31 +000064 }
Lukasz Anforowicze643ec92021-12-22 15:45:15 +000065
66 #[test]
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000067 #[allow(clippy::clone_on_copy)]
68 fn test_explicitly_defaulted_constructors() {
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000069 assert_impl_all!(StructWithExplicitlyDefaultedConstructors: Default);
70 let s: StructWithExplicitlyDefaultedConstructors = Default::default();
Lukasz Anforowiczbedbdee2022-01-05 01:14:52 +000071 assert_eq!(0, s.field_with_no_initializer); // Using `MaybeUninit<T>::zeroed()`.
Lukasz Anforowicze643ec92021-12-22 15:45:15 +000072 assert_eq!(123, s.field_with_explicit_initializer);
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000073
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 Anforowicze643ec92021-12-22 15:45:15 +000086 }
Lukasz Anforowicz9bab8352021-12-22 17:35:31 +000087
88 #[test]
89 fn test_nontrivial_struct() {
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000090 // 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 Anforowicz9bab8352021-12-22 17:35:31 +000096 assert_not_impl_all!(NonTrivialStructWithConstructors: Default);
Lukasz Anforowiczcd32f062022-01-05 01:14:07 +000097 assert_not_impl_all!(NonTrivialStructWithConstructors: From<i32>);
98
99 // TODO(b/200067242): Support constructing non-trivially-relocatable
100 // types. See also <internal link>.
Lukasz Anforowicz9bab8352021-12-22 17:35:31 +0000101 }
Lukasz Anforowicz13cf7492021-12-22 15:29:52 +0000102}