Skip to content

Commit 29cfe61

Browse files
authored
Merge pull request swiftlang#71253 from DougGregor/hash-table-iteration-considered-harmful
Fix nondeterminism in explicitly-specified generic macro arguments
2 parents 1e9af24 + 7712903 commit 29cfe61

File tree

2 files changed

+53
-18
lines changed

2 files changed

+53
-18
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13703,6 +13703,25 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1370313703
if (simplifiedBoundType->isTypeVariableOrMember())
1370413704
return formUnsolved();
1370513705

13706+
std::function<GenericParamList *(ValueDecl *)> getGenericParams =
13707+
[&](ValueDecl *decl) -> GenericParamList * {
13708+
auto genericContext = decl->getAsGenericContext();
13709+
if (!genericContext)
13710+
return nullptr;
13711+
13712+
auto genericParams = genericContext->getGenericParams();
13713+
if (!genericParams) {
13714+
// If declaration is a non-generic typealias, let's point
13715+
// to the underlying generic declaration.
13716+
if (auto *TA = dyn_cast<TypeAliasDecl>(decl)) {
13717+
if (auto *UGT = TA->getUnderlyingType()->getAs<AnyGenericType>())
13718+
return getGenericParams(UGT->getDecl());
13719+
}
13720+
}
13721+
13722+
return genericParams;
13723+
};
13724+
1370613725
ValueDecl *decl;
1370713726
SmallVector<OpenedType, 2> openedTypes;
1370813727
if (auto *bound = dyn_cast<TypeAliasType>(type1.getPointer())) {
@@ -13759,27 +13778,19 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1375913778
decl = overloadChoice.getDecl();
1376013779

1376113780
auto openedOverloadTypes = getOpenedTypes(overloadLocator);
13762-
openedTypes.append(openedOverloadTypes.begin(), openedOverloadTypes.end());
13763-
}
13764-
13765-
std::function<GenericParamList *(ValueDecl *)> getGenericParams =
13766-
[&](ValueDecl *decl) -> GenericParamList * {
13767-
auto genericContext = decl->getAsGenericContext();
13768-
if (!genericContext)
13769-
return nullptr;
1377013781

13771-
auto genericParams = genericContext->getGenericParams();
13772-
if (!genericParams) {
13773-
// If declaration is a non-generic typealias, let's point
13774-
// to the underlying generic declaration.
13775-
if (auto *TA = dyn_cast<TypeAliasDecl>(decl)) {
13776-
if (auto *UGT = TA->getUnderlyingType()->getAs<AnyGenericType>())
13777-
return getGenericParams(UGT->getDecl());
13782+
auto genericParams = getGenericParams(decl);
13783+
if (genericParams) {
13784+
for (auto gp : *genericParams) {
13785+
auto found = find_if(openedOverloadTypes, [&](auto entry) {
13786+
return entry.first->getDepth() == gp->getDepth() &&
13787+
entry.first->getIndex() == gp->getIndex();
13788+
});
13789+
assert(found != openedOverloadTypes.end());
13790+
openedTypes.push_back(*found);
1377813791
}
1377913792
}
13780-
13781-
return genericParams;
13782-
};
13793+
}
1378313794

1378413795
if (!decl->getAsGenericContext())
1378513796
return SolutionKind::Error;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// REQUIRES: swift_swift_parser
2+
3+
// RUN: %target-typecheck-verify-swift -swift-version 5
4+
5+
protocol P {
6+
associatedtype A
7+
}
8+
9+
@freestanding(expression)
10+
macro resolve<T, U: P>(_ first: U.A, _ second: U) -> T = #externalMacro(module: "A", type: "B")
11+
// expected-warning@-1{{external macro implementation type 'A.B' could not be found}}
12+
// expected-note@-2{{'resolve' declared here}}
13+
14+
protocol Q { }
15+
16+
struct X: P {
17+
typealias A = Int
18+
}
19+
20+
func test(i: Int) {
21+
_ = #resolve<any Q, X>(i, X())
22+
// expected-error@-1{{external macro implementation type 'A.B' could not be found for macro 'resolve'; plugin for module 'A' not found}}
23+
}
24+

0 commit comments

Comments
 (0)