You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: tests.rs
    path of file: ./repos/solang/src/codegen/subexpression_elimination
    
    the code of the file until where you have to start completion: // SPDX-License-Identifier: Apache-2.0

#![cfg(test)]

use crate::codegen::cfg::{ASTFunction, BasicBlock, ControlFlowGraph, Instr};
use crate::codegen::subexpression_elimination::anticipated_expressions::AnticipatedExpressions;
use crate::codegen::subexpression_elimination::common_subexpression_tracker::CommonSubExpressionTracker;
use crate::codegen::subexpression_elimination::{AvailableExpression, AvailableExpressionSet};
use crate::codegen::Expression;
use crate::sema::ast::{ExternalCallAccounts, StringLocation, Type};
use num_bigint::{BigInt, Sign};
use num_rational::BigRational;
use solang_parser::pt::Loc;

#[test]
fn add_variable_function_arg() {
    let var = Expression::Variable {
        loc: Loc::Codegen,
        ty: Type::Int(2),
        var_no: 1,
    };
    let arg = Expression::FunctionArg {
        loc: Loc::Codegen,
        ty: Type::Int(1),
        arg_no: 1,
    };
    let add = Expression::Add {
        loc: Loc::Codegen,
        ty: Type::Int(0),
        overflowing: false,
        left: Box::new(var.clone()),
        right: Box::new(arg.clone()),
    };

    let instr = Instr::Set {
        loc: Loc::Codegen,
        res: 6,
        expr: add,
    };

    let mut ave = AvailableExpression::default();
    let mut set = AvailableExpressionSet::default();
    let mut cst = CommonSubExpressionTracker::default();

    set.process_instruction(&instr, &mut ave, &mut Some(&mut cst));

    assert!(set.find_expression(&var).is_some());
    assert!(set.find_expression(&arg).is_some());
}

#[test]
fn add_constants() {
    let var = Expression::NumberLiteral {
        loc: Loc::Codegen,
        ty: Type::Int(2),
        value: BigInt::new(Sign::Plus, vec![3]),
    };
    let num = Expression::NumberLiteral {
        loc: Loc::Codegen,
        ty: Type::Int(1),
        value: BigInt::new(Sign::Plus, vec![2]),
    };
    let sub = Expression::Subtract {
        loc: Loc::Codegen,
        ty: Type::Int(0),
        overflowing: false,
        left: Box::new(var.clone()),
        right: Box::new(num.clone()),
    };

    let instr = Instr::SelfDestruct { recipient: sub };

    let mut ave = AvailableExpression::default();
    let mut set = AvailableExpressionSet::default();
    let mut cst = CommonSubExpressionTracker::default();

    set.process_instruction(&instr, &mut ave, &mut Some(&mut cst));

    assert!(set.find_expression(&var).is_some());
    assert!(set.find_expression(&num).is_some());
}

#[test]
fn add_commutative() {
    let cte = Expression::NumberLiteral {
        loc: Loc::Codegen,
        ty: Type::Int(32),
        value: BigInt::from(20),
    };
    let var = Expression::Variable {
        loc: Loc::Codegen,
        ty: Type::Int
    
fn kill() {
    let var = Expression::Variable {
        loc: Loc::Codegen,
        ty: Type::Int(8),
        var_no: 2,
    };
    let cte = Expression::NumberLiteral {
        loc: Loc::Codegen,
        ty: Type::Int(8),
        value: BigInt::from(3),
    };
    let arg = Expression::FunctionArg {
        loc: Loc::Codegen,
        ty: Type::Int(9),
        arg_no: 5,
    };

    let sum = Expression::Add {
        loc: Loc::Codegen,
        ty: Type::Int(8),
        overflowing: false,
        left: Box::new(var.clone()),
        right: Box::new(cte.clone()),
    };
    let sub = Expression::Subtract {
        loc: Loc::Codegen,
        ty: Type::Int(3),
        overflowing: false,
        left: Box::new(cte.clone()),
        right: Box::new(arg.clone()),
    };
    let div = Expression::SignedDivide {
        loc: Loc::Codegen,
        ty: Type::Int(8),
        left: Box::new(sum.clone()),
        right: Box::new(sub.clone()),
    };
    let mul = Expression::Multiply {
        loc: Loc::Codegen,
        ty: Type::Int(8),
        overflowing: false,
        left: Box::new(var.clone()),
        right: Box::new(cte.clone()),
    };

    let shift = Expression::ShiftRight {
        loc: Loc::Codegen,
        ty: Type::Int(2),
        left: Box::new(mul.clone()),
        right: Box::new(div.clone()),
        signed: true,
    };
    let modu = Expression::SignedModulo {
        loc: Loc::Codegen,
        ty: Type::Int(8),
        left: Box::new(cte.clone()),
        right: Box::new(arg.clone()),
    };

    let zero = Expression::ZeroExt {
        loc: Loc::Codegen,
        ty: Type::Int(54),
        expr: Box::new(shift.clone()),
    };
    let unary = Expression::Negate {
        loc: Loc::Codegen,
        ty: Type::Int(44),
        overflowing: true,
        expr: Box::new(modu.clone()),
    };

    let pot = Expression::Power {
        loc: Loc::Codegen,
        ty: Type::Int(4),
        overflowing: true,
        base: Box::new(zero.clone()),
        exp: Box::new(unary.clone()),
    };

    let instr = Instr::Set {
        loc: Loc::Codegen,
        res: 0,
        expr: pot.clone(),
    };

    let mut ave = AvailableExpression::default();
    let mut set = AvailableExpressionSet::default();
    let mut cst = CommonSubExpressionTracker::default();

    set.process_instruction(&instr, &mut ave, &mut Some(&mut cst));
    set.kill(2);

    // Available expressions
    assert!(set.find_expression(&unary).is_some());
    assert!(set.find_expression(&modu).is_some());
    assert!(set.find_expression(&sub).is_some());
    assert!(set.find_expression(&arg).is_some());
    assert!(set.find_expression(&cte).is_some());

    // Unavailable expressions
    assert!(set.find_expression(&var).is_none());
    assert!(set.find_expression(&sum).is_none());
    assert!(set.find_expression(&shift).is_none());
    assert!(set.find_expression(&mul).is_none());
    assert!(set.find_expression(&div).is_none());
    assert!(set.find_expression(&zero).is_none());
    assert!(set.find_expression(&pot).is_none());
}