/// Given an parsed literal array, ensure that it is valid. All the elements in the array
/// must of the same type. The array might be a multidimensional array; all the leaf nodes
/// must match.
Given an parsed literal array, ensure that it is valid. All the elements in the array
must of the same type. The array might be a multidimensional array; all the leaf nodes
must match.
Given an parsed literal array ensure that it is valid . All the elements in the array must of the same type . The array might be a multidimensional array ; all the leaf nodes must match .
fn resolve_array_literal(
    loc: &pt::Loc,
    exprs: &[pt::Expression],
    file_no: usize,
    contract_no: Option<usize>,
    ns: &mut Namespace,
    symtable: &Symtable,
    is_constant: bool,
    diagnostics: &mut Vec<Diagnostic>,
    resolve_to: Option<&Type>,
) -> Result<Expression, ()> {
    let mut dims = Box::new(Vec::new());
    let mut flattened = Vec::new();
    check_subarrays(exprs, &mut Some(&mut dims), &mut flattened, ns, diagnostics)?;
    if flattened.is_empty() {
        diagnostics.push(Diagnostic::error(
            *loc,
            "array requires at least one element".to_string(),
        ));
        return Err(());
    }
    let mut flattened = flattened.iter();
    let resolve_to = resolve_to.map(|ty| if let Type::Array(ty, _) = ty { ty } else { ty });
    // We follow the solidity scheme were everthing gets implicitly converted to the
    // type of the first element
    let first = expression(
        flattened.next().unwrap(),
        file_no,
        contract_no,
        ns,
        symtable,
        is_constant,
        diagnostics,
        resolve_to,
    )?;
    let ty = if let Some(ty) = resolve_to {
        ty.clone()
    } else {
        first.ty()
    };
    let mut exprs = vec![first];
    for e in flattened {
        let mut other = expression(
            e,
            file_no,
            contract_no,
            ns,
            symtable,
            is_constant,
            diagnostics,
            Some(&ty),
        )?;
        if other.ty() != ty {
            other = cast(&e.loc(), other, &ty, true, ns, diagnostics)?;
        }
        exprs.push(other);
    }
    let aty = Type::Array(
        Box::new(ty),
        dims.iter()
            .map(|n| Some(BigInt::from_u32(*n).unwrap()))
            .collect::<Vec<Option<BigInt>>>(),
    );
    if is_constant {
        Ok(Expression::ConstArrayLiteral(*loc, aty, *dims, exprs))
    } else {
        Ok(Expression::ArrayLiteral(*loc, aty, *dims, exprs))
    }
}
fn resolve_array_literal ( loc : & pt :: Loc , exprs : & [ pt :: Expression ] , file_no : usize , contract_no : Option < usize > , ns : & mut Namespace , symtable : & Symtable , is_constant : bool , diagnostics : & mut Vec < Diagnostic > , resolve_to : Option < & Type > , ) -> Result < Expression , ( ) > { let mut dims = Box :: new ( Vec :: new ( ) ) ; let mut flattened = Vec :: new ( ) ; check_subarrays ( exprs , & mut Some ( & mut dims ) , & mut flattened , ns , diagnostics ) ? ; if flattened . is_empty ( ) { diagnostics . push ( Diagnostic :: error ( * loc , " " . to_string ( ) , ) ) ; return Err ( ( ) ) ; } let mut flattened = flattened . iter ( ) ; let resolve_to = resolve_to . map ( | ty | if let Type :: Array ( ty , _ ) = ty { ty } else { ty } ) ; // We follow the solidity scheme were everthing gets implicitly converted to the // type of the first element let first = expression ( flattened . next ( ) . unwrap ( ) , file_no , contract_no , ns , symtable , is_constant , diagnostics , resolve_to , ) ? ; let ty = if let Some ( ty ) = resolve_to { ty . clone ( ) } else { first . ty ( ) } ; let mut exprs = vec ! [ first ] ; for e in flattened { let mut other = expression ( e , file_no , contract_no , ns , symtable , is_constant , diagnostics , Some ( & ty ) , ) ? ; if other . ty ( ) != ty { other = cast ( & e . loc ( ) , other , & ty , true , ns , diagnostics ) ? ; } exprs . push ( other ) ; } let aty = Type :: Array ( Box :: new ( ty ) , dims . iter ( ) . map ( | n | Some ( BigInt :: from_u32 ( * n ) . unwrap ( ) ) ) . collect :: < Vec < Option < BigInt > > > ( ) , ) ; if is_constant { Ok ( Expression :: ConstArrayLiteral ( * loc , aty , * dims , exprs ) ) } else { Ok ( Expression :: ArrayLiteral ( * loc , aty , * dims , exprs ) ) } }
Given an parsed literal array, ensure that it is valid.
Given an parsed literal array ensure that it is valid .
loc
&pt::Loc
exprs
&[pt::Expression]
file_no
usize
contract_no
Option<usize>
ns
&mut Namespace
symtable
&Symtable
is_constant
bool
diagnostics
&mut Vec<Diagnostic>
resolve_to
Option<&Type>