@@ -15,6 +15,28 @@ use crate::{
15
15
} ;
16
16
use std:: { convert:: TryFrom , ops:: Index } ;
17
17
18
+ /// The position at which an expression is, used while lowering
19
+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
20
+ pub enum ExprPos {
21
+ /// The expression is in the left hand side of an assignment
22
+ Lhs ,
23
+ /// The expression is in the right hand side of an assignment
24
+ Rhs ,
25
+ /// The expression is an array being indexed, needed to allow constant
26
+ /// arrays to be dinamically indexed
27
+ ArrayBase ,
28
+ }
29
+
30
+ impl ExprPos {
31
+ /// Returns an lhs position if the current position is lhs otherwise ArrayBase
32
+ fn maybe_array_base ( & self ) -> Self {
33
+ match * self {
34
+ ExprPos :: Lhs => * self ,
35
+ _ => ExprPos :: ArrayBase ,
36
+ }
37
+ }
38
+ }
39
+
18
40
#[ derive( Debug ) ]
19
41
pub struct Context {
20
42
pub expressions : Arena < Expression > ,
@@ -323,10 +345,10 @@ impl Context {
323
345
mut stmt : StmtContext ,
324
346
parser : & mut Parser ,
325
347
expr : Handle < HirExpr > ,
326
- lhs : bool ,
348
+ pos : ExprPos ,
327
349
body : & mut Block ,
328
350
) -> Result < ( Option < Handle < Expression > > , SourceMetadata ) > {
329
- let res = self . lower_inner ( & stmt, parser, expr, lhs , body) ;
351
+ let res = self . lower_inner ( & stmt, parser, expr, pos , body) ;
330
352
331
353
stmt. hir_exprs . clear ( ) ;
332
354
self . stmt_ctx = Some ( stmt) ;
@@ -344,10 +366,10 @@ impl Context {
344
366
mut stmt : StmtContext ,
345
367
parser : & mut Parser ,
346
368
expr : Handle < HirExpr > ,
347
- lhs : bool ,
369
+ pos : ExprPos ,
348
370
body : & mut Block ,
349
371
) -> Result < ( Handle < Expression > , SourceMetadata ) > {
350
- let res = self . lower_expect_inner ( & stmt, parser, expr, lhs , body) ;
372
+ let res = self . lower_expect_inner ( & stmt, parser, expr, pos , body) ;
351
373
352
374
stmt. hir_exprs . clear ( ) ;
353
375
self . stmt_ctx = Some ( stmt) ;
@@ -365,10 +387,10 @@ impl Context {
365
387
stmt : & StmtContext ,
366
388
parser : & mut Parser ,
367
389
expr : Handle < HirExpr > ,
368
- lhs : bool ,
390
+ pos : ExprPos ,
369
391
body : & mut Block ,
370
392
) -> Result < ( Handle < Expression > , SourceMetadata ) > {
371
- let ( maybe_expr, meta) = self . lower_inner ( stmt, parser, expr, lhs , body) ?;
393
+ let ( maybe_expr, meta) = self . lower_inner ( stmt, parser, expr, pos , body) ?;
372
394
373
395
let expr = match maybe_expr {
374
396
Some ( e) => e,
@@ -389,16 +411,18 @@ impl Context {
389
411
stmt : & StmtContext ,
390
412
parser : & mut Parser ,
391
413
expr : Handle < HirExpr > ,
392
- lhs : bool ,
414
+ pos : ExprPos ,
393
415
body : & mut Block ,
394
416
) -> Result < ( Option < Handle < Expression > > , SourceMetadata ) > {
395
417
let HirExpr { ref kind, meta } = stmt. hir_exprs [ expr] ;
396
418
397
419
let handle = match * kind {
398
420
HirExprKind :: Access { base, index } => {
399
- let base = self . lower_expect_inner ( stmt, parser, base, true , body) ?. 0 ;
421
+ let base = self
422
+ . lower_expect_inner ( stmt, parser, base, pos. maybe_array_base ( ) , body) ?
423
+ . 0 ;
400
424
let ( index, index_meta) =
401
- self . lower_expect_inner ( stmt, parser, index, false , body) ?;
425
+ self . lower_expect_inner ( stmt, parser, index, ExprPos :: Rhs , body) ?;
402
426
403
427
let pointer = parser
404
428
. solve_constant ( self , index, index_meta)
@@ -427,7 +451,7 @@ impl Context {
427
451
self . add_expression ( Expression :: Access { base, index } , meta, body)
428
452
} ) ;
429
453
430
- if !lhs {
454
+ if ExprPos :: Rhs == pos {
431
455
let resolved = parser. resolve_type ( self , pointer, meta) ?;
432
456
if resolved. pointer_class ( ) . is_some ( ) {
433
457
return Ok ( (
@@ -440,18 +464,18 @@ impl Context {
440
464
pointer
441
465
}
442
466
HirExprKind :: Select { base, ref field } => {
443
- let base = self . lower_expect_inner ( stmt, parser, base, lhs , body) ?. 0 ;
467
+ let base = self . lower_expect_inner ( stmt, parser, base, pos , body) ?. 0 ;
444
468
445
- parser. field_selection ( self , lhs , body, base, field, meta) ?
469
+ parser. field_selection ( self , ExprPos :: Lhs == pos , body, base, field, meta) ?
446
470
}
447
- HirExprKind :: Constant ( constant) if !lhs => {
471
+ HirExprKind :: Constant ( constant) if pos == ExprPos :: Rhs => {
448
472
self . add_expression ( Expression :: Constant ( constant) , meta, body)
449
473
}
450
- HirExprKind :: Binary { left, op, right } if !lhs => {
474
+ HirExprKind :: Binary { left, op, right } if pos == ExprPos :: Rhs => {
451
475
let ( mut left, left_meta) =
452
- self . lower_expect_inner ( stmt, parser, left, false , body) ?;
476
+ self . lower_expect_inner ( stmt, parser, left, pos , body) ?;
453
477
let ( mut right, right_meta) =
454
- self . lower_expect_inner ( stmt, parser, right, false , body) ?;
478
+ self . lower_expect_inner ( stmt, parser, right, pos , body) ?;
455
479
456
480
match op {
457
481
BinaryOperator :: ShiftLeft | BinaryOperator :: ShiftRight => self
@@ -543,14 +567,14 @@ impl Context {
543
567
_ => self . add_expression ( Expression :: Binary { left, op, right } , meta, body) ,
544
568
}
545
569
}
546
- HirExprKind :: Unary { op, expr } if !lhs => {
547
- let expr = self . lower_expect_inner ( stmt, parser, expr, false , body) ?. 0 ;
570
+ HirExprKind :: Unary { op, expr } if pos == ExprPos :: Rhs => {
571
+ let expr = self . lower_expect_inner ( stmt, parser, expr, pos , body) ?. 0 ;
548
572
549
573
self . add_expression ( Expression :: Unary { op, expr } , meta, body)
550
574
}
551
575
HirExprKind :: Variable ( ref var) => {
552
- if lhs {
553
- if !var. mutable {
576
+ if pos != ExprPos :: Rhs {
577
+ if !var. mutable && ExprPos :: Lhs == pos {
554
578
parser. errors . push ( Error {
555
579
kind : ErrorKind :: SemanticError (
556
580
"Variable cannot be used in LHS position" . into ( ) ,
@@ -566,7 +590,7 @@ impl Context {
566
590
var. expr
567
591
}
568
592
}
569
- HirExprKind :: Call ( ref call) if !lhs => {
593
+ HirExprKind :: Call ( ref call) if pos != ExprPos :: Lhs => {
570
594
let maybe_expr = parser. function_or_constructor_call (
571
595
self ,
572
596
stmt,
@@ -581,14 +605,14 @@ impl Context {
581
605
condition,
582
606
accept,
583
607
reject,
584
- } if !lhs => {
608
+ } if ExprPos :: Lhs != pos => {
585
609
let condition = self
586
- . lower_expect_inner ( stmt, parser, condition, false , body) ?
610
+ . lower_expect_inner ( stmt, parser, condition, ExprPos :: Rhs , body) ?
587
611
. 0 ;
588
612
let ( mut accept, accept_meta) =
589
- self . lower_expect_inner ( stmt, parser, accept, false , body) ?;
613
+ self . lower_expect_inner ( stmt, parser, accept, pos , body) ?;
590
614
let ( mut reject, reject_meta) =
591
- self . lower_expect_inner ( stmt, parser, reject, false , body) ?;
615
+ self . lower_expect_inner ( stmt, parser, reject, pos , body) ?;
592
616
593
617
self . binary_implicit_conversion (
594
618
parser,
@@ -608,10 +632,11 @@ impl Context {
608
632
body,
609
633
)
610
634
}
611
- HirExprKind :: Assign { tgt, value } if !lhs => {
612
- let ( pointer, ptr_meta) = self . lower_expect_inner ( stmt, parser, tgt, true , body) ?;
635
+ HirExprKind :: Assign { tgt, value } if ExprPos :: Lhs != pos => {
636
+ let ( pointer, ptr_meta) =
637
+ self . lower_expect_inner ( stmt, parser, tgt, ExprPos :: Lhs , body) ?;
613
638
let ( mut value, value_meta) =
614
- self . lower_expect_inner ( stmt, parser, value, false , body) ?;
639
+ self . lower_expect_inner ( stmt, parser, value, ExprPos :: Rhs , body) ?;
615
640
616
641
let scalar_components = self . expr_scalar_components ( parser, pointer, ptr_meta) ?;
617
642
@@ -686,7 +711,9 @@ impl Context {
686
711
false => BinaryOperator :: Subtract ,
687
712
} ;
688
713
689
- let pointer = self . lower_expect_inner ( stmt, parser, expr, true , body) ?. 0 ;
714
+ let pointer = self
715
+ . lower_expect_inner ( stmt, parser, expr, ExprPos :: Lhs , body) ?
716
+ . 0 ;
690
717
let left = self . add_expression ( Expression :: Load { pointer } , meta, body) ;
691
718
692
719
let uint = match parser. resolve_type ( self , left, meta) ?. scalar_kind ( ) {
0 commit comments