|
|
@@ -202,11 +202,10 @@ static auto CheckCalleeFunctionReturnType(Context& context, SemIR::LocId loc_id,
|
|
|
}
|
|
|
|
|
|
// Performs a call where the callee is a function.
|
|
|
-static auto PerformCallToFunction(Context& context, SemIR::LocId loc_id,
|
|
|
- SemIR::InstId callee_id,
|
|
|
- const SemIR::CalleeFunction& callee_function,
|
|
|
- llvm::ArrayRef<SemIR::InstId> arg_ids)
|
|
|
- -> SemIR::InstId {
|
|
|
+static auto PerformCallToFunction(
|
|
|
+ Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
|
|
|
+ const SemIR::CalleeFunction::Function& callee_function,
|
|
|
+ llvm::ArrayRef<SemIR::InstId> arg_ids) -> SemIR::InstId {
|
|
|
// If the callee is a generic function, determine the generic argument values
|
|
|
// for the call.
|
|
|
auto callee_specific_id = ResolveCalleeInCall(
|
|
|
@@ -293,33 +292,12 @@ static auto PerformCallToFunction(Context& context, SemIR::LocId loc_id,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
|
|
|
- llvm::ArrayRef<SemIR::InstId> arg_ids) -> SemIR::InstId {
|
|
|
- // Try treating the callee as a function first.
|
|
|
- auto callee_function = GetCalleeFunction(context.sem_ir(), callee_id);
|
|
|
- if (callee_function.is_error) {
|
|
|
- return SemIR::ErrorInst::InstId;
|
|
|
- }
|
|
|
- if (callee_function.cpp_overload_set_id.has_value()) {
|
|
|
- auto self_id = callee_function.self_id;
|
|
|
- callee_id = PerformCppOverloadResolution(
|
|
|
- context, loc_id, callee_function.cpp_overload_set_id, self_id, arg_ids);
|
|
|
- callee_function = GetCalleeFunction(context.sem_ir(), callee_id);
|
|
|
- if (callee_function.is_error) {
|
|
|
- return SemIR::ErrorInst::InstId;
|
|
|
- }
|
|
|
- CARBON_CHECK(!callee_function.cpp_overload_set_id.has_value());
|
|
|
-
|
|
|
- // Preserve the `self` argument from the original callee.
|
|
|
- CARBON_CHECK(!callee_function.self_id.has_value());
|
|
|
- callee_function.self_id = self_id;
|
|
|
- }
|
|
|
- if (callee_function.function_id.has_value()) {
|
|
|
- return PerformCallToFunction(context, loc_id, callee_id, callee_function,
|
|
|
- arg_ids);
|
|
|
- }
|
|
|
-
|
|
|
- // Callee isn't a function, so try treating it as a generic type.
|
|
|
+// Performs a call where the callee is a generic type. If it's not a generic
|
|
|
+// type, produces a diagnostic.
|
|
|
+static auto PerformCallToNonFunction(Context& context, SemIR::LocId loc_id,
|
|
|
+ SemIR::InstId callee_id,
|
|
|
+ llvm::ArrayRef<SemIR::InstId> arg_ids)
|
|
|
+ -> SemIR::InstId {
|
|
|
auto type_inst =
|
|
|
context.types().GetAsInst(context.insts().Get(callee_id).type_id());
|
|
|
CARBON_KIND_SWITCH(type_inst) {
|
|
|
@@ -342,4 +320,45 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
|
|
|
+ llvm::ArrayRef<SemIR::InstId> arg_ids) -> SemIR::InstId {
|
|
|
+ // Try treating the callee as a function first.
|
|
|
+ auto callee_function = GetCalleeFunction(context.sem_ir(), callee_id);
|
|
|
+ CARBON_KIND_SWITCH(callee_function.info) {
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::Error _): {
|
|
|
+ return SemIR::ErrorInst::InstId;
|
|
|
+ }
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::Function fn): {
|
|
|
+ return PerformCallToFunction(context, loc_id, callee_id, fn, arg_ids);
|
|
|
+ }
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::NonFunction _): {
|
|
|
+ return PerformCallToNonFunction(context, loc_id, callee_id, arg_ids);
|
|
|
+ }
|
|
|
+
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::CppOverloadSet overload): {
|
|
|
+ callee_id = PerformCppOverloadResolution(context, loc_id,
|
|
|
+ overload.cpp_overload_set_id,
|
|
|
+ overload.self_id, arg_ids);
|
|
|
+ auto overload_result = GetCalleeFunction(context.sem_ir(), callee_id);
|
|
|
+ CARBON_KIND_SWITCH(overload_result.info) {
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::Error _): {
|
|
|
+ return SemIR::ErrorInst::InstId;
|
|
|
+ }
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::Function fn): {
|
|
|
+ // Preserve the `self` argument from the original callee.
|
|
|
+ CARBON_CHECK(!fn.self_id.has_value());
|
|
|
+ fn.self_id = overload.self_id;
|
|
|
+ return PerformCallToFunction(context, loc_id, callee_id, fn, arg_ids);
|
|
|
+ }
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::CppOverloadSet _): {
|
|
|
+ CARBON_FATAL("overloads can't be recursive");
|
|
|
+ }
|
|
|
+ case CARBON_KIND(SemIR::CalleeFunction::NonFunction _): {
|
|
|
+ CARBON_FATAL("overloads should produce functions");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
} // namespace Carbon::Check
|