Skip to content

Commit 861041c

Browse files
authored
Merge pull request #2712 from swiftwasm/release/5.4
[pull] swiftwasm-release/5.4 from release/5.4
2 parents 3523847 + 53cfe01 commit 861041c

File tree

7 files changed

+115
-26
lines changed

7 files changed

+115
-26
lines changed

include/swift/AST/Decl.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3195,6 +3195,17 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
31953195
/// declaration, or \c nullptr if it doesn't have one.
31963196
ConstructorDecl *getDefaultInitializer() const;
31973197

3198+
/// Force the synthesis of all members named \c member requiring semantic
3199+
/// analysis and install them in the member list of this nominal type.
3200+
///
3201+
/// \Note The use of this method in the compiler signals an architectural
3202+
/// problem with the caller. Use \c TypeChecker::lookup* instead of
3203+
/// introducing new usages.
3204+
///
3205+
/// FIXME: This method presents a problem with respect to the consistency
3206+
/// and idempotency of lookups in the compiler. If we instead had a model
3207+
/// where lookup requests would explicitly return semantic members or parsed
3208+
/// members this function could disappear.
31983209
void synthesizeSemanticMembersIfNeeded(DeclName member);
31993210

32003211
/// Retrieves the static 'shared' property of a global actor type, which

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,6 +1821,18 @@ static int compareAssociatedTypes(AssociatedTypeDecl *assocType1,
18211821
return 0;
18221822
}
18231823

1824+
static void lookupConcreteNestedType(NominalTypeDecl *decl,
1825+
Identifier name,
1826+
SmallVectorImpl<TypeDecl *> &concreteDecls) {
1827+
SmallVector<ValueDecl *, 2> foundMembers;
1828+
decl->getParentModule()->lookupQualified(
1829+
decl, DeclNameRef(name),
1830+
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers,
1831+
foundMembers);
1832+
for (auto member : foundMembers)
1833+
concreteDecls.push_back(cast<TypeDecl>(member));
1834+
}
1835+
18241836
TypeDecl *EquivalenceClass::lookupNestedType(
18251837
GenericSignatureBuilder &builder,
18261838
Identifier name,
@@ -1893,19 +1905,9 @@ TypeDecl *EquivalenceClass::lookupNestedType(
18931905
// FIXME: Shouldn't we always look here?
18941906
if (!bestAssocType && concreteDecls.empty()) {
18951907
Type typeToSearch = concreteType ? concreteType : superclass;
1896-
auto *decl = typeToSearch ? typeToSearch->getAnyNominal() : nullptr;
1897-
if (decl) {
1898-
SmallVector<ValueDecl *, 2> foundMembers;
1899-
decl->getParentModule()->lookupQualified(
1900-
decl, DeclNameRef(name),
1901-
NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers,
1902-
foundMembers);
1903-
for (auto member : foundMembers) {
1904-
if (auto type = dyn_cast<TypeDecl>(member)) {
1905-
concreteDecls.push_back(type);
1906-
}
1907-
}
1908-
}
1908+
if (typeToSearch)
1909+
if (auto *decl = typeToSearch->getAnyNominal())
1910+
lookupConcreteNestedType(decl, name, concreteDecls);
19091911
}
19101912

19111913
// Infer same-type constraints among same-named associated type anchors.
@@ -3560,8 +3562,6 @@ static Type substituteConcreteType(Type parentType,
35603562
if (parentType->is<ErrorType>())
35613563
return parentType;
35623564

3563-
assert(concreteDecl);
3564-
35653565
auto *dc = concreteDecl->getDeclContext();
35663566

35673567
// Form an unsubstituted type referring to the given type declaration,
@@ -3598,10 +3598,31 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
35983598
resolutionKind,
35993599
wantExactPotentialArchetype);
36003600
if (!resolvedBase) return resolvedBase;
3601+
36013602
// If the base is concrete, so is this member.
36023603
if (auto parentType = resolvedBase.getAsConcreteType()) {
3603-
auto concreteType = substituteConcreteType(parentType,
3604-
depMemTy->getAssocType());
3604+
TypeDecl *concreteDecl = depMemTy->getAssocType();
3605+
if (!concreteDecl) {
3606+
// If we have an unresolved dependent member type, perform a
3607+
// name lookup.
3608+
if (auto *decl = parentType->getAnyNominal()) {
3609+
SmallVector<TypeDecl *, 2> concreteDecls;
3610+
lookupConcreteNestedType(decl, depMemTy->getName(), concreteDecls);
3611+
3612+
if (concreteDecls.empty())
3613+
return ResolvedType::forUnresolved(nullptr);
3614+
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+
3621+
concreteDecl = *bestConcreteTypeIter;
3622+
}
3623+
}
3624+
3625+
auto concreteType = substituteConcreteType(parentType, concreteDecl);
36053626
return ResolvedType::forConcrete(concreteType);
36063627
}
36073628

lib/Sema/TypeCheckNameLookup.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,32 @@ LookupResult TypeChecker::lookupUnqualified(DeclContext *dc, DeclNameRef name,
273273
return result;
274274
}
275275

276+
// An unfortunate hack to kick the decl checker into adding semantic members to
277+
// the current type before we attempt a semantic lookup. The places this method
278+
// looks needs to be in sync with \c extractDirectlyReferencedNominalTypes.
279+
// See the note in \c synthesizeSemanticMembersIfNeeded about a better, more
280+
// just, and peaceful world.
281+
static void installSemanticMembersIfNeeded(Type type, DeclNameRef name) {
282+
// Look-through class-bound archetypes to ensure we synthesize e.g.
283+
// inherited constructors.
284+
if (auto archetypeTy = type->getAs<ArchetypeType>()) {
285+
if (auto super = archetypeTy->getSuperclass()) {
286+
type = super;
287+
}
288+
}
289+
290+
if (type->isExistentialType()) {
291+
auto layout = type->getExistentialLayout();
292+
if (auto super = layout.explicitSuperclass) {
293+
type = super;
294+
}
295+
}
296+
297+
if (auto *current = type->getAnyNominal()) {
298+
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
299+
}
300+
}
301+
276302
LookupResult
277303
TypeChecker::lookupUnqualifiedType(DeclContext *dc, DeclNameRef name,
278304
SourceLoc loc,
@@ -320,9 +346,7 @@ LookupResult TypeChecker::lookupMember(DeclContext *dc,
320346
subOptions &= ~NL_RemoveNonVisible;
321347

322348
// Make sure we've resolved implicit members, if we need them.
323-
if (auto *current = type->getAnyNominal()) {
324-
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
325-
}
349+
installSemanticMembersIfNeeded(type, name);
326350

327351
LookupResultBuilder builder(result, dc, options);
328352
SmallVector<ValueDecl *, 4> lookupResults;
@@ -392,9 +416,7 @@ LookupTypeResult TypeChecker::lookupMemberType(DeclContext *dc,
392416
subOptions |= NL_IncludeUsableFromInline;
393417

394418
// Make sure we've resolved implicit members, if we need them.
395-
if (auto *current = type->getAnyNominal()) {
396-
current->synthesizeSemanticMembersIfNeeded(name.getFullName());
397-
}
419+
installSemanticMembersIfNeeded(type, name);
398420

399421
if (!dc->lookupQualified(type, name, subOptions, decls))
400422
return result;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class A {
2+
required init(_ x: Int) {}
3+
}
4+
5+
class B : A {}
6+
class C : A {}
7+
8+
protocol P {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-frontend -typecheck -verify -primary-file %s %S/Inputs/inherited-init-multifile-other.swift
2+
// RUN: %target-swift-frontend -typecheck -verify %s -primary-file %S/Inputs/inherited-init-multifile-other.swift
3+
4+
func make<Result: B>(ofClass cls: Result.Type) -> Result {
5+
return cls.init(1)
6+
}
7+
8+
func make(ofClass cls: (C & P).Type) -> C {
9+
return cls.init(1)
10+
}

validation-test/compiler_crashers_2/rdar56398071.swift renamed to validation-test/compiler_crashers_2_fixed/rdar56398071.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
// RUN: not --crash %target-swift-frontend -primary-file %s -emit-silgen
2-
3-
// REQUIRES: asserts
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir
42

53
public protocol WrappedSignedInteger: SignedInteger where Stride == Int {
64
typealias WrappedInteger = Int
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public struct LowerModel {
4+
public typealias Index = Int
5+
}
6+
7+
public protocol LowerChildA {
8+
typealias Model = LowerModel
9+
typealias ModelIndex = Model.Index
10+
}
11+
12+
public protocol LowerChildB {
13+
typealias Model = LowerModel
14+
typealias ModelIndex = Model.Index
15+
}
16+
17+
public protocol Parent: LowerChildA & LowerChildB {}
18+
19+
public func foo<T : Parent>(_: T, _: T.Model, _: T.ModelIndex) {}

0 commit comments

Comments
 (0)