88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ use task:: local_data:: { local_data_pop, local_data_set} ;
12+
1113// helper for transmutation, shown below.
12- type RustClosure = ( int , int ) ;
14+ type RustClosure = ( int , int ) ;
15+
1316pub struct Handler < T , U > {
1417 handle : RustClosure ,
1518 prev : Option < @Handler < T , U > > ,
1619}
1720
1821pub struct Condition < T , U > {
1922 name : & static /str ,
20- key : task:: local_data:: LocalDataKey < Handler < T , U > >
23+ key : task:: local_data:: LocalDataKey < Handler < T , U > >
2124}
2225
23- impl < T , U > Condition < T , U > {
24-
25- fn trap ( & self , h : & self /fn ( & T ) ->U ) -> Trap /& self <T , U > {
26+ impl < T , U > Condition < T , U > {
27+ fn trap ( & self , h : & self /fn ( T ) -> U ) -> Trap /& self <T , U > {
2628 unsafe {
2729 let p : * RustClosure = :: cast:: transmute ( & h) ;
2830 let prev = task:: local_data:: local_data_get ( self . key ) ;
29- let h = @Handler { handle : * p, prev : prev} ;
30- move Trap { cond : self , handler : h }
31+ let h = @Handler { handle : * p, prev : prev } ;
32+ Trap { cond : self , handler : h }
3133 }
3234 }
3335
34- fn raise ( t : & T ) -> U {
35- do self . raise_default ( t) {
36- fail fmt ! ( "Unhandled condition: %s: %?" ,
37- self . name,
38- t) ;
39- }
36+ fn raise ( t : T ) -> U {
37+ let msg = fmt ! ( "Unhandled condition: %s: %?" , self . name, t) ;
38+ self . raise_default ( t, || fail msg)
4039 }
4140
42- fn raise_default ( t : & T , default : fn ( ) -> U ) -> U {
41+ fn raise_default ( t : T , default : & fn ( ) -> U ) -> U {
4342 unsafe {
44- match task :: local_data :: local_data_pop ( self . key ) {
43+ match local_data_pop ( self . key ) {
4544 None => {
4645 debug ! ( "Condition.raise: found no handler" ) ;
4746 default ( )
4847 }
49-
5048 Some ( handler) => {
5149 debug ! ( "Condition.raise: found handler" ) ;
5250 match handler. prev {
53- None => ( ) ,
54- Some ( hp) =>
55- task:: local_data:: local_data_set ( self . key , hp)
51+ None => { }
52+ Some ( hp) => local_data_set ( self . key , hp)
5653 }
57- let handle : & fn ( & T ) -> U =
54+ let handle : & fn ( T ) -> U =
5855 :: cast:: transmute ( handler. handle ) ;
5956 let u = handle ( t) ;
60- task:: local_data:: local_data_set ( self . key ,
61- handler) ;
62- move u
57+ local_data_set ( self . key , handler) ;
58+ u
6359 }
6460 }
6561 }
6662 }
6763}
6864
69-
70-
7165struct Trap < T , U > {
72- cond : & Condition < T , U > ,
66+ cond : & Condition < T , U > ,
7367 handler : @Handler < T , U >
7468}
7569
76- impl < T , U > Trap < T , U > {
70+ impl < T , U > Trap < T , U > {
7771 fn in < V > ( & self , inner : & self /fn ( ) -> V ) -> V {
7872 unsafe {
7973 let _g = Guard { cond : self . cond } ;
8074 debug ! ( "Trap: pushing handler to TLS" ) ;
81- task :: local_data :: local_data_set ( self . cond . key , self . handler ) ;
75+ local_data_set ( self . cond . key , self . handler ) ;
8276 inner ( )
8377 }
8478 }
8579}
8680
8781struct Guard < T , U > {
88- cond : & Condition < T , U > ,
89- drop {
82+ cond : & Condition < T , U >
83+ }
84+
85+ impl < T , U > Guard < T , U > : Drop {
86+ fn finalize ( & self ) {
9087 unsafe {
9188 debug ! ( "Guard: popping handler from TLS" ) ;
92- let curr = task :: local_data :: local_data_pop ( self . cond. key) ;
89+ let curr = local_data_pop ( self . cond . key ) ;
9390 match curr {
94- None => ( ) ,
95- Some ( h) =>
96- match h. prev {
97- None => ( ) ,
98- Some ( hp) => {
99- task:: local_data:: local_data_set ( self . cond . key , hp)
100- }
91+ None => { }
92+ Some ( h) => match h. prev {
93+ None => { }
94+ Some ( hp) => local_data_set ( self . cond . key , hp)
10195 }
10296 }
10397 }
10498 }
10599}
106100
107-
108101#[ cfg( test) ]
109102mod test {
110-
111103 condition ! {
112104 sadness: int -> int;
113105 }
114106
115107 fn trouble ( i : int ) {
116- debug ! ( "trouble: raising conition " ) ;
117- let j = sadness:: cond. raise ( & i) ;
108+ debug ! ( "trouble: raising condition " ) ;
109+ let j = sadness:: cond. raise ( i) ;
118110 debug ! ( "trouble: handler recovered with %d" , j) ;
119111 }
120112
121113 fn nested_trap_test_inner ( ) {
122-
123114 let mut inner_trapped = false ;
124115
125116 do sadness:: cond. trap ( |_j| {
@@ -136,7 +127,6 @@ mod test {
136127
137128 #[ test]
138129 fn nested_trap_test_outer ( ) {
139-
140130 let mut outer_trapped = false ;
141131
142132 do sadness:: cond. trap ( |_j| {
@@ -152,15 +142,14 @@ mod test {
152142 }
153143
154144 fn nested_reraise_trap_test_inner ( ) {
155-
156145 let mut inner_trapped = false ;
157146
158147 do sadness:: cond. trap ( |_j| {
159148 debug ! ( "nested_reraise_trap_test_inner: in handler" ) ;
160149 inner_trapped = true ;
161150 let i = 10 ;
162151 debug ! ( "nested_reraise_trap_test_inner: handler re-raising" ) ;
163- sadness:: cond. raise ( & i)
152+ sadness:: cond. raise ( i)
164153 } ) . in {
165154 debug ! ( "nested_reraise_trap_test_inner: in protected block" ) ;
166155 trouble ( 1 ) ;
@@ -171,7 +160,6 @@ mod test {
171160
172161 #[ test]
173162 fn nested_reraise_trap_test_outer ( ) {
174-
175163 let mut outer_trapped = false ;
176164
177165 do sadness:: cond. trap ( |_j| {
@@ -187,18 +175,16 @@ mod test {
187175
188176 #[ test]
189177 fn test_default ( ) {
190-
191178 let mut trapped = false ;
192179
193180 do sadness:: cond. trap ( |j| {
194181 debug ! ( "test_default: in handler" ) ;
195- sadness:: cond. raise_default ( j, || { trapped=true ; 5 } )
182+ sadness:: cond. raise_default ( j, || { trapped=true ; 5 } )
196183 } ) . in {
197184 debug ! ( "test_default: in protected block" ) ;
198185 trouble ( 1 ) ;
199186 }
200187
201188 assert trapped;
202189 }
203-
204190}
0 commit comments