• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use core::cell::Cell;
2 use core::clone::Clone;
3 use core::mem;
4 use core::ops::DerefMut;
5 use core::option::*;
6 
7 #[test]
test_get_ptr()8 fn test_get_ptr() {
9     unsafe {
10         let x: Box<_> = Box::new(0);
11         let addr_x: *const isize = mem::transmute(&*x);
12         let opt = Some(x);
13         let y = opt.unwrap();
14         let addr_y: *const isize = mem::transmute(&*y);
15         assert_eq!(addr_x, addr_y);
16     }
17 }
18 
19 #[test]
test_get_str()20 fn test_get_str() {
21     let x = "test".to_string();
22     let addr_x = x.as_ptr();
23     let opt = Some(x);
24     let y = opt.unwrap();
25     let addr_y = y.as_ptr();
26     assert_eq!(addr_x, addr_y);
27 }
28 
29 #[test]
test_get_resource()30 fn test_get_resource() {
31     use core::cell::RefCell;
32     use std::rc::Rc;
33 
34     struct R {
35         i: Rc<RefCell<isize>>,
36     }
37 
38     impl Drop for R {
39         fn drop(&mut self) {
40             let ii = &*self.i;
41             let i = *ii.borrow();
42             *ii.borrow_mut() = i + 1;
43         }
44     }
45 
46     fn r(i: Rc<RefCell<isize>>) -> R {
47         R { i }
48     }
49 
50     let i = Rc::new(RefCell::new(0));
51     {
52         let x = r(i.clone());
53         let opt = Some(x);
54         let _y = opt.unwrap();
55     }
56     assert_eq!(*i.borrow(), 1);
57 }
58 
59 #[test]
60 #[allow(for_loops_over_fallibles)]
test_option_dance()61 fn test_option_dance() {
62     let x = Some(());
63     let mut y = Some(5);
64     let mut y2 = 0;
65     for _x in x {
66         y2 = y.take().unwrap();
67     }
68     assert_eq!(y2, 5);
69     assert!(y.is_none());
70 }
71 
72 #[test]
73 #[should_panic]
test_option_too_much_dance()74 fn test_option_too_much_dance() {
75     struct A;
76     let mut y = Some(A);
77     let _y2 = y.take().unwrap();
78     let _y3 = y.take().unwrap();
79 }
80 
81 #[test]
test_and()82 fn test_and() {
83     let x: Option<isize> = Some(1);
84     assert_eq!(x.and(Some(2)), Some(2));
85     assert_eq!(x.and(None::<isize>), None);
86 
87     let x: Option<isize> = None;
88     assert_eq!(x.and(Some(2)), None);
89     assert_eq!(x.and(None::<isize>), None);
90 
91     /* FIXME(#110395)
92     const FOO: Option<isize> = Some(1);
93     const A: Option<isize> = FOO.and(Some(2));
94     const B: Option<isize> = FOO.and(None);
95     assert_eq!(A, Some(2));
96     assert_eq!(B, None);
97 
98     const BAR: Option<isize> = None;
99     const C: Option<isize> = BAR.and(Some(2));
100     const D: Option<isize> = BAR.and(None);
101     assert_eq!(C, None);
102     assert_eq!(D, None);
103     */
104 }
105 
106 #[test]
test_and_then()107 fn test_and_then() {
108     const fn plus_one(x: isize) -> Option<isize> {
109         Some(x + 1)
110     }
111 
112     const fn none(_: isize) -> Option<isize> {
113         None
114     }
115 
116     let x: Option<isize> = Some(1);
117     assert_eq!(x.and_then(plus_one), Some(2));
118     assert_eq!(x.and_then(none), None);
119 
120     let x: Option<isize> = None;
121     assert_eq!(x.and_then(plus_one), None);
122     assert_eq!(x.and_then(none), None);
123 
124     /* FIXME(#110395)
125     const FOO: Option<isize> = Some(1);
126     const A: Option<isize> = FOO.and_then(plus_one);
127     const B: Option<isize> = FOO.and_then(none);
128     assert_eq!(A, Some(2));
129     assert_eq!(B, None);
130 
131     const BAR: Option<isize> = None;
132     const C: Option<isize> = BAR.and_then(plus_one);
133     const D: Option<isize> = BAR.and_then(none);
134     assert_eq!(C, None);
135     assert_eq!(D, None);
136     */
137 }
138 
139 #[test]
test_or()140 fn test_or() {
141     let x: Option<isize> = Some(1);
142     assert_eq!(x.or(Some(2)), Some(1));
143     assert_eq!(x.or(None), Some(1));
144 
145     let x: Option<isize> = None;
146     assert_eq!(x.or(Some(2)), Some(2));
147     assert_eq!(x.or(None), None);
148 
149     /* FIXME(#110395)
150     const FOO: Option<isize> = Some(1);
151     const A: Option<isize> = FOO.or(Some(2));
152     const B: Option<isize> = FOO.or(None);
153     assert_eq!(A, Some(1));
154     assert_eq!(B, Some(1));
155 
156     const BAR: Option<isize> = None;
157     const C: Option<isize> = BAR.or(Some(2));
158     const D: Option<isize> = BAR.or(None);
159     assert_eq!(C, Some(2));
160     assert_eq!(D, None);
161     */
162 }
163 
164 #[test]
test_or_else()165 fn test_or_else() {
166     const fn two() -> Option<isize> {
167         Some(2)
168     }
169 
170     const fn none() -> Option<isize> {
171         None
172     }
173 
174     let x: Option<isize> = Some(1);
175     assert_eq!(x.or_else(two), Some(1));
176     assert_eq!(x.or_else(none), Some(1));
177 
178     let x: Option<isize> = None;
179     assert_eq!(x.or_else(two), Some(2));
180     assert_eq!(x.or_else(none), None);
181 
182 /* FIXME(#110395)
183     const FOO: Option<isize> = Some(1);
184     const A: Option<isize> = FOO.or_else(two);
185     const B: Option<isize> = FOO.or_else(none);
186     assert_eq!(A, Some(1));
187     assert_eq!(B, Some(1));
188 
189     const BAR: Option<isize> = None;
190     const C: Option<isize> = BAR.or_else(two);
191     const D: Option<isize> = BAR.or_else(none);
192     assert_eq!(C, Some(2));
193     assert_eq!(D, None);
194 */
195 }
196 
197 #[test]
test_unwrap()198 fn test_unwrap() {
199     assert_eq!(Some(1).unwrap(), 1);
200     let s = Some("hello".to_string()).unwrap();
201     assert_eq!(s, "hello");
202 }
203 
204 #[test]
205 #[should_panic]
test_unwrap_panic1()206 fn test_unwrap_panic1() {
207     let x: Option<isize> = None;
208     x.unwrap();
209 }
210 
211 #[test]
212 #[should_panic]
test_unwrap_panic2()213 fn test_unwrap_panic2() {
214     let x: Option<String> = None;
215     x.unwrap();
216 }
217 
218 #[test]
test_unwrap_or()219 fn test_unwrap_or() {
220     let x: Option<isize> = Some(1);
221     assert_eq!(x.unwrap_or(2), 1);
222 
223     let x: Option<isize> = None;
224     assert_eq!(x.unwrap_or(2), 2);
225 
226     /* FIXME(#110395)
227     const A: isize = Some(1).unwrap_or(2);
228     const B: isize = None.unwrap_or(2);
229     assert_eq!(A, 1);
230     assert_eq!(B, 2);
231     */
232 }
233 
234 #[test]
test_unwrap_or_else()235 fn test_unwrap_or_else() {
236     const fn two() -> isize {
237         2
238     }
239 
240     let x: Option<isize> = Some(1);
241     assert_eq!(x.unwrap_or_else(two), 1);
242 
243     let x: Option<isize> = None;
244     assert_eq!(x.unwrap_or_else(two), 2);
245 
246     /* FIXME(#110395)
247     const A: isize = Some(1).unwrap_or_else(two);
248     const B: isize = None.unwrap_or_else(two);
249     assert_eq!(A, 1);
250     assert_eq!(B, 2);
251     */
252 }
253 
254 #[test]
test_unwrap_unchecked()255 fn test_unwrap_unchecked() {
256     assert_eq!(unsafe { Some(1).unwrap_unchecked() }, 1);
257     let s = unsafe { Some("hello".to_string()).unwrap_unchecked() };
258     assert_eq!(s, "hello");
259 }
260 
261 #[test]
test_iter()262 fn test_iter() {
263     let val = 5;
264 
265     let x = Some(val);
266     let mut it = x.iter();
267 
268     assert_eq!(it.size_hint(), (1, Some(1)));
269     assert_eq!(it.next(), Some(&val));
270     assert_eq!(it.size_hint(), (0, Some(0)));
271     assert!(it.next().is_none());
272 
273     let mut it = (&x).into_iter();
274     assert_eq!(it.next(), Some(&val));
275 }
276 
277 #[test]
test_mut_iter()278 fn test_mut_iter() {
279     let mut val = 5;
280     let new_val = 11;
281 
282     let mut x = Some(val);
283     {
284         let mut it = x.iter_mut();
285 
286         assert_eq!(it.size_hint(), (1, Some(1)));
287 
288         match it.next() {
289             Some(interior) => {
290                 assert_eq!(*interior, val);
291                 *interior = new_val;
292             }
293             None => assert!(false),
294         }
295 
296         assert_eq!(it.size_hint(), (0, Some(0)));
297         assert!(it.next().is_none());
298     }
299     assert_eq!(x, Some(new_val));
300 
301     let mut y = Some(val);
302     let mut it = (&mut y).into_iter();
303     assert_eq!(it.next(), Some(&mut val));
304 }
305 
306 #[test]
test_ord()307 fn test_ord() {
308     let small = Some(1.0f64);
309     let big = Some(5.0f64);
310     let nan = Some(0.0f64 / 0.0);
311     assert!(!(nan < big));
312     assert!(!(nan > big));
313     assert!(small < big);
314     assert!(None < big);
315     assert!(big > None);
316 }
317 
318 #[test]
test_collect()319 fn test_collect() {
320     let v: Option<Vec<isize>> = (0..0).map(|_| Some(0)).collect();
321     assert!(v == Some(vec![]));
322 
323     let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
324     assert!(v == Some(vec![0, 1, 2]));
325 
326     let v: Option<Vec<isize>> = (0..3).map(|x| if x > 1 { None } else { Some(x) }).collect();
327     assert!(v == None);
328 
329     // test that it does not take more elements than it needs
330     let mut functions: [Box<dyn Fn() -> Option<()>>; 3] =
331         [Box::new(|| Some(())), Box::new(|| None), Box::new(|| panic!())];
332 
333     let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
334 
335     assert!(v == None);
336 }
337 
338 #[test]
test_copied()339 fn test_copied() {
340     let val = 1;
341     let val_ref = &val;
342     let opt_none: Option<&'static u32> = None;
343     let opt_ref = Some(&val);
344     let opt_ref_ref = Some(&val_ref);
345 
346     // None works
347     assert_eq!(opt_none.clone(), None);
348     assert_eq!(opt_none.copied(), None);
349 
350     // Immutable ref works
351     assert_eq!(opt_ref.clone(), Some(&val));
352     assert_eq!(opt_ref.copied(), Some(1));
353 
354     // Double Immutable ref works
355     assert_eq!(opt_ref_ref.clone(), Some(&val_ref));
356     assert_eq!(opt_ref_ref.clone().copied(), Some(&val));
357     assert_eq!(opt_ref_ref.copied().copied(), Some(1));
358 }
359 
360 #[test]
test_cloned()361 fn test_cloned() {
362     let val = 1;
363     let val_ref = &val;
364     let opt_none: Option<&'static u32> = None;
365     let opt_ref = Some(&val);
366     let opt_ref_ref = Some(&val_ref);
367 
368     // None works
369     assert_eq!(opt_none.clone(), None);
370     assert_eq!(opt_none.cloned(), None);
371 
372     // Immutable ref works
373     assert_eq!(opt_ref.clone(), Some(&val));
374     assert_eq!(opt_ref.cloned(), Some(1));
375 
376     // Double Immutable ref works
377     assert_eq!(opt_ref_ref.clone(), Some(&val_ref));
378     assert_eq!(opt_ref_ref.clone().cloned(), Some(&val));
379     assert_eq!(opt_ref_ref.cloned().cloned(), Some(1));
380 }
381 
382 #[test]
test_try()383 fn test_try() {
384     fn try_option_some() -> Option<u8> {
385         let val = Some(1)?;
386         Some(val)
387     }
388     assert_eq!(try_option_some(), Some(1));
389 
390     fn try_option_none() -> Option<u8> {
391         let val = None?;
392         Some(val)
393     }
394     assert_eq!(try_option_none(), None);
395 }
396 
397 #[test]
test_option_as_deref()398 fn test_option_as_deref() {
399     // Some: &Option<T: Deref>::Some(T) -> Option<&T::Deref::Target>::Some(&*T)
400     let ref_option = &Some(&42);
401     assert_eq!(ref_option.as_deref(), Some(&42));
402 
403     let ref_option = &Some(String::from("a result"));
404     assert_eq!(ref_option.as_deref(), Some("a result"));
405 
406     let ref_option = &Some(vec![1, 2, 3, 4, 5]);
407     assert_eq!(ref_option.as_deref(), Some([1, 2, 3, 4, 5].as_slice()));
408 
409     // None: &Option<T: Deref>>::None -> None
410     let ref_option: &Option<&i32> = &None;
411     assert_eq!(ref_option.as_deref(), None);
412 }
413 
414 #[test]
test_option_as_deref_mut()415 fn test_option_as_deref_mut() {
416     // Some: &mut Option<T: Deref>::Some(T) -> Option<&mut T::Deref::Target>::Some(&mut *T)
417     let mut val = 42;
418     let ref_option = &mut Some(&mut val);
419     assert_eq!(ref_option.as_deref_mut(), Some(&mut 42));
420 
421     let ref_option = &mut Some(String::from("a result"));
422     assert_eq!(ref_option.as_deref_mut(), Some(String::from("a result").deref_mut()));
423 
424     let ref_option = &mut Some(vec![1, 2, 3, 4, 5]);
425     assert_eq!(ref_option.as_deref_mut(), Some([1, 2, 3, 4, 5].as_mut_slice()));
426 
427     // None: &mut Option<T: Deref>>::None -> None
428     let ref_option: &mut Option<&mut i32> = &mut None;
429     assert_eq!(ref_option.as_deref_mut(), None);
430 }
431 
432 #[test]
test_replace()433 fn test_replace() {
434     let mut x = Some(2);
435     let old = x.replace(5);
436 
437     assert_eq!(x, Some(5));
438     assert_eq!(old, Some(2));
439 
440     let mut x = None;
441     let old = x.replace(3);
442 
443     assert_eq!(x, Some(3));
444     assert_eq!(old, None);
445 }
446 
447 #[test]
option_const()448 fn option_const() {
449     // test that the methods of `Option` are usable in a const context
450 
451     const OPTION: Option<usize> = Some(32);
452     assert_eq!(OPTION, Some(32));
453 
454     // FIXME(#110395)
455     // const OPTION_FROM: Option<usize> = Option::from(32);
456     // assert_eq!(OPTION_FROM, Some(32));
457 
458     const REF: Option<&usize> = OPTION.as_ref();
459     assert_eq!(REF, Some(&32));
460 
461     // const REF_FROM: Option<&usize> = Option::from(&OPTION);
462     // assert_eq!(REF_FROM, Some(&32));
463 
464     const IS_SOME: bool = OPTION.is_some();
465     assert!(IS_SOME);
466 
467     const IS_NONE: bool = OPTION.is_none();
468     assert!(!IS_NONE);
469 
470     const COPIED: Option<usize> = OPTION.as_ref().copied();
471     assert_eq!(COPIED, OPTION);
472 }
473 
474 #[test]
option_const_mut()475 const fn option_const_mut() {
476     // test that the methods of `Option` that take mutable references are usable in a const context
477 
478     let mut option: Option<usize> = Some(32);
479 
480     let _take = option.take();
481     let _replace = option.replace(42);
482 
483     {
484         let as_mut = option.as_mut();
485         match as_mut {
486             Some(v) => *v = 32,
487             None => unreachable!(),
488         }
489     }
490 /* FIXME(const-hack)
491     {
492         let as_mut: Option<&mut usize> = Option::from(&mut option);
493         match as_mut {
494             Some(v) => *v = 42,
495             None => unreachable!(),
496         }
497     }
498 */
499 }
500 
501 #[test]
test_unwrap_drop()502 fn test_unwrap_drop() {
503     struct Dtor<'a> {
504         x: &'a Cell<isize>,
505     }
506 
507     impl<'a> std::ops::Drop for Dtor<'a> {
508         fn drop(&mut self) {
509             self.x.set(self.x.get() - 1);
510         }
511     }
512 
513     fn unwrap<T>(o: Option<T>) -> T {
514         match o {
515             Some(v) => v,
516             None => panic!(),
517         }
518     }
519 
520     let x = &Cell::new(1);
521 
522     {
523         let b = Some(Dtor { x });
524         let _c = unwrap(b);
525     }
526 
527     assert_eq!(x.get(), 0);
528 }
529 
530 #[test]
option_ext()531 fn option_ext() {
532     let thing = "{{ f }}";
533     let f = thing.find("{{");
534 
535     if f.is_none() {
536         println!("None!");
537     }
538 }
539 
540 #[test]
zip_options()541 fn zip_options() {
542     let x = Some(10);
543     let y = Some("foo");
544     let z: Option<usize> = None;
545 
546     assert_eq!(x.zip(y), Some((10, "foo")));
547     assert_eq!(x.zip(z), None);
548     assert_eq!(z.zip(x), None);
549 }
550 
551 #[test]
unzip_options()552 fn unzip_options() {
553     let x = Some((10, "foo"));
554     let y = None::<(bool, i32)>;
555 
556     assert_eq!(x.unzip(), (Some(10), Some("foo")));
557     assert_eq!(y.unzip(), (None, None));
558 }
559 
560 #[test]
zip_unzip_roundtrip()561 fn zip_unzip_roundtrip() {
562     let x = Some(10);
563     let y = Some("foo");
564 
565     let z = x.zip(y);
566     assert_eq!(z, Some((10, "foo")));
567 
568     let a = z.unzip();
569     assert_eq!(a, (x, y));
570 }
571