Skip to content

Commit 41d7a51

Browse files
authored
Merge pull request #3940 from swiftwasm/main
2 parents 3e923f5 + 4715a34 commit 41d7a51

File tree

9 files changed

+84
-62
lines changed

9 files changed

+84
-62
lines changed

docs/DifferentiableProgramming.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,7 @@ func foo<T, U, V>(_ x: T, _ y: U, _ z: V) -> W { ... }
17431743

17441744
// Transpose with respect to `x` and `z`, requiring that `T` and `V` to conform
17451745
// to `Differentiable & AdditiveArithmetic` and equal their corresponding
1746-
`TangentVector` types.
1746+
// `TangentVector` types.
17471747
@transpose(of: foo, wrt: (x, z))
17481748
func _<
17491749
T: Differentiable & AdditiveArithmetic,
@@ -1911,7 +1911,7 @@ result (labeled `value`) and a differential (labeled `differential`). The
19111911
differential is a linear map (`@differentiable(linear)`) function that takes the
19121912
`TangentVector` nested types of all of the types of the original function's
19131913
parameters to differentiate with respect to, and returns the `TangentVector`
1914-
nested type of the orgiinal function's result type.
1914+
nested type of the original function's result type.
19151915

19161916
###### Differentiability parameters
19171917

lib/ClangImporter/ImportDecl.cpp

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9751,39 +9751,33 @@ static void loadAllMembersOfSuperclassIfNeeded(ClassDecl *CD) {
97519751
E->loadAllMembers();
97529752
}
97539753

9754-
static void loadAllMembersOfRecordDecl(StructDecl *recordDecl) {
9755-
auto &ctx = recordDecl->getASTContext();
9754+
void ClangImporter::Implementation::loadAllMembersOfRecordDecl(
9755+
StructDecl *recordDecl) {
97569756
auto clangRecord = cast<clang::RecordDecl>(recordDecl->getClangDecl());
97579757

9758-
// This is only to keep track of the members we've already seen.
9759-
llvm::SmallPtrSet<Decl *, 16> addedMembers;
9760-
for (auto member : recordDecl->getCurrentMembersWithoutLoading())
9761-
addedMembers.insert(member);
9762-
9763-
for (auto member : clangRecord->decls()) {
9764-
auto namedDecl = dyn_cast<clang::NamedDecl>(member);
9765-
if (!namedDecl)
9766-
continue;
9767-
9768-
// Don't try to load ourselves (this will create an infinite loop).
9769-
if (auto possibleSelf = dyn_cast<clang::RecordDecl>(member))
9770-
if (possibleSelf->getDefinition() == clangRecord)
9771-
continue;
9772-
9758+
// Import all of the members.
9759+
llvm::SmallVector<Decl *, 16> members;
9760+
for (const clang::Decl *m : clangRecord->decls()) {
9761+
auto nd = dyn_cast<clang::NamedDecl>(m);
97739762
// Currently, we don't import unnamed bitfields.
9774-
if (isa<clang::FieldDecl>(member) &&
9775-
cast<clang::FieldDecl>(member)->isUnnamedBitfield())
9763+
if (isa<clang::FieldDecl>(m) &&
9764+
cast<clang::FieldDecl>(m)->isUnnamedBitfield())
97769765
continue;
97779766

9778-
auto name = ctx.getClangModuleLoader()->importName(namedDecl);
9779-
if (!name)
9780-
continue;
9767+
if (nd && nd == nd->getCanonicalDecl() &&
9768+
nd->getDeclContext() == clangRecord &&
9769+
isVisibleClangEntry(nd))
9770+
insertMembersAndAlternates(nd, members);
9771+
}
97819772

9782-
for (auto found : recordDecl->lookupDirect(name)) {
9783-
if (addedMembers.insert(found).second &&
9784-
found->getDeclContext() == recordDecl)
9785-
recordDecl->addMember(found);
9786-
}
9773+
// Add the members here.
9774+
for (auto member: members) {
9775+
// FIXME: constructors are added eagerly, but shouldn't be
9776+
// FIXME: subscripts are added eagerly, but shouldn't be
9777+
if (!isa<AccessorDecl>(member) &&
9778+
!isa<SubscriptDecl>(member) &&
9779+
!isa<ConstructorDecl>(member))
9780+
recordDecl->addMember(member);
97879781
}
97889782
}
97899783

@@ -9819,13 +9813,7 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
98199813
}
98209814

98219815
if (isa_and_nonnull<clang::RecordDecl>(D->getClangDecl())) {
9822-
// We haven't loaded any members yet, so tell our context that it still has
9823-
// lazy members. Otherwise, we won't be able to look up any individual
9824-
// members (lazily) in "loadAllMembersOfRecordDecl".
9825-
cast<StructDecl>(D)->setHasLazyMembers(true);
98269816
loadAllMembersOfRecordDecl(cast<StructDecl>(D));
9827-
// Now that all members are loaded, mark the context as lazily complete.
9828-
cast<StructDecl>(D)->setHasLazyMembers(false);
98299817
return;
98309818
}
98319819

lib/ClangImporter/ImporterImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
13901390
void
13911391
loadAllMembersOfObjcContainer(Decl *D,
13921392
const clang::ObjCContainerDecl *objcContainer);
1393+
void loadAllMembersOfRecordDecl(StructDecl *recordDecl);
1394+
13931395
void collectMembersToAdd(const clang::ObjCContainerDecl *objcContainer,
13941396
Decl *D, DeclContext *DC,
13951397
SmallVectorImpl<Decl *> &members);

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,7 @@ static bool isScratchBuffer(SILValue value) {
18931893

18941894
bool swift::memInstMustInitialize(Operand *memOper) {
18951895
SILValue address = memOper->get();
1896+
18961897
SILInstruction *memInst = memOper->getUser();
18971898

18981899
switch (memInst->getKind()) {
@@ -1908,6 +1909,12 @@ bool swift::memInstMustInitialize(Operand *memOper) {
19081909
case SILInstructionKind::InjectEnumAddrInst:
19091910
return true;
19101911

1912+
case SILInstructionKind::BeginApplyInst:
1913+
case SILInstructionKind::TryApplyInst:
1914+
case SILInstructionKind::ApplyInst: {
1915+
FullApplySite applySite(memInst);
1916+
return applySite.isIndirectResultOperand(*memOper);
1917+
}
19111918
case SILInstructionKind::StoreInst:
19121919
return cast<StoreInst>(memInst)->getOwnershipQualifier()
19131920
== StoreOwnershipQualifier::Init;

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,19 @@ ActorIsolationRestriction ActorIsolationRestriction::forDeclaration(
428428
// nonisolated, they need cross-actor restrictions (e.g., for Sendable).
429429
if (auto *ctor = dyn_cast<ConstructorDecl>(decl))
430430
if (!ctor->isConvenienceInit())
431-
if (auto *parent = dyn_cast<ClassDecl>(ctor->getParent()))
432-
if (parent->isAnyActor())
433-
return forActorSelf(parent, /*isCrossActor=*/true);
431+
if (auto *parent = ctor->getParent()->getSelfClassDecl())
432+
if (parent->isAnyActor())
433+
return forActorSelf(parent, /*isCrossActor=*/true);
434+
435+
// `nonisolated let` members are cross-actor as well.
436+
if (auto var = dyn_cast<VarDecl>(decl)) {
437+
if (var->isInstanceMember() && var->isLet()) {
438+
if (auto parent = var->getDeclContext()->getSelfClassDecl()) {
439+
if (parent->isActor() && !parent->isDistributedActor())
440+
return forActorSelf(parent, /*isCrossActor=*/true);
441+
}
442+
}
443+
}
434444

435445
return forUnrestricted();
436446

@@ -3214,18 +3224,6 @@ ActorIsolation ActorIsolationRequest::evaluate(
32143224
// If this declaration has one of the actor isolation attributes, report
32153225
// that.
32163226
if (isolationFromAttr) {
3217-
// Nonisolated declarations must involve Sendable types.
3218-
if (*isolationFromAttr == ActorIsolation::Independent) {
3219-
SubstitutionMap subs;
3220-
if (auto genericEnv = value->getInnermostDeclContext()
3221-
->getGenericEnvironmentOfContext()) {
3222-
subs = genericEnv->getForwardingSubstitutionMap();
3223-
}
3224-
diagnoseNonSendableTypesInReference(
3225-
ConcreteDeclRef(value, subs), value->getDeclContext(),
3226-
value->getLoc(), ConcurrentReferenceKind::Nonisolated);
3227-
}
3228-
32293227
// Classes with global actors have additional rules regarding inheritance.
32303228
if (isolationFromAttr->isGlobalActor()) {
32313229
if (auto classDecl = dyn_cast<ClassDecl>(value))

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,6 +2864,17 @@ static void emitDeclaredHereIfNeeded(DiagnosticEngine &diags,
28642864

28652865
bool ConformanceChecker::checkActorIsolation(
28662866
ValueDecl *requirement, ValueDecl *witness) {
2867+
/// Retrieve a concrete witness for Sendable checking.
2868+
auto getConcreteWitness = [&] {
2869+
if (auto genericEnv = witness->getInnermostDeclContext()
2870+
->getGenericEnvironmentOfContext()) {
2871+
return ConcreteDeclRef(
2872+
witness, genericEnv->getForwardingSubstitutionMap());
2873+
}
2874+
2875+
return ConcreteDeclRef(witness);
2876+
};
2877+
28672878
// Ensure that the witness is not actor-isolated in a manner that makes it
28682879
// unsuitable as a witness.
28692880
bool isCrossActor = false;
@@ -3014,8 +3025,8 @@ bool ConformanceChecker::checkActorIsolation(
30143025

30153026
case ActorIsolationRestriction::CrossActorSelf: {
30163027
if (diagnoseNonSendableTypesInReference(
3017-
witness, DC, witness->getLoc(),
3018-
ConcurrentReferenceKind::CrossActor)) {
3028+
getConcreteWitness(), DC, witness->getLoc(),
3029+
ConcurrentReferenceKind::CrossActor)) {
30193030
return true;
30203031
}
30213032

@@ -3145,8 +3156,8 @@ bool ConformanceChecker::checkActorIsolation(
31453156
return false;
31463157

31473158
return diagnoseNonSendableTypesInReference(
3148-
witness, DC, witness->getLoc(),
3149-
ConcurrentReferenceKind::CrossActor);
3159+
getConcreteWitness(), DC, witness->getLoc(),
3160+
ConcurrentReferenceKind::CrossActor);
31503161
}
31513162

31523163
// If the witness has a global actor but the requirement does not, we have

test/Concurrency/concurrent_value_checking.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func testUnsafeSendableInAsync() async {
157157
// ----------------------------------------------------------------------
158158
// Sendable restriction on key paths.
159159
// ----------------------------------------------------------------------
160-
class NC: Hashable { // expected-note 3{{class 'NC' does not conform to the 'Sendable' protocol}}
160+
class NC: Hashable { // expected-note 2{{class 'NC' does not conform to the 'Sendable' protocol}}
161161
func hash(into: inout Hasher) { }
162162
static func==(_: NC, _: NC) -> Bool { true }
163163
}
@@ -174,9 +174,12 @@ func testKeyPaths(dict: [NC: Int], nc: NC) {
174174
// Sendable restriction on nonisolated declarations.
175175
// ----------------------------------------------------------------------
176176
actor ANI {
177-
// FIXME: improve diagnostics to talk about nonisolated
178-
nonisolated let nc = NC() // expected-warning{{cannot use property 'nc' with a non-sendable type 'NC' across actors}}
179-
nonisolated func f() -> NC? { nil } // expected-warning{{cannot call function returning non-sendable type 'NC?' across actors}}
177+
nonisolated let nc = NC()
178+
nonisolated func f() -> NC? { nil }
179+
}
180+
181+
func testANI(ani: ANI) async {
182+
_ = ani.nc // expected-warning{{cannot use property 'nc' with a non-sendable type 'NC' across actors}}
180183
}
181184

182185
// ----------------------------------------------------------------------

test/Concurrency/sendable_checking.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,15 @@ func testCV(
5353
// expected-note@-1{{a function type must be marked '@Sendable' to conform to 'Sendable'}}
5454
acceptSendableFn(fn) // expected-error{{passing non-sendable parameter 'fn' to function expecting a @Sendable closure}}
5555
}
56+
57+
// rdar://83942484 - spurious Sendable diagnostics
58+
@available(SwiftStdlib 5.1, *)
59+
public protocol MyProto {
60+
func foo<F>(aFoo: F) async where F: Sendable
61+
}
62+
63+
@available(SwiftStdlib 5.1, *)
64+
public actor MyActor: MyProto {
65+
public func foo<F>(aFoo: F) async where F: Sendable { }
66+
public func bar<B>(aBar: B) async where B: Sendable { }
67+
}

test/Interop/Cxx/operators/member-inline-module-interface.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,17 @@
6060
// CHECK: func __operatorSubscriptConst(_ x: Int32) -> UnsafePointer<Int32>
6161

6262
// CHECK: @available(*, unavailable, message: "use subscript")
63-
// CHECK: func __operatorSubscriptConst(_ x: Bool) -> UnsafePointer<Bool>
63+
// CHECK: mutating func __operatorSubscript(_ x: Int32) -> UnsafeMutablePointer<Int32>
6464

6565
// CHECK: @available(*, unavailable, message: "use subscript")
66-
// CHECK: func __operatorSubscriptConst(_ x: Double) -> UnsafePointer<Double>
66+
// CHECK: mutating func __operatorSubscript(_ x: Bool) -> UnsafeMutablePointer<Bool>
6767

6868
// CHECK: @available(*, unavailable, message: "use subscript")
69-
// CHECK: mutating func __operatorSubscript(_ x: Int32) -> UnsafeMutablePointer<Int32>
69+
// CHECK: func __operatorSubscriptConst(_ x: Bool) -> UnsafePointer<Bool>
7070

7171
// CHECK: @available(*, unavailable, message: "use subscript")
72-
// CHECK: mutating func __operatorSubscript(_ x: Bool) -> UnsafeMutablePointer<Bool>
72+
// CHECK: func __operatorSubscriptConst(_ x: Double) -> UnsafePointer<Double>
73+
7374
// CHECK: }
7475

7576

0 commit comments

Comments
 (0)