Skip to content

Commit 9d3b2e5

Browse files
authored
Merge pull request #2743 from swiftwasm/release/5.4
[pull] swiftwasm-release/5.4 from release/5.4
2 parents 861041c + 0b45124 commit 9d3b2e5

File tree

6 files changed

+62
-13
lines changed

6 files changed

+62
-13
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,13 @@ static void lookupConcreteNestedType(NominalTypeDecl *decl,
18331833
concreteDecls.push_back(cast<TypeDecl>(member));
18341834
}
18351835

1836+
static auto findBestConcreteNestedType(SmallVectorImpl<TypeDecl *> &concreteDecls) {
1837+
return std::min_element(concreteDecls.begin(), concreteDecls.end(),
1838+
[](TypeDecl *type1, TypeDecl *type2) {
1839+
return TypeDecl::compare(type1, type2) < 0;
1840+
});
1841+
}
1842+
18361843
TypeDecl *EquivalenceClass::lookupNestedType(
18371844
GenericSignatureBuilder &builder,
18381845
Identifier name,
@@ -1940,11 +1947,7 @@ TypeDecl *EquivalenceClass::lookupNestedType(
19401947
"Lookup should never keep a non-anchor associated type");
19411948
} else if (!concreteDecls.empty()) {
19421949
// Find the best concrete type.
1943-
auto bestConcreteTypeIter =
1944-
std::min_element(concreteDecls.begin(), concreteDecls.end(),
1945-
[](TypeDecl *type1, TypeDecl *type2) {
1946-
return TypeDecl::compare(type1, type2) < 0;
1947-
});
1950+
auto bestConcreteTypeIter = findBestConcreteNestedType(concreteDecls);
19481951

19491952
// Put the best concrete type first; the rest will follow.
19501953
entry.types.push_back(*bestConcreteTypeIter);
@@ -3559,7 +3562,8 @@ static Type getStructuralType(TypeDecl *typeDecl, bool keepSugar) {
35593562

35603563
static Type substituteConcreteType(Type parentType,
35613564
TypeDecl *concreteDecl) {
3562-
if (parentType->is<ErrorType>())
3565+
if (parentType->is<ErrorType>() ||
3566+
parentType->is<UnresolvedType>())
35633567
return parentType;
35643568

35653569
auto *dc = concreteDecl->getDeclContext();
@@ -3612,18 +3616,14 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
36123616
if (concreteDecls.empty())
36133617
return ResolvedType::forUnresolved(nullptr);
36143618

3615-
auto bestConcreteTypeIter =
3616-
std::min_element(concreteDecls.begin(), concreteDecls.end(),
3617-
[](TypeDecl *type1, TypeDecl *type2) {
3618-
return TypeDecl::compare(type1, type2) < 0;
3619-
});
3620-
3619+
auto bestConcreteTypeIter = findBestConcreteNestedType(concreteDecls);
36213620
concreteDecl = *bestConcreteTypeIter;
36223621
}
36233622
}
36243623

36253624
auto concreteType = substituteConcreteType(parentType, concreteDecl);
3626-
return ResolvedType::forConcrete(concreteType);
3625+
return maybeResolveEquivalenceClass(concreteType, resolutionKind,
3626+
wantExactPotentialArchetype);
36273627
}
36283628

36293629
// Find the nested type declaration for this.

lib/SILOptimizer/Analysis/SimplifyInstruction.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,13 @@ static SILValue simplifyDeadCast(SingleValueInstruction *Cast) {
348348
for (Operand *op : Cast->getUses()) {
349349
switch (op->getUser()->getKind()) {
350350
case SILInstructionKind::DestroyValueInst:
351+
break;
351352
case SILInstructionKind::StrongReleaseInst:
352353
case SILInstructionKind::StrongRetainInst:
354+
// ref-casts can cast from an Optional<Classtype>. But strong_retain/
355+
// strong_release don't accept an optional.
356+
if (!Cast->getOperand(0)->getType().isReferenceCounted(Cast->getModule()))
357+
return SILValue();
353358
break;
354359
default:
355360
return SILValue();

stdlib/public/core/KeyPath.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,6 +1932,11 @@ func _modifyAtWritableKeyPath_impl<Root, Value>(
19321932
root: inout Root,
19331933
keyPath: WritableKeyPath<Root, Value>
19341934
) -> (UnsafeMutablePointer<Value>, AnyObject?) {
1935+
if type(of: keyPath).kind == .reference {
1936+
return _modifyAtReferenceWritableKeyPath_impl(root: root,
1937+
keyPath: _unsafeUncheckedDowncast(keyPath,
1938+
to: ReferenceWritableKeyPath<Root, Value>.self))
1939+
}
19351940
return keyPath._projectMutableAddress(from: &root)
19361941
}
19371942

test/SILOptimizer/sil_combine.sil

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,20 @@ bb0(%0 : $C1):
836836
return %0 : $C1
837837
}
838838

839+
// strong_retain/strong_release don't accept an Optional<reference>.
840+
//
841+
// CHECK-LABEL: sil @dontOptimizeRefCastOfOptional
842+
// CHECK: %1 = unchecked_ref_cast %0
843+
// CHECK: strong_retain %1
844+
// CHECK: } // end sil function 'dontOptimizeRefCastOfOptional'
845+
sil @dontOptimizeRefCastOfOptional : $@convention(thin) (@guaranteed Optional<C1>) -> () {
846+
bb0(%0 : $Optional<C1>):
847+
%1 = unchecked_ref_cast %0 : $Optional<C1> to $C1
848+
strong_retain %1 : $C1
849+
%3 = tuple ()
850+
return %3 : $()
851+
}
852+
839853
// CHECK-LABEL: sil @dead_end_cow_mutation
840854
// CHECK: bb0
841855
// CHECK-NEXT: strong_retain %0

test/stdlib/KeyPath.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,16 @@ keyPath.test("ReferenceWritableKeyPath statically typed as WritableKeyPath") {
10431043
expectEqual(outer[keyPath: upcastKeyPath], 43)
10441044
outer[keyPath: upcastKeyPath] = 44
10451045
expectEqual(outer[keyPath: upcastKeyPath], 44)
1046+
1047+
func setWithInout<T>(_ lhs: inout T, _ rhs: T) { lhs = rhs }
1048+
1049+
expectEqual(outer[keyPath: keyPath], 44)
1050+
setWithInout(&outer[keyPath: keyPath], 45);
1051+
expectEqual(outer[keyPath: keyPath], 45)
1052+
1053+
expectEqual(outer[keyPath: upcastKeyPath], 45)
1054+
setWithInout(&outer[keyPath: upcastKeyPath], 46)
1055+
expectEqual(outer[keyPath: upcastKeyPath], 46)
10461056
}
10471057

10481058
runAllTests()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -emit-ir -primary-file %s
2+
3+
public protocol FooProtocol {
4+
associatedtype Bar
5+
}
6+
7+
public struct Foo<Bar>: FooProtocol {
8+
public var bar: Bar
9+
}
10+
11+
public protocol BazProtocol: FooProtocol {
12+
associatedtype Foo1: FooProtocol where Foo1.Bar == Foo2.Bar
13+
associatedtype Foo2Bar
14+
typealias Foo2 = Foo<Foo2Bar>
15+
}

0 commit comments

Comments
 (0)