Skip somer error reporting when the record type has errors

The added test cases around function/event invocations report the
following flurry of errors when only the first one is relevant and
actionable. There's little use in reporting a mismatch with "error".
Squelch them.

    error in <...>/function-invoke-mismatch-error.zeek, line 8: identifier not defined: MyEnumTypo
    error in <...>/function-invoke-mismatch-error.zeek, line 12 and error: type mismatch (M::MY_ENUM_A and error)
    error in <...>/function-invoke-mismatch-error.zeek, line 12: argument type mismatch in function call (M::to_string(M::MY_ENUM_A))
    error in <...>/function-invoke-mismatch-error.zeek, line 16 and error: type mismatch (M::MY_ENUM_B and error)
    error in <...>/function-invoke-mismatch-error.zeek, line 16: argument type mismatch in function call (M::to_string(M::MY_ENUM_B))
    error in <...>/function-invoke-mismatch-error.zeek, line 20 and error: type mismatch (M::e and error)
    error in <...>/function-invoke-mismatch-error.zeek, line 20: argument type mismatch in function call (M::to_string(M::e))

Record coercion also reports noisy errors when coercing to a type that
has errors for individual fields, type clashing with "error":

    $ zeek language/record-field-error.zeek
    error in ./language/record-coerce-error.zeek, line 8: identifier not defined: MyEnumTypo
    error in ./language/record-coerce-error.zeek, line 19 and ./language/record-coerce-error.zeek, line 5: type clash for field "e" ((coerce [$e=MY_ENUM_B, $s=test] to MyRecord) and MyEnum)
This commit is contained in:
Arne Welzel 2023-01-26 21:14:32 +01:00
parent 589e042e26
commit adf56ef4d8
7 changed files with 90 additions and 2 deletions

View file

@ -4101,6 +4101,20 @@ ValPtr ArithCoerceExpr::Fold(Val* v) const
return result;
}
// Returns true if the record type or any of its fields have an error.
static bool record_type_has_errors(const RecordType* rt)
{
if ( IsErrorType(rt->Tag()) )
return true;
if ( rt->NumFields() > 0 )
for ( const auto* td : *rt->Types() )
if ( IsErrorType(td->type->Tag()) )
return true;
return false;
}
RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
: UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op))
{
@ -4120,6 +4134,12 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r)
RecordType* t_r = type->AsRecordType();
RecordType* sub_r = op->GetType()->AsRecordType();
if ( record_type_has_errors(t_r) || record_type_has_errors(sub_r) )
{
SetError();
return;
}
int map_size = t_r->NumFields();
map.resize(map_size, -1); // -1 = field is not mapped
@ -4574,7 +4594,9 @@ CallExpr::CallExpr(ExprPtr arg_func, ListExprPtr arg_args, bool in_hook, bool _i
return;
}
if ( ! func_type->MatchesIndex(args.get()) )
if ( record_type_has_errors(func_type->AsFuncType()->Params()->AsRecordType()) )
SetError();
else if ( ! func_type->MatchesIndex(args.get()) )
SetError("argument type mismatch in function call");
else
{
@ -4943,7 +4965,9 @@ EventExpr::EventExpr(const char* arg_name, ListExprPtr arg_args)
return;
}
if ( ! func_type->MatchesIndex(args.get()) )
if ( record_type_has_errors(func_type->AsFuncType()->Params()->AsRecordType()) )
SetError();
else if ( ! func_type->MatchesIndex(args.get()) )
SetError("argument type mismatch in event invocation");
else
{