Skip to content

Commit 7a37ad3

Browse files
committed
Ensure that we set opaque type substitutions on local variables.
We were never setting these opaque type substitutions, but code generation was silently failing. Now we assert, so move the code into the proper common location so we always set opaque type substitutions on properties. Fixes rdar://86800325.
1 parent b0ed490 commit 7a37ad3

File tree

3 files changed

+46
-23
lines changed

3 files changed

+46
-23
lines changed

lib/Sema/CSApply.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8420,6 +8420,30 @@ static Optional<SolutionApplicationTarget> applySolutionToInitialization(
84208420
cs, resultTarget.getAsExpr(), resultTarget.getDeclContext()));
84218421
}
84228422

8423+
// If this property has an opaque result type, set the underlying type
8424+
// substitutions based on the initializer.
8425+
if (auto var = resultTarget.getInitializationPattern()->getSingleVar()) {
8426+
SubstitutionMap substitutions;
8427+
if (auto opaque = var->getOpaqueResultTypeDecl()) {
8428+
resultTarget.getAsExpr()->forEachChildExpr([&](Expr *expr) -> Expr * {
8429+
if (auto coercionExpr = dyn_cast<UnderlyingToOpaqueExpr>(expr)) {
8430+
auto newSubstitutions =
8431+
coercionExpr->substitutions.mapReplacementTypesOutOfContext();
8432+
if (substitutions.empty()) {
8433+
substitutions = newSubstitutions;
8434+
} else {
8435+
assert(substitutions.getCanonical() ==
8436+
newSubstitutions.getCanonical());
8437+
}
8438+
}
8439+
return expr;
8440+
});
8441+
8442+
opaque->setUnderlyingTypeSubstitutions(substitutions);
8443+
}
8444+
}
8445+
8446+
84238447
return resultTarget;
84248448
}
84258449

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -538,29 +538,6 @@ bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
538538
PBD->setPattern(patternNumber, pattern, initContext);
539539
PBD->setInit(patternNumber, init);
540540

541-
// Bind a property with an opaque return type to the underlying type
542-
// given by the initializer.
543-
if (auto var = pattern->getSingleVar()) {
544-
SubstitutionMap substitutions;
545-
if (auto opaque = var->getOpaqueResultTypeDecl()) {
546-
init->forEachChildExpr([&](Expr *expr) -> Expr * {
547-
if (auto coercionExpr = dyn_cast<UnderlyingToOpaqueExpr>(expr)) {
548-
auto newSubstitutions =
549-
coercionExpr->substitutions.mapReplacementTypesOutOfContext();
550-
if (substitutions.empty()) {
551-
substitutions = newSubstitutions;
552-
} else {
553-
assert(substitutions.getCanonical() ==
554-
newSubstitutions.getCanonical());
555-
}
556-
}
557-
return expr;
558-
});
559-
560-
opaque->setUnderlyingTypeSubstitutions(substitutions);
561-
}
562-
}
563-
564541
if (hadError)
565542
PBD->setInvalid();
566543

test/IRGen/opaque_result_type.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,25 @@ public enum EnumWithTupleWithOpaqueField {
253253
case a(Int)
254254
case b((OpaqueProps, String))
255255
}
256+
257+
// rdar://86800325 - Make sure we don't crash on result builders.
258+
@resultBuilder
259+
struct Builder {
260+
static func buildBlock(_: Any...) -> Int { 5 }
261+
}
262+
263+
protocol P2 {
264+
associatedtype A: P2
265+
266+
@Builder var builder: A { get }
267+
}
268+
269+
extension Int: P2 {
270+
var builder: some P2 { 5 }
271+
}
272+
273+
struct UseBuilder: P2 {
274+
var builder: some P2 {
275+
let extractedExpr: some P2 = 5
276+
}
277+
}

0 commit comments

Comments
 (0)