@@ -12,9 +12,11 @@ use crate::{
1212} ;
1313
1414#[ allow( clippy:: too_many_lines) ]
15+ #[ allow( unused_variables) ]
1516pub fn destruct (
1617 d : & Destruct ,
1718 parent : Thunk < Val > ,
19+ fctx : Pending < Context > ,
1820 new_bindings : & mut GcHashMap < IStr , Thunk < Val > > ,
1921) -> Result < ( ) > {
2022 match d {
@@ -89,6 +91,7 @@ pub fn destruct(
8991 full: full. clone( ) ,
9092 index: i,
9193 } ) ) ,
94+ fctx. clone ( ) ,
9295 new_bindings,
9396 ) ?;
9497 }
@@ -119,6 +122,7 @@ pub fn destruct(
119122 start: start. len( ) ,
120123 end: end. len( ) ,
121124 } ) ) ,
125+ fctx. clone ( ) ,
122126 new_bindings,
123127 ) ?;
124128 }
@@ -151,6 +155,7 @@ pub fn destruct(
151155 index: i,
152156 end: end. len( ) ,
153157 } ) ) ,
158+ fctx. clone ( ) ,
154159 new_bindings,
155160 ) ?;
156161 }
@@ -189,36 +194,51 @@ pub fn destruct(
189194 Ok ( obj)
190195 }
191196 }
192- let field_names: Vec < _ > = fields. iter ( ) . map ( |f| f. 0 . clone ( ) ) . collect ( ) ;
197+ let field_names: Vec < _ > = fields
198+ . iter ( )
199+ . filter ( |f| f. 2 . is_none ( ) )
200+ . map ( |f| f. 0 . clone ( ) )
201+ . collect ( ) ;
193202 let full = Thunk :: new ( tb ! ( DataThunk {
194203 parent,
195204 field_names: field_names. clone( ) ,
196205 has_rest: rest. is_some( )
197206 } ) ) ;
198207
199- for ( field, d) in fields {
208+ for ( field, d, default ) in fields {
200209 #[ derive( Trace ) ]
201210 struct FieldThunk {
202211 full : Thunk < ObjValue > ,
203212 field : IStr ,
213+ default : Option < ( Pending < Context > , LocExpr ) > ,
204214 }
205215 impl ThunkValue for FieldThunk {
206216 type Output = Val ;
207217
208218 fn get ( self : Box < Self > , s : State ) -> Result < Self :: Output > {
209219 let full = self . full . evaluate ( s. clone ( ) ) ?;
210- let field = full. get ( s, self . field ) ?. expect ( "shape is checked" ) ;
211- Ok ( field)
220+ if let Some ( field) = full. get ( s. clone ( ) , self . field ) ? {
221+ Ok ( field)
222+ } else {
223+ let ( fctx, expr) = self . default . as_ref ( ) . expect ( "shape is checked" ) ;
224+ Ok ( evaluate ( s, fctx. clone ( ) . unwrap ( ) , & expr) ?)
225+ }
212226 }
213227 }
214228 let value = Thunk :: new ( tb ! ( FieldThunk {
215229 full: full. clone( ) ,
216- field: field. clone( )
230+ field: field. clone( ) ,
231+ default : default . clone( ) . map( |e| ( fctx. clone( ) , e) ) ,
217232 } ) ) ;
218233 if let Some ( d) = d {
219- destruct ( d, value, new_bindings) ?;
234+ destruct ( d, value, fctx . clone ( ) , new_bindings) ?;
220235 } else {
221- destruct ( & Destruct :: Full ( field. clone ( ) ) , value, new_bindings) ?;
236+ destruct (
237+ & Destruct :: Full ( field. clone ( ) ) ,
238+ value,
239+ fctx. clone ( ) ,
240+ new_bindings,
241+ ) ?;
222242 }
223243 }
224244 }
@@ -251,10 +271,10 @@ pub fn evaluate_dest(
251271 }
252272 let data = Thunk :: new ( tb ! ( EvaluateThunkValue {
253273 name: into. name( ) ,
254- fctx,
274+ fctx: fctx . clone ( ) ,
255275 expr: value. clone( ) ,
256276 } ) ) ;
257- destruct ( into, data, new_bindings) ?;
277+ destruct ( into, data, fctx , new_bindings) ?;
258278 }
259279 BindSpec :: Function {
260280 name,
0 commit comments