/// Test for equality; first check string equality, then integer equality
Test for equality; first check string equality, then integer equality
Test for equality ; first check string equality then integer equality
fn equal(
    loc: &pt::Loc,
    l: &pt::Expression,
    r: &pt::Expression,
    file_no: usize,
    contract_no: Option<usize>,
    ns: &mut Namespace,
    symtable: &Symtable,
    is_constant: bool,
    diagnostics: &mut Vec<Diagnostic>,
) -> Result<Expression, ()> {
    let left = expression(
        l,
        file_no,
        contract_no,
        ns,
        symtable,
        is_constant,
        diagnostics,
        None,
    )?;
    let right = expression(
        r,
        file_no,
        contract_no,
        ns,
        symtable,
        is_constant,
        diagnostics,
        None,
    )?;
    // Comparing stringliteral against stringliteral
    if let (Expression::BytesLiteral(_, _, l), Expression::BytesLiteral(_, _, r)) = (&left, &right)
    {
        return Ok(Expression::BoolLiteral(*loc, l == r));
    }
    let left_type = left.ty();
    let right_type = right.ty();
    // compare string against literal
    match (&left, &right_type.deref_any()) {
        (Expression::BytesLiteral(_, _, l), Type::String)
        | (Expression::BytesLiteral(_, _, l), Type::DynamicBytes) => {
            return Ok(Expression::StringCompare(
                *loc,
                StringLocation::RunTime(Box::new(cast(
                    &r.loc(),
                    right,
                    &right_type.deref_any(),
                    true,
                    ns,
                    diagnostics,
                )?)),
                StringLocation::CompileTime(l.clone()),
            ));
        }
        _ => {}
    }
    match (&right, &left_type.deref_any()) {
        (Expression::BytesLiteral(_, _, literal), Type::String)
        | (Expression::BytesLiteral(_, _, literal), Type::DynamicBytes) => {
            return Ok(Expression::StringCompare(
                *loc,
                StringLocation::RunTime(Box::new(cast(
                    &l.loc(),
                    left,
                    &left_type.deref_any(),
                    true,
                    ns,
                    diagnostics,
                )?)),
                StringLocation::CompileTime(literal.clone()),
            ));
        }
        _ => {}
    }
    // compare string
    match (&left_type.deref_any(), &right_type.deref_any()) {
        (Type::String, Type::String) | (Type::DynamicBytes, Type::DynamicBytes) => {
            return Ok(Expression::StringCompare(
                *loc,
                StringLocation::RunTime(Box::new(cast(
                    &l.loc(),
                    left,
                    &left_type.deref_any(),
                    true,
                    ns,
                    diagnostics,
                )?)),
                StringLocation::RunTime(Box::new(cast(
                    &r.loc(),
                    right,
                    &right_type.deref_any(),
                    true,
                    ns,
                    diagnostics,
                )?)),
            ));
        }
        _ => {}
    }
    let ty = coerce(&left_type, &l.loc(), &right_type, &r.loc(), ns, diagnostics)?;
    Ok(Expression::Equal(
        *loc,
        Box::new(cast(&l.loc(), left, &ty, true, ns, diagnostics)?),
        Box::new(cast(&r.loc(), right, &ty, true, ns, diagnostics)?),
    ))
}
fn equal ( loc : & pt :: Loc , l : & pt :: Expression , r : & pt :: Expression , file_no : usize , contract_no : Option < usize > , ns : & mut Namespace , symtable : & Symtable , is_constant : bool , diagnostics : & mut Vec < Diagnostic > , ) -> Result < Expression , ( ) > { let left = expression ( l , file_no , contract_no , ns , symtable , is_constant , diagnostics , None , ) ? ; let right = expression ( r , file_no , contract_no , ns , symtable , is_constant , diagnostics , None , ) ? ; // Comparing stringliteral against stringliteral if let ( Expression :: BytesLiteral ( _ , _ , l ) , Expression :: BytesLiteral ( _ , _ , r ) ) = ( & left , & right ) { return Ok ( Expression :: BoolLiteral ( * loc , l == r ) ) ; } let left_type = left . ty ( ) ; let right_type = right . ty ( ) ; // compare string against literal match ( & left , & right_type . deref_any ( ) ) { ( Expression :: BytesLiteral ( _ , _ , l ) , Type :: String ) | ( Expression :: BytesLiteral ( _ , _ , l ) , Type :: DynamicBytes ) => { return Ok ( Expression :: StringCompare ( * loc , StringLocation :: RunTime ( Box :: new ( cast ( & r . loc ( ) , right , & right_type . deref_any ( ) , true , ns , diagnostics , ) ? ) ) , StringLocation :: CompileTime ( l . clone ( ) ) , ) ) ; } _ => { } } match ( & right , & left_type . deref_any ( ) ) { ( Expression :: BytesLiteral ( _ , _ , literal ) , Type :: String ) | ( Expression :: BytesLiteral ( _ , _ , literal ) , Type :: DynamicBytes ) => { return Ok ( Expression :: StringCompare ( * loc , StringLocation :: RunTime ( Box :: new ( cast ( & l . loc ( ) , left , & left_type . deref_any ( ) , true , ns , diagnostics , ) ? ) ) , StringLocation :: CompileTime ( literal . clone ( ) ) , ) ) ; } _ => { } } // compare string match ( & left_type . deref_any ( ) , & right_type . deref_any ( ) ) { ( Type :: String , Type :: String ) | ( Type :: DynamicBytes , Type :: DynamicBytes ) => { return Ok ( Expression :: StringCompare ( * loc , StringLocation :: RunTime ( Box :: new ( cast ( & l . loc ( ) , left , & left_type . deref_any ( ) , true , ns , diagnostics , ) ? ) ) , StringLocation :: RunTime ( Box :: new ( cast ( & r . loc ( ) , right , & right_type . deref_any ( ) , true , ns , diagnostics , ) ? ) ) , ) ) ; } _ => { } } let ty = coerce ( & left_type , & l . loc ( ) , & right_type , & r . loc ( ) , ns , diagnostics ) ? ; Ok ( Expression :: Equal ( * loc , Box :: new ( cast ( & l . loc ( ) , left , & ty , true , ns , diagnostics ) ? ) , Box :: new ( cast ( & r . loc ( ) , right , & ty , true , ns , diagnostics ) ? ) , ) ) }
Test for equality; first check string equality, then integer equality
Test for equality ; first check string equality then integer equality
loc
&pt::Loc
l
&pt::Expression
r
&pt::Expression
file_no
usize
contract_no
Option<usize>
ns
&mut Namespace
symtable
&Symtable
is_constant
bool
diagnostics
&mut Vec<Diagnostic>