@@ -7,7 +7,7 @@ use std::sync::Arc;
77use either:: Either ;
88use simplicity:: jet:: Elements ;
99use simplicity:: node:: { CoreConstructible as _, JetConstructible as _} ;
10- use simplicity:: { Cmr , FailEntropy } ;
10+ use simplicity:: { types , Cmr , FailEntropy } ;
1111
1212use self :: builtins:: array_fold;
1313use crate :: array:: { BTreeSlice , Partition } ;
@@ -26,7 +26,7 @@ use crate::value::StructuralValue;
2626use crate :: witness:: Arguments ;
2727use crate :: Value ;
2828
29- type ProgNode = Arc < named:: ConstructNode < Elements > > ;
29+ type ProgNode < ' brand > = Arc < named:: ConstructNode < ' brand , Elements > > ;
3030
3131/// Each SimplicityHL expression expects an _input value_.
3232/// A SimplicityHL expression is translated into a Simplicity expression
@@ -39,7 +39,7 @@ type ProgNode = Arc<named::ConstructNode<Elements>>;
3939/// Bindings from inner scopes overwrite bindings from outer scopes.
4040/// Bindings live as long as their scope.
4141#[ derive( Debug , Clone ) ]
42- struct Scope {
42+ struct Scope < ' brand > {
4343 /// For each scope, the set of assigned variables.
4444 ///
4545 /// A stack of scopes. Each scope is a stack of patterns.
@@ -66,15 +66,15 @@ struct Scope {
6666 /// Later assignments occur higher in the tree than earlier assignments.
6767 /// ```
6868 variables : Vec < Vec < Pattern > > ,
69- ctx : simplicity:: types:: Context ,
69+ ctx : simplicity:: types:: Context < ' brand > ,
7070 /// Tracker of function calls.
7171 call_tracker : Arc < CallTracker > ,
7272 /// Values for parameters inside the SimplicityHL program.
7373 arguments : Arguments ,
7474 include_debug_symbols : bool ,
7575}
7676
77- impl Scope {
77+ impl < ' brand > Scope < ' brand > {
7878 /// Create the main scope.
7979 ///
8080 /// _This function should be called at the start of the compilation and then never again._
@@ -84,13 +84,14 @@ impl Scope {
8484 /// The supplied `arguments` are consistent with the program's parameters.
8585 /// Call [`Arguments::is_consistent`] before calling this method!
8686 pub fn new (
87+ ctx : simplicity:: types:: Context < ' brand > ,
8788 call_tracker : Arc < CallTracker > ,
8889 arguments : Arguments ,
8990 include_debug_symbols : bool ,
9091 ) -> Self {
9192 Self {
9293 variables : vec ! [ vec![ Pattern :: Ignore ] ] ,
93- ctx : simplicity :: types :: Context :: new ( ) ,
94+ ctx,
9495 call_tracker,
9596 arguments,
9697 include_debug_symbols,
@@ -183,12 +184,12 @@ impl Scope {
183184 /// ```
184185 ///
185186 /// The expression `drop (IOH & OH)` returns the seeked value.
186- pub fn get ( & self , target : & BasePattern ) -> Option < PairBuilder < ProgNode > > {
187+ pub fn get ( & self , target : & BasePattern ) -> Option < PairBuilder < ProgNode < ' brand > > > {
187188 BasePattern :: from ( & self . get_input_pattern ( ) ) . translate ( & self . ctx , target)
188189 }
189190
190191 /// Access the Simplicity type inference context.
191- pub fn ctx ( & self ) -> & simplicity:: types:: Context {
192+ pub fn ctx ( & self ) -> & simplicity:: types:: Context < ' brand > {
192193 & self . ctx
193194 }
194195
@@ -200,10 +201,10 @@ impl Scope {
200201 /// for debug symbols will simply ignore it. The semantics of the program remain unchanged.
201202 pub fn with_debug_symbol < S : AsRef < Span > > (
202203 & mut self ,
203- args : PairBuilder < ProgNode > ,
204- body : & ProgNode ,
204+ args : PairBuilder < ProgNode < ' brand > > ,
205+ body : & ProgNode < ' brand > ,
205206 span : & S ,
206- ) -> Result < PairBuilder < ProgNode > , RichError > {
207+ ) -> Result < PairBuilder < ProgNode < ' brand > > , RichError > {
207208 match self . call_tracker . get_cmr ( span. as_ref ( ) ) {
208209 Some ( cmr) if self . include_debug_symbols => {
209210 let false_and_args = ProgNode :: bit ( self . ctx ( ) , false ) . pair ( args) ;
@@ -221,12 +222,12 @@ impl Scope {
221222 }
222223}
223224
224- fn compile_blk (
225+ fn compile_blk < ' brand > (
225226 stmts : & [ Statement ] ,
226- scope : & mut Scope ,
227+ scope : & mut Scope < ' brand > ,
227228 index : usize ,
228229 last_expr : Option < & Expression > ,
229- ) -> Result < PairBuilder < ProgNode > , RichError > {
230+ ) -> Result < PairBuilder < ProgNode < ' brand > > , RichError > {
230231 if index >= stmts. len ( ) {
231232 return match last_expr {
232233 Some ( expr) => expr. compile ( scope) ,
@@ -263,22 +264,28 @@ impl Program {
263264 arguments : Arguments ,
264265 include_debug_symbols : bool ,
265266 ) -> Result < Arc < named:: CommitNode < Elements > > , RichError > {
266- let mut scope = Scope :: new (
267- Arc :: clone ( self . call_tracker ( ) ) ,
268- arguments,
269- include_debug_symbols,
270- ) ;
271-
272- let main = self . main ( ) ;
273- let construct = main. compile ( & mut scope) . map ( PairBuilder :: build) ?;
274- // SimplicityHL types should be correct by construction. If not, assign the
275- // whole main function as the span for them, which is as sensible as anything.
276- named:: finalize_types ( & construct) . with_span ( main)
267+ types:: Context :: with_context ( |ctx| {
268+ let mut scope = Scope :: new (
269+ ctx,
270+ Arc :: clone ( self . call_tracker ( ) ) ,
271+ arguments,
272+ include_debug_symbols,
273+ ) ;
274+
275+ let main = self . main ( ) ;
276+ let construct = main. compile ( & mut scope) . map ( PairBuilder :: build) ?;
277+ // SimplicityHL types should be correct by construction. If not, assign the
278+ // whole main function as the span for them, which is as sensible as anything.
279+ named:: finalize_types ( & construct) . with_span ( main)
280+ } )
277281 }
278282}
279283
280284impl Expression {
281- fn compile ( & self , scope : & mut Scope ) -> Result < PairBuilder < ProgNode > , RichError > {
285+ fn compile < ' brand > (
286+ & self ,
287+ scope : & mut Scope < ' brand > ,
288+ ) -> Result < PairBuilder < ProgNode < ' brand > > , RichError > {
282289 match self . inner ( ) {
283290 ExpressionInner :: Block ( stmts, expr) => {
284291 scope. push_scope ( ) ;
@@ -292,7 +299,10 @@ impl Expression {
292299}
293300
294301impl SingleExpression {
295- fn compile ( & self , scope : & mut Scope ) -> Result < PairBuilder < ProgNode > , RichError > {
302+ fn compile < ' brand > (
303+ & self ,
304+ scope : & mut Scope < ' brand > ,
305+ ) -> Result < PairBuilder < ProgNode < ' brand > > , RichError > {
296306 let expr = match self . inner ( ) {
297307 SingleExpressionInner :: Constant ( value) => {
298308 let value = StructuralValue :: from ( value) ;
@@ -360,7 +370,10 @@ impl SingleExpression {
360370}
361371
362372impl Call {
363- fn compile ( & self , scope : & mut Scope ) -> Result < PairBuilder < ProgNode > , RichError > {
373+ fn compile < ' brand > (
374+ & self ,
375+ scope : & mut Scope < ' brand > ,
376+ ) -> Result < PairBuilder < ProgNode < ' brand > > , RichError > {
364377 let args_ast = SingleExpression :: tuple ( self . args ( ) . clone ( ) , * self . as_ref ( ) ) ;
365378 let args = args_ast. compile ( scope) ?;
366379
@@ -453,8 +466,13 @@ impl Call {
453466/// The fold `(fold f)_n : E^(<2^n) × A → A`
454467/// takes the list of type `E^(<2^n)` and an initial accumulator of type `A`,
455468/// and it produces the final accumulator of type `A`.
456- fn list_fold ( bound : NonZeroPow2Usize , f : & ProgNode ) -> Result < ProgNode , simplicity:: types:: Error > {
457- fn next_f_array ( f_array : & ProgNode ) -> Result < ProgNode , simplicity:: types:: Error > {
469+ fn list_fold < ' brand > (
470+ bound : NonZeroPow2Usize ,
471+ f : & ProgNode < ' brand > ,
472+ ) -> Result < ProgNode < ' brand > , simplicity:: types:: Error > {
473+ fn next_f_array < ' brand > (
474+ f_array : & ProgNode < ' brand > ,
475+ ) -> Result < ProgNode < ' brand > , simplicity:: types:: Error > {
458476 /* f_(n + 1) : E^(2^(n + 1)) × A → A
459477 * f_(n + 1) := OIH ▵ (OOH ▵ IH; f_n); f_n
460478 */
@@ -464,10 +482,10 @@ fn list_fold(bound: NonZeroPow2Usize, f: &ProgNode) -> Result<ProgNode, simplici
464482 let half2_acc = ProgNode :: o ( ) . i ( ) . h ( ctx) . pair ( updated_acc) ;
465483 half2_acc. comp ( f_array) . map ( PairBuilder :: build)
466484 }
467- fn next_f_fold (
468- f_array : & ProgNode ,
469- f_fold : & ProgNode ,
470- ) -> Result < ProgNode , simplicity:: types:: Error > {
485+ fn next_f_fold < ' brand > (
486+ f_array : & ProgNode < ' brand > ,
487+ f_fold : & ProgNode < ' brand > ,
488+ ) -> Result < ProgNode < ' brand > , simplicity:: types:: Error > {
471489 /* (fold f)_(n + 1) : E<2^(n + 1) × A → A
472490 * (fold f)_(n + 1) := OOH ▵ (OIH ▵ IH);
473491 * case (drop (fold f)_n)
@@ -525,16 +543,18 @@ fn list_fold(bound: NonZeroPow2Usize, f: &ProgNode) -> Result<ProgNode, simplici
525543/// In this case, the loop continues without returning anything.
526544/// The loop returns the final iterator after the final iteration
527545/// if `f` never returned a successful output.
528- fn for_while (
546+ fn for_while < ' brand > (
529547 bit_width : Pow2Usize ,
530- f : PairBuilder < ProgNode > ,
531- ) -> Result < PairBuilder < ProgNode > , simplicity:: types:: Error > {
548+ f : PairBuilder < ProgNode < ' brand > > ,
549+ ) -> Result < PairBuilder < ProgNode < ' brand > > , simplicity:: types:: Error > {
532550 /* for_while_0 f : E × A → A
533551 * for_while_0 f := (OH ▵ (IH ▵ false); f) ▵ IH;
534552 * case (injl OH)
535553 * (OH ▵ (IH ▵ true); f)
536554 */
537- fn for_while_0 ( f : & ProgNode ) -> Result < PairBuilder < ProgNode > , simplicity:: types:: Error > {
555+ fn for_while_0 < ' brand > (
556+ f : & ProgNode < ' brand > ,
557+ ) -> Result < PairBuilder < ProgNode < ' brand > > , simplicity:: types:: Error > {
538558 let ctx = f. inference_context ( ) ;
539559 let f_output = ProgNode :: o ( )
540560 . h ( ctx)
@@ -557,7 +577,9 @@ fn for_while(
557577 * where
558578 * f : A × (C × 2^(2^(n + 1))) → B + A
559579 */
560- fn adapt_f ( f : & ProgNode ) -> Result < PairBuilder < ProgNode > , simplicity:: types:: Error > {
580+ fn adapt_f < ' brand > (
581+ f : & ProgNode < ' brand > ,
582+ ) -> Result < PairBuilder < ProgNode < ' brand > > , simplicity:: types:: Error > {
561583 let ctx = f. inference_context ( ) ;
562584 let f_input = ProgNode :: o ( ) . h ( ctx) . pair (
563585 ProgNode :: i ( )
@@ -626,7 +648,10 @@ fn for_while(
626648}
627649
628650impl Match {
629- fn compile ( & self , scope : & mut Scope ) -> Result < PairBuilder < ProgNode > , RichError > {
651+ fn compile < ' brand > (
652+ & self ,
653+ scope : & mut Scope < ' brand > ,
654+ ) -> Result < PairBuilder < ProgNode < ' brand > > , RichError > {
630655 scope. push_scope ( ) ;
631656 scope. insert (
632657 self . left ( )
0 commit comments