// This code below is adapted from the `Option` implementation in the Rust core library which is // released under the MIT licenses with the following copyright notice: // // Copyright (c) The Rust Project Contributors use core::ops::{Deref, DerefMut}; use core::pin::Pin; use core::ptr; use core::{hint, mem}; // summary=test::option::replace;Argument[0].Reference;ReturnValue;value;dfc-generated // summary=test::option::replace;Argument[1];Argument[0].Reference;value;dfc-generated // sink=test::option::replace;Argument[0];pointer-access;df-generated pub fn replace(dest: &mut T, src: T) -> T { unsafe { let result = ptr::read(dest); ptr::write(dest, src); result } } #[derive(Copy, Eq, Debug, Hash)] pub enum MyOption { MyNone, MySome(T), } use MyOption::*; // Type implementation impl MyOption { pub fn is_some(&self) -> bool { matches!(*self, MySome(_)) } // summary=::is_some_and;Argument[0].ReturnValue;ReturnValue;value;dfc-generated // summary=::is_some_and;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0];value;dfc-generated pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool { match self { MyNone => false, MySome(x) => f(x), } } pub fn is_none(&self) -> bool { !self.is_some() } // summary=::is_none_or;Argument[0].ReturnValue;ReturnValue;value;dfc-generated // summary=::is_none_or;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0];value;dfc-generated pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool { match self { MyNone => true, MySome(x) => f(x), } } // summary=::as_ref;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;value;dfc-generated pub fn as_ref(&self) -> MyOption<&T> { match *self { MySome(ref x) => MySome(x), MyNone => MyNone, } } // summary=::as_mut;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;value;dfc-generated pub fn as_mut(&mut self) -> MyOption<&mut T> { match *self { MySome(ref mut x) => MySome(x), MyNone => MyNone, } } // MISSING: Flow through `Pin` pub fn as_pin_ref(self: Pin<&Self>) -> MyOption> { // FIXME(const-hack): use `map` once that is possible match Pin::get_ref(self).as_ref() { // SAFETY: `x` is guaranteed to be pinned because it comes from `self` // which is pinned. MySome(x) => unsafe { MySome(Pin::new_unchecked(x)) }, MyNone => MyNone, } } // MISSING: Flow through `Pin` pub fn as_pin_mut(self: Pin<&mut Self>) -> MyOption> { // SAFETY: `get_unchecked_mut` is never used to move the `MyOption` inside `self`. // `x` is guaranteed to be pinned because it comes from `self` which is pinned. unsafe { // FIXME(const-hack): use `map` once that is possible match Pin::get_unchecked_mut(self).as_mut() { MySome(x) => MySome(Pin::new_unchecked(x)), MyNone => MyNone, } } } // summary=::unwrap;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue;value;dfc-generated pub fn unwrap(self) -> T { match self { MySome(val) => val, MyNone => panic!("called `MyOption::unwrap()` on a `MyNone` value"), } } // summary=::unwrap_or;Argument[0];ReturnValue;value;dfc-generated // summary=::unwrap_or;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue;value;dfc-generated pub fn unwrap_or(self, default: T) -> T { match self { MySome(x) => x, MyNone => default, } } // summary=::unwrap_or_else;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue;value;dfc-generated // summary=::unwrap_or_else;Argument[0].ReturnValue;ReturnValue;value;dfc-generated pub fn unwrap_or_else(self, f: F) -> T where F: FnOnce() -> T, { match self { MySome(x) => x, MyNone => f(), } } // summary=::unwrap_or_default;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue;value;dfc-generated pub fn unwrap_or_default(self) -> T where T: Default, { match self { MySome(x) => x, MyNone => T::default(), } } // summary=::unwrap_unchecked;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue;value;dfc-generated #[track_caller] pub unsafe fn unwrap_unchecked(self) -> T { match self { MySome(val) => val, // SAFETY: the safety contract must be upheld by the caller. MyNone => unsafe { hint::unreachable_unchecked() }, } } // Transforming contained values // summary=::map;Argument[0].ReturnValue;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated // summary=::map;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0];value;dfc-generated pub fn map(self, f: F) -> MyOption where F: FnOnce(T) -> U, { match self { MySome(x) => MySome(f(x)), MyNone => MyNone, } } // summary=::inspect;Argument[self];ReturnValue;value;dfc-generated // summary=::inspect;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0].Reference;value;dfc-generated pub fn inspect(self, f: F) -> Self { if let MySome(ref x) = self { f(x); } self } // summary=::map_or;Argument[0];ReturnValue;value;dfc-generated // summary=::map_or;Argument[1].ReturnValue;ReturnValue;value;dfc-generated // summary=::map_or;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[1].Parameter[0];value;dfc-generated pub fn map_or(self, default: U, f: F) -> U where F: FnOnce(T) -> U, { match self { MySome(t) => f(t), MyNone => default, } } // summary=::map_or_else;Argument[0].ReturnValue;ReturnValue;value;dfc-generated // summary=::map_or_else;Argument[1].ReturnValue;ReturnValue;value;dfc-generated // summary=::map_or_else;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[1].Parameter[0];value;dfc-generated pub fn map_or_else(self, default: D, f: F) -> U where D: FnOnce() -> U, F: FnOnce(T) -> U, { match self { MySome(t) => f(t), MyNone => default(), } } // summary=::ok_or;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue.Field[core::result::Result::Ok(0)];value;dfc-generated // summary=::ok_or;Argument[0];ReturnValue.Field[core::result::Result::Err(0)];value;dfc-generated pub fn ok_or(self, err: E) -> Result { match self { MySome(v) => Ok(v), MyNone => Err(err), } } // summary=::ok_or_else;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue.Field[core::result::Result::Ok(0)];value;dfc-generated // summary=::ok_or_else;Argument[0].ReturnValue;ReturnValue.Field[core::result::Result::Err(0)];value;dfc-generated pub fn ok_or_else(self, err: F) -> Result where F: FnOnce() -> E, { match self { MySome(v) => Ok(v), MyNone => Err(err()), } } // MISSING: `Deref` trait pub fn as_deref(&self) -> MyOption<&T::Target> where T: Deref, { self.as_ref().map(|t| t.deref()) } // MISSING: `Deref` trait pub fn as_deref_mut(&mut self) -> MyOption<&mut T::Target> where T: DerefMut, { self.as_mut().map(|t| t.deref_mut()) } // summary=::and;Argument[0];ReturnValue;value;dfc-generated pub fn and(self, optb: MyOption) -> MyOption { match self { MySome(_) => optb, MyNone => MyNone, } } // summary=::and_then;Argument[0].ReturnValue;ReturnValue;value;dfc-generated // summary=::and_then;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0];value;dfc-generated pub fn and_then(self, f: F) -> MyOption where F: FnOnce(T) -> MyOption, { match self { MySome(x) => f(x), MyNone => MyNone, } } // summary=::filter;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0].Reference;value;dfc-generated // summary=::filter;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn filter

(self, predicate: P) -> Self where P: FnOnce(&T) -> bool, { if let MySome(x) = self { if predicate(&x) { return MySome(x); } } MyNone } // summary=::or;Argument[0];ReturnValue;value;dfc-generated // summary=::or;Argument[self];ReturnValue;value;dfc-generated pub fn or(self, optb: MyOption) -> MyOption { match self { x @ MySome(_) => x, MyNone => optb, } } // summary=::or_else;Argument[self];ReturnValue;value;dfc-generated // summary=::or_else;Argument[0].ReturnValue;ReturnValue;value;dfc-generated pub fn or_else(self, f: F) -> MyOption where F: FnOnce() -> MyOption, { match self { x @ MySome(_) => x, MyNone => f(), } } // summary=::xor;Argument[0];ReturnValue;value;dfc-generated // summary=::xor;Argument[self];ReturnValue;value;dfc-generated pub fn xor(self, optb: MyOption) -> MyOption { match (self, optb) { (a @ MySome(_), MyNone) => a, (MyNone, b @ MySome(_)) => b, _ => MyNone, } } // summary=::insert;Argument[0];Argument[self].Reference.Field[test::option::MyOption::MySome(0)];value;dfc-generated // summary=::insert;Argument[0];ReturnValue.Reference;value;dfc-generated // The content of `self` is overwritten so it does not flow to the return value. // SPURIOUS-summary=::insert;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Reference;value;dfc-generated pub fn insert(&mut self, value: T) -> &mut T { *self = MySome(value); // SAFETY: the code above just filled the MyOption unsafe { self.as_mut().unwrap_unchecked() } } // summary=::get_or_insert;Argument[0];Argument[self].Reference.Field[test::option::MyOption::MySome(0)];value;dfc-generated // summary=::get_or_insert;Argument[0];ReturnValue.Reference;value;dfc-generated // summary=::get_or_insert;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Reference;value;dfc-generated pub fn get_or_insert(&mut self, value: T) -> &mut T { self.get_or_insert_with(|| value) } // summary=::get_or_insert_default;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Reference;value;dfc-generated pub fn get_or_insert_default(&mut self) -> &mut T where T: Default, { self.get_or_insert_with(T::default) } // summary=::get_or_insert_with;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Reference;value;dfc-generated // MISSING: Mutating `self` parameter. pub fn get_or_insert_with(&mut self, f: F) -> &mut T where F: FnOnce() -> T, { if let MyNone = self { *self = MySome(f()); } // SAFETY: a `MyNone` variant for `self` would have been replaced by a `MySome` // variant in the code above. unsafe { self.as_mut().unwrap_unchecked() } } // summary=::take;Argument[self].Reference;ReturnValue;value;dfc-generated // sink=::take;Argument[self];pointer-access;df-generated pub fn take(&mut self) -> MyOption { // FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready replace(self, MyNone) } // summary=::take_if;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0].Reference;value;dfc-generated // summary=::take_if;Argument[self].Reference;ReturnValue;value;dfc-generated // sink=::take_if;Argument[self];pointer-access;df-generated pub fn take_if

(&mut self, predicate: P) -> MyOption where P: FnOnce(&mut T) -> bool, { if self.as_mut().map_or(false, predicate) { self.take() } else { MyNone } } // summary=::replace;Argument[0];Argument[self].Reference.Field[test::option::MyOption::MySome(0)];value;dfc-generated // summary=::replace;Argument[self].Reference;ReturnValue;value;dfc-generated // sink=::replace;Argument[self];pointer-access;df-generated pub fn replace(&mut self, value: T) -> MyOption { replace(self, MySome(value)) } // summary=::zip;Argument[0].Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Field[1];value;dfc-generated // summary=::zip;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Field[0];value;dfc-generated pub fn zip(self, other: MyOption) -> MyOption<(T, U)> { match (self, other) { (MySome(a), MySome(b)) => MySome((a, b)), _ => MyNone, } } // summary=::zip_with;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[1].Parameter[0];value;dfc-generated // summary=::zip_with;Argument[0].Field[test::option::MyOption::MySome(0)];Argument[1].Parameter[1];value;dfc-generated // summary=::zip_with;Argument[1].ReturnValue;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn zip_with(self, other: MyOption, f: F) -> MyOption where F: FnOnce(T, U) -> R, { match (self, other) { (MySome(a), MySome(b)) => MySome(f(a, b)), _ => MyNone, } } } impl MyOption<(T, U)> { // summary=::unzip;Argument[self].Field[test::option::MyOption::MySome(0)].Field[0];ReturnValue.Field[0].Field[test::option::MyOption::MySome(0)];value;dfc-generated // summary=::unzip;Argument[self].Field[test::option::MyOption::MySome(0)].Field[1];ReturnValue.Field[1].Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn unzip(self) -> (MyOption, MyOption) { match self { MySome((a, b)) => (MySome(a), MySome(b)), MyNone => (MyNone, MyNone), } } } impl MyOption<&T> { // summary=::copied;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn copied(self) -> MyOption where T: Copy, { // FIXME(const-hack): this implementation, which sidesteps using `MyOption::map` since it's not const // ready yet, should be reverted when possible to avoid code repetition match self { MySome(&v) => MySome(v), MyNone => MyNone, } } // MISSING: summary=::cloned;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn cloned(self) -> MyOption where T: Clone, { match self { MySome(t) => MySome(t.clone()), MyNone => MyNone, } } } impl MyOption<&mut T> { // summary=::copied;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn copied(self) -> MyOption where T: Copy, { match self { MySome(&mut t) => MySome(t), MyNone => MyNone, } } // MISSING: summary=::cloned;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn cloned(self) -> MyOption where T: Clone, { match self { MySome(t) => MySome(t.clone()), MyNone => MyNone, } } } impl MyOption> { // summary=::transpose;Argument[self].Field[test::option::MyOption::MySome(0)].Field[core::result::Result::Err(0)];ReturnValue.Field[core::result::Result::Err(0)];value;dfc-generated // summary=::transpose;Argument[self].Field[test::option::MyOption::MySome(0)].Field[core::result::Result::Ok(0)];ReturnValue.Field[core::result::Result::Ok(0)].Field[test::option::MyOption::MySome(0)];value;dfc-generated pub fn transpose(self) -> Result, E> { match self { MySome(Ok(x)) => Ok(MySome(x)), MySome(Err(e)) => Err(e), MyNone => Ok(MyNone), } } } impl Clone for MyOption where T: Clone, { // MISSING: summary=::clone;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated fn clone(&self) -> Self { match self { MySome(x) => MySome(x.clone()), MyNone => MyNone, } } // MISSING: Flow through `clone_from` trait method which is not modeled. fn clone_from(&mut self, source: &Self) { match (self, source) { (MySome(to), MySome(from)) => to.clone_from(from), (to, from) => *to = from.clone(), } } } impl Default for MyOption { fn default() -> MyOption { MyNone } } impl From for MyOption { // summary=::from;Argument[0];ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated fn from(val: T) -> MyOption { MySome(val) } } impl<'a, T> From<&'a MyOption> for MyOption<&'a T> { // summary=::from;Argument[0].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;value;dfc-generated fn from(o: &'a MyOption) -> MyOption<&'a T> { o.as_ref() } } impl<'a, T> From<&'a mut MyOption> for MyOption<&'a mut T> { // summary=::from;Argument[0].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;value;dfc-generated fn from(o: &'a mut MyOption) -> MyOption<&'a mut T> { o.as_mut() } } impl PartialEq for MyOption { fn eq(&self, other: &Self) -> bool { // Spelling out the cases explicitly optimizes better than // `_ => false` match (self, other) { (MySome(l), MySome(r)) => *l == *r, (MySome(_), MyNone) => false, (MyNone, MySome(_)) => false, (MyNone, MyNone) => true, } } } impl MyOption> { // summary=::flatten;Argument[self].Field[test::option::MyOption::MySome(0)];ReturnValue;value;dfc-generated pub fn flatten(self) -> MyOption { // FIXME(const-hack): could be written with `and_then` match self { MySome(inner) => inner, MyNone => MyNone, } } }