Skip to content

Commit 81f7124

Browse files
authored
Merge pull request #40790 from DougGregor/opaque-type-local-variables
Ensure that we set opaque type substitutions on local variables.
2 parents 967465e + 7a37ad3 commit 81f7124

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)