Skip to content

Commit a1b113f

Browse files
authored
Merge pull request #6133 from slavapestov/argument-tuple-crap
More correct implementation of SE-0110
2 parents 41d8b2f + dbb9d31 commit a1b113f

File tree

10 files changed

+1459
-148
lines changed

10 files changed

+1459
-148
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2621,9 +2621,6 @@ ERROR(tuple_pattern_in_non_tuple_context,none,
26212621
ERROR(closure_argument_list_tuple,none,
26222622
"contextual closure type %0 expects %1 argument%s1, "
26232623
"but %2 %select{were|was}3 used in closure body", (Type, unsigned, unsigned, bool))
2624-
ERROR(closure_argument_list_single_tuple,none,
2625-
"contextual closure type specifies %0, but %1 %select{was|were}2 used in closure body, "
2626-
"try adding extra parentheses around the single tuple argument", (Type, unsigned, bool))
26272624
ERROR(closure_argument_list_missing,none,
26282625
"contextual type for closure argument list expects %0 argument%s0, "
26292626
"which cannot be implicitly ignored", (unsigned))

lib/Sema/CSApply.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4702,6 +4702,15 @@ Expr *ExprRewriter::coerceCallArguments(
47024702
bool hasTrailingClosure,
47034703
ConstraintLocatorBuilder locator) {
47044704

4705+
// Total hack: In Swift 3 mode, we can end up with an arity mismatch due to
4706+
// loss of ParenType sugar.
4707+
if (cs.getASTContext().isSwiftVersion3()) {
4708+
if (isa<TupleExpr>(arg))
4709+
if (auto *parenType = dyn_cast<ParenType>(paramType.getPointer()))
4710+
if (isa<TupleType>(parenType->getUnderlyingType().getPointer()))
4711+
paramType = parenType->getUnderlyingType();
4712+
}
4713+
47054714
bool allParamsMatch = cs.getType(arg)->isEqual(paramType);
47064715

47074716
// Find the callee declaration.

lib/Sema/CSDiag.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5051,7 +5051,13 @@ static bool diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI,
50515051
TC.Context.SourceMgr, FnExpr->getEndLoc());
50525052
}
50535053
} else {
5054-
llvm_unreachable("unexpected argument expression type");
5054+
// FIXME: Due to a quirk of CSApply, we can end up without a
5055+
// ParenExpr if the argument has an '@lvalue TupleType'.
5056+
assert((isa<TupleType>(ArgExpr->getType().getPointer()) ||
5057+
isa<ParenType>(ArgExpr->getType().getPointer())) &&
5058+
"unexpected argument expression type");
5059+
insertLoc = ArgExpr->getLoc();
5060+
50555061
// Can't be TupleShuffleExpr because this argExpr is not yet resolved.
50565062
}
50575063

lib/Sema/CSSimplify.cpp

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,25 +1210,48 @@ ConstraintSystem::SolutionKind
12101210
ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
12111211
TypeMatchOptions flags,
12121212
ConstraintLocatorBuilder locator) {
1213-
// If we have type variables that have been bound to fixed types, look through
1214-
// to the fixed type.
12151213
bool isArgumentTupleConversion
12161214
= kind == ConstraintKind::ArgumentTupleConversion ||
12171215
kind == ConstraintKind::OperatorArgumentTupleConversion;
1218-
type1 = getFixedTypeRecursive(type1, flags, kind == ConstraintKind::Equal,
1219-
isArgumentTupleConversion);
12201216

1221-
auto desugar1 = type1->getDesugaredType();
1222-
TypeVariableType *typeVar1 = desugar1->getAs<TypeVariableType>();
1217+
// If we're doing an argument tuple conversion, or just matching the input
1218+
// types of two function types, we have to be careful to preserve
1219+
// ParenType sugar.
1220+
bool isArgumentTupleMatch = isArgumentTupleConversion;
1221+
bool isSwiftVersion3 = getASTContext().isSwiftVersion3();
1222+
1223+
// ... but not in Swift 3 mode, where this behavior was broken.
1224+
if (!isSwiftVersion3)
1225+
if (auto elt = locator.last())
1226+
if (elt->getKind() == ConstraintLocator::FunctionArgument)
1227+
isArgumentTupleMatch = true;
12231228

1229+
// If we have type variables that have been bound to fixed types, look through
1230+
// to the fixed type.
1231+
type1 = getFixedTypeRecursive(type1, flags, kind == ConstraintKind::Equal,
1232+
isArgumentTupleMatch);
12241233
type2 = getFixedTypeRecursive(type2, flags, kind == ConstraintKind::Equal,
1225-
isArgumentTupleConversion);
1234+
isArgumentTupleMatch);
1235+
1236+
auto desugar1 = type1->getDesugaredType();
12261237
auto desugar2 = type2->getDesugaredType();
1227-
TypeVariableType *typeVar2 = desugar2->getAs<TypeVariableType>();
1238+
TypeVariableType *typeVar1, *typeVar2;
1239+
if (isArgumentTupleMatch &&
1240+
!isSwiftVersion3) {
1241+
typeVar1 = dyn_cast<TypeVariableType>(type1.getPointer());
1242+
typeVar2 = dyn_cast<TypeVariableType>(type2.getPointer());
1243+
1244+
// If the types are obviously equivalent, we're done.
1245+
if (type1.getPointer() == type2.getPointer())
1246+
return SolutionKind::Solved;
1247+
} else {
1248+
typeVar1 = desugar1->getAs<TypeVariableType>();
1249+
typeVar2 = desugar2->getAs<TypeVariableType>();
12281250

1229-
// If the types are obviously equivalent, we're done.
1230-
if (desugar1->isEqual(desugar2))
1231-
return SolutionKind::Solved;
1251+
// If the types are obviously equivalent, we're done.
1252+
if (desugar1->isEqual(desugar2))
1253+
return SolutionKind::Solved;
1254+
}
12321255

12331256
// Local function that should be used to produce the return value whenever
12341257
// this function was unable to resolve the constraint. It should be used
@@ -1435,12 +1458,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
14351458
}
14361459
}
14371460

1438-
bool isTypeVarOrMember1 = desugar1->isTypeVariableOrMember();
1439-
bool isTypeVarOrMember2 = desugar2->isTypeVariableOrMember();
1440-
1441-
llvm::SmallVector<RestrictionOrFix, 4> conversionsOrFixes;
1442-
bool concrete = !isTypeVarOrMember1 && !isTypeVarOrMember2;
1443-
14441461
// If this is an argument conversion, handle it directly. The rules are
14451462
// different from normal conversions.
14461463
if (kind == ConstraintKind::ArgumentTupleConversion ||
@@ -1452,6 +1469,22 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
14521469
return formUnsolvedResult();
14531470
}
14541471

1472+
if (isArgumentTupleMatch &&
1473+
!isSwiftVersion3) {
1474+
if (!typeVar1 && !typeVar2) {
1475+
if (isa<ParenType>(type1.getPointer()) !=
1476+
isa<ParenType>(type2.getPointer())) {
1477+
return SolutionKind::Error;
1478+
}
1479+
}
1480+
}
1481+
1482+
bool isTypeVarOrMember1 = desugar1->isTypeVariableOrMember();
1483+
bool isTypeVarOrMember2 = desugar2->isTypeVariableOrMember();
1484+
1485+
llvm::SmallVector<RestrictionOrFix, 4> conversionsOrFixes;
1486+
bool concrete = !isTypeVarOrMember1 && !isTypeVarOrMember2;
1487+
14551488
// Decompose parallel structure.
14561489
TypeMatchOptions subflags =
14571490
getDefaultDecompositionOptions(flags) - TMF_ApplyingFix;

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,24 +1500,6 @@ bool TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
15001500
convertType.getType()->hasUnresolvedType())) {
15011501
convertType = TypeLoc();
15021502
convertTypePurpose = CTP_Unused;
1503-
} else if (auto closure = dyn_cast<ClosureExpr>(expr)) {
1504-
auto *P = closure->getParameters();
1505-
1506-
if (P->size() == 1 && convertType.getType()->is<FunctionType>()) {
1507-
auto hintFnType = convertType.getType()->castTo<FunctionType>();
1508-
auto hintFnInputType = hintFnType->getInput();
1509-
1510-
// Cannot use hintFnInputType->is<TupleType>() since it would desugar ParenType
1511-
if (isa<TupleType>(hintFnInputType.getPointer())) {
1512-
TupleType *tupleTy = hintFnInputType->castTo<TupleType>();
1513-
1514-
if (tupleTy->getNumElements() >= 2) {
1515-
diagnose(P->getStartLoc(), diag::closure_argument_list_single_tuple,
1516-
hintFnInputType, P->size(), P->size() > 1);
1517-
return true;
1518-
}
1519-
}
1520-
}
15211503
}
15221504
}
15231505

0 commit comments

Comments
 (0)