Skip to content

Commit 99dc522

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents 1b9746e + 3b6805a commit 99dc522

File tree

8 files changed

+119
-38
lines changed

8 files changed

+119
-38
lines changed

SwiftCompilerSources/Sources/AST/Type.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ extension TypeProperties {
180180
public var hasArchetype: Bool { rawType.bridged.hasArchetype() }
181181
public var hasTypeParameter: Bool { rawType.bridged.hasTypeParameter() }
182182
public var hasLocalArchetype: Bool { rawType.bridged.hasLocalArchetype() }
183+
public var hasDynamicSelf: Bool { rawType.bridged.hasDynamicSelf() }
183184
public var isEscapable: Bool { rawType.bridged.isEscapable() }
184185
public var isNoEscape: Bool { rawType.bridged.isNoEscape() }
185186
public var isBuiltinType: Bool { rawType.bridged.isBuiltinType() }

SwiftCompilerSources/Sources/Optimizer/ModulePasses/EmbeddedSwiftDiagnostics.swift

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,27 @@ private struct FunctionChecker {
130130
throw Diagnostic(.embedded_swift_allocating_type, (instruction as! SingleValueInstruction).type,
131131
at: instruction.location)
132132
}
133-
case is BeginApplyInst:
134-
throw Diagnostic(.embedded_swift_allocating_coroutine, at: instruction.location)
133+
135134
case is ThunkInst:
136-
throw Diagnostic(.embedded_swift_allocating, at: instruction.location)
135+
if context.options.noAllocations {
136+
throw Diagnostic(.embedded_swift_allocating, at: instruction.location)
137+
}
138+
139+
case let ba as BeginApplyInst:
140+
if context.options.noAllocations {
141+
throw Diagnostic(.embedded_swift_allocating_coroutine, at: instruction.location)
142+
}
143+
try checkApply(apply: ba)
137144

138145
case let pai as PartialApplyInst:
139146
if context.options.noAllocations && !pai.isOnStack {
140147
throw Diagnostic(.embedded_swift_allocating_closure, at: instruction.location)
141148
}
149+
try checkApply(apply: pai)
150+
151+
// Remaining apply instructions
152+
case let apply as ApplySite:
153+
try checkApply(apply: apply)
142154

143155
case let bi as BuiltinInst:
144156
switch bi.id {
@@ -156,39 +168,45 @@ private struct FunctionChecker {
156168
break
157169
}
158170

159-
case let apply as ApplySite:
160-
if context.options.noAllocations && apply.isAsync {
161-
throw Diagnostic(.embedded_swift_allocating_type, at: instruction.location)
162-
}
171+
default:
172+
break
173+
}
174+
}
163175

164-
if !apply.callee.type.hasValidSignatureForEmbedded,
165-
// Some runtime functions have generic parameters in SIL, which are not used in IRGen.
166-
// Therefore exclude runtime functions at all.
167-
!apply.callsEmbeddedRuntimeFunction
168-
{
169-
switch apply.callee {
170-
case let cmi as ClassMethodInst:
171-
throw Diagnostic(.embedded_cannot_specialize_class_method, cmi.member, at: instruction.location)
172-
case let wmi as WitnessMethodInst:
173-
throw Diagnostic(.embedded_cannot_specialize_witness_method, wmi.member, at: instruction.location)
174-
default:
175-
throw Diagnostic(.embedded_call_generic_function, at: instruction.location)
176-
}
177-
}
176+
mutating func checkApply(apply: ApplySite) throws {
177+
if context.options.noAllocations && apply.isAsync {
178+
throw Diagnostic(.embedded_swift_allocating_type, at: apply.location)
179+
}
178180

179-
// Although all (non-generic) functions are initially put into the worklist there are two reasons
180-
// to call `checkFunction` recursively:
181-
// * To get a better caller info in the diagnostics.
182-
// * When passing an opened existential to a generic function, it's valid in Embedded swift even if the
183-
// generic is not specialized. We need to check such generic functions, too.
184-
if let callee = apply.referencedFunction {
185-
callStack.push(CallSite(apply: apply, callee: callee))
186-
try checkFunction(callee)
187-
_ = callStack.pop()
181+
if !apply.callee.type.hasValidSignatureForEmbedded,
182+
// Some runtime functions have generic parameters in SIL, which are not used in IRGen.
183+
// Therefore exclude runtime functions at all.
184+
!apply.callsEmbeddedRuntimeFunction
185+
{
186+
switch apply.callee {
187+
case let cmi as ClassMethodInst:
188+
throw Diagnostic(.embedded_cannot_specialize_class_method, cmi.member, at: apply.location)
189+
case let wmi as WitnessMethodInst:
190+
throw Diagnostic(.embedded_cannot_specialize_witness_method, wmi.member, at: apply.location)
191+
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+
}
197+
throw Diagnostic(.embedded_call_generic_function, at: apply.location)
188198
}
199+
}
189200

190-
default:
191-
break
201+
// Although all (non-generic) functions are initially put into the worklist there are two reasons
202+
// to call `checkFunction` recursively:
203+
// * To get a better caller info in the diagnostics.
204+
// * When passing an opened existential to a generic function, it's valid in Embedded swift even if the
205+
// generic is not specialized. We need to check such generic functions, too.
206+
if let callee = apply.referencedFunction {
207+
callStack.push(CallSite(apply: apply, callee: callee))
208+
try checkFunction(callee)
209+
_ = callStack.pop()
192210
}
193211
}
194212

@@ -355,6 +373,15 @@ private extension ApplySite {
355373
}
356374
return false
357375
}
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+
}
358385
}
359386

360387
private extension Type {

SwiftCompilerSources/Sources/Optimizer/ModulePasses/MandatoryPerformanceOptimizations.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,13 @@ private func shouldInline(apply: FullApplySite, callee: Function, alreadyInlined
258258
return false
259259
}
260260

261-
if !callee.canBeInlinedIntoCaller(withSerializedKind: apply.parentFunction.serializedKind) &&
262-
// Even if the serialization kind doesn't match, we need to make sure to inline witness method thunks
263-
// in embedded swift.
264-
callee.thunkKind != .thunk
265-
{
261+
guard callee.canBeInlinedIntoCaller(withSerializedKind: apply.parentFunction.serializedKind) ||
262+
// Even if the serialization kind doesn't match, we need to make sure to inline witness method thunks
263+
// in embedded swift.
264+
callee.thunkKind == .thunk ||
265+
// Force inlining transparent co-routines. This might be necessary if `-enable-testing` is turned on.
266+
(apply is BeginApplyInst && callee.isTransparent)
267+
else {
266268
return false
267269
}
268270

include/swift/AST/ASTBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,6 +3077,7 @@ struct BridgedASTType {
30773077
BRIDGED_INLINE bool isGenericAtAnyLevel() const;
30783078
BRIDGED_INLINE bool hasTypeParameter() const;
30793079
BRIDGED_INLINE bool hasLocalArchetype() const;
3080+
BRIDGED_INLINE bool hasDynamicSelf() const;
30803081
BRIDGED_INLINE bool isArchetype() const;
30813082
BRIDGED_INLINE bool archetypeRequiresClass() const;
30823083
BRIDGED_INLINE bool isExistentialArchetype() const;

include/swift/AST/ASTBridgingImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,10 @@ bool BridgedASTType::hasLocalArchetype() const {
436436
return unbridged()->hasLocalArchetype();
437437
}
438438

439+
bool BridgedASTType::hasDynamicSelf() const {
440+
return unbridged()->hasDynamicSelfType();
441+
}
442+
439443
bool BridgedASTType::isArchetype() const {
440444
return unbridged()->is<swift::ArchetypeType>();
441445
}

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,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Make sure this can be compiled without any errors
2+
3+
// RUN: %target-swift-frontend %s -emit-ir -o /dev/null -enable-experimental-feature Embedded -enable-testing
4+
// RUN: %target-swift-frontend %s -emit-ir -o /dev/null -enable-experimental-feature Embedded -enable-testing -no-allocations
5+
6+
7+
// REQUIRES: VENDOR=apple
8+
// REQUIRES: OS=macosx
9+
// REQUIRES: swift_feature_Embedded
10+
11+
public protocol P {
12+
var storage: UInt32 { get set }
13+
}
14+
15+
struct MyStruct: P {
16+
var storage: UInt32
17+
}
18+
19+

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)