mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix a couple of common crashers related to functions with default arguments. (rdar://problem/21799331 and rdar://problem/21643052, plus dupes.)
If a function declaration possessed default parameters, and was invoked with a single argument expression that was modeled as a type variable, the compiler would often crash during type application. This was due to the fact that during simplification, we would bind the type variable to the full tuple type of the parameter list. Later on, during constraint application, we would then look to whatever expression created the type variable for information on its default arguments - even if no such thing was possible. (E.g., we would examine, say, an IfExpr expecting to find information on its default arguments.) In these cases, we should have instead been binding the argument type variable to the first element of the parameter tuple. Swift SVN r30486
This commit is contained in:
@@ -1392,12 +1392,41 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
|
||||
return SolutionKind::Solved;
|
||||
}
|
||||
|
||||
// We need to be careful about mapping 'raw' argument type variables to
|
||||
// parameter tuples containing default args. If we naively bind the type
|
||||
// variable to the parameter tuple, we'll later end up looking to whatever
|
||||
// expression created the type variable to find the declarations for default
|
||||
// arguments. This can obviously be problematic if the expression in
|
||||
// question is not an application. (For example, We don't want to introspect
|
||||
// an 'if' expression to see if it has default arguments.) Instead, we
|
||||
// should bind the type variable to the first element type of the tuple.
|
||||
case TypeMatchKind::ArgumentTupleConversion:
|
||||
if (typeVar1 &&
|
||||
!typeVar1->getImpl().literalConformanceProto &&
|
||||
kind == TypeMatchKind::ArgumentTupleConversion &&
|
||||
(flags & TMF_GenerateConstraints) &&
|
||||
dyn_cast<ParenType>(type1.getPointer())) {
|
||||
|
||||
auto tupleTy = type2->getAs<TupleType>();
|
||||
|
||||
if (tupleTy &&
|
||||
tupleTy->getElementTypes().size() > 1 &&
|
||||
tupleTy->hasAnyDefaultValues()) {
|
||||
|
||||
addConstraint(getConstraintKind(kind),
|
||||
typeVar1,
|
||||
tupleTy->getElementType(0),
|
||||
getConstraintLocator(locator));
|
||||
return SolutionKind::Solved;
|
||||
}
|
||||
}
|
||||
SWIFT_FALLTHROUGH;
|
||||
|
||||
case TypeMatchKind::ConformsTo:
|
||||
case TypeMatchKind::Subtype:
|
||||
case TypeMatchKind::Conversion:
|
||||
case TypeMatchKind::ExplicitConversion:
|
||||
case TypeMatchKind::ArgumentConversion:
|
||||
case TypeMatchKind::ArgumentTupleConversion:
|
||||
case TypeMatchKind::OperatorArgumentTupleConversion:
|
||||
case TypeMatchKind::OperatorArgumentConversion:
|
||||
if (flags & TMF_GenerateConstraints) {
|
||||
|
||||
Reference in New Issue
Block a user