]> git.lizzy.rs Git - rust.git/blob - library/core/tests/any.rs
Auto merge of #107267 - cjgillot:keep-aggregate, r=oli-obk
[rust.git] / library / core / tests / any.rs
1 use core::any::*;
2
3 #[derive(PartialEq, Debug)]
4 struct Test;
5
6 static TEST: &'static str = "Test";
7
8 #[test]
9 fn any_referenced() {
10     let (a, b, c) = (&5 as &dyn Any, &TEST as &dyn Any, &Test as &dyn Any);
11
12     assert!(a.is::<i32>());
13     assert!(!b.is::<i32>());
14     assert!(!c.is::<i32>());
15
16     assert!(!a.is::<&'static str>());
17     assert!(b.is::<&'static str>());
18     assert!(!c.is::<&'static str>());
19
20     assert!(!a.is::<Test>());
21     assert!(!b.is::<Test>());
22     assert!(c.is::<Test>());
23 }
24
25 #[test]
26 fn any_owning() {
27     let (a, b, c) = (
28         Box::new(5_usize) as Box<dyn Any>,
29         Box::new(TEST) as Box<dyn Any>,
30         Box::new(Test) as Box<dyn Any>,
31     );
32
33     assert!(a.is::<usize>());
34     assert!(!b.is::<usize>());
35     assert!(!c.is::<usize>());
36
37     assert!(!a.is::<&'static str>());
38     assert!(b.is::<&'static str>());
39     assert!(!c.is::<&'static str>());
40
41     assert!(!a.is::<Test>());
42     assert!(!b.is::<Test>());
43     assert!(c.is::<Test>());
44 }
45
46 #[test]
47 fn any_downcast_ref() {
48     let a = &5_usize as &dyn Any;
49
50     match a.downcast_ref::<usize>() {
51         Some(&5) => {}
52         x => panic!("Unexpected value {x:?}"),
53     }
54
55     match a.downcast_ref::<Test>() {
56         None => {}
57         x => panic!("Unexpected value {x:?}"),
58     }
59 }
60
61 #[test]
62 fn any_downcast_mut() {
63     let mut a = 5_usize;
64     let mut b: Box<_> = Box::new(7_usize);
65
66     let a_r = &mut a as &mut dyn Any;
67     let tmp: &mut usize = &mut *b;
68     let b_r = tmp as &mut dyn Any;
69
70     match a_r.downcast_mut::<usize>() {
71         Some(x) => {
72             assert_eq!(*x, 5);
73             *x = 612;
74         }
75         x => panic!("Unexpected value {x:?}"),
76     }
77
78     match b_r.downcast_mut::<usize>() {
79         Some(x) => {
80             assert_eq!(*x, 7);
81             *x = 413;
82         }
83         x => panic!("Unexpected value {x:?}"),
84     }
85
86     match a_r.downcast_mut::<Test>() {
87         None => (),
88         x => panic!("Unexpected value {x:?}"),
89     }
90
91     match b_r.downcast_mut::<Test>() {
92         None => (),
93         x => panic!("Unexpected value {x:?}"),
94     }
95
96     match a_r.downcast_mut::<usize>() {
97         Some(&mut 612) => {}
98         x => panic!("Unexpected value {x:?}"),
99     }
100
101     match b_r.downcast_mut::<usize>() {
102         Some(&mut 413) => {}
103         x => panic!("Unexpected value {x:?}"),
104     }
105 }
106
107 #[test]
108 fn any_fixed_vec() {
109     let test = [0_usize; 8];
110     let test = &test as &dyn Any;
111     assert!(test.is::<[usize; 8]>());
112     assert!(!test.is::<[usize; 10]>());
113 }
114
115 #[test]
116 fn any_unsized() {
117     fn is_any<T: Any + ?Sized>() {}
118     is_any::<[i32]>();
119 }
120
121 #[test]
122 fn distinct_type_names() {
123     // https://github.com/rust-lang/rust/issues/84666
124
125     struct Velocity(f32, f32);
126
127     fn type_name_of_val<T>(_: T) -> &'static str {
128         type_name::<T>()
129     }
130
131     assert_ne!(type_name_of_val(Velocity), type_name_of_val(Velocity(0.0, -9.8)),);
132 }
133
134 #[test]
135 fn dyn_type_name() {
136     trait Foo {
137         type Bar;
138     }
139
140     assert_eq!(
141         "dyn core::ops::function::Fn(i32, i32) -> i32",
142         std::any::type_name::<dyn Fn(i32, i32) -> i32>()
143     );
144     assert_eq!(
145         "dyn coretests::any::dyn_type_name::Foo<Bar = i32> \
146         + core::marker::Send + core::marker::Sync",
147         std::any::type_name::<dyn Foo<Bar = i32> + Send + Sync>()
148     );
149 }
150
151 // Test the `Provider` API.
152
153 struct SomeConcreteType {
154     some_string: String,
155 }
156
157 impl Provider for SomeConcreteType {
158     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
159         demand
160             .provide_ref::<String>(&self.some_string)
161             .provide_ref::<str>(&self.some_string)
162             .provide_value_with::<String>(|| "bye".to_owned());
163     }
164 }
165
166 // Test the provide and request mechanisms with a by-reference trait object.
167 #[test]
168 fn test_provider() {
169     let obj: &dyn Provider = &SomeConcreteType { some_string: "hello".to_owned() };
170
171     assert_eq!(&**request_ref::<String>(obj).unwrap(), "hello");
172     assert_eq!(&*request_value::<String>(obj).unwrap(), "bye");
173     assert_eq!(request_value::<u8>(obj), None);
174 }
175
176 // Test the provide and request mechanisms with a boxed trait object.
177 #[test]
178 fn test_provider_boxed() {
179     let obj: Box<dyn Provider> = Box::new(SomeConcreteType { some_string: "hello".to_owned() });
180
181     assert_eq!(&**request_ref::<String>(&*obj).unwrap(), "hello");
182     assert_eq!(&*request_value::<String>(&*obj).unwrap(), "bye");
183     assert_eq!(request_value::<u8>(&*obj), None);
184 }
185
186 // Test the provide and request mechanisms with a concrete object.
187 #[test]
188 fn test_provider_concrete() {
189     let obj = SomeConcreteType { some_string: "hello".to_owned() };
190
191     assert_eq!(&**request_ref::<String>(&obj).unwrap(), "hello");
192     assert_eq!(&*request_value::<String>(&obj).unwrap(), "bye");
193     assert_eq!(request_value::<u8>(&obj), None);
194 }
195
196 trait OtherTrait: Provider {}
197
198 impl OtherTrait for SomeConcreteType {}
199
200 impl dyn OtherTrait {
201     fn get_ref<T: 'static + ?Sized>(&self) -> Option<&T> {
202         request_ref::<T>(self)
203     }
204 }
205
206 // Test the provide and request mechanisms via an intermediate trait.
207 #[test]
208 fn test_provider_intermediate() {
209     let obj: &dyn OtherTrait = &SomeConcreteType { some_string: "hello".to_owned() };
210     assert_eq!(obj.get_ref::<str>().unwrap(), "hello");
211 }