@@ -20,21 +20,14 @@ use crate::{
2020use arcstr:: ArcStr ;
2121use indexmap:: { IndexMap , IndexSet } ;
2222use std:: hash:: Hash ;
23-
24- #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
25- enum VariableKind {
26- // Can only be used once.
27- Linear ,
28- // Replicable, but needs no dereliction
29- Replicable ,
30- }
23+ use crate :: par:: process:: VariableUsage ;
3124
3225#[ derive( Clone , Debug ) ]
3326pub enum Error {
3427 /// Error that is emitted when a variable that was never bound/captured is used
3528 UnboundVar ( Span , #[ allow( unused) ] Var ) ,
36- /// Error that is emitted when a linear variable is not used
37- UnusedVar ( Span ) ,
29+ /// Error that is emitted when it is unclear how a variable is used (move/copy)
30+ UnknownVariableUsage ( Span ) ,
3831 GlobalNotFound ( GlobalName ) ,
3932 DependencyCycle {
4033 global : GlobalName ,
@@ -68,7 +61,7 @@ impl Error {
6861
6962 pub fn spans ( & self ) -> ( Span , Vec < Span > ) {
7063 match self {
71- Error :: UnboundVar ( span, _) | Error :: UnusedVar ( span) | Error :: UnguardedLoop ( span, _) => {
64+ Error :: UnboundVar ( span, _) | Error :: UnknownVariableUsage ( span) | Error :: UnguardedLoop ( span, _) => {
7265 ( span. clone ( ) , vec ! [ ] )
7366 }
7467
@@ -116,15 +109,14 @@ pub struct LoopLabel(Option<LocalName>);
116109
117110#[ derive( Debug ) ]
118111pub struct Context {
119- vars : BTreeMap < Var , ( TypedTree , VariableKind ) > ,
112+ vars : BTreeMap < Var , TypedTree > ,
120113 loop_points : BTreeMap < LoopLabel , BTreeSet < LoopLabel > > ,
121114 unguarded_loop_labels : Vec < LoopLabel > ,
122115}
123116
124117pub struct PackData {
125118 names : Vec < Var > ,
126119 types : Vec < Type > ,
127- kinds : Vec < VariableKind > ,
128120 loop_points : BTreeMap < LoopLabel , BTreeSet < LoopLabel > > ,
129121 unguarded_loop_labels : Vec < LoopLabel > ,
130122}
@@ -140,8 +132,7 @@ impl Context {
140132 let mut m_trees = vec ! [ ] ;
141133 let mut m_tys = vec ! [ ] ;
142134 let mut m_vars = vec ! [ ] ;
143- let mut m_kind = vec ! [ ] ;
144- for ( name, ( tree, kind) ) in core:: mem:: take ( & mut self . vars ) {
135+ for ( name, tree) in core:: mem:: take ( & mut self . vars ) {
145136 if let Some ( captures) = captures {
146137 if let Var :: Name ( name) = & name {
147138 if !captures. names . contains_key ( name) && Some ( name) != driver {
@@ -161,15 +152,13 @@ impl Context {
161152 m_vars. push ( name) ;
162153 m_trees. push ( tree. tree ) ;
163154 m_tys. push ( tree. ty ) ;
164- m_kind. push ( kind) ;
165155 }
166156 let context_in = multiplex_trees ( m_trees) ;
167157 (
168158 context_in,
169159 PackData {
170160 names : m_vars,
171161 types : m_tys,
172- kinds : m_kind,
173162 loop_points : core:: mem:: take ( & mut self . loop_points ) ,
174163 unguarded_loop_labels : core:: mem:: take ( & mut self . unguarded_loop_labels ) ,
175164 } ,
@@ -178,13 +167,13 @@ impl Context {
178167
179168 pub fn unpack ( & mut self , packed : & PackData , net : & mut Net ) -> Tree {
180169 let mut m_trees = vec ! [ ] ;
181- for ( name, ( ty , kind ) ) in packed
170+ for ( name, ty ) in packed
182171 . names
183172 . iter ( )
184- . zip ( packed. types . iter ( ) . zip ( packed . kinds . iter ( ) ) )
173+ . zip ( packed. types . iter ( ) )
185174 {
186175 let ( v0, v1) = net. create_wire ( ) ;
187- self . bind_variable_with_kind ( name. clone ( ) , v0. with_type ( ty. clone ( ) ) , kind . clone ( ) ) ;
176+ self . bind_variable ( name. clone ( ) , v0. with_type ( ty. clone ( ) ) ) ;
188177 m_trees. push ( v1) ;
189178 }
190179 self . loop_points = packed. loop_points . clone ( ) ;
@@ -193,8 +182,8 @@ impl Context {
193182 context_out
194183 }
195184
196- fn bind_variable_with_kind ( & mut self , var : Var , tree : TypedTree , kind : VariableKind ) {
197- match self . vars . insert ( var. clone ( ) , ( tree, kind ) ) {
185+ fn bind_variable ( & mut self , var : Var , tree : TypedTree ) {
186+ match self . vars . insert ( var. clone ( ) , tree) {
198187 Some ( x) => panic ! ( "{:?}" , x) ,
199188 None => ( ) ,
200189 }
@@ -234,13 +223,6 @@ pub(crate) fn multiplex_trees(mut trees: Vec<Tree>) -> Tree {
234223}
235224
236225impl Compiler {
237- fn get_kind ( & self , tree : & TypedTree ) -> VariableKind {
238- match tree. ty . is_linear ( & self . type_defs ) . unwrap ( ) {
239- true => VariableKind :: Linear ,
240- false => VariableKind :: Replicable ,
241- }
242- }
243-
244226 fn compile_global ( & mut self , name : & GlobalName ) -> Result < TypedTree > {
245227 if let Some ( id) = self . global_name_to_id . get ( name) {
246228 let ty = self . id_to_ty . get ( * id) . unwrap ( ) . clone ( ) ;
@@ -386,13 +368,13 @@ impl Compiler {
386368 f : impl FnOnce ( & mut Self ) -> Result < T > ,
387369 ) -> Result < T > {
388370 let mut vars = BTreeMap :: new ( ) ;
389- for ( name, _ ) in captures. names . iter ( ) {
390- let ( tree, kind ) = self . use_variable ( name, false ) ?;
391- vars. insert ( Var :: Name ( name. clone ( ) ) , ( tree, kind ) ) ;
371+ for ( name, ( _span , usage ) ) in captures. names . iter ( ) {
372+ let tree = self . use_variable ( name, usage , false ) ?;
373+ vars. insert ( Var :: Name ( name. clone ( ) ) , tree) ;
392374 }
393375 for ( label, _) in self . context . loop_points . clone ( ) . iter ( ) {
394- let ( tree, kind ) = self . use_var ( & Var :: Loop ( label. 0 . clone ( ) ) , false ) ?;
395- vars. insert ( Var :: Loop ( label. 0 . clone ( ) ) , ( tree, kind ) ) ;
376+ let tree = self . use_var ( & Var :: Loop ( label. 0 . clone ( ) ) , & VariableUsage :: Copy , false ) ?;
377+ vars. insert ( Var :: Loop ( label. 0 . clone ( ) ) , tree) ;
396378 }
397379 let loop_points_before = self . context . loop_points . clone ( ) ;
398380 core:: mem:: swap ( & mut vars, & mut self . context . vars ) ;
@@ -403,50 +385,44 @@ impl Compiler {
403385 }
404386
405387 fn bind_variable ( & mut self , var : impl Into < Var > , tree : TypedTree ) -> Result < ( ) > {
406- let kind = self . get_kind ( & tree) ;
407- let prev = self . context . vars . insert ( var. into ( ) , ( tree, kind) ) ;
388+ let prev = self . context . vars . insert ( var. into ( ) , tree) ;
408389 match prev {
409- Some ( ( prev_tree, prev_kind) ) => {
410- if prev_kind == VariableKind :: Linear {
411- return Err ( Error :: UnusedVar ( Span :: default ( ) ) ) ;
412- }
390+ Some ( prev_tree) => {
413391 self . net . link ( prev_tree. tree , Tree :: Era ) ;
414392 Ok ( ( ) )
415393 }
416394 None => Ok ( ( ) ) ,
417395 }
418396 }
419397
420- fn use_var ( & mut self , var : & Var , in_command : bool ) -> Result < ( TypedTree , VariableKind ) > {
421- if let Some ( ( tree, kind ) ) = self . context . vars . remove ( var) {
398+ fn use_var ( & mut self , var : & Var , usage : & VariableUsage , in_command : bool ) -> Result < TypedTree > {
399+ if let Some ( tree) = self . context . vars . remove ( var) {
422400 if in_command {
423- return Ok ( ( tree, kind ) ) ;
401+ return Ok ( tree) ;
424402 }
425- match kind {
426- VariableKind :: Linear => Ok ( ( tree, kind ) ) ,
427- kind => {
403+ match usage {
404+ VariableUsage :: Move => Ok ( tree) ,
405+ VariableUsage :: Copy => {
428406 let ( w0, w1) = self . net . create_wire ( ) ;
429407 let ( v0, v1) = self . net . create_wire ( ) ;
430408 self . net
431409 . link ( Tree :: Dup ( Box :: new ( v0) , Box :: new ( w0) ) , tree. tree ) ;
432410 self . context . vars . insert (
433411 var. clone ( ) ,
434- (
412+
435413 TypedTree {
436414 tree : w1,
437415 ty : tree. ty . clone ( ) ,
438416 } ,
439- kind,
440- ) ,
441417 ) ;
442- Ok ( (
418+ Ok (
443419 TypedTree {
444420 tree : v1,
445421 ty : tree. ty . clone ( ) ,
446- } ,
447- kind ,
448- ) )
449- }
422+ }
423+ )
424+ } ,
425+ VariableUsage :: Unknown => Err ( Error :: UnknownVariableUsage ( Span :: None ) ) ,
450426 }
451427 } else {
452428 Err ( Error :: UnboundVar ( Default :: default ( ) , var. clone ( ) ) )
@@ -464,9 +440,10 @@ impl Compiler {
464440 fn use_variable (
465441 & mut self ,
466442 name : & LocalName ,
443+ usage : & VariableUsage ,
467444 in_command : bool ,
468- ) -> Result < ( TypedTree , VariableKind ) > {
469- return self . use_var ( & Var :: Name ( name. clone ( ) ) , in_command) ;
445+ ) -> Result < TypedTree > {
446+ self . use_var ( & Var :: Name ( name. clone ( ) ) , usage , in_command)
470447 }
471448
472449 fn create_typed_wire ( & mut self , t : Type ) -> ( TypedTree , TypedTree ) {
@@ -523,7 +500,7 @@ impl Compiler {
523500 fn compile_expression ( & mut self , expr : & Expression < Type > ) -> Result < TypedTree > {
524501 match expr {
525502 Expression :: Global ( _, name, _) => self . use_global ( name) ,
526- Expression :: Variable ( _, name, _ ) => Ok ( self . use_variable ( name, false ) ?. 0 ) ,
503+ Expression :: Variable ( _, name, _typ , usage ) => Ok ( self . use_variable ( name, usage , false ) ?) ,
527504
528505 Expression :: Box ( _, captures, expression, typ) => self . with_captures ( captures, |this| {
529506 let ( context_in, pack_data) = this. context . pack ( None , None , None , & mut this. net ) ;
@@ -575,9 +552,10 @@ impl Compiler {
575552 Process :: Do {
576553 span,
577554 name,
555+ usage,
578556 typ,
579557 command,
580- } => self . compile_command ( span, name. clone ( ) , typ. clone ( ) , command) ,
558+ } => self . compile_command ( span, name. clone ( ) , usage , typ. clone ( ) , command) ,
581559
582560 Process :: Telltypes ( _, _) => unreachable ! ( ) ,
583561 }
@@ -587,19 +565,20 @@ impl Compiler {
587565 & mut self ,
588566 span : & Span ,
589567 name : LocalName ,
568+ usage : & VariableUsage ,
590569 ty : Type ,
591570 cmd : & Command < Type > ,
592571 ) -> Result < ( ) > {
593572 match cmd {
594573 Command :: Link ( expr) => {
595- let subject = self . use_variable ( & name, true ) ?. 0 ;
574+ let subject = self . use_variable ( & name, usage , true ) ?;
596575 let value = self . compile_expression ( expr) ?;
597576 self . link_typed ( subject, value) ;
598577 self . end_context ( ) ?;
599578 }
600579 // types get erased.
601580 Command :: SendType ( argument, process) => {
602- let subject = self . use_variable ( & name, true ) ?. 0 ;
581+ let subject = self . use_variable ( & name, usage , true ) ?;
603582 let Type :: Forall ( _, type_name, ret_type) = self . normalize_type ( subject. ty . clone ( ) )
604583 else {
605584 panic ! ( "Unexpected type for SendType: {:?}" , subject. ty) ;
@@ -611,7 +590,7 @@ impl Compiler {
611590 self . compile_process ( process) ?;
612591 }
613592 Command :: ReceiveType ( parameter, process) => {
614- let subject = self . use_variable ( & name, true ) ?. 0 ;
593+ let subject = self . use_variable ( & name, usage , true ) ?;
615594 let Type :: Exists ( _, type_name, ret_type) = self . normalize_type ( subject. ty . clone ( ) )
616595 else {
617596 panic ! ( "Unexpected type for ReceiveType: {:?}" , subject. ty) ;
@@ -636,7 +615,7 @@ impl Compiler {
636615 // name = free
637616 // free = (name < expr >)
638617 // < process >
639- let subject = self . use_variable ( & name, true ) ?. 0 ;
618+ let subject = self . use_variable ( & name, usage , true ) ?;
640619 let Type :: Function ( _, _, ret_type) = self . normalize_type ( subject. ty . clone ( ) ) else {
641620 panic ! ( "Unexpected type for Receive: {:?}" , subject. ty) ;
642621 } ;
@@ -655,7 +634,7 @@ impl Compiler {
655634 // name = free
656635 // free = (name target)
657636 // < process >
658- let subject = self . use_variable ( & name, true ) ?. 0 ;
637+ let subject = self . use_variable ( & name, usage , true ) ?;
659638 let Type :: Pair ( _, arg_type, ret_type) = self . normalize_type ( subject. ty . clone ( ) )
660639 else {
661640 panic ! ( "Unexpected type for Receive: {:?}" , subject. ty) ;
@@ -671,7 +650,7 @@ impl Compiler {
671650 self . compile_process ( process) ?;
672651 }
673652 Command :: Signal ( chosen, process) => {
674- let subject = self . use_variable ( & name, true ) ?. 0 ;
653+ let subject = self . use_variable ( & name, usage , true ) ?;
675654 let Type :: Choice ( _, branches) = self . normalize_type ( subject. ty . clone ( ) ) else {
676655 panic ! ( "Unexpected type for Signal: {:?}" , subject. ty) ;
677656 } ;
@@ -686,7 +665,7 @@ impl Compiler {
686665 }
687666 Command :: Case ( names, processes) => {
688667 self . context . unguarded_loop_labels . clear ( ) ;
689- let old_tree = self . use_variable ( & name, true ) ?. 0 ;
668+ let old_tree = self . use_variable ( & name, usage , true ) ?;
690669 // Multiplex all other variables in the context.
691670 let ( context_in, pack_data) = self . context . pack ( None , None , None , & mut self . net ) ;
692671
@@ -720,7 +699,7 @@ impl Compiler {
720699 // < name ! >
721700 // ==
722701 // name = *
723- let a = self . use_variable ( & name, true ) ?. 0 . tree ;
702+ let a = self . use_variable ( & name, usage , true ) ?. tree ;
724703 self . net . link ( a, Tree :: Era ) ;
725704 self . end_context ( ) ?;
726705 }
@@ -729,7 +708,7 @@ impl Compiler {
729708 // ==
730709 // name = *
731710 // < process >
732- let a = self . use_variable ( & name, true ) ?. 0 . tree ;
711+ let a = self . use_variable ( & name, usage , true ) ?. tree ;
733712 self . net . link ( a, Tree :: Era ) ;
734713 self . compile_process ( process) ?;
735714 }
@@ -744,13 +723,10 @@ impl Compiler {
744723 let ( def0, def1) = self . net . create_wire ( ) ;
745724 let prev = self . context . vars . insert (
746725 Var :: Loop ( label. 0 . clone ( ) ) ,
747- (
748726 def0. with_type ( Type :: Break ( Span :: default ( ) ) ) ,
749- VariableKind :: Replicable ,
750- ) ,
751727 ) ;
752728
753- if let Some ( ( prev_tree, _ ) ) = prev {
729+ if let Some ( prev_tree) = prev {
754730 self . net . link ( prev_tree. tree , Tree :: Era ) ;
755731 }
756732
@@ -782,8 +758,8 @@ impl Compiler {
782758 if self . context . unguarded_loop_labels . contains ( & label) {
783759 return Err ( Error :: UnguardedLoop ( span. clone ( ) , label. clone ( ) . 0 ) ) ;
784760 }
785- let ( tree, _ ) = self . use_var ( & Var :: Loop ( label. 0 . clone ( ) ) , false ) ?;
786- let driver_tree = self . use_variable ( & name, true ) ?. 0 ;
761+ let tree = self . use_var ( & Var :: Loop ( label. 0 . clone ( ) ) , & VariableUsage :: Copy , false ) ?;
762+ let driver_tree = self . use_variable ( & name, usage , true ) ?;
787763 self . bind_variable ( driver. clone ( ) , driver_tree) ?;
788764 let labels_in_scope = self . context . loop_points . get ( & label) . unwrap ( ) . clone ( ) ;
789765 let ( context_in, _) = self . context . pack (
@@ -800,12 +776,8 @@ impl Compiler {
800776
801777 fn end_context ( & mut self ) -> Result < ( ) > {
802778 // drop all replicables
803- for ( _, ( value, kind) ) in core:: mem:: take ( & mut self . context . vars ) . into_iter ( ) {
804- if kind == VariableKind :: Linear {
805- return Err ( Error :: UnusedVar ( Default :: default ( ) ) ) ;
806- } else {
807- self . net . link ( value. tree , Tree :: Era ) ;
808- }
779+ for ( _, value) in core:: mem:: take ( & mut self . context . vars ) . into_iter ( ) {
780+ self . net . link ( value. tree , Tree :: Era ) ;
809781 }
810782 self . context . loop_points = Default :: default ( ) ;
811783 Ok ( ( ) )
0 commit comments