mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 21:21:04 +01:00
Remove caching of return slot usage. (#4163)
The caching isn't buying us much, and is adding complexity and divergence between the codepaths for generic and non-generic functions. This means we no longer suppress diagnostics for the second or subsequent time we call a function with an incomplete return type. If we want to add that back, it might be worth considering moving the suppression to `TryToCompleteType` and only diagnosing that a type is incomplete once, regardless of why we're requiring it to be complete.
This commit is contained in:
@@ -73,49 +73,29 @@ auto CheckFunctionTypeMatches(Context& context,
|
||||
auto CheckFunctionReturnType(Context& context, SemIRLoc loc,
|
||||
SemIR::Function& function,
|
||||
SemIR::SpecificId specific_id)
|
||||
-> SemIR::Function::ReturnSlot {
|
||||
// If we have already checked the return type, we have nothing to do.
|
||||
if (function.return_slot != SemIR::Function::ReturnSlot::NotComputed &&
|
||||
!specific_id.is_valid()) {
|
||||
return function.return_slot;
|
||||
-> SemIR::ReturnInfo {
|
||||
auto return_info = function.GetReturnInfo(context.sem_ir(), 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.return_slot == SemIR::ReturnSlot::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 = function.GetReturnInfo(context.sem_ir(), specific_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function.return_storage_id.is_valid()) {
|
||||
// Implicit `-> ()` has no return slot.
|
||||
function.return_slot = SemIR::Function::ReturnSlot::Absent;
|
||||
return function.return_slot;
|
||||
}
|
||||
|
||||
auto return_type_id =
|
||||
function.GetDeclaredReturnType(context.sem_ir(), specific_id);
|
||||
CARBON_CHECK(return_type_id.is_valid())
|
||||
<< "Have return storage but no return type.";
|
||||
|
||||
// Check the return type is complete. Only diagnose incompleteness if we've
|
||||
// not already done so.
|
||||
auto diagnose_incomplete_return_type = [&] {
|
||||
CARBON_DIAGNOSTIC(IncompleteTypeInFunctionReturnType, Error,
|
||||
"Function returns incomplete type `{0}`.", SemIR::TypeId);
|
||||
return context.emitter().Build(loc, IncompleteTypeInFunctionReturnType,
|
||||
return_type_id);
|
||||
};
|
||||
SemIR::Function::ReturnSlot result;
|
||||
if (!context.TryToCompleteType(
|
||||
return_type_id,
|
||||
function.return_slot == SemIR::Function::ReturnSlot::Error
|
||||
? std::nullopt
|
||||
: std::optional(diagnose_incomplete_return_type))) {
|
||||
result = SemIR::Function::ReturnSlot::Error;
|
||||
} else if (SemIR::GetInitRepr(context.sem_ir(), return_type_id)
|
||||
.has_return_slot()) {
|
||||
result = SemIR::Function::ReturnSlot::Present;
|
||||
} else {
|
||||
result = SemIR::Function::ReturnSlot::Absent;
|
||||
}
|
||||
if (!specific_id.is_valid()) {
|
||||
function.return_slot = result;
|
||||
}
|
||||
return result;
|
||||
return return_info;
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
Reference in New Issue
Block a user