@@ -1802,14 +1802,8 @@ namespace {
1802
1802
// /
1803
1803
// / \param locator The locator to use for generated constraints and
1804
1804
// / type variables.
1805
- // /
1806
- // / \param bindPatternVarsOneWay When true, generate fresh type variables
1807
- // / for the types of each variable declared within the pattern, along
1808
- // / with a one-way constraint binding that to the type to which the
1809
- // / variable will be ascribed or inferred.
1810
1805
Type getTypeForPattern (
1811
1806
Pattern *pattern, ConstraintLocatorBuilder locator,
1812
- bool bindPatternVarsOneWay,
1813
1807
PatternBindingDecl *patternBinding = nullptr ,
1814
1808
unsigned patternBindingIndex = 0 ) {
1815
1809
assert (pattern);
@@ -1828,15 +1822,13 @@ namespace {
1828
1822
auto *subPattern = paren->getSubPattern ();
1829
1823
auto underlyingType = getTypeForPattern (
1830
1824
subPattern,
1831
- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
1832
- bindPatternVarsOneWay);
1825
+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
1833
1826
1834
1827
return setType (underlyingType);
1835
1828
}
1836
1829
case PatternKind::Binding: {
1837
1830
auto *subPattern = cast<BindingPattern>(pattern)->getSubPattern ();
1838
- auto type = getTypeForPattern (subPattern, locator,
1839
- bindPatternVarsOneWay);
1831
+ auto type = getTypeForPattern (subPattern, locator);
1840
1832
// Var doesn't affect the type.
1841
1833
return setType (type);
1842
1834
}
@@ -1932,100 +1924,65 @@ namespace {
1932
1924
var->getNameStr ().starts_with (" $__builder" );
1933
1925
};
1934
1926
1935
- // When we are supposed to bind pattern variables, create a fresh
1936
- // type variable and a one-way constraint to assign it to either the
1937
- // deduced type or the externally-imposed type.
1938
- Type oneWayVarType;
1939
- if (bindPatternVarsOneWay) {
1940
- oneWayVarType = CS.createTypeVariable (
1941
- CS.getConstraintLocator (locator), TVO_CanBindToNoEscape);
1942
-
1943
- // If there is externally-imposed type, and the variable
1944
- // is marked as `weak`, let's fallthrough and allow the
1945
- // `one-way` constraint to be fixed in diagnostic mode.
1946
- //
1947
- // That would make sure that type of this variable is
1948
- // recorded in the constraint system, which would then
1949
- // be used instead of `getVarType` upon discovering a
1950
- // reference to this variable in subsequent expression(s).
1951
- //
1952
- // If we let constraint generation fail here, it would trigger
1953
- // interface type request via `var->getType()` that would
1954
- // attempt to validate `weak` attribute, and produce a
1955
- // diagnostic in the middle of the solver path.
1956
-
1957
- CS.addConstraint (ConstraintKind::OneWayEqual, oneWayVarType,
1958
- varType, locator);
1959
-
1960
- if (useLocatableTypes ())
1961
- oneWayVarType = makeTypeLocatableIfPossible (oneWayVarType);
1962
- }
1963
-
1964
- // Ascribe a type to the declaration so it's always available to
1965
- // constraint system.
1966
- if (oneWayVarType) {
1967
- CS.setType (var, oneWayVarType);
1968
- } else {
1969
- // Otherwise, let's use the type of the pattern. The type
1970
- // of the declaration has to be r-value, so let's add an
1971
- // equality constraint if pattern type has any type variables
1972
- // that are allowed to be l-value.
1973
- bool foundLValueVars = false ;
1974
-
1975
- // Note that it wouldn't be always correct to allocate a single type
1976
- // variable, that disallows l-value types, to use as a declaration
1977
- // type because equality constraint would drop TVO_CanBindToLValue
1978
- // from the right-hand side (which is not the case for `OneWayEqual`)
1979
- // e.g.:
1980
- //
1981
- // struct S { var x, y: Int }
1982
- //
1983
- // func test(s: S) {
1984
- // let (x, y) = (s.x, s.y)
1985
- // }
1986
- //
1987
- // Single type variable approach results in the following constraint:
1988
- // `$T_x_y = ($T_s_x, $T_s_y)` where both `$T_s_x` and `$T_s_y` have
1989
- // to allow l-value, but `$T_x_y` does not. Early simplification of `=`
1990
- // constraint (due to right-hand side being a "concrete" tuple type)
1991
- // would drop l-value option from `$T_s_x` and `$T_s_y` which leads to
1992
- // a failure during member lookup because `x` and `y` are both
1993
- // `@lvalue Int`. To avoid that, declaration type would mimic pattern
1994
- // type with all l-value options stripped, so the equality constraint
1995
- // becomes `($T_x, $_T_y) = ($T_s_x, $T_s_y)` which doesn't result in
1996
- // stripping of l-value flag from the right-hand side since
1997
- // simplification can only happen when either side is resolved.
1998
- auto declTy = varType.transformRec ([&](Type type) -> std::optional<Type> {
1999
- if (auto *typeVar = type->getAs <TypeVariableType>()) {
2000
- if (typeVar->getImpl ().canBindToLValue ()) {
2001
- foundLValueVars = true ;
2002
-
2003
- // Drop l-value from the options but preserve the rest.
2004
- auto options = typeVar->getImpl ().getRawOptions ();
2005
- options &= ~TVO_CanBindToLValue;
2006
-
2007
- return Type (CS.createTypeVariable (typeVar->getImpl ().getLocator (),
2008
- options));
2009
- }
1927
+ // Otherwise, let's use the type of the pattern. The type
1928
+ // of the declaration has to be r-value, so let's add an
1929
+ // equality constraint if pattern type has any type variables
1930
+ // that are allowed to be l-value.
1931
+ bool foundLValueVars = false ;
1932
+
1933
+ // Note that it wouldn't be always correct to allocate a single type
1934
+ // variable, that disallows l-value types, to use as a declaration
1935
+ // type because equality constraint would drop TVO_CanBindToLValue
1936
+ // from the right-hand side (which is not the case for `OneWayEqual`)
1937
+ // e.g.:
1938
+ //
1939
+ // struct S { var x, y: Int }
1940
+ //
1941
+ // func test(s: S) {
1942
+ // let (x, y) = (s.x, s.y)
1943
+ // }
1944
+ //
1945
+ // Single type variable approach results in the following constraint:
1946
+ // `$T_x_y = ($T_s_x, $T_s_y)` where both `$T_s_x` and `$T_s_y` have
1947
+ // to allow l-value, but `$T_x_y` does not. Early simplification of `=`
1948
+ // constraint (due to right-hand side being a "concrete" tuple type)
1949
+ // would drop l-value option from `$T_s_x` and `$T_s_y` which leads to
1950
+ // a failure during member lookup because `x` and `y` are both
1951
+ // `@lvalue Int`. To avoid that, declaration type would mimic pattern
1952
+ // type with all l-value options stripped, so the equality constraint
1953
+ // becomes `($T_x, $_T_y) = ($T_s_x, $T_s_y)` which doesn't result in
1954
+ // stripping of l-value flag from the right-hand side since
1955
+ // simplification can only happen when either side is resolved.
1956
+ auto declTy = varType.transformRec ([&](Type type) -> std::optional<Type> {
1957
+ if (auto *typeVar = type->getAs <TypeVariableType>()) {
1958
+ if (typeVar->getImpl ().canBindToLValue ()) {
1959
+ foundLValueVars = true ;
1960
+
1961
+ // Drop l-value from the options but preserve the rest.
1962
+ auto options = typeVar->getImpl ().getRawOptions ();
1963
+ options &= ~TVO_CanBindToLValue;
1964
+
1965
+ return Type (CS.createTypeVariable (typeVar->getImpl ().getLocator (),
1966
+ options));
2010
1967
}
2011
- return std::nullopt;
2012
- });
2013
-
2014
- // If pattern types allows l-value types, let's create an
2015
- // equality constraint between r-value only declaration type
2016
- // and l-value pattern type that would take care of looking
2017
- // through l-values when necessary.
2018
- if (foundLValueVars) {
2019
- CS.addConstraint (ConstraintKind::Equal, declTy, varType,
2020
- CS.getConstraintLocator (locator));
2021
1968
}
1969
+ return std::nullopt;
1970
+ });
2022
1971
2023
- if (useLocatableTypes ())
2024
- declTy = makeTypeLocatableIfPossible (declTy);
2025
-
2026
- CS.setType (var, declTy);
1972
+ // If pattern types allows l-value types, let's create an
1973
+ // equality constraint between r-value only declaration type
1974
+ // and l-value pattern type that would take care of looking
1975
+ // through l-values when necessary.
1976
+ if (foundLValueVars) {
1977
+ CS.addConstraint (ConstraintKind::Equal, declTy, varType,
1978
+ CS.getConstraintLocator (locator));
2027
1979
}
2028
1980
1981
+ if (useLocatableTypes ())
1982
+ declTy = makeTypeLocatableIfPossible (declTy);
1983
+
1984
+ CS.setType (var, declTy);
1985
+
2029
1986
return setType (varType);
2030
1987
}
2031
1988
@@ -2053,8 +2010,7 @@ namespace {
2053
2010
// ascribed type.
2054
2011
Type subPatternType = getTypeForPattern (
2055
2012
subPattern,
2056
- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2057
- bindPatternVarsOneWay);
2013
+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
2058
2014
2059
2015
// NOTE: The order here is important! Pattern matching equality is
2060
2016
// not symmetric (we need to fix that either by using a different
@@ -2082,8 +2038,7 @@ namespace {
2082
2038
auto *eltPattern = tupleElt.getPattern ();
2083
2039
Type eltTy = getTypeForPattern (
2084
2040
eltPattern,
2085
- locator.withPathElement (LocatorPathElt::PatternMatch (eltPattern)),
2086
- bindPatternVarsOneWay);
2041
+ locator.withPathElement (LocatorPathElt::PatternMatch (eltPattern)));
2087
2042
2088
2043
tupleTypeElts.push_back (TupleTypeElt (eltTy, tupleElt.getLabel ()));
2089
2044
}
@@ -2096,8 +2051,7 @@ namespace {
2096
2051
// The subpattern must have optional type.
2097
2052
Type subPatternType = getTypeForPattern (
2098
2053
subPattern,
2099
- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2100
- bindPatternVarsOneWay);
2054
+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
2101
2055
2102
2056
return setType (OptionalType::get (subPatternType));
2103
2057
}
@@ -2127,8 +2081,7 @@ namespace {
2127
2081
if (auto *subPattern = isPattern->getSubPattern ()) {
2128
2082
auto subPatternType = getTypeForPattern (
2129
2083
subPattern,
2130
- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2131
- bindPatternVarsOneWay);
2084
+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
2132
2085
2133
2086
// NOTE: The order here is important! Pattern matching equality is
2134
2087
// not symmetric (we need to fix that either by using a different
@@ -2231,8 +2184,7 @@ namespace {
2231
2184
// types.
2232
2185
Type subPatternType = getTypeForPattern (
2233
2186
subPattern,
2234
- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2235
- bindPatternVarsOneWay);
2187
+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
2236
2188
2237
2189
SmallVector<AnyFunctionType::Param, 4 > params;
2238
2190
decomposeTuple (subPatternType, params);
@@ -3657,7 +3609,7 @@ static bool generateInitPatternConstraints(ConstraintSystem &cs,
3657
3609
Type patternType;
3658
3610
if (auto pattern = target.getInitializationPattern ()) {
3659
3611
patternType = cs.generateConstraints (
3660
- pattern, locator, target. shouldBindPatternVarsOneWay (),
3612
+ pattern, locator,
3661
3613
target.getInitializationPatternBindingDecl (),
3662
3614
target.getInitializationPatternBindingIndex ());
3663
3615
} else {
@@ -3709,7 +3661,6 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
3709
3661
static std::optional<SequenceIterationInfo>
3710
3662
generateForEachStmtConstraints (ConstraintSystem &cs, DeclContext *dc,
3711
3663
ForEachStmt *stmt, Pattern *typeCheckedPattern,
3712
- bool shouldBindPatternVarsOneWay,
3713
3664
bool ignoreForEachWhereClause) {
3714
3665
ASTContext &ctx = cs.getASTContext ();
3715
3666
bool isAsync = stmt->getAwaitLoc ().isValid ();
@@ -3771,8 +3722,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
3771
3722
ctx, StaticSpellingKind::None, pattern, makeIteratorCall, dc);
3772
3723
3773
3724
auto makeIteratorTarget = SyntacticElementTarget::forInitialization (
3774
- makeIteratorCall, /* patternType=*/ Type (), PB, /* index=*/ 0 ,
3775
- /* shouldBindPatternsOneWay=*/ false );
3725
+ makeIteratorCall, /* patternType=*/ Type (), PB, /* index=*/ 0 );
3776
3726
3777
3727
ContextualTypeInfo contextInfo (sequenceProto->getDeclaredInterfaceType (),
3778
3728
CTP_ForEachSequence);
@@ -3867,8 +3817,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
3867
3817
3868
3818
// Generate constraints for the pattern.
3869
3819
Type initType =
3870
- cs.generateConstraints (typeCheckedPattern, elementLocator,
3871
- shouldBindPatternVarsOneWay, nullptr , 0 );
3820
+ cs.generateConstraints (typeCheckedPattern, elementLocator, nullptr , 0 );
3872
3821
if (!initType)
3873
3822
return std::nullopt;
3874
3823
@@ -3938,8 +3887,7 @@ generateForEachPreambleConstraints(ConstraintSystem &cs,
3938
3887
3939
3888
// Generate constraints for the pattern.
3940
3889
Type patternType = cs.generateConstraints (
3941
- pattern, elementLocator, target.shouldBindPatternVarsOneWay (), nullptr ,
3942
- 0 );
3890
+ pattern, elementLocator, nullptr , 0 );
3943
3891
if (!patternType)
3944
3892
return std::nullopt;
3945
3893
@@ -3957,8 +3905,7 @@ generateForEachPreambleConstraints(ConstraintSystem &cs,
3957
3905
target.getForEachStmtInfo () = *packIterationInfo;
3958
3906
} else {
3959
3907
auto sequenceIterationInfo = generateForEachStmtConstraints (
3960
- cs, dc, stmt, pattern, target.shouldBindPatternVarsOneWay (),
3961
- target.ignoreForEachWhereClause ());
3908
+ cs, dc, stmt, pattern, target.ignoreForEachWhereClause ());
3962
3909
if (!sequenceIterationInfo) {
3963
3910
return std::nullopt;
3964
3911
}
@@ -4115,8 +4062,7 @@ bool ConstraintSystem::generateConstraints(
4115
4062
}
4116
4063
4117
4064
auto target = init ? SyntacticElementTarget::forInitialization (
4118
- init, patternType, patternBinding, index ,
4119
- /* bindPatternVarsOneWay=*/ true )
4065
+ init, patternType, patternBinding, index )
4120
4066
: SyntacticElementTarget::forUninitializedVar (
4121
4067
patternBinding, index , patternType);
4122
4068
@@ -4148,7 +4094,7 @@ bool ConstraintSystem::generateConstraints(
4148
4094
// Generate constraints to bind all of the internal declarations
4149
4095
// and verify the pattern.
4150
4096
Type patternType = generateConstraints (
4151
- pattern, locator, /* shouldBindPatternVarsOneWay */ true ,
4097
+ pattern, locator,
4152
4098
target.getPatternBindingOfUninitializedVar (),
4153
4099
target.getIndexOfUninitializedVar ());
4154
4100
@@ -4183,11 +4129,10 @@ Expr *ConstraintSystem::generateConstraints(Expr *expr, DeclContext *dc) {
4183
4129
4184
4130
Type ConstraintSystem::generateConstraints (
4185
4131
Pattern *pattern, ConstraintLocatorBuilder locator,
4186
- bool bindPatternVarsOneWay, PatternBindingDecl *patternBinding,
4132
+ PatternBindingDecl *patternBinding,
4187
4133
unsigned patternIndex) {
4188
4134
ConstraintGenerator cg (*this , nullptr );
4189
- auto ty = cg.getTypeForPattern (pattern, locator, bindPatternVarsOneWay,
4190
- patternBinding, patternIndex);
4135
+ auto ty = cg.getTypeForPattern (pattern, locator, patternBinding, patternIndex);
4191
4136
assert (ty);
4192
4137
4193
4138
// Gather the ExprPatterns, and form a conjunction for their expressions.
@@ -4248,8 +4193,7 @@ bool ConstraintSystem::generateConstraints(StmtCondition condition,
4248
4193
return true ;
4249
4194
4250
4195
auto target = SyntacticElementTarget::forInitialization (
4251
- condElement.getInitializer (), dc, Type (), pattern,
4252
- /* bindPatternVarsOneWay=*/ true );
4196
+ condElement.getInitializer (), dc, Type (), pattern);
4253
4197
if (generateConstraints (target, FreeTypeVariableBinding::Disallow))
4254
4198
return true ;
4255
4199
0 commit comments