mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
This adds fields to `EntityWithParamsBase` to reflect the intention with `extern library` design. I'm renaming `decl_id` because it shouldn't be expected to be assigned anymore. import_ref.cpp I'm deliberately keeping on `first_owning_decl_id` (which will break when importing `extern library` declarations). Most other cases are for diagnostics, and I'm using `latest_decl_id` to try and get the closest declaration to the error. Note I'm partly splitting out this PR to show the test effect, which apparently we don't test related cases.
99 lines
4.1 KiB
C++
99 lines
4.1 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/check/function.h"
|
|
|
|
#include "toolchain/check/merge.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
auto CheckFunctionTypeMatches(Context& context,
|
|
const SemIR::Function& new_function,
|
|
const SemIR::Function& prev_function,
|
|
SemIR::SpecificId prev_specific_id,
|
|
bool check_syntax) -> bool {
|
|
if (!CheckRedeclParamsMatch(context, DeclParams(new_function),
|
|
DeclParams(prev_function), prev_specific_id,
|
|
check_syntax)) {
|
|
return false;
|
|
}
|
|
|
|
// TODO: Pass a specific ID for `prev_function` instead of substitutions and
|
|
// use it here.
|
|
auto new_return_type_id =
|
|
new_function.GetDeclaredReturnType(context.sem_ir());
|
|
auto prev_return_type_id =
|
|
prev_function.GetDeclaredReturnType(context.sem_ir(), prev_specific_id);
|
|
if (new_return_type_id == SemIR::TypeId::Error ||
|
|
prev_return_type_id == SemIR::TypeId::Error) {
|
|
return false;
|
|
}
|
|
if (!context.types().AreEqualAcrossDeclarations(new_return_type_id,
|
|
prev_return_type_id)) {
|
|
CARBON_DIAGNOSTIC(
|
|
FunctionRedeclReturnTypeDiffers, Error,
|
|
"Function redeclaration differs because return type is `{0}`.",
|
|
SemIR::TypeId);
|
|
CARBON_DIAGNOSTIC(
|
|
FunctionRedeclReturnTypeDiffersNoReturn, Error,
|
|
"Function redeclaration differs because no return type is provided.");
|
|
auto diag =
|
|
new_return_type_id.is_valid()
|
|
? context.emitter().Build(new_function.latest_decl_id(),
|
|
FunctionRedeclReturnTypeDiffers,
|
|
new_return_type_id)
|
|
: context.emitter().Build(new_function.latest_decl_id(),
|
|
FunctionRedeclReturnTypeDiffersNoReturn);
|
|
if (prev_return_type_id.is_valid()) {
|
|
CARBON_DIAGNOSTIC(FunctionRedeclReturnTypePrevious, Note,
|
|
"Previously declared with return type `{0}`.",
|
|
SemIR::TypeId);
|
|
diag.Note(prev_function.latest_decl_id(),
|
|
FunctionRedeclReturnTypePrevious, prev_return_type_id);
|
|
} else {
|
|
CARBON_DIAGNOSTIC(FunctionRedeclReturnTypePreviousNoReturn, Note,
|
|
"Previously declared with no return type.");
|
|
diag.Note(prev_function.latest_decl_id(),
|
|
FunctionRedeclReturnTypePreviousNoReturn);
|
|
}
|
|
diag.Emit();
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
auto CheckFunctionReturnType(Context& context, SemIRLoc loc,
|
|
SemIR::Function& function,
|
|
SemIR::SpecificId specific_id)
|
|
-> SemIR::ReturnTypeInfo {
|
|
auto return_info = SemIR::ReturnTypeInfo::ForFunction(context.sem_ir(),
|
|
function, specific_id);
|
|
|
|
// If we couldn't determine the return information due to the return type
|
|
// being incomplete, try to complete it now.
|
|
if (return_info.init_repr.kind == SemIR::InitRepr::Incomplete) {
|
|
auto diagnose_incomplete_return_type = [&] {
|
|
CARBON_DIAGNOSTIC(IncompleteTypeInFunctionReturnType, Error,
|
|
"Function returns incomplete type `{0}`.",
|
|
SemIR::TypeId);
|
|
return context.emitter().Build(loc, IncompleteTypeInFunctionReturnType,
|
|
return_info.type_id);
|
|
};
|
|
|
|
// TODO: Consider suppressing the diagnostic if we've already diagnosed a
|
|
// definition or call to this function.
|
|
if (context.TryToCompleteType(return_info.type_id,
|
|
diagnose_incomplete_return_type)) {
|
|
return_info = SemIR::ReturnTypeInfo::ForFunction(context.sem_ir(),
|
|
function, specific_id);
|
|
}
|
|
}
|
|
|
|
return return_info;
|
|
}
|
|
|
|
} // namespace Carbon::Check
|