Skip to content

Commit 3abea6b

Browse files
committed
[Constraint system] Use the PatternBindingDecl context when possible.
Make sure that we're resolving types and patterns using the PatternBindingDecl context, both for the type resolver context and the contextual pattern used for pattern resolution. Fixes a regression with implicitly-unwrapped options reported as SR-11998 / rdar://problem/58455441.
1 parent 75bad90 commit 3abea6b

File tree

7 files changed

+104
-24
lines changed

7 files changed

+104
-24
lines changed

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7395,7 +7395,9 @@ static Optional<SolutionApplicationTarget> applySolutionToInitialization(
73957395
TypeResolutionOptions options =
73967396
isa<EditorPlaceholderExpr>(initializer->getSemanticsProvidingExpr())
73977397
? TypeResolverContext::EditorPlaceholderExpr
7398-
: TypeResolverContext::InExpression;
7398+
: target.getInitializationPatternBindingDecl()
7399+
? TypeResolverContext::PatternBindingDecl
7400+
: TypeResolverContext::InExpression;
73997401
options |= TypeResolutionFlags::OverrideType;
74007402

74017403
// Determine the type of the pattern.
@@ -7411,9 +7413,7 @@ static Optional<SolutionApplicationTarget> applySolutionToInitialization(
74117413
finalPatternType = finalPatternType->reconstituteSugar(/*recursive =*/false);
74127414

74137415
// Apply the solution to the pattern as well.
7414-
auto contextualPattern =
7415-
ContextualPattern::forRawPattern(target.getInitializationPattern(),
7416-
target.getDeclContext());
7416+
auto contextualPattern = target.getInitializationContextualPattern();
74177417
if (auto coercedPattern = TypeChecker::coercePatternToType(
74187418
contextualPattern, finalPatternType, options)) {
74197419
resultTarget.setPattern(coercedPattern);

lib/Sema/CSGen.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,9 +2225,12 @@ namespace {
22252225
/// for the types of each variable declared within the pattern, along
22262226
/// with a one-way constraint binding that to the type to which the
22272227
/// variable will be ascribed or inferred.
2228-
Type getTypeForPattern(Pattern *pattern, ConstraintLocatorBuilder locator,
2229-
Type externalPatternType,
2230-
bool bindPatternVarsOneWay) {
2228+
Type getTypeForPattern(
2229+
Pattern *pattern, ConstraintLocatorBuilder locator,
2230+
Type externalPatternType,
2231+
bool bindPatternVarsOneWay,
2232+
PatternBindingDecl *patternBinding = nullptr,
2233+
unsigned patternBindingIndex = 0) {
22312234
// If there's no pattern, then we have an unknown subpattern. Create a
22322235
// type variable.
22332236
if (!pattern) {
@@ -2319,8 +2322,11 @@ namespace {
23192322
case PatternKind::Typed: {
23202323
// FIXME: Need a better locator for a pattern as a base.
23212324
// Compute the type ascribed to the pattern.
2322-
auto contextualPattern =
2323-
ContextualPattern::forRawPattern(pattern, CurDC);
2325+
auto contextualPattern = patternBinding
2326+
? ContextualPattern::forPatternBindingDecl(
2327+
patternBinding, patternBindingIndex)
2328+
: ContextualPattern::forRawPattern(pattern, CurDC);
2329+
23242330
Type type = TypeChecker::typeCheckPattern(contextualPattern);
23252331
Type openedType = CS.openUnboundGenericType(type, locator);
23262332

@@ -4097,7 +4103,9 @@ static bool generateInitPatternConstraints(
40974103
auto locator =
40984104
cs.getConstraintLocator(initializer, LocatorPathElt::ContextualType());
40994105
Type patternType = cs.generateConstraints(
4100-
pattern, locator, target.shouldBindPatternVarsOneWay());
4106+
pattern, locator, target.shouldBindPatternVarsOneWay(),
4107+
target.getInitializationPatternBindingDecl(),
4108+
target.getInitializationPatternBindingIndex());
41014109
assert(patternType && "All patterns have a type");
41024110

41034111
if (auto wrappedVar = target.getInitializationWrappedVar()) {
@@ -4199,11 +4207,13 @@ Expr *ConstraintSystem::generateConstraints(Expr *expr, DeclContext *dc) {
41994207
return generateConstraintsFor(*this, expr, dc);
42004208
}
42014209

4202-
Type ConstraintSystem::generateConstraints(Pattern *pattern,
4203-
ConstraintLocatorBuilder locator,
4204-
bool bindPatternVarsOneWay) {
4210+
Type ConstraintSystem::generateConstraints(
4211+
Pattern *pattern, ConstraintLocatorBuilder locator,
4212+
bool bindPatternVarsOneWay, PatternBindingDecl *patternBinding,
4213+
unsigned patternIndex) {
42054214
ConstraintGenerator cg(*this, nullptr);
4206-
return cg.getTypeForPattern(pattern, locator, Type(), bindPatternVarsOneWay);
4215+
return cg.getTypeForPattern(pattern, locator, Type(), bindPatternVarsOneWay,
4216+
patternBinding, patternIndex);
42074217
}
42084218

42094219
bool ConstraintSystem::generateConstraints(StmtCondition condition,
@@ -4276,7 +4286,8 @@ bool ConstraintSystem::generateConstraints(
42764286
// any variables that show up in this pattern, because those variables
42774287
// can be referenced in the guard expressions and the body.
42784288
Type patternType = generateConstraints(
4279-
pattern, locator, /* bindPatternVarsOneWay=*/true);
4289+
pattern, locator, /* bindPatternVarsOneWay=*/true,
4290+
/*patternBinding=*/nullptr, /*patternBindingIndex=*/0);
42804291

42814292
// Convert the subject type to the pattern, which establishes the
42824293
// bindings.

lib/Sema/ConstraintSystem.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4160,6 +4160,8 @@ SolutionApplicationTarget::SolutionApplicationTarget(
41604160
expression.wrappedVar = nullptr;
41614161
expression.isDiscarded = isDiscarded;
41624162
expression.bindPatternVarsOneWay = false;
4163+
expression.patternBinding = nullptr;
4164+
expression.patternBindingIndex = 0;
41634165
}
41644166

41654167
void SolutionApplicationTarget::maybeApplyPropertyWrapper() {
@@ -4242,6 +4244,30 @@ SolutionApplicationTarget SolutionApplicationTarget::forInitialization(
42424244
return target;
42434245
}
42444246

4247+
SolutionApplicationTarget SolutionApplicationTarget::forInitialization(
4248+
Expr *initializer, DeclContext *dc, Type patternType,
4249+
PatternBindingDecl *patternBinding, unsigned patternBindingIndex,
4250+
bool bindPatternVarsOneWay) {
4251+
auto result = forInitialization(
4252+
initializer, dc, patternType,
4253+
patternBinding->getPattern(patternBindingIndex), bindPatternVarsOneWay);
4254+
result.expression.patternBinding = patternBinding;
4255+
result.expression.patternBindingIndex = patternBindingIndex;
4256+
return result;
4257+
}
4258+
4259+
ContextualPattern
4260+
SolutionApplicationTarget::getInitializationContextualPattern() const {
4261+
assert(kind == Kind::expression);
4262+
assert(expression.contextualPurpose == CTP_Initialization);
4263+
if (expression.patternBinding) {
4264+
return ContextualPattern::forPatternBindingDecl(
4265+
expression.patternBinding, expression.patternBindingIndex);
4266+
}
4267+
4268+
return ContextualPattern::forRawPattern(expression.pattern, expression.dc);
4269+
}
4270+
42454271
bool SolutionApplicationTarget::infersOpaqueReturnType() const {
42464272
assert(kind == Kind::expression);
42474273
switch (expression.contextualPurpose) {

lib/Sema/ConstraintSystem.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,12 @@ class SolutionApplicationTarget {
12061206
/// Whether to bind the variables encountered within the pattern to
12071207
/// fresh type variables via one-way constraints.
12081208
bool bindPatternVarsOneWay;
1209+
1210+
/// The pattern binding declaration for an initialization, if any.
1211+
PatternBindingDecl *patternBinding;
1212+
1213+
/// The index into the pattern binding declaration, if any.
1214+
unsigned patternBindingIndex;
12091215
} expression;
12101216

12111217
struct {
@@ -1267,6 +1273,13 @@ class SolutionApplicationTarget {
12671273
Expr *initializer, DeclContext *dc, Type patternType, Pattern *pattern,
12681274
bool bindPatternVarsOneWay);
12691275

1276+
/// Form a target for the initialization of a pattern binding entry from
1277+
/// an expression.
1278+
static SolutionApplicationTarget forInitialization(
1279+
Expr *initializer, DeclContext *dc, Type patternType,
1280+
PatternBindingDecl *patternBinding, unsigned patternBindingIndex,
1281+
bool bindPatternVarsOneWay);
1282+
12701283
Expr *getAsExpr() const {
12711284
switch (kind) {
12721285
case Kind::expression:
@@ -1351,6 +1364,9 @@ class SolutionApplicationTarget {
13511364
return expression.pattern;
13521365
}
13531366

1367+
/// For a pattern initialization target, retrieve the contextual pattern.
1368+
ContextualPattern getInitializationContextualPattern() const;
1369+
13541370
/// Whether this is an initialization for an Optional.Some pattern.
13551371
bool isOptionalSomePatternInit() const {
13561372
return kind == Kind::expression &&
@@ -1374,6 +1390,18 @@ class SolutionApplicationTarget {
13741390
return expression.wrappedVar;
13751391
}
13761392

1393+
PatternBindingDecl *getInitializationPatternBindingDecl() const {
1394+
assert(kind == Kind::expression);
1395+
assert(expression.contextualPurpose == CTP_Initialization);
1396+
return expression.patternBinding;
1397+
}
1398+
1399+
unsigned getInitializationPatternBindingIndex() const {
1400+
assert(kind == Kind::expression);
1401+
assert(expression.contextualPurpose == CTP_Initialization);
1402+
return expression.patternBindingIndex;
1403+
}
1404+
13771405
/// Whether this context infers an opaque return type.
13781406
bool infersOpaqueReturnType() const;
13791407

@@ -3398,7 +3426,9 @@ class ConstraintSystem {
33983426
///
33993427
/// \returns a possibly-sanitized initializer, or null if an error occurred.
34003428
Type generateConstraints(Pattern *P, ConstraintLocatorBuilder locator,
3401-
bool bindPatternVarsOneWay);
3429+
bool bindPatternVarsOneWay,
3430+
PatternBindingDecl *patternBinding,
3431+
unsigned patternIndex);
34023432

34033433
/// Generate constraints for a statement condition.
34043434
///

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,11 +2352,16 @@ TypeChecker::getTypeOfCompletionOperator(DeclContext *DC, Expr *LHS,
23522352
}
23532353
}
23542354

2355-
bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
2356-
DeclContext *DC,
2357-
Type patternType) {
2358-
auto target = SolutionApplicationTarget::forInitialization(
2359-
initializer, DC, patternType, pattern, /*bindPatternVarsOneWay=*/false);
2355+
bool TypeChecker::typeCheckBinding(
2356+
Pattern *&pattern, Expr *&initializer, DeclContext *DC,
2357+
Type patternType, PatternBindingDecl *PBD, unsigned patternNumber) {
2358+
SolutionApplicationTarget target =
2359+
PBD ? SolutionApplicationTarget::forInitialization(
2360+
initializer, DC, patternType, PBD, patternNumber,
2361+
/*bindPatternVarsOneWay=*/false)
2362+
: SolutionApplicationTarget::forInitialization(
2363+
initializer, DC, patternType, pattern,
2364+
/*bindPatternVarsOneWay=*/false);
23602365

23612366
// Type-check the initializer.
23622367
bool unresolvedTypeExprs = false;
@@ -2425,7 +2430,8 @@ bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
24252430
}
24262431
}
24272432

2428-
bool hadError = TypeChecker::typeCheckBinding(pattern, init, DC, patternType);
2433+
bool hadError = TypeChecker::typeCheckBinding(
2434+
pattern, init, DC, patternType, PBD, patternNumber);
24292435
if (!init) {
24302436
PBD->setInvalid();
24312437
return true;
@@ -2550,7 +2556,8 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
25502556
// Collect constraints from the element pattern.
25512557
auto pattern = Stmt->getPattern();
25522558
InitType = cs.generateConstraints(
2553-
pattern, elementLocator, /*bindPatternVarsOneWay=*/false);
2559+
pattern, elementLocator, /*bindPatternVarsOneWay=*/false,
2560+
/*patternBinding=*/nullptr, /*patternBindingIndex=*/0);
25542561
if (!InitType)
25552562
return true;
25562563

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,9 @@ void coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
916916

917917
/// Type-check an initialized variable pattern declaration.
918918
bool typeCheckBinding(Pattern *&P, Expr *&Init, DeclContext *DC,
919-
Type patternType);
919+
Type patternType,
920+
PatternBindingDecl *PBD = nullptr,
921+
unsigned patternNumber = 0);
920922
bool typeCheckPatternBinding(PatternBindingDecl *PBD, unsigned patternNumber,
921923
Type patternType = Type());
922924

test/Constraints/iuo.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,7 @@ var y: Int = 2
225225

226226
let r = sr6988(x: x, y: y)
227227
let _: Int = r
228+
229+
// SR-11998 / rdar://problem/58455441
230+
class C<T> {}
231+
var sub: C! = C<Int>()

0 commit comments

Comments
 (0)