Browse Source

Use named fields for casts in ast::Expression (#1078)

Signed-off-by: Sean Young <sean@mess.org>
Sean Young 3 years ago
parent
commit
bb9cc0bb5a

+ 9 - 9
src/bin/languageserver/mod.rs

@@ -599,19 +599,19 @@ impl SolangServer {
             ast::Expression::StorageLoad(_locs, _typ, expr1) => {
                 SolangServer::construct_expr(expr1, lookup_tbl, symtab, ns);
             }
-            ast::Expression::ZeroExt(_locs, _typ, expr1) => {
-                SolangServer::construct_expr(expr1, lookup_tbl, symtab, ns);
+            ast::Expression::ZeroExt { expr, .. } => {
+                SolangServer::construct_expr(expr, lookup_tbl, symtab, ns);
             }
-            ast::Expression::SignExt(_locs, _typ, expr1) => {
-                SolangServer::construct_expr(expr1, lookup_tbl, symtab, ns);
+            ast::Expression::SignExt { expr, .. } => {
+                SolangServer::construct_expr(expr, lookup_tbl, symtab, ns);
             }
-            ast::Expression::Trunc(_locs, _typ, expr1) => {
-                SolangServer::construct_expr(expr1, lookup_tbl, symtab, ns);
+            ast::Expression::Trunc { expr, .. } => {
+                SolangServer::construct_expr(expr, lookup_tbl, symtab, ns);
             }
-            ast::Expression::Cast(_locs, _typ, expr1) => {
-                SolangServer::construct_expr(expr1, lookup_tbl, symtab, ns);
+            ast::Expression::Cast { expr, .. } => {
+                SolangServer::construct_expr(expr, lookup_tbl, symtab, ns);
             }
-            ast::Expression::BytesCast(_loc, _typ1, _typ2, expr) => {
+            ast::Expression::BytesCast { expr, .. } => {
                 SolangServer::construct_expr(expr, lookup_tbl, symtab, ns);
             }
 

+ 37 - 31
src/codegen/expression.rs

@@ -496,63 +496,69 @@ pub fn expression(
         ast::Expression::And(loc, left, right) => {
             and(left, cfg, contract_no, func, ns, vartab, loc, right, opt)
         }
-        ast::Expression::CheckingTrunc(loc, ty, e) => {
-            checking_trunc(loc, e, ty, cfg, contract_no, func, ns, vartab, opt)
+        ast::Expression::CheckingTrunc { loc, to, expr } => {
+            checking_trunc(loc, expr, to, cfg, contract_no, func, ns, vartab, opt)
         }
-        ast::Expression::Trunc(loc, ty, e) => Expression::Trunc(
+        ast::Expression::Trunc { loc, to, expr } => Expression::Trunc(
             *loc,
-            ty.clone(),
-            Box::new(expression(e, cfg, contract_no, func, ns, vartab, opt)),
+            to.clone(),
+            Box::new(expression(expr, cfg, contract_no, func, ns, vartab, opt)),
         ),
-        ast::Expression::ZeroExt(loc, ty, e) => Expression::ZeroExt(
+        ast::Expression::ZeroExt { loc, to, expr } => Expression::ZeroExt(
             *loc,
-            ty.clone(),
-            Box::new(expression(e, cfg, contract_no, func, ns, vartab, opt)),
+            to.clone(),
+            Box::new(expression(expr, cfg, contract_no, func, ns, vartab, opt)),
         ),
-        ast::Expression::SignExt(loc, ty, e) => Expression::SignExt(
+        ast::Expression::SignExt { loc, to, expr } => Expression::SignExt(
             *loc,
-            ty.clone(),
-            Box::new(expression(e, cfg, contract_no, func, ns, vartab, opt)),
+            to.clone(),
+            Box::new(expression(expr, cfg, contract_no, func, ns, vartab, opt)),
         ),
-        ast::Expression::Cast(loc, ty @ Type::Address(_), e) => {
-            if let Ok((_, address)) = eval_const_number(e, ns) {
-                Expression::NumberLiteral(*loc, ty.clone(), address)
+        ast::Expression::Cast { loc, to, expr } if matches!(to, Type::Address(_)) => {
+            if let Ok((_, address)) = eval_const_number(expr, ns) {
+                Expression::NumberLiteral(*loc, to.clone(), address)
             } else {
                 Expression::Cast(
                     *loc,
-                    ty.clone(),
-                    Box::new(expression(e, cfg, contract_no, func, ns, vartab, opt)),
+                    to.clone(),
+                    Box::new(expression(expr, cfg, contract_no, func, ns, vartab, opt)),
                 )
             }
         }
-        ast::Expression::Cast(loc, ty @ Type::Array(..), e)
-            if matches!(**e, ast::Expression::ArrayLiteral(..)) =>
+        ast::Expression::Cast { loc, to, expr }
+            if matches!(to, Type::Array(..))
+                && matches!(**expr, ast::Expression::ArrayLiteral(..)) =>
         {
-            let codegen_expr = expression(e, cfg, contract_no, func, ns, vartab, opt);
-            array_literal_to_memory_array(loc, &codegen_expr, ty, cfg, vartab)
+            let codegen_expr = expression(expr, cfg, contract_no, func, ns, vartab, opt);
+            array_literal_to_memory_array(loc, &codegen_expr, to, cfg, vartab)
         }
-        ast::Expression::Cast(loc, ty, e) => {
-            if e.ty() == Type::Rational {
-                let (_, n) = eval_const_rational(e, ns).unwrap();
+        ast::Expression::Cast { loc, to, expr } => {
+            if expr.ty() == Type::Rational {
+                let (_, n) = eval_const_rational(expr, ns).unwrap();
 
-                Expression::NumberLiteral(*loc, ty.clone(), n.to_integer())
-            } else if matches!(ty, Type::String | Type::DynamicBytes)
+                Expression::NumberLiteral(*loc, to.clone(), n.to_integer())
+            } else if matches!(to, Type::String | Type::DynamicBytes)
                 && matches!(expr.ty(), Type::String | Type::DynamicBytes)
             {
-                expression(e, cfg, contract_no, func, ns, vartab, opt)
+                expression(expr, cfg, contract_no, func, ns, vartab, opt)
             } else {
                 Expression::Cast(
                     *loc,
-                    ty.clone(),
-                    Box::new(expression(e, cfg, contract_no, func, ns, vartab, opt)),
+                    to.clone(),
+                    Box::new(expression(expr, cfg, contract_no, func, ns, vartab, opt)),
                 )
             }
         }
-        ast::Expression::BytesCast(loc, ty, from, e) => Expression::BytesCast(
+        ast::Expression::BytesCast {
+            loc,
+            to,
+            from,
+            expr,
+        } => Expression::BytesCast(
             *loc,
-            ty.clone(),
+            to.clone(),
             from.clone(),
-            Box::new(expression(e, cfg, contract_no, func, ns, vartab, opt)),
+            Box::new(expression(expr, cfg, contract_no, func, ns, vartab, opt)),
         ),
         ast::Expression::Load(loc, ty, e) => Expression::Load(
             *loc,

+ 3 - 3
src/codegen/unused_variable.rs

@@ -42,9 +42,9 @@ pub fn should_remove_assignment(
 
         Expression::StorageLoad(_, _, expr)
         | Expression::Load(_, _, expr)
-        | Expression::Trunc(_, _, expr)
-        | Expression::Cast(_, _, expr)
-        | Expression::BytesCast(_, _, _, expr) => should_remove_assignment(ns, expr, func, opt),
+        | Expression::Trunc { expr, .. }
+        | Expression::Cast { expr, .. }
+        | Expression::BytesCast { expr, .. } => should_remove_assignment(ns, expr, func, opt),
 
         _ => false,
     }

+ 42 - 18
src/sema/ast.rs

@@ -686,13 +686,37 @@ pub enum Expression {
     Load(pt::Loc, Type, Box<Expression>),
     GetRef(pt::Loc, Type, Box<Expression>),
     StorageLoad(pt::Loc, Type, Box<Expression>),
-    ZeroExt(pt::Loc, Type, Box<Expression>),
-    SignExt(pt::Loc, Type, Box<Expression>),
-    Trunc(pt::Loc, Type, Box<Expression>),
-    CheckingTrunc(pt::Loc, Type, Box<Expression>),
-    Cast(pt::Loc, Type, Box<Expression>),
-    BytesCast(pt::Loc, Type, Type, Box<Expression>),
-
+    ZeroExt {
+        loc: pt::Loc,
+        to: Type,
+        expr: Box<Expression>,
+    },
+    SignExt {
+        loc: pt::Loc,
+        to: Type,
+        expr: Box<Expression>,
+    },
+    Trunc {
+        loc: pt::Loc,
+        to: Type,
+        expr: Box<Expression>,
+    },
+    CheckingTrunc {
+        loc: pt::Loc,
+        to: Type,
+        expr: Box<Expression>,
+    },
+    Cast {
+        loc: pt::Loc,
+        to: Type,
+        expr: Box<Expression>,
+    },
+    BytesCast {
+        loc: pt::Loc,
+        from: Type,
+        to: Type,
+        expr: Box<Expression>,
+    },
     PreIncrement(pt::Loc, Type, bool, Box<Expression>),
     PreDecrement(pt::Loc, Type, bool, Box<Expression>),
     PostIncrement(pt::Loc, Type, bool, Box<Expression>),
@@ -842,11 +866,11 @@ impl Recurse for Expression {
                 }
                 Expression::Load(_, _, expr)
                 | Expression::StorageLoad(_, _, expr)
-                | Expression::ZeroExt(_, _, expr)
-                | Expression::SignExt(_, _, expr)
-                | Expression::Trunc(_, _, expr)
-                | Expression::Cast(_, _, expr)
-                | Expression::BytesCast(_, _, _, expr)
+                | Expression::ZeroExt { expr, .. }
+                | Expression::SignExt { expr, .. }
+                | Expression::Trunc { expr, .. }
+                | Expression::Cast { expr, .. }
+                | Expression::BytesCast { expr, .. }
                 | Expression::PreIncrement(_, _, _, expr)
                 | Expression::PreDecrement(_, _, _, expr)
                 | Expression::PostIncrement(_, _, _, expr)
@@ -971,12 +995,12 @@ impl CodeLocation for Expression {
             | Expression::Load(loc, ..)
             | Expression::GetRef(loc, ..)
             | Expression::StorageLoad(loc, ..)
-            | Expression::ZeroExt(loc, ..)
-            | Expression::SignExt(loc, ..)
-            | Expression::Trunc(loc, ..)
-            | Expression::CheckingTrunc(loc, ..)
-            | Expression::Cast(loc, ..)
-            | Expression::BytesCast(loc, ..)
+            | Expression::ZeroExt { loc, .. }
+            | Expression::SignExt { loc, .. }
+            | Expression::Trunc { loc, .. }
+            | Expression::CheckingTrunc { loc, .. }
+            | Expression::Cast { loc, .. }
+            | Expression::BytesCast { loc, .. }
             | Expression::More(loc, ..)
             | Expression::Less(loc, ..)
             | Expression::MoreEqual(loc, ..)

+ 16 - 11
src/sema/dotgraphviz.rs

@@ -569,12 +569,12 @@ impl Dot {
 
                 self.add_expression(expr, func, ns, node, String::from("expr"));
             }
-            Expression::ZeroExt(loc, ty, expr) => {
+            Expression::ZeroExt { loc, to, expr } => {
                 let node = self.add_node(
                     Node::new(
                         "zero_ext",
                         vec![
-                            format!("zero extend {}", ty.to_string(ns)),
+                            format!("zero extend {}", to.to_string(ns)),
                             ns.loc_to_string(loc),
                         ],
                     ),
@@ -584,12 +584,12 @@ impl Dot {
 
                 self.add_expression(expr, func, ns, node, String::from("expr"));
             }
-            Expression::SignExt(loc, ty, expr) => {
+            Expression::SignExt { loc, to, expr } => {
                 let node = self.add_node(
                     Node::new(
                         "sign_ext",
                         vec![
-                            format!("sign extend {}", ty.to_string(ns)),
+                            format!("sign extend {}", to.to_string(ns)),
                             ns.loc_to_string(loc),
                         ],
                     ),
@@ -599,12 +599,12 @@ impl Dot {
 
                 self.add_expression(expr, func, ns, node, String::from("expr"));
             }
-            Expression::Trunc(loc, ty, expr) => {
+            Expression::Trunc { loc, to, expr } => {
                 let node = self.add_node(
                     Node::new(
                         "trunc",
                         vec![
-                            format!("truncate {}", ty.to_string(ns)),
+                            format!("truncate {}", to.to_string(ns)),
                             ns.loc_to_string(loc),
                         ],
                     ),
@@ -614,12 +614,12 @@ impl Dot {
 
                 self.add_expression(expr, func, ns, node, String::from("expr"));
             }
-            Expression::CheckingTrunc(loc, ty, expr) => {
+            Expression::CheckingTrunc { loc, to, expr } => {
                 let node = self.add_node(
                     Node::new(
                         "trunc",
                         vec![
-                            format!("checking truncate {}", ty.to_string(ns)),
+                            format!("checking truncate {}", to.to_string(ns)),
                             ns.loc_to_string(loc),
                         ],
                     ),
@@ -629,11 +629,11 @@ impl Dot {
 
                 self.add_expression(expr, func, ns, node, String::from("expr"));
             }
-            Expression::Cast(loc, ty, expr) => {
+            Expression::Cast { loc, to, expr } => {
                 let node = self.add_node(
                     Node::new(
                         "cast",
-                        vec![format!("cast {}", ty.to_string(ns)), ns.loc_to_string(loc)],
+                        vec![format!("cast {}", to.to_string(ns)), ns.loc_to_string(loc)],
                     ),
                     Some(parent),
                     Some(parent_rel),
@@ -641,7 +641,12 @@ impl Dot {
 
                 self.add_expression(expr, func, ns, node, String::from("expr"));
             }
-            Expression::BytesCast(loc, to, from, expr) => {
+            Expression::BytesCast {
+                loc,
+                to,
+                from,
+                expr,
+            } => {
                 let node = self.add_node(
                     Node::new(
                         "bytes_cast",

+ 8 - 8
src/sema/eval.rs

@@ -109,9 +109,9 @@ pub fn eval_const_number(
             Ok((*loc, l >> r))
         }
         Expression::NumberLiteral(loc, _, n) => Ok((*loc, n.clone())),
-        Expression::ZeroExt(loc, _, n) => Ok((*loc, eval_const_number(n, ns)?.1)),
-        Expression::SignExt(loc, _, n) => Ok((*loc, eval_const_number(n, ns)?.1)),
-        Expression::Cast(loc, _, n) => Ok((*loc, eval_const_number(n, ns)?.1)),
+        Expression::ZeroExt { loc, expr, .. } => Ok((*loc, eval_const_number(expr, ns)?.1)),
+        Expression::SignExt { loc, expr, .. } => Ok((*loc, eval_const_number(expr, ns)?.1)),
+        Expression::Cast { loc, expr, .. } => Ok((*loc, eval_const_number(expr, ns)?.1)),
         Expression::Not(loc, n) => Ok((*loc, !eval_const_number(n, ns)?.1)),
         Expression::Complement(loc, _, n) => Ok((*loc, !eval_const_number(n, ns)?.1)),
         Expression::UnaryMinus(loc, _, n) => Ok((*loc, -eval_const_number(n, ns)?.1)),
@@ -174,7 +174,7 @@ pub fn eval_const_rational(
         }
         Expression::NumberLiteral(loc, _, n) => Ok((*loc, BigRational::from_integer(n.clone()))),
         Expression::RationalNumberLiteral(loc, _, n) => Ok((*loc, n.clone())),
-        Expression::Cast(loc, _, n) => Ok((*loc, eval_const_rational(n, ns)?.1)),
+        Expression::Cast { loc, expr, .. } => Ok((*loc, eval_const_rational(expr, ns)?.1)),
         Expression::UnaryMinus(loc, _, n) => Ok((*loc, -eval_const_rational(n, ns)?.1)),
         Expression::ConstantVariable(_, _, Some(contract_no), var_no) => {
             let expr = ns.contracts[*contract_no].variables[*var_no]
@@ -495,18 +495,18 @@ fn eval_constants_in_expression(
                 (None, true)
             }
         }
-        Expression::ZeroExt(loc, ty, expr) => {
+        Expression::ZeroExt { loc, to, expr } => {
             let expr = eval_constants_in_expression(expr, ns).0;
             if let Some(Expression::NumberLiteral(_, _, n)) = expr {
-                (Some(Expression::NumberLiteral(*loc, ty.clone(), n)), true)
+                (Some(Expression::NumberLiteral(*loc, to.clone(), n)), true)
             } else {
                 (None, true)
             }
         }
-        Expression::SignExt(loc, ty, expr) => {
+        Expression::SignExt { loc, to, expr } => {
             let expr = eval_constants_in_expression(expr, ns).0;
             if let Some(Expression::NumberLiteral(_, _, n)) = expr {
-                (Some(Expression::NumberLiteral(*loc, ty.clone(), n)), true)
+                (Some(Expression::NumberLiteral(*loc, to.clone(), n)), true)
             } else {
                 (None, true)
             }

+ 306 - 137
src/sema/expression.rs

@@ -70,12 +70,6 @@ impl RetrieveType for Expression {
             | Expression::Load(_, ty, _)
             | Expression::GetRef(_, ty, _)
             | Expression::StorageLoad(_, ty, _)
-            | Expression::ZeroExt(_, ty, _)
-            | Expression::SignExt(_, ty, _)
-            | Expression::Trunc(_, ty, _)
-            | Expression::CheckingTrunc(_, ty, _)
-            | Expression::Cast(_, ty, _)
-            | Expression::BytesCast(_, ty, ..)
             | Expression::Complement(_, ty, _)
             | Expression::UnaryMinus(_, ty, _)
             | Expression::ConditionalOperator(_, ty, ..)
@@ -87,6 +81,12 @@ impl RetrieveType for Expression {
             | Expression::PostDecrement(_, ty, ..)
             | Expression::Assign(_, ty, ..) => ty.clone(),
             Expression::Subscript(_, ty, ..) => ty.clone(),
+            Expression::ZeroExt { to, .. }
+            | Expression::SignExt { to, .. }
+            | Expression::Trunc { to, .. }
+            | Expression::CheckingTrunc { to, .. }
+            | Expression::Cast { to, .. }
+            | Expression::BytesCast { to, .. } => to.clone(),
             Expression::StorageArrayLength { ty, .. } => ty.clone(),
             Expression::ExternalFunctionCallRaw { .. } => {
                 panic!("two return values");
@@ -384,7 +384,11 @@ impl Expression {
                     && from_dims.len() == 1
                     && matches!(to_dims.last().unwrap(), ArrayLength::Dynamic)
                 {
-                    return Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())));
+                    return Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    });
                 }
             }
 
@@ -460,17 +464,21 @@ impl Expression {
 
                 // TODO needs runtime checks
                 match from_width.cmp(&to_width) {
-                    Ordering::Greater => {
-                        Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
-                    }
-                    Ordering::Less => Ok(Expression::ZeroExt(
-                        *loc,
-                        to.clone(),
-                        Box::new(self.clone()),
-                    )),
-                    Ordering::Equal => {
-                        Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
-                    }
+                    Ordering::Greater => Ok(Expression::Trunc {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
+                    Ordering::Less => Ok(Expression::ZeroExt {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
+                    Ordering::Equal => Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
                 }
             }
             (Type::Enum(enum_no), Type::Uint(to_width))
@@ -490,17 +498,21 @@ impl Expression {
                 let from_width = enum_ty.ty.bits(ns);
 
                 match from_width.cmp(to_width) {
-                    Ordering::Greater => {
-                        Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
-                    }
-                    Ordering::Less => Ok(Expression::ZeroExt(
-                        *loc,
-                        to.clone(),
-                        Box::new(self.clone()),
-                    )),
-                    Ordering::Equal => {
-                        Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
-                    }
+                    Ordering::Greater => Ok(Expression::Trunc {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
+                    Ordering::Less => Ok(Expression::ZeroExt {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
+                    Ordering::Equal => Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
                 }
             }
             (Type::Bytes(1), Type::Uint(8)) | (Type::Uint(8), Type::Bytes(1)) => Ok(self.clone()),
@@ -517,15 +529,23 @@ impl Expression {
                         ));
                         Err(())
                     } else {
-                        Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
+                        Ok(Expression::Trunc {
+                            loc: *loc,
+                            to: to.clone(),
+                            expr: Box::new(self.clone()),
+                        })
                     }
                 }
-                Ordering::Less => Ok(Expression::ZeroExt(
-                    *loc,
-                    to.clone(),
-                    Box::new(self.clone()),
-                )),
-                Ordering::Equal => Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone()))),
+                Ordering::Less => Ok(Expression::ZeroExt {
+                    loc: *loc,
+                    to: to.clone(),
+                    expr: Box::new(self.clone()),
+                }),
+                Ordering::Equal => Ok(Expression::Cast {
+                    loc: *loc,
+                    to: to.clone(),
+                    expr: Box::new(self.clone()),
+                }),
             },
             (Type::Int(from_len), Type::Int(to_len)) => match from_len.cmp(to_len) {
                 Ordering::Greater => {
@@ -540,19 +560,31 @@ impl Expression {
                         ));
                         Err(())
                     } else {
-                        Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
+                        Ok(Expression::Trunc {
+                            loc: *loc,
+                            to: to.clone(),
+                            expr: Box::new(self.clone()),
+                        })
                     }
                 }
-                Ordering::Less => Ok(Expression::SignExt(
-                    *loc,
-                    to.clone(),
-                    Box::new(self.clone()),
-                )),
-                Ordering::Equal => Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone()))),
+                Ordering::Less => Ok(Expression::SignExt {
+                    loc: *loc,
+                    to: to.clone(),
+                    expr: Box::new(self.clone()),
+                }),
+                Ordering::Equal => Ok(Expression::Cast {
+                    loc: *loc,
+                    to: to.clone(),
+                    expr: Box::new(self.clone()),
+                }),
             },
-            (Type::Uint(from_len), Type::Int(to_len)) if to_len > from_len => Ok(
-                Expression::ZeroExt(*loc, to.clone(), Box::new(self.clone())),
-            ),
+            (Type::Uint(from_len), Type::Int(to_len)) if to_len > from_len => {
+                Ok(Expression::ZeroExt {
+                    loc: *loc,
+                    to: to.clone(),
+                    expr: Box::new(self.clone()),
+                })
+            }
             (Type::Int(from_len), Type::Uint(to_len)) => {
                 if implicit {
                     diagnostics.push(Diagnostic::cast_error(
@@ -565,15 +597,23 @@ impl Expression {
                     ));
                     Err(())
                 } else if from_len > to_len {
-                    Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Trunc {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 } else if from_len < to_len {
-                    Ok(Expression::SignExt(
-                        *loc,
-                        to.clone(),
-                        Box::new(self.clone()),
-                    ))
+                    Ok(Expression::SignExt {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             (Type::Uint(from_len), Type::Int(to_len)) => {
@@ -588,15 +628,23 @@ impl Expression {
                     ));
                     Err(())
                 } else if from_len > to_len {
-                    Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Trunc {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 } else if from_len < to_len {
-                    Ok(Expression::ZeroExt(
-                        *loc,
-                        to.clone(),
-                        Box::new(self.clone()),
-                    ))
+                    Ok(Expression::ZeroExt {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // Casting value to uint
@@ -617,17 +665,23 @@ impl Expression {
                             ));
                             Err(())
                         } else {
-                            Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
+                            Ok(Expression::Trunc {
+                                loc: *loc,
+                                to: to.clone(),
+                                expr: Box::new(self.clone()),
+                            })
                         }
                     }
-                    Ordering::Less => Ok(Expression::SignExt(
-                        *loc,
-                        to.clone(),
-                        Box::new(self.clone()),
-                    )),
-                    Ordering::Equal => {
-                        Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
-                    }
+                    Ordering::Less => Ok(Expression::SignExt {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
+                    Ordering::Equal => Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
                 }
             }
             (Type::Value, Type::Int(to_len)) => {
@@ -645,15 +699,23 @@ impl Expression {
                     ));
                     Err(())
                 } else if from_len > to_len {
-                    Ok(Expression::Trunc(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Trunc {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 } else if from_len < to_len {
-                    Ok(Expression::ZeroExt(
-                        *loc,
-                        to.clone(),
-                        Box::new(self.clone()),
-                    ))
+                    Ok(Expression::ZeroExt {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // Casting value to uint
@@ -674,20 +736,22 @@ impl Expression {
                             ),
                         ));
 
-                        Ok(Expression::CheckingTrunc(
-                            *loc,
-                            to.clone(),
-                            Box::new(self.clone()),
-                        ))
-                    }
-                    Ordering::Less => Ok(Expression::SignExt(
-                        *loc,
-                        to.clone(),
-                        Box::new(self.clone()),
-                    )),
-                    Ordering::Equal => {
-                        Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                        Ok(Expression::CheckingTrunc {
+                            loc: *loc,
+                            to: to.clone(),
+                            expr: Box::new(self.clone()),
+                        })
                     }
+                    Ordering::Less => Ok(Expression::SignExt {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
+                    Ordering::Equal => Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    }),
                 }
             }
             // Casting int to address
@@ -711,19 +775,35 @@ impl Expression {
                     };
 
                     let expr = if *from_len > address_bits {
-                        Expression::Trunc(*loc, address_to_int, Box::new(self.clone()))
+                        Expression::Trunc {
+                            loc: *loc,
+                            to: address_to_int,
+                            expr: Box::new(self.clone()),
+                        }
                     } else if *from_len < address_bits {
                         if from.is_signed_int() {
-                            Expression::ZeroExt(*loc, address_to_int, Box::new(self.clone()))
+                            Expression::ZeroExt {
+                                loc: *loc,
+                                to: address_to_int,
+                                expr: Box::new(self.clone()),
+                            }
                         } else {
-                            Expression::SignExt(*loc, address_to_int, Box::new(self.clone()))
+                            Expression::SignExt {
+                                loc: *loc,
+                                to: address_to_int,
+                                expr: Box::new(self.clone()),
+                            }
                         }
                     } else {
                         self.clone()
                     };
 
                     // Now cast integer to address
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(expr)))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(expr),
+                    })
                 }
             }
             // Casting address to int
@@ -747,15 +827,31 @@ impl Expression {
                         Type::Uint(address_bits)
                     };
 
-                    let expr = Expression::Cast(*loc, address_to_int, Box::new(self.clone()));
+                    let expr = Expression::Cast {
+                        loc: *loc,
+                        to: address_to_int,
+                        expr: Box::new(self.clone()),
+                    };
                     // now resize int to request size with sign extension etc
                     if *to_len < address_bits {
-                        Ok(Expression::Trunc(*loc, to.clone(), Box::new(expr)))
+                        Ok(Expression::Trunc {
+                            loc: *loc,
+                            to: to.clone(),
+                            expr: Box::new(expr),
+                        })
                     } else if *to_len > address_bits {
                         if to.is_signed_int() {
-                            Ok(Expression::ZeroExt(*loc, to.clone(), Box::new(expr)))
+                            Ok(Expression::ZeroExt {
+                                loc: *loc,
+                                to: to.clone(),
+                                expr: Box::new(expr),
+                            })
                         } else {
-                            Ok(Expression::SignExt(*loc, to.clone(), Box::new(expr)))
+                            Ok(Expression::SignExt {
+                                loc: *loc,
+                                to: to.clone(),
+                                expr: Box::new(expr),
+                            })
                         }
                     } else {
                         Ok(expr)
@@ -780,11 +876,11 @@ impl Expression {
                     Ok(Expression::ShiftLeft(
                         *loc,
                         to.clone(),
-                        Box::new(Expression::ZeroExt(
-                            self.loc(),
-                            to.clone(),
-                            Box::new(self.clone()),
-                        )),
+                        Box::new(Expression::ZeroExt {
+                            loc: self.loc(),
+                            to: to.clone(),
+                            expr: Box::new(self.clone()),
+                        }),
                         Box::new(Expression::NumberLiteral(
                             *loc,
                             Type::Uint(*to_len as u16 * 8),
@@ -794,10 +890,10 @@ impl Expression {
                 } else {
                     let shift = (from_len - to_len) * 8;
 
-                    Ok(Expression::Trunc(
-                        *loc,
-                        to.clone(),
-                        Box::new(Expression::ShiftRight(
+                    Ok(Expression::Trunc {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(Expression::ShiftRight(
                             self.loc(),
                             from.clone(),
                             Box::new(self.clone()),
@@ -808,14 +904,18 @@ impl Expression {
                             )),
                             false,
                         )),
-                    ))
+                    })
                 }
             }
             (Type::Rational, Type::Uint(_) | Type::Int(_) | Type::Value) => {
                 match eval_const_rational(self, ns) {
                     Ok((_, big_number)) => {
                         if big_number.is_integer() {
-                            return Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())));
+                            return Ok(Expression::Cast {
+                                loc: *loc,
+                                to: to.clone(),
+                                expr: Box::new(self.clone()),
+                            });
                         }
 
                         diagnostics.push(Diagnostic::cast_error(
@@ -835,12 +935,19 @@ impl Expression {
                     }
                 }
             }
-            (Type::Uint(_) | Type::Int(_) | Type::Value, Type::Rational) => {
-                Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+            (Type::Uint(_) | Type::Int(_) | Type::Value, Type::Rational) => Ok(Expression::Cast {
+                loc: *loc,
+                to: to.clone(),
+                expr: Box::new(self.clone()),
+            }),
+            (Type::Bytes(_), Type::DynamicBytes) | (Type::DynamicBytes, Type::Bytes(_)) => {
+                Ok(Expression::BytesCast {
+                    loc: *loc,
+                    to: to.clone(),
+                    from: from.clone(),
+                    expr: Box::new(self.clone()),
+                })
             }
-            (Type::Bytes(_), Type::DynamicBytes) | (Type::DynamicBytes, Type::Bytes(_)) => Ok(
-                Expression::BytesCast(*loc, to.clone(), from.clone(), Box::new(self.clone())),
-            ),
             // Explicit conversion from bytesN to int/uint only allowed with expliciy
             // cast and if it is the same size (i.e. no conversion required)
             (Type::Bytes(from_len), Type::Uint(to_len))
@@ -866,7 +973,11 @@ impl Expression {
                     ));
                     Err(())
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // Explicit conversion to bytesN from int/uint only allowed with expliciy
@@ -894,7 +1005,11 @@ impl Expression {
                     ));
                     Err(())
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // Explicit conversion from bytesN to address only allowed with expliciy
@@ -921,7 +1036,11 @@ impl Expression {
                     ));
                     Err(())
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // Explicit conversion between contract and address is allowed
@@ -939,7 +1058,11 @@ impl Expression {
                     ));
                     Err(())
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // Conversion between contracts is allowed if it is a base
@@ -955,13 +1078,19 @@ impl Expression {
                     ));
                     Err(())
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // conversion from address payable to address is implicitly allowed (not vice versa)
-            (Type::Address(true), Type::Address(false)) => {
-                Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
-            }
+            (Type::Address(true), Type::Address(false)) => Ok(Expression::Cast {
+                loc: *loc,
+                to: to.clone(),
+                expr: Box::new(self.clone()),
+            }),
             // Explicit conversion to bytesN from int/uint only allowed with expliciy
             // cast and if it is the same size (i.e. no conversion required)
             (Type::Address(_), Type::Bytes(to_len)) => {
@@ -986,13 +1115,21 @@ impl Expression {
                     ));
                     Err(())
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             (Type::String, Type::DynamicBytes) | (Type::DynamicBytes, Type::String)
                 if !implicit =>
             {
-                Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                Ok(Expression::Cast {
+                    loc: *loc,
+                    to: to.clone(),
+                    expr: Box::new(self.clone()),
+                })
             }
             // string conversions
             // (Type::Bytes(_), Type::String) => Ok(Expression::Cast(self.loc(), to.clone(), Box::new(self.clone()))),
@@ -1076,7 +1213,11 @@ impl Expression {
                     ));
                     Err(())
                 } else {
-                    Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                    Ok(Expression::Cast {
+                        loc: *loc,
+                        to: to.clone(),
+                        expr: Box::new(self.clone()),
+                    })
                 }
             }
             // Match any array with ArrayLength::AnyFixed if is it fixed for that dimension, and the
@@ -1091,7 +1232,11 @@ impl Expression {
                 Ok(self.clone())
             }
             (Type::DynamicBytes, Type::Slice(ty)) if ty.as_ref() == &Type::Bytes(1) => {
-                Ok(Expression::Cast(*loc, to.clone(), Box::new(self.clone())))
+                Ok(Expression::Cast {
+                    loc: *loc,
+                    to: to.clone(),
+                    expr: Box::new(self.clone()),
+                })
             }
             _ => {
                 diagnostics.push(Diagnostic::cast_error(
@@ -3656,11 +3801,11 @@ pub fn new(
             ),
         ));
 
-        Expression::CheckingTrunc(
-            size_loc,
-            expected_ty.clone(),
-            Box::new(size_expr.cast(&size_loc, &size_ty, true, ns, diagnostics)?),
-        )
+        Expression::CheckingTrunc {
+            loc: size_loc,
+            to: expected_ty.clone(),
+            expr: Box::new(size_expr.cast(&size_loc, &size_ty, true, ns, diagnostics)?),
+        }
     } else {
         size_expr.cast(&size_loc, &expected_ty, true, ns, diagnostics)?
     };
@@ -4069,11 +4214,23 @@ fn assign_expr(
                 if left_length == right_length {
                     set
                 } else if right_length < left_length && set_type.is_signed_int() {
-                    Expression::SignExt(*loc, ty.clone(), Box::new(set))
+                    Expression::SignExt {
+                        loc: *loc,
+                        to: ty.clone(),
+                        expr: Box::new(set),
+                    }
                 } else if right_length < left_length && !set_type.is_signed_int() {
-                    Expression::ZeroExt(*loc, ty.clone(), Box::new(set))
+                    Expression::ZeroExt {
+                        loc: *loc,
+                        to: ty.clone(),
+                        expr: Box::new(set),
+                    }
                 } else {
-                    Expression::Trunc(*loc, ty.clone(), Box::new(set))
+                    Expression::Trunc {
+                        loc: *loc,
+                        to: ty.clone(),
+                        expr: Box::new(set),
+                    }
                 }
             }
             _ => set.cast(&right.loc(), ty, true, ns, diagnostics)?,
@@ -4727,7 +4884,7 @@ fn member_access(
                 if ns.target.is_substrate() {
                     let mut is_this = false;
 
-                    if let Expression::Cast(_, _, this) = &expr {
+                    if let Expression::Cast { expr: this, .. } = &expr {
                         if let Expression::Builtin(_, _, Builtin::GetAddress, _) = this.as_ref() {
                             is_this = true;
                         }
@@ -6901,11 +7058,23 @@ pub fn cast_shift_arg(
     if from_width == to_width {
         expr
     } else if from_width < to_width && ty.is_signed_int() {
-        Expression::SignExt(*loc, ty.clone(), Box::new(expr))
+        Expression::SignExt {
+            loc: *loc,
+            to: ty.clone(),
+            expr: Box::new(expr),
+        }
     } else if from_width < to_width && !ty.is_signed_int() {
-        Expression::ZeroExt(*loc, ty.clone(), Box::new(expr))
+        Expression::ZeroExt {
+            loc: *loc,
+            to: ty.clone(),
+            expr: Box::new(expr),
+        }
     } else {
-        Expression::Trunc(*loc, ty.clone(), Box::new(expr))
+        Expression::Trunc {
+            loc: *loc,
+            to: ty.clone(),
+            expr: Box::new(expr),
+        }
     }
 }
 

+ 8 - 8
src/sema/unused_variable.rs

@@ -29,9 +29,9 @@ pub fn assigned_variable(ns: &mut Namespace, exp: &Expression, symtable: &mut Sy
 
         Expression::StorageLoad(_, _, expr)
         | Expression::Load(_, _, expr)
-        | Expression::Trunc(_, _, expr)
-        | Expression::Cast(_, _, expr)
-        | Expression::BytesCast(_, _, _, expr) => {
+        | Expression::Trunc { expr, .. }
+        | Expression::Cast { expr, .. }
+        | Expression::BytesCast { expr, .. } => {
             assigned_variable(ns, expr, symtable);
         }
 
@@ -91,11 +91,11 @@ pub fn used_variable(ns: &mut Namespace, exp: &Expression, symtable: &mut Symtab
 
         Expression::StorageLoad(_, _, expr)
         | Expression::Load(_, _, expr)
-        | Expression::SignExt(_, _, expr)
-        | Expression::ZeroExt(_, _, expr)
-        | Expression::Trunc(_, _, expr)
-        | Expression::Cast(_, _, expr)
-        | Expression::BytesCast(_, _, _, expr) => {
+        | Expression::SignExt { expr, .. }
+        | Expression::ZeroExt { expr, .. }
+        | Expression::Trunc { expr, .. }
+        | Expression::Cast { expr, .. }
+        | Expression::BytesCast { expr, .. } => {
             used_variable(ns, expr, symtable);
         }