]> git.lizzy.rs Git - rust.git/blob - library/core/tests/any.rs
Auto merge of #98100 - bjorn3:use_object_for_bitcode_reading, r=wesleywiser
[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 the `Provider` API.
135
136 struct SomeConcreteType {
137     some_string: String,
138 }
139
140 impl Provider for SomeConcreteType {
141     fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
142         demand
143             .provide_ref::<String>(&self.some_string)
144             .provide_ref::<str>(&self.some_string)
145             .provide_value::<String>(|| "bye".to_owned());
146     }
147 }
148
149 // Test the provide and request mechanisms with a by-reference trait object.
150 #[test]
151 fn test_provider() {
152     let obj: &dyn Provider = &SomeConcreteType { some_string: "hello".to_owned() };
153
154     assert_eq!(&**request_ref::<String>(obj).unwrap(), "hello");
155     assert_eq!(&*request_value::<String>(obj).unwrap(), "bye");
156     assert_eq!(request_value::<u8>(obj), None);
157 }
158
159 // Test the provide and request mechanisms with a boxed trait object.
160 #[test]
161 fn test_provider_boxed() {
162     let obj: Box<dyn Provider> = Box::new(SomeConcreteType { some_string: "hello".to_owned() });
163
164     assert_eq!(&**request_ref::<String>(&*obj).unwrap(), "hello");
165     assert_eq!(&*request_value::<String>(&*obj).unwrap(), "bye");
166     assert_eq!(request_value::<u8>(&*obj), None);
167 }
168
169 // Test the provide and request mechanisms with a concrete object.
170 #[test]
171 fn test_provider_concrete() {
172     let obj = SomeConcreteType { some_string: "hello".to_owned() };
173
174     assert_eq!(&**request_ref::<String>(&obj).unwrap(), "hello");
175     assert_eq!(&*request_value::<String>(&obj).unwrap(), "bye");
176     assert_eq!(request_value::<u8>(&obj), None);
177 }
178
179 trait OtherTrait: Provider {}
180
181 impl OtherTrait for SomeConcreteType {}
182
183 impl dyn OtherTrait {
184     fn get_ref<T: 'static + ?Sized>(&self) -> Option<&T> {
185         request_ref::<T>(self)
186     }
187 }
188
189 // Test the provide and request mechanisms via an intermediate trait.
190 #[test]
191 fn test_provider_intermediate() {
192     let obj: &dyn OtherTrait = &SomeConcreteType { some_string: "hello".to_owned() };
193     assert_eq!(obj.get_ref::<str>().unwrap(), "hello");
194 }