1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
use joker::track::*; use id::Id; use fun::Fun; use patt::{Patt, CompoundPatt}; use expr::Expr; #[derive(Debug, PartialEq)] pub enum Decl { Fun(Fun) } impl TrackingRef for Decl { fn tracking_ref(&self) -> &Option<Span> { let Decl::Fun(ref fun) = *self; fun.tracking_ref() } } impl TrackingMut for Decl { fn tracking_mut(&mut self) -> &mut Option<Span> { let Decl::Fun(ref mut fun) = *self; fun.tracking_mut() } } impl Untrack for Decl { fn untrack(&mut self) { let Decl::Fun(ref mut fun) = *self; fun.untrack(); } } #[derive(Debug, PartialEq)] pub enum Dtor { Simple(Option<Span>, Id, Option<Expr>), Compound(Option<Span>, CompoundPatt<Id>, Expr) } impl TrackingRef for Dtor { fn tracking_ref(&self) -> &Option<Span> { match *self { Dtor::Simple(ref location, _, _) | Dtor::Compound(ref location, _, _) => location } } } impl TrackingMut for Dtor { fn tracking_mut(&mut self) -> &mut Option<Span> { match *self { Dtor::Simple(ref mut location, _, _) | Dtor::Compound(ref mut location, _, _) => location } } } impl Untrack for Dtor { fn untrack(&mut self) { match *self { Dtor::Simple(ref mut location, ref mut id, ref mut init) => { *location = None; id.untrack(); init.untrack(); } Dtor::Compound(ref mut location, ref mut patt, ref mut init) => { *location = None; patt.untrack(); init.untrack(); } } } } pub trait DtorExt { fn from_simple_init(Id, Expr) -> Dtor; fn from_compound_init(CompoundPatt<Id>, Expr) -> Dtor; fn from_init(Patt<Id>, Expr) -> Dtor; fn from_init_opt(Patt<Id>, Option<Expr>) -> Result<Dtor, CompoundPatt<Id>>; } impl DtorExt for Dtor { fn from_compound_init(lhs: CompoundPatt<Id>, rhs: Expr) -> Dtor { Dtor::Compound(span(&lhs, &rhs), lhs, rhs) } fn from_simple_init(lhs: Id, rhs: Expr) -> Dtor { Dtor::Simple(span(&lhs, &rhs), lhs, Some(rhs)) } fn from_init(lhs: Patt<Id>, rhs: Expr) -> Dtor { let loc = span(&lhs, &rhs); match lhs { Patt::Simple(id) => Dtor::Simple(loc, id, Some(rhs)), Patt::Compound(patt) => Dtor::Compound(loc, patt, rhs) } } fn from_init_opt(lhs: Patt<Id>, rhs: Option<Expr>) -> Result<Dtor, CompoundPatt<Id>> { match (lhs, rhs) { (Patt::Simple(id), rhs) => { Ok(Dtor::Simple(*id.tracking_ref(), id, rhs)) } (Patt::Compound(patt), None) => Err(patt), (Patt::Compound(patt), Some(rhs)) => { Ok(Dtor::Compound(span(&patt, &rhs), patt, rhs)) } } } }