/// Resolve a struct literal with named fields
Resolve a struct literal with named fields
Resolve a struct literal with named fields
fn named_struct_literal(
    loc: &pt::Loc,
    struct_no: usize,
    args: &[pt::NamedArgument],
    file_no: usize,
    contract_no: Option<usize>,
    ns: &mut Namespace,
    symtable: &Symtable,
    is_constant: bool,
    diagnostics: &mut Vec<Diagnostic>,
) -> Result<Expression, ()> {
    let struct_def = ns.structs[struct_no].clone();
    if args.len() != struct_def.fields.len() {
        diagnostics.push(Diagnostic::error(
            *loc,
            format!(
                "struct ‘{}’ has {} fields, not {}",
                struct_def.name,
                struct_def.fields.len(),
                args.len()
            ),
        ));
        Err(())
    } else {
        let mut fields = Vec::new();
        fields.resize(args.len(), Expression::Poison);
        for a in args {
            match struct_def
                .fields
                .iter()
                .enumerate()
                .find(|(_, f)| f.name == a.name.name)
            {
                Some((i, f)) => {
                    let expr = expression(
                        &a.expr,
                        file_no,
                        contract_no,
                        ns,
                        symtable,
                        is_constant,
                        diagnostics,
                        Some(&f.ty),
                    )?;
                    fields[i] = cast(loc, expr, &f.ty, true, ns, diagnostics)?;
                }
                None => {
                    diagnostics.push(Diagnostic::error(
                        a.name.loc,
                        format!(
                            "struct ‘{}’ has no field ‘{}’",
                            struct_def.name, a.name.name,
                        ),
                    ));
                    return Err(());
                }
            }
        }
        let ty = Type::Struct(struct_no);
        Ok(Expression::StructLiteral(*loc, ty, fields))
    }
}
fn named_struct_literal ( loc : & pt :: Loc , struct_no : usize , args : & [ pt :: NamedArgument ] , file_no : usize , contract_no : Option < usize > , ns : & mut Namespace , symtable : & Symtable , is_constant : bool , diagnostics : & mut Vec < Diagnostic > , ) -> Result < Expression , ( ) > { let struct_def = ns . structs [ struct_no ] . clone ( ) ; if args . len ( ) != struct_def . fields . len ( ) { diagnostics . push ( Diagnostic :: error ( * loc , format ! ( " struct_def name struct_def fields len ( ) args len ( ) ) , ) ) ; Err ( ( ) ) } else { let mut fields = Vec :: new ( ) ; fields . resize ( args . len ( ) , Expression :: Poison ) ; for a in args { match struct_def . fields . iter ( ) . enumerate ( ) . find ( | ( _ , f ) | f . name == a . name . name ) { Some ( ( i , f ) ) => { let expr = expression ( & a . expr , file_no , contract_no , ns , symtable , is_constant , diagnostics , Some ( & f . ty ) , ) ? ; fields [ i ] = cast ( loc , expr , & f . ty , true , ns , diagnostics ) ? ; } None => { diagnostics . push ( Diagnostic :: error ( a . name . loc , format ! ( " struct_def name a name name ) , ) ) ; return Err ( ( ) ) ; } } } let ty = Type :: Struct ( struct_no ) ; Ok ( Expression :: StructLiteral ( * loc , ty , fields ) ) } }
Resolve a struct literal with named fields
Resolve a struct literal with named fields
loc
&pt::Loc
struct_no
usize
args
&[pt::NamedArgument]
file_no
usize
contract_no
Option<usize>
ns
&mut Namespace
symtable
&Symtable
is_constant
bool
diagnostics
&mut Vec<Diagnostic>