Skip to content

Commit be32287

Browse files
committed
EmbeddedSwiftDiagnostics: improve error message for non-specialized generic function calls
Tell the user if the specialization isn't done because of a dynamic Self type. rdar://150865684
1 parent aacb4d4 commit be32287

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

SwiftCompilerSources/Sources/Optimizer/ModulePasses/EmbeddedSwiftDiagnostics.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ private struct FunctionChecker {
189189
case let wmi as WitnessMethodInst:
190190
throw Diagnostic(.embedded_cannot_specialize_witness_method, wmi.member, at: apply.location)
191191
default:
192+
if apply.substitutionMap.replacementTypes.contains(where: { $0.hasDynamicSelf }),
193+
apply.calleeHasGenericSelfMetatypeParameter
194+
{
195+
throw Diagnostic(.embedded_call_generic_function_with_dynamic_self, at: apply.location)
196+
}
192197
throw Diagnostic(.embedded_call_generic_function, at: apply.location)
193198
}
194199
}
@@ -368,6 +373,15 @@ private extension ApplySite {
368373
}
369374
return false
370375
}
376+
377+
var calleeHasGenericSelfMetatypeParameter: Bool {
378+
let convention = FunctionConvention(for: callee.type.canonicalType, in: parentFunction)
379+
guard convention.hasSelfParameter, let selfParam = convention.parameters.last else {
380+
return false
381+
}
382+
let selfParamType = selfParam.type
383+
return selfParamType.isMetatype && selfParamType.instanceTypeOfMetatype.isGenericTypeParameter
384+
}
371385
}
372386

373387
private extension Type {

include/swift/AST/DiagnosticsSIL.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,9 @@ ERROR(embedded_swift_allocating,none,
415415
ERROR(embedded_capture_of_generic_value_with_deinit,none,
416416
"capturing generic non-copyable type with deinit in escaping closure not supported in embedded Swift", ())
417417
ERROR(embedded_call_generic_function,none,
418-
"cannot specialize generic function in this context", ())
418+
"cannot specialize generic function or default protocol method in this context", ())
419+
ERROR(embedded_call_generic_function_with_dynamic_self,none,
420+
"cannot call an initializer or static method, which is defined as default protocol method, from a class method or initializer", ())
419421
NOTE(embedded_specialization_called_from,none,
420422
"generic specialization called here", ())
421423
NOTE(embedded_existential_created,none,

test/embedded/generic-error.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-emit-ir -parse-as-library -module-name main -verify %s -enable-experimental-feature Embedded -swift-version 5 -wmo -o /dev/null
2+
3+
// REQUIRES: swift_in_compiler
4+
// REQUIRES: optimized_stdlib
5+
// REQUIRES: swift_feature_Embedded
6+
7+
// We don't support calling a default witness method (which is generic) with dynamic self.
8+
9+
public protocol P {
10+
init(x: Int)
11+
}
12+
13+
extension P {
14+
init(y: Int) {
15+
self.init(x: y)
16+
}
17+
}
18+
19+
public class C: P {
20+
public required init(x: Int) {}
21+
22+
public convenience init(z: Int) {
23+
self.init(y: z) // expected-error {{cannot call an initializer or static method, which is defined as default protocol method, from a class method or initializer}}
24+
}
25+
}

0 commit comments

Comments
 (0)