@@ -1802,14 +1802,8 @@ namespace {
18021802 // /
18031803 // / \param locator The locator to use for generated constraints and
18041804 // / 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.
18101805 Type getTypeForPattern (
18111806 Pattern *pattern, ConstraintLocatorBuilder locator,
1812- bool bindPatternVarsOneWay,
18131807 PatternBindingDecl *patternBinding = nullptr ,
18141808 unsigned patternBindingIndex = 0 ) {
18151809 assert (pattern);
@@ -1828,15 +1822,13 @@ namespace {
18281822 auto *subPattern = paren->getSubPattern ();
18291823 auto underlyingType = getTypeForPattern (
18301824 subPattern,
1831- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
1832- bindPatternVarsOneWay);
1825+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
18331826
18341827 return setType (underlyingType);
18351828 }
18361829 case PatternKind::Binding: {
18371830 auto *subPattern = cast<BindingPattern>(pattern)->getSubPattern ();
1838- auto type = getTypeForPattern (subPattern, locator,
1839- bindPatternVarsOneWay);
1831+ auto type = getTypeForPattern (subPattern, locator);
18401832 // Var doesn't affect the type.
18411833 return setType (type);
18421834 }
@@ -1932,100 +1924,65 @@ namespace {
19321924 var->getNameStr ().starts_with (" $__builder" );
19331925 };
19341926
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));
20101967 }
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));
20211968 }
1969+ return std::nullopt ;
1970+ });
20221971
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));
20271979 }
20281980
1981+ if (useLocatableTypes ())
1982+ declTy = makeTypeLocatableIfPossible (declTy);
1983+
1984+ CS.setType (var, declTy);
1985+
20291986 return setType (varType);
20301987 }
20311988
@@ -2053,8 +2010,7 @@ namespace {
20532010 // ascribed type.
20542011 Type subPatternType = getTypeForPattern (
20552012 subPattern,
2056- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2057- bindPatternVarsOneWay);
2013+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
20582014
20592015 // NOTE: The order here is important! Pattern matching equality is
20602016 // not symmetric (we need to fix that either by using a different
@@ -2082,8 +2038,7 @@ namespace {
20822038 auto *eltPattern = tupleElt.getPattern ();
20832039 Type eltTy = getTypeForPattern (
20842040 eltPattern,
2085- locator.withPathElement (LocatorPathElt::PatternMatch (eltPattern)),
2086- bindPatternVarsOneWay);
2041+ locator.withPathElement (LocatorPathElt::PatternMatch (eltPattern)));
20872042
20882043 tupleTypeElts.push_back (TupleTypeElt (eltTy, tupleElt.getLabel ()));
20892044 }
@@ -2096,8 +2051,7 @@ namespace {
20962051 // The subpattern must have optional type.
20972052 Type subPatternType = getTypeForPattern (
20982053 subPattern,
2099- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2100- bindPatternVarsOneWay);
2054+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
21012055
21022056 return setType (OptionalType::get (subPatternType));
21032057 }
@@ -2127,8 +2081,7 @@ namespace {
21272081 if (auto *subPattern = isPattern->getSubPattern ()) {
21282082 auto subPatternType = getTypeForPattern (
21292083 subPattern,
2130- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2131- bindPatternVarsOneWay);
2084+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
21322085
21332086 // NOTE: The order here is important! Pattern matching equality is
21342087 // not symmetric (we need to fix that either by using a different
@@ -2231,8 +2184,7 @@ namespace {
22312184 // types.
22322185 Type subPatternType = getTypeForPattern (
22332186 subPattern,
2234- locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2235- bindPatternVarsOneWay);
2187+ locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)));
22362188
22372189 SmallVector<AnyFunctionType::Param, 4 > params;
22382190 decomposeTuple (subPatternType, params);
@@ -3657,7 +3609,7 @@ static bool generateInitPatternConstraints(ConstraintSystem &cs,
36573609 Type patternType;
36583610 if (auto pattern = target.getInitializationPattern ()) {
36593611 patternType = cs.generateConstraints (
3660- pattern, locator, target. shouldBindPatternVarsOneWay (),
3612+ pattern, locator,
36613613 target.getInitializationPatternBindingDecl (),
36623614 target.getInitializationPatternBindingIndex ());
36633615 } else {
@@ -3709,7 +3661,6 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
37093661static std::optional<SequenceIterationInfo>
37103662generateForEachStmtConstraints (ConstraintSystem &cs, DeclContext *dc,
37113663 ForEachStmt *stmt, Pattern *typeCheckedPattern,
3712- bool shouldBindPatternVarsOneWay,
37133664 bool ignoreForEachWhereClause) {
37143665 ASTContext &ctx = cs.getASTContext ();
37153666 bool isAsync = stmt->getAwaitLoc ().isValid ();
@@ -3771,8 +3722,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
37713722 ctx, StaticSpellingKind::None, pattern, makeIteratorCall, dc);
37723723
37733724 auto makeIteratorTarget = SyntacticElementTarget::forInitialization (
3774- makeIteratorCall, /* patternType=*/ Type (), PB, /* index=*/ 0 ,
3775- /* shouldBindPatternsOneWay=*/ false );
3725+ makeIteratorCall, /* patternType=*/ Type (), PB, /* index=*/ 0 );
37763726
37773727 ContextualTypeInfo contextInfo (sequenceProto->getDeclaredInterfaceType (),
37783728 CTP_ForEachSequence);
@@ -3867,8 +3817,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs, DeclContext *dc,
38673817
38683818 // Generate constraints for the pattern.
38693819 Type initType =
3870- cs.generateConstraints (typeCheckedPattern, elementLocator,
3871- shouldBindPatternVarsOneWay, nullptr , 0 );
3820+ cs.generateConstraints (typeCheckedPattern, elementLocator, nullptr , 0 );
38723821 if (!initType)
38733822 return std::nullopt ;
38743823
@@ -3938,8 +3887,7 @@ generateForEachPreambleConstraints(ConstraintSystem &cs,
39383887
39393888 // Generate constraints for the pattern.
39403889 Type patternType = cs.generateConstraints (
3941- pattern, elementLocator, target.shouldBindPatternVarsOneWay (), nullptr ,
3942- 0 );
3890+ pattern, elementLocator, nullptr , 0 );
39433891 if (!patternType)
39443892 return std::nullopt ;
39453893
@@ -3957,8 +3905,7 @@ generateForEachPreambleConstraints(ConstraintSystem &cs,
39573905 target.getForEachStmtInfo () = *packIterationInfo;
39583906 } else {
39593907 auto sequenceIterationInfo = generateForEachStmtConstraints (
3960- cs, dc, stmt, pattern, target.shouldBindPatternVarsOneWay (),
3961- target.ignoreForEachWhereClause ());
3908+ cs, dc, stmt, pattern, target.ignoreForEachWhereClause ());
39623909 if (!sequenceIterationInfo) {
39633910 return std::nullopt ;
39643911 }
@@ -4115,8 +4062,7 @@ bool ConstraintSystem::generateConstraints(
41154062 }
41164063
41174064 auto target = init ? SyntacticElementTarget::forInitialization (
4118- init, patternType, patternBinding, index,
4119- /* bindPatternVarsOneWay=*/ true )
4065+ init, patternType, patternBinding, index)
41204066 : SyntacticElementTarget::forUninitializedVar (
41214067 patternBinding, index, patternType);
41224068
@@ -4148,7 +4094,7 @@ bool ConstraintSystem::generateConstraints(
41484094 // Generate constraints to bind all of the internal declarations
41494095 // and verify the pattern.
41504096 Type patternType = generateConstraints (
4151- pattern, locator, /* shouldBindPatternVarsOneWay */ true ,
4097+ pattern, locator,
41524098 target.getPatternBindingOfUninitializedVar (),
41534099 target.getIndexOfUninitializedVar ());
41544100
@@ -4183,11 +4129,10 @@ Expr *ConstraintSystem::generateConstraints(Expr *expr, DeclContext *dc) {
41834129
41844130Type ConstraintSystem::generateConstraints (
41854131 Pattern *pattern, ConstraintLocatorBuilder locator,
4186- bool bindPatternVarsOneWay, PatternBindingDecl *patternBinding,
4132+ PatternBindingDecl *patternBinding,
41874133 unsigned patternIndex) {
41884134 ConstraintGenerator cg (*this , nullptr );
4189- auto ty = cg.getTypeForPattern (pattern, locator, bindPatternVarsOneWay,
4190- patternBinding, patternIndex);
4135+ auto ty = cg.getTypeForPattern (pattern, locator, patternBinding, patternIndex);
41914136 assert (ty);
41924137
41934138 // Gather the ExprPatterns, and form a conjunction for their expressions.
@@ -4248,8 +4193,7 @@ bool ConstraintSystem::generateConstraints(StmtCondition condition,
42484193 return true ;
42494194
42504195 auto target = SyntacticElementTarget::forInitialization (
4251- condElement.getInitializer (), dc, Type (), pattern,
4252- /* bindPatternVarsOneWay=*/ true );
4196+ condElement.getInitializer (), dc, Type (), pattern);
42534197 if (generateConstraints (target, FreeTypeVariableBinding::Disallow))
42544198 return true ;
42554199
0 commit comments