improve error messages
This commit is contained in:
@@ -3905,17 +3905,83 @@ runtime_write_declaration_matches :: proc(checker: ^Checker, function: ast.Funct
|
||||
type_from_syntax(checker, function.result, function.pkg, function.file) == types.C_LONG
|
||||
}
|
||||
|
||||
signature_type_diagnostic :: proc(
|
||||
checker: ^Checker,
|
||||
function: ast.Function,
|
||||
value: types.Type,
|
||||
depth := 0,
|
||||
) -> source.Diagnostic_Id {
|
||||
if depth > 64 || is_type_metatype_syntax(checker, value) {
|
||||
return source.INVALID_DIAGNOSTIC
|
||||
}
|
||||
item, ok := types.node(&checker.module.types, value)
|
||||
if !ok {
|
||||
return source.INVALID_DIAGNOSTIC
|
||||
}
|
||||
if item.kind == .Named && !item.declared && item.qualifier == 0 {
|
||||
name := symbol.Id(item.name)
|
||||
if param, found := comptime_param_for_name(function, name);
|
||||
found && is_comptime_type_param(checker, param) {
|
||||
return source.INVALID_DIAGNOSTIC
|
||||
}
|
||||
span := function.span
|
||||
for type_use in checker.ast_module.type_uses {
|
||||
if type_use.file == function.file && type_use.type == value &&
|
||||
type_use.span.start >= function.span.start && type_use.span.end <= function.span.end {
|
||||
span = type_use.span
|
||||
break
|
||||
}
|
||||
}
|
||||
diagnostic := source.addf(
|
||||
checker.diagnostics,
|
||||
span,
|
||||
"unknown symbol '%s'",
|
||||
symbol_text(checker, name),
|
||||
)
|
||||
source.set_primary_label(checker.diagnostics, diagnostic, "unknown symbol")
|
||||
return diagnostic
|
||||
}
|
||||
if diagnostic := signature_type_diagnostic(
|
||||
checker, function, item.child, depth+1,
|
||||
); diagnostic != source.INVALID_DIAGNOSTIC {
|
||||
return diagnostic
|
||||
}
|
||||
if diagnostic := signature_type_diagnostic(
|
||||
checker, function, item.extra, depth+1,
|
||||
); diagnostic != source.INVALID_DIAGNOSTIC {
|
||||
return diagnostic
|
||||
}
|
||||
if item.kind == .Function {
|
||||
for param in types.params_for(&checker.module.types, value) {
|
||||
if diagnostic := signature_type_diagnostic(
|
||||
checker, function, param.type, depth+1,
|
||||
); diagnostic != source.INVALID_DIAGNOSTIC {
|
||||
return diagnostic
|
||||
}
|
||||
}
|
||||
}
|
||||
return source.INVALID_DIAGNOSTIC
|
||||
}
|
||||
|
||||
validate_declarations :: proc(checker: ^Checker) {
|
||||
for function, function_id in checker.ast_module.functions {
|
||||
if len(function.unsupported_reason) > 0 {
|
||||
continue
|
||||
}
|
||||
has_comptime := function_has_comptime_params(function)
|
||||
signature_poisoned := function.diagnostic != source.INVALID_DIAGNOSTIC
|
||||
signature_poisoned := checker.template_diagnostics[function_id] != source.INVALID_DIAGNOSTIC
|
||||
locals: [dynamic]symbol.Id
|
||||
locals.allocator = checker.allocator
|
||||
comptime_prefix := 0
|
||||
for param in function.params {
|
||||
if !signature_poisoned {
|
||||
if diagnostic := signature_type_diagnostic(
|
||||
checker, function, param.type,
|
||||
); diagnostic != source.INVALID_DIAGNOSTIC {
|
||||
checker.template_diagnostics[function_id] = diagnostic
|
||||
signature_poisoned = true
|
||||
}
|
||||
}
|
||||
dependent := param.comptime_value && type_pattern_mentions_comptime(
|
||||
checker, function, comptime_prefix, param.type,
|
||||
)
|
||||
@@ -3994,6 +4060,18 @@ validate_declarations :: proc(checker: ^Checker) {
|
||||
)
|
||||
}
|
||||
}
|
||||
if !signature_poisoned {
|
||||
signature_types := [2]types.Type{function.result, function.error}
|
||||
for value in signature_types {
|
||||
if diagnostic := signature_type_diagnostic(
|
||||
checker, function, value,
|
||||
); diagnostic != source.INVALID_DIAGNOSTIC {
|
||||
checker.template_diagnostics[function_id] = diagnostic
|
||||
signature_poisoned = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !has_comptime && !signature_poisoned {
|
||||
result_type := type_from_syntax(checker, function.result, function.pkg, function.file)
|
||||
if function.c_abi && types.is_noreturn(result_type) {
|
||||
|
||||
Reference in New Issue
Block a user