Merge pull request #7100 from slavapestov/fix-type-join-metatype-3.1
AST: Fix Type::join() to do the right thing with class metatypes [3.1]
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index abb45a5..fe32923 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -680,11 +680,11 @@
static bool rangeContainsPlaceholderEnd(const char *CurPtr,
const char *End) {
- while (CurPtr++ < End - 1) {
- if (*CurPtr== '\n') {
+ for (auto SubStr = CurPtr; SubStr != End - 1; ++SubStr) {
+ if (SubStr[0] == '\n') {
return false;
}
- if (CurPtr[0] == '#' && CurPtr[1] == '>') {
+ if (SubStr[0] == '#' && SubStr[1] == '>') {
return true;
}
}
@@ -710,7 +710,7 @@
// started with a '.'.
if (*CurPtr == '.' && *TokStart != '.')
break;
- if (Identifier::isEditorPlaceholder(StringRef(CurPtr, 2)) &&
+ if (Identifier::isEditorPlaceholder(StringRef(CurPtr, BufferEnd-CurPtr)) &&
rangeContainsPlaceholderEnd(CurPtr + 2, BufferEnd)) {
break;
}
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index ad1c660..4073c77 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -7243,7 +7243,7 @@
// Form a reference to the witness itself.
Type openedFullType, openedType;
std::tie(openedFullType, openedType)
- = cs.getTypeOfMemberReference(base->getType(), witness,
+ = cs.getTypeOfMemberReference(base->getType(), witness, dc,
/*isTypeReference=*/false,
/*isDynamicResult=*/false,
FunctionRefKind::DoubleApply,
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 229ff13..a0f7585 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1019,6 +1019,8 @@
namespace {
class ConstraintGenerator : public ExprVisitor<ConstraintGenerator, Type> {
ConstraintSystem &CS;
+ DeclContext *CurDC;
+ SmallVector<DeclContext*, 4> DCStack;
/// \brief Add constraints for a reference to a named member of the given
/// base type, and return the type of such a reference.
@@ -1031,7 +1033,7 @@
auto tv = CS.createTypeVariable(
CS.getConstraintLocator(expr, ConstraintLocator::Member),
TVO_CanBindToLValue);
- CS.addValueMemberConstraint(baseTy, name, tv, functionRefKind,
+ CS.addValueMemberConstraint(baseTy, name, tv, CurDC, functionRefKind,
CS.getConstraintLocator(expr, ConstraintLocator::Member));
return tv;
}
@@ -1055,7 +1057,7 @@
OverloadChoice choice(CS.getType(base), decl, /*isSpecialized=*/false,
functionRefKind);
auto locator = CS.getConstraintLocator(expr, ConstraintLocator::Member);
- CS.addBindOverloadConstraint(tv, choice, locator);
+ CS.addBindOverloadConstraint(tv, choice, locator, CurDC);
return tv;
}
@@ -1153,10 +1155,11 @@
if (decl) {
OverloadChoice choice(baseTy, decl, /*isSpecialized=*/false,
FunctionRefKind::DoubleApply);
- CS.addBindOverloadConstraint(fnTy, choice, subscriptMemberLocator);
+ CS.addBindOverloadConstraint(fnTy, choice, subscriptMemberLocator,
+ CurDC);
} else {
CS.addValueMemberConstraint(baseTy, Context.Id_subscript,
- fnTy, FunctionRefKind::DoubleApply,
+ fnTy, CurDC, FunctionRefKind::DoubleApply,
subscriptMemberLocator);
}
@@ -1168,10 +1171,26 @@
}
public:
- ConstraintGenerator(ConstraintSystem &CS) : CS(CS) { }
- virtual ~ConstraintGenerator() = default;
+ ConstraintGenerator(ConstraintSystem &CS) : CS(CS), CurDC(CS.DC) { }
+ virtual ~ConstraintGenerator() {
+ // We really ought to have this assertion:
+ // assert(DCStack.empty() && CurDC == CS.DC);
+ // Unfortunately, ASTWalker is really bad at letting us establish
+ // invariants like this because walkToExprPost isn't called if
+ // something early-aborts the walk.
+ }
ConstraintSystem &getConstraintSystem() const { return CS; }
+
+ void enterClosure(ClosureExpr *closure) {
+ DCStack.push_back(CurDC);
+ CurDC = closure;
+ }
+
+ void exitClosure(ClosureExpr *closure) {
+ assert(CurDC == closure);
+ CurDC = DCStack.pop_back_val();
+ }
virtual Type visitErrorExpr(ErrorExpr *E) {
// FIXME: Can we do anything with error expressions at this point?
@@ -1238,7 +1257,7 @@
segmentTyV, locator);
DeclName segmentName(C, C.Id_init, { C.Id_stringInterpolationSegment });
- CS.addValueMemberConstraint(tvMeta, segmentName, methodTy,
+ CS.addValueMemberConstraint(tvMeta, segmentName, methodTy, CurDC,
FunctionRefKind::DoubleApply, locator);
}
@@ -1347,7 +1366,8 @@
CS.resolveOverload(locator, tv,
OverloadChoice(Type(), E->getDecl(),
E->isSpecialized(),
- E->getFunctionRefKind()));
+ E->getFunctionRefKind()),
+ CurDC);
if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
if (VD->getInterfaceType() &&
@@ -1427,7 +1447,7 @@
return nullptr;
// Record this overload set.
- CS.addOverloadSet(tv, choices, locator);
+ CS.addOverloadSet(tv, choices, CurDC, locator);
return tv;
}
@@ -1473,7 +1493,7 @@
// member, i.e., an enum case or a static variable.
auto baseMetaTy = MetatypeType::get(baseTy);
CS.addUnresolvedValueMemberConstraint(baseMetaTy, expr->getName(),
- memberTy, functionRefKind,
+ memberTy, CurDC, functionRefKind,
memberLocator);
// If there is an argument, apply it.
@@ -1534,7 +1554,7 @@
/*options=*/0);
auto methodTy = FunctionType::get(argsTy, resultTy);
CS.addValueMemberConstraint(baseTy, expr->getName(),
- methodTy, expr->getFunctionRefKind(),
+ methodTy, CurDC, expr->getFunctionRefKind(),
CS.getConstraintLocator(expr, ConstraintLocator::ConstructorMember));
// The result of the expression is the partial application of the
@@ -2887,6 +2907,8 @@
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
auto &CS = CG.getConstraintSystem();
if (closure->hasSingleExpressionBody()) {
+ CG.enterClosure(closure);
+
// Visit the closure itself, which produces a function type.
auto funcTy = CG.visit(expr)->castTo<FunctionType>();
CS.setType(expr, funcTy);
@@ -2912,6 +2934,8 @@
Expr *walkToExprPost(Expr *expr) override {
if (auto closure = dyn_cast<ClosureExpr>(expr)) {
if (closure->hasSingleExpressionBody()) {
+ CG.exitClosure(closure);
+
auto &CS = CG.getConstraintSystem();
Type closureTy = CS.getType(closure);
@@ -3311,7 +3335,7 @@
return Result;
ConstraintLocator *Locator = CS.getConstraintLocator(nullptr);
TypeVariableType *TV = CS.createTypeVariable(Locator, TVO_CanBindToLValue);
- CS.addOverloadSet(TV, LookupResult.ViableCandidates, Locator);
+ CS.addOverloadSet(TV, LookupResult.ViableCandidates, &DC, Locator);
Optional<Solution> OpSolution = CS.solveSingle();
if (!OpSolution.hasValue())
return Result;
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 432781a..3e4e4a5 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -653,6 +653,21 @@
getCalleeDeclAndArgs(cs, locator, argLabelsScratch);
auto params = decomposeParamType(paramType, callee, calleeLevel);
+ if (callee && cs.getASTContext().isSwiftVersion3()
+ && argType->is<TupleType>()) {
+ // Hack: In Swift 3 mode, accept `foo(x, y)` for `foo((x, y))` when the
+ // callee is a function-typed property or an enum constructor whose
+ // argument is a single unlabeled type parameter.
+ if (auto *prop = dyn_cast<VarDecl>(callee)) {
+ auto *fnType = prop->getInterfaceType()->getAs<AnyFunctionType>();
+ if (fnType && fnType->getInput()->isTypeParameter())
+ argType = ParenType::get(cs.getASTContext(), argType);
+ } else if (auto *enumCtor = dyn_cast<EnumElementDecl>(callee)) {
+ if (enumCtor->getArgumentInterfaceType()->isTypeParameter())
+ argType = ParenType::get(cs.getASTContext(), argType);
+ }
+ }
+
// Extract the arguments.
auto args = decomposeArgType(argType, argLabels);
@@ -1258,8 +1273,6 @@
// Obviously, this must not happen at the top level, or the
// algorithm would not terminate.
addUnsolvedConstraint(Constraint::create(*this, kind, type1, type2,
- DeclName(),
- FunctionRefKind::Compound,
getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -2182,6 +2195,7 @@
ConstraintSystem::SolutionKind
ConstraintSystem::simplifyConstructionConstraint(
Type valueType, FunctionType *fnType, TypeMatchOptions flags,
+ DeclContext *useDC,
FunctionRefKind functionRefKind, ConstraintLocator *locator) {
// Desugar the value type.
@@ -2256,9 +2270,9 @@
}
NameLookupOptions lookupOptions = defaultConstructorLookupOptions;
- if (isa<AbstractFunctionDecl>(DC))
+ if (isa<AbstractFunctionDecl>(useDC))
lookupOptions |= NameLookupFlags::KnownPrivate;
- auto ctors = TC.lookupConstructors(DC, valueType, lookupOptions);
+ auto ctors = TC.lookupConstructors(useDC, valueType, lookupOptions);
if (!ctors)
return SolutionKind::Error;
@@ -2275,7 +2289,8 @@
// variable T. T2 is the result type provided via the construction
// constraint itself.
addValueMemberConstraint(MetatypeType::get(valueType, TC.Context), name,
- FunctionType::get(tv, resultType), functionRefKind,
+ FunctionType::get(tv, resultType),
+ useDC, functionRefKind,
getConstraintLocator(
fnLocator,
ConstraintLocator::ConstructorMember));
@@ -2317,7 +2332,6 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, kind, type, protocol->getDeclaredType(),
- DeclName(), FunctionRefKind::Compound,
getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -2410,8 +2424,7 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, ConstraintKind::CheckedCast, fromType,
- toType, DeclName(), FunctionRefKind::Compound,
- getConstraintLocator(locator)));
+ toType, getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -2541,8 +2554,7 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, ConstraintKind::OptionalObject, optLValueTy,
- second, DeclName(), FunctionRefKind::Compound,
- getConstraintLocator(locator)));
+ second, getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -3110,6 +3122,7 @@
ConstraintSystem::simplifyMemberConstraint(ConstraintKind kind,
Type baseTy, DeclName member,
Type memberTy,
+ DeclContext *useDC,
FunctionRefKind functionRefKind,
TypeMatchOptions flags,
ConstraintLocatorBuilder locatorB) {
@@ -3141,8 +3154,8 @@
// If requested, generate a constraint.
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
- Constraint::create(*this, kind, baseTy, memberTy, member,
- functionRefKind, locator));
+ Constraint::createMember(*this, kind, baseTy, memberTy, member, useDC,
+ functionRefKind, locator));
return SolutionKind::Solved;
}
@@ -3158,7 +3171,7 @@
// If we found viable candidates, then we're done!
if (!result.ViableCandidates.empty()) {
- addOverloadSet(memberTy, result.ViableCandidates, locator,
+ addOverloadSet(memberTy, result.ViableCandidates, useDC, locator,
result.getFavoredChoice());
return SolutionKind::Solved;
@@ -3196,7 +3209,7 @@
// Look through one level of optional.
addValueMemberConstraint(baseObjTy->getOptionalObjectType(),
- member, memberTy, functionRefKind, locator);
+ member, memberTy, useDC, functionRefKind, locator);
return SolutionKind::Solved;
}
return SolutionKind::Error;
@@ -3213,7 +3226,6 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, ConstraintKind::Defaultable, first, second,
- DeclName(), FunctionRefKind::Compound,
getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -3238,7 +3250,6 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, ConstraintKind::DynamicTypeOf, type1, type2,
- DeclName(), FunctionRefKind::Compound,
getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -3300,8 +3311,7 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, ConstraintKind::BridgingConversion, type1,
- type2, DeclName(), FunctionRefKind::Compound,
- getConstraintLocator(locator)));
+ type2, getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -3527,9 +3537,7 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, ConstraintKind::EscapableFunctionOf,
- type1, type2,
- DeclName(), FunctionRefKind::Compound,
- getConstraintLocator(locator)));
+ type1, type2, getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -3602,8 +3610,7 @@
if (flags.contains(TMF_GenerateConstraints)) {
addUnsolvedConstraint(
Constraint::create(*this, ConstraintKind::ApplicableFunction, type1,
- type2, DeclName(), FunctionRefKind::Compound,
- getConstraintLocator(locator)));
+ type2, getConstraintLocator(locator)));
return SolutionKind::Solved;
}
@@ -3673,6 +3680,7 @@
// Construct the instance from the input arguments.
return simplifyConstructionConstraint(instance2, func1, subflags,
+ /*FIXME?*/ DC,
FunctionRefKind::SingleApply,
getConstraintLocator(outerLocator));
}
@@ -3889,18 +3897,12 @@
if (flags.contains(TMF_GenerateConstraints)) {
auto int8Con = Constraint::create(*this, ConstraintKind::Bind,
baseType2, TC.getInt8Type(DC),
- DeclName(),
- FunctionRefKind::Compound,
getConstraintLocator(locator));
auto uint8Con = Constraint::create(*this, ConstraintKind::Bind,
baseType2, TC.getUInt8Type(DC),
- DeclName(),
- FunctionRefKind::Compound,
getConstraintLocator(locator));
auto voidCon = Constraint::create(*this, ConstraintKind::Bind,
baseType2, TC.Context.TheEmptyTupleType,
- DeclName(),
- FunctionRefKind::Compound,
getConstraintLocator(locator));
Constraint *disjunctionChoices[] = {int8Con, uint8Con, voidCon};
@@ -4229,8 +4231,7 @@
case SolutionKind::Error:
// Add a failing constraint, if needed.
if (shouldAddNewFailingConstraint()) {
- auto c = Constraint::create(*this, kind, first, second, DeclName(),
- FunctionRefKind::Compound,
+ auto c = Constraint::create(*this, kind, first, second,
getConstraintLocator(locator));
if (isFavored) c->setFavored();
addNewFailingConstraint(c);
@@ -4256,9 +4257,7 @@
// Coercion (the common case).
Constraint *coerceConstraint =
Constraint::create(*this, ConstraintKind::Conversion,
- fromType, toType, DeclName(),
- FunctionRefKind::Compound,
- locatorPtr);
+ fromType, toType, locatorPtr);
coerceConstraint->setFavored();
constraints.push_back(coerceConstraint);
@@ -4267,9 +4266,7 @@
// The source type can be explicitly converted to the destination type.
Constraint *bridgingConstraint =
Constraint::create(*this, ConstraintKind::BridgingConversion,
- fromType, toType, DeclName(),
- FunctionRefKind::Compound,
- locatorPtr);
+ fromType, toType, locatorPtr);
constraints.push_back(bridgingConstraint);
}
@@ -4347,7 +4344,8 @@
case ConstraintKind::BindOverload:
resolveOverload(constraint.getLocator(), constraint.getFirstType(),
- constraint.getOverloadChoice());
+ constraint.getOverloadChoice(),
+ constraint.getOverloadUseDC());
return SolutionKind::Solved;
case ConstraintKind::ConformsTo:
@@ -4391,6 +4389,7 @@
constraint.getFirstType(),
constraint.getMember(),
constraint.getSecondType(),
+ constraint.getMemberUseDC(),
constraint.getFunctionRefKind(),
TMF_GenerateConstraints,
constraint.getLocator());
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index bdd20c6..88689f6 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1641,6 +1641,24 @@
return { true, expr };
}
+ /// Determine whether this is an arithmetic expression comprised entirely
+ /// of literals.
+ static bool isArithmeticExprOfLiterals(Expr *expr) {
+ expr = expr->getSemanticsProvidingExpr();
+
+ if (auto prefix = dyn_cast<PrefixUnaryExpr>(expr))
+ return isArithmeticExprOfLiterals(prefix->getArg());
+
+ if (auto postfix = dyn_cast<PostfixUnaryExpr>(expr))
+ return isArithmeticExprOfLiterals(postfix->getArg());
+
+ if (auto binary = dyn_cast<BinaryExpr>(expr))
+ return isArithmeticExprOfLiterals(binary->getArg()->getElement(0)) &&
+ isArithmeticExprOfLiterals(binary->getArg()->getElement(1));
+
+ return isa<IntegerLiteralExpr>(expr) || isa<FloatLiteralExpr>(expr);
+ }
+
Expr *walkToExprPost(Expr *expr) override {
if (expr == PrimaryExpr) {
// If this is primary expression and there are no candidates
@@ -1688,7 +1706,7 @@
// If there are fewer than two overloads in the chain
// there is no point of solving this expression,
// because we won't be able to reduce its domain.
- if (numOverloadSets > 1)
+ if (numOverloadSets > 1 && !isArithmeticExprOfLiterals(expr))
Candidates.push_back(Candidate(CS, expr));
return expr;
diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp
index e94515c..2a10aa3 100644
--- a/lib/Sema/Constraint.cpp
+++ b/lib/Sema/Constraint.cpp
@@ -40,16 +40,12 @@
}
Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
- DeclName Member, FunctionRefKind functionRefKind,
ConstraintLocator *locator,
ArrayRef<TypeVariableType *> typeVars)
: Kind(Kind), HasRestriction(false), HasFix(false), IsActive(false),
RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()),
- Types { First, Second, Member }, Locator(locator)
+ Types { First, Second }, Locator(locator)
{
- TheFunctionRefKind = static_cast<unsigned>(functionRefKind);
- assert(getFunctionRefKind() == functionRefKind);
-
switch (Kind) {
case ConstraintKind::Bind:
case ConstraintKind::Equal:
@@ -72,23 +68,19 @@
case ConstraintKind::OptionalObject:
assert(!First.isNull());
assert(!Second.isNull());
- assert(!Member && "Relational constraint cannot have a member");
break;
case ConstraintKind::ApplicableFunction:
assert(First->is<FunctionType>()
&& "The left-hand side type should be a function type");
- assert(!Member && "Relational constraint cannot have a member");
break;
case ConstraintKind::ValueMember:
case ConstraintKind::UnresolvedValueMember:
- assert(Member && "Member constraint has no member");
- break;
+ llvm_unreachable("Wrong constructor for member constraint");
case ConstraintKind::Defaultable:
assert(!First.isNull());
assert(!Second.isNull());
- assert(!Member && "Defaultable constraint cannot have a member");
break;
case ConstraintKind::BindOverload:
@@ -101,13 +93,32 @@
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
}
-Constraint::Constraint(Type type, OverloadChoice choice,
+Constraint::Constraint(ConstraintKind kind, Type first, Type second,
+ DeclName member, DeclContext *useDC,
+ FunctionRefKind functionRefKind,
+ ConstraintLocator *locator,
+ ArrayRef<TypeVariableType *> typeVars)
+ : Kind(kind), HasRestriction(false), HasFix(false), IsActive(false),
+ RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()),
+ Member { first, second, member, useDC }, Locator(locator)
+{
+ assert(kind == ConstraintKind::ValueMember ||
+ kind == ConstraintKind::UnresolvedValueMember);
+ TheFunctionRefKind = static_cast<unsigned>(functionRefKind);
+ assert(getFunctionRefKind() == functionRefKind);
+ assert(member && "Member constraint has no member");
+ assert(useDC && "Member constraint has no use DC");
+
+ std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
+}
+
+Constraint::Constraint(Type type, OverloadChoice choice, DeclContext *useDC,
ConstraintLocator *locator,
ArrayRef<TypeVariableType *> typeVars)
: Kind(ConstraintKind::BindOverload),
HasRestriction(false), HasFix(false), IsActive(false),
RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()),
- Overload{type, choice}, Locator(locator)
+ Overload{type, choice, useDC}, Locator(locator)
{
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
}
@@ -119,7 +130,7 @@
: Kind(kind), Restriction(restriction),
HasRestriction(true), HasFix(false), IsActive(false),
RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()),
- Types{ first, second, Identifier() }, Locator(locator)
+ Types{ first, second }, Locator(locator)
{
assert(!first.isNull());
assert(!second.isNull());
@@ -133,7 +144,7 @@
HasRestriction(false), HasFix(true),
IsActive(false), RememberChoice(false), IsFavored(false),
NumTypeVariables(typeVars.size()),
- Types{ first, second, Identifier() }, Locator(locator)
+ Types{ first, second }, Locator(locator)
{
assert(!first.isNull());
assert(!second.isNull());
@@ -170,21 +181,18 @@
case ConstraintKind::SelfObjectOfProtocol:
case ConstraintKind::ApplicableFunction:
case ConstraintKind::OptionalObject:
- return create(cs, getKind(), getFirstType(), getSecondType(),
- DeclName(), FunctionRefKind::Compound, getLocator());
+ case ConstraintKind::Defaultable:
+ return create(cs, getKind(), getFirstType(), getSecondType(), getLocator());
case ConstraintKind::BindOverload:
return createBindOverload(cs, getFirstType(), getOverloadChoice(),
- getLocator());
+ getOverloadUseDC(), getLocator());
case ConstraintKind::ValueMember:
case ConstraintKind::UnresolvedValueMember:
- return create(cs, getKind(), getFirstType(), getSecondType(), getMember(),
- getFunctionRefKind(), getLocator());
-
- case ConstraintKind::Defaultable:
- return create(cs, getKind(), getFirstType(), getSecondType(),
- getMember(), getFunctionRefKind(), getLocator());
+ return createMember(cs, getKind(), getFirstType(), getSecondType(),
+ getMember(), getMemberUseDC(), getFunctionRefKind(),
+ getLocator());
case ConstraintKind::Disjunction:
return createDisjunction(cs, getNestedConstraints(), getLocator());
@@ -218,7 +226,7 @@
return;
}
- Types.First->print(Out);
+ getFirstType()->print(Out);
bool skipSecond = false;
@@ -293,10 +301,10 @@
}
case ConstraintKind::ValueMember:
- Out << "[." << Types.Member << ": value] == ";
+ Out << "[." << Member.Member << ": value] == ";
break;
case ConstraintKind::UnresolvedValueMember:
- Out << "[(implicit) ." << Types.Member << ": value] == ";
+ Out << "[(implicit) ." << Member.Member << ": value] == ";
break;
case ConstraintKind::Defaultable:
Out << " can default to ";
@@ -306,7 +314,7 @@
}
if (!skipSecond)
- Types.Second->print(Out);
+ getSecondType()->print(Out);
if (auto restriction = getRestriction()) {
Out << ' ' << getName(*restriction);
@@ -504,8 +512,7 @@
}
Constraint *Constraint::create(ConstraintSystem &cs, ConstraintKind kind,
- Type first, Type second, DeclName member,
- FunctionRefKind functionRefKind,
+ Type first, Type second,
ConstraintLocator *locator) {
// Collect type variables.
SmallVector<TypeVariableType *, 4> typeVars;
@@ -524,12 +531,32 @@
// Create the constraint.
unsigned size = totalSizeToAlloc<TypeVariableType*>(typeVars.size());
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
- return new (mem) Constraint(kind, first, second, member, functionRefKind,
- locator, typeVars);
+ return new (mem) Constraint(kind, first, second, locator, typeVars);
+}
+
+Constraint *Constraint::createMember(ConstraintSystem &cs, ConstraintKind kind,
+ Type first, Type second, DeclName member,
+ DeclContext *useDC,
+ FunctionRefKind functionRefKind,
+ ConstraintLocator *locator) {
+ // Collect type variables.
+ SmallVector<TypeVariableType *, 4> typeVars;
+ if (first->hasTypeVariable())
+ first->getTypeVariables(typeVars);
+ if (second->hasTypeVariable())
+ second->getTypeVariables(typeVars);
+ uniqueTypeVariables(typeVars);
+
+ // Create the constraint.
+ unsigned size = totalSizeToAlloc<TypeVariableType*>(typeVars.size());
+ void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
+ return new (mem) Constraint(kind, first, second, member, useDC,
+ functionRefKind, locator, typeVars);
}
Constraint *Constraint::createBindOverload(ConstraintSystem &cs, Type type,
OverloadChoice choice,
+ DeclContext *useDC,
ConstraintLocator *locator) {
// Collect type variables.
SmallVector<TypeVariableType *, 4> typeVars;
@@ -542,7 +569,7 @@
// Create the constraint.
unsigned size = totalSizeToAlloc<TypeVariableType*>(typeVars.size());
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
- return new (mem) Constraint(type, choice, locator, typeVars);
+ return new (mem) Constraint(type, choice, useDC, locator, typeVars);
}
Constraint *Constraint::createRestricted(ConstraintSystem &cs,
diff --git a/lib/Sema/Constraint.h b/lib/Sema/Constraint.h
index 2c93231..d7110de 100644
--- a/lib/Sema/Constraint.h
+++ b/lib/Sema/Constraint.h
@@ -328,11 +328,22 @@
/// \brief The second type.
Type Second;
+ } Types;
+
+ struct {
+ /// \brief The type of the base.
+ Type First;
+
+ /// \brief The type of the member.
+ Type Second;
/// \brief If non-null, the name of a member of the first type is that
/// being related to the second type.
DeclName Member;
- } Types;
+
+ /// \brief The DC in which the use appears.
+ DeclContext *UseDC;
+ } Member;
/// The set of constraints for a disjunction.
ArrayRef<Constraint *> Nested;
@@ -343,6 +354,9 @@
/// \brief The overload choice
OverloadChoice Choice;
+
+ /// \brief The DC in which the use appears.
+ DeclContext *UseDC;
} Overload;
};
@@ -358,14 +372,19 @@
ConstraintLocator *locator, ArrayRef<TypeVariableType *> typeVars);
/// Construct a new constraint.
+ Constraint(ConstraintKind kind, Type first, Type second,
+ ConstraintLocator *locator,
+ ArrayRef<TypeVariableType *> typeVars);
+
+ /// Construct a new member constraint.
Constraint(ConstraintKind kind, Type first, Type second, DeclName member,
- FunctionRefKind functionRefKind,
+ DeclContext *useDC, FunctionRefKind functionRefKind,
ConstraintLocator *locator,
ArrayRef<TypeVariableType *> typeVars);
/// Construct a new overload-binding constraint.
- Constraint(Type type, OverloadChoice choice, ConstraintLocator *locator,
- ArrayRef<TypeVariableType *> typeVars);
+ Constraint(Type type, OverloadChoice choice, DeclContext *useDC,
+ ConstraintLocator *locator, ArrayRef<TypeVariableType *> typeVars);
/// Construct a restricted constraint.
Constraint(ConstraintKind kind, ConversionRestrictionKind restriction,
@@ -385,13 +404,20 @@
public:
/// Create a new constraint.
static Constraint *create(ConstraintSystem &cs, ConstraintKind Kind,
- Type First, Type Second, DeclName Member,
- FunctionRefKind functionRefKind,
+ Type First, Type Second,
ConstraintLocator *locator);
+ /// Create a new member constraint.
+ static Constraint *createMember(ConstraintSystem &cs, ConstraintKind kind,
+ Type first, Type second, DeclName member,
+ DeclContext *useDC,
+ FunctionRefKind functionRefKind,
+ ConstraintLocator *locator);
+
/// Create an overload-binding constraint.
static Constraint *createBindOverload(ConstraintSystem &cs, Type type,
OverloadChoice choice,
+ DeclContext *useDC,
ConstraintLocator *locator);
/// Create a restricted relational constraint.
@@ -494,18 +520,36 @@
/// \brief Retrieve the first type in the constraint.
Type getFirstType() const {
- assert(getKind() != ConstraintKind::Disjunction);
+ switch (getKind()) {
+ case ConstraintKind::Disjunction:
+ llvm_unreachable("disjunction constraints have no type operands");
- if (getKind() == ConstraintKind::BindOverload)
+ case ConstraintKind::BindOverload:
return Overload.First;
- return Types.First;
+ case ConstraintKind::ValueMember:
+ case ConstraintKind::UnresolvedValueMember:
+ return Member.First;
+
+ default:
+ return Types.First;
+ }
}
/// \brief Retrieve the second type in the constraint.
Type getSecondType() const {
- assert(getKind() != ConstraintKind::Disjunction);
- return Types.Second;
+ switch (getKind()) {
+ case ConstraintKind::Disjunction:
+ case ConstraintKind::BindOverload:
+ llvm_unreachable("constraint has no second type");
+
+ case ConstraintKind::ValueMember:
+ case ConstraintKind::UnresolvedValueMember:
+ return Member.Second;
+
+ default:
+ return Types.Second;
+ }
}
/// \brief Retrieve the protocol in a conformance constraint.
@@ -515,7 +559,7 @@
DeclName getMember() const {
assert(Kind == ConstraintKind::ValueMember ||
Kind == ConstraintKind::UnresolvedValueMember);
- return Types.Member;
+ return Member.Member;
}
/// \brief Determine whether this constraint kind has a second type.
@@ -546,6 +590,19 @@
return Overload.Choice;
}
+ /// Retrieve the DC in which the overload was used.
+ DeclContext *getOverloadUseDC() const {
+ assert(Kind == ConstraintKind::BindOverload);
+ return Overload.UseDC;
+ }
+
+ /// Retrieve the DC in which the member was used.
+ DeclContext *getMemberUseDC() const {
+ assert(Kind == ConstraintKind::ValueMember ||
+ Kind == ConstraintKind::UnresolvedValueMember);
+ return Member.UseDC;
+ }
+
/// \brief Retrieve the locator for this constraint.
ConstraintLocator *getLocator() const { return Locator; }
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index 67fc11d..7398757 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -1021,7 +1021,7 @@
std::pair<Type, Type>
ConstraintSystem::getTypeOfMemberReference(
- Type baseTy, ValueDecl *value,
+ Type baseTy, ValueDecl *value, DeclContext *useDC,
bool isTypeReference,
bool isDynamicResult,
FunctionRefKind functionRefKind,
@@ -1084,7 +1084,7 @@
locator, replacements, innerDC, outerDC,
/*skipProtocolSelfConstraint=*/true);
} else {
- openedType = TC.getUnopenedTypeOfReference(value, baseTy, DC, base,
+ openedType = TC.getUnopenedTypeOfReference(value, baseTy, useDC, base,
/*wantInterfaceType=*/true);
// The type of 'Self' that will be added if the declaration
@@ -1251,13 +1251,14 @@
void ConstraintSystem::addOverloadSet(Type boundType,
ArrayRef<OverloadChoice> choices,
+ DeclContext *useDC,
ConstraintLocator *locator,
OverloadChoice *favoredChoice) {
assert(!choices.empty() && "Empty overload set");
// If there is a single choice, add the bind overload directly.
if (choices.size() == 1) {
- addBindOverloadConstraint(boundType, choices.front(), locator);
+ addBindOverloadConstraint(boundType, choices.front(), locator, useDC);
return;
}
@@ -1270,6 +1271,7 @@
Constraint::createBindOverload(*this,
boundType,
*favoredChoice,
+ useDC,
locator);
bindOverloadConstraint->setFavored();
@@ -1282,7 +1284,7 @@
continue;
overloads.push_back(Constraint::createBindOverload(*this, boundType, choice,
- locator));
+ useDC, locator));
}
addDisjunctionConstraint(overloads, locator, ForgetChoice, favoredChoice);
@@ -1363,7 +1365,8 @@
void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
Type boundType,
- OverloadChoice choice) {
+ OverloadChoice choice,
+ DeclContext *useDC) {
// Determine the type to which we'll bind the overload set's type.
Type refType;
Type openedFullType;
@@ -1407,7 +1410,7 @@
auto anchor = locator ? locator->getAnchor() : nullptr;
auto base = getDotBase(anchor);
std::tie(openedFullType, refType)
- = getTypeOfMemberReference(baseTy, choice.getDecl(),
+ = getTypeOfMemberReference(baseTy, choice.getDecl(), useDC,
isTypeReference, isDynamicResult,
choice.getFunctionRefKind(),
locator, base, nullptr);
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index eb447dc..4af6d62 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -1592,19 +1592,22 @@
/// Add a constraint that binds an overload set to a specific choice.
void addBindOverloadConstraint(Type boundTy, OverloadChoice choice,
- ConstraintLocator *locator) {
- resolveOverload(locator, boundTy, choice);
+ ConstraintLocator *locator,
+ DeclContext *useDC) {
+ resolveOverload(locator, boundTy, choice, useDC);
}
/// \brief Add a value member constraint to the constraint system.
void addValueMemberConstraint(Type baseTy, DeclName name, Type memberTy,
+ DeclContext *useDC,
FunctionRefKind functionRefKind,
ConstraintLocatorBuilder locator) {
assert(baseTy);
assert(memberTy);
assert(name);
+ assert(useDC);
switch (simplifyMemberConstraint(ConstraintKind::ValueMember, baseTy, name,
- memberTy, functionRefKind,
+ memberTy, useDC, functionRefKind,
TMF_GenerateConstraints, locator)) {
case SolutionKind::Unsolved:
llvm_unreachable("Unsolved result when generating constraints!");
@@ -1615,9 +1618,9 @@
case SolutionKind::Error:
if (shouldAddNewFailingConstraint()) {
addNewFailingConstraint(
- Constraint::create(*this, ConstraintKind::ValueMember, baseTy,
- memberTy, name, functionRefKind,
- getConstraintLocator(locator)));
+ Constraint::createMember(*this, ConstraintKind::ValueMember, baseTy,
+ memberTy, name, useDC, functionRefKind,
+ getConstraintLocator(locator)));
}
break;
}
@@ -1626,14 +1629,16 @@
/// \brief Add a value member constraint for an UnresolvedMemberRef
/// to the constraint system.
void addUnresolvedValueMemberConstraint(Type baseTy, DeclName name,
- Type memberTy,
+ Type memberTy, DeclContext *useDC,
FunctionRefKind functionRefKind,
ConstraintLocatorBuilder locator) {
assert(baseTy);
assert(memberTy);
assert(name);
+ assert(useDC);
switch (simplifyMemberConstraint(ConstraintKind::UnresolvedValueMember,
- baseTy, name, memberTy, functionRefKind,
+ baseTy, name, memberTy,
+ useDC, functionRefKind,
TMF_GenerateConstraints, locator)) {
case SolutionKind::Unsolved:
llvm_unreachable("Unsolved result when generating constraints!");
@@ -1644,9 +1649,10 @@
case SolutionKind::Error:
if (shouldAddNewFailingConstraint()) {
addNewFailingConstraint(
- Constraint::create(*this, ConstraintKind::UnresolvedValueMember,
- baseTy, memberTy, name, functionRefKind,
- getConstraintLocator(locator)));
+ Constraint::createMember(*this, ConstraintKind::UnresolvedValueMember,
+ baseTy, memberTy, name,
+ useDC, functionRefKind,
+ getConstraintLocator(locator)));
}
break;
}
@@ -1998,7 +2004,7 @@
/// \returns a pair containing the full opened type (which includes the opened
/// base) and opened type of a reference to this member.
std::pair<Type, Type> getTypeOfMemberReference(
- Type baseTy, ValueDecl *decl,
+ Type baseTy, ValueDecl *decl, DeclContext *useDC,
bool isTypeReference,
bool isDynamicResult,
FunctionRefKind functionRefKind,
@@ -2010,7 +2016,7 @@
/// \brief Add a new overload set to the list of unresolved overload
/// sets.
void addOverloadSet(Type boundType, ArrayRef<OverloadChoice> choices,
- ConstraintLocator *locator,
+ DeclContext *useDC, ConstraintLocator *locator,
OverloadChoice *favored = nullptr);
/// If the given type is ImplicitlyUnwrappedOptional<T>, and we're in a context
@@ -2145,7 +2151,7 @@
public:
/// \brief Resolve the given overload set to the given choice.
void resolveOverload(ConstraintLocator *locator, Type boundType,
- OverloadChoice choice);
+ OverloadChoice choice, DeclContext *useDC);
/// \brief Simplify a type, by replacing type variables with either their
/// fixed types (if available) or their representatives.
@@ -2200,6 +2206,7 @@
SolutionKind simplifyConstructionConstraint(Type valueType,
FunctionType *fnType,
TypeMatchOptions flags,
+ DeclContext *DC,
FunctionRefKind functionRefKind,
ConstraintLocator *locator);
@@ -2238,7 +2245,7 @@
/// \brief Attempt to simplify the given member constraint.
SolutionKind simplifyMemberConstraint(ConstraintKind kind,
Type baseType, DeclName member,
- Type memberType,
+ Type memberType, DeclContext *useDC,
FunctionRefKind functionRefKind,
TypeMatchOptions flags,
ConstraintLocatorBuilder locator);
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index e068ed5..a456484 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1190,7 +1190,7 @@
LocatorPathElt(ConstraintLocator::Requirement, req));
llvm::DenseMap<CanType, TypeVariableType *> reqReplacements;
std::tie(openedFullReqType, reqType)
- = cs->getTypeOfMemberReference(selfTy, req,
+ = cs->getTypeOfMemberReference(selfTy, req, dc,
/*isTypeReference=*/false,
/*isDynamicResult=*/false,
FunctionRefKind::DoubleApply,
@@ -1228,7 +1228,7 @@
llvm::DenseMap<CanType, TypeVariableType *> witnessReplacements;
if (witness->getDeclContext()->isTypeContext()) {
std::tie(openedFullWitnessType, openWitnessType)
- = cs->getTypeOfMemberReference(selfTy, witness,
+ = cs->getTypeOfMemberReference(selfTy, witness, dc,
/*isTypeReference=*/false,
/*isDynamicResult=*/false,
FunctionRefKind::DoubleApply,
diff --git a/test/Compatibility/tuple_arguments.swift b/test/Compatibility/tuple_arguments.swift
index 227aafc..c4e16f8 100644
--- a/test/Compatibility/tuple_arguments.swift
+++ b/test/Compatibility/tuple_arguments.swift
@@ -19,6 +19,7 @@
// but now crash. These are bugs in Swift 3 mode that should be fixed.
func concrete(_ x: Int) {}
+func concreteLabeled(x: Int) {}
func concreteTwo(_ x: Int, _ y: Int) {} // expected-note 3 {{'concreteTwo' declared here}}
func concreteTuple(_ x: (Int, Int)) {}
@@ -26,6 +27,10 @@
concrete(3)
concrete((3))
+ concreteLabeled(x: 3)
+ concreteLabeled(x: (3))
+ concreteLabeled((x: 3)) // expected-error {{missing argument label 'x:' in call}}
+
concreteTwo(3, 4)
concreteTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -72,6 +77,7 @@
}
func generic<T>(_ x: T) {}
+func genericLabeled<T>(x: T) {}
func genericTwo<T, U>(_ x: T, _ y: U) {} // expected-note 5 {{'genericTwo' declared here}}
func genericTuple<T, U>(_ x: (T, U)) {}
@@ -81,6 +87,11 @@
generic((3))
generic((3, 4))
+ genericLabeled(x: 3)
+ genericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ genericLabeled(x: (3))
+ genericLabeled(x: (3, 4))
+
genericTwo(3, 4)
genericTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -250,6 +261,7 @@
extension Concrete {
func generic<T>(_ x: T) {}
+ func genericLabeled<T>(x: T) {}
func genericTwo<T, U>(_ x: T, _ y: U) {} // expected-note 5 {{'genericTwo' declared here}}
func genericTuple<T, U>(_ x: (T, U)) {}
}
@@ -262,6 +274,11 @@
s.generic((3))
s.generic((3, 4))
+ s.genericLabeled(x: 3)
+ s.genericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ s.genericLabeled(x: (3))
+ s.genericLabeled(x: (3, 4))
+
s.genericTwo(3, 4)
s.genericTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -378,6 +395,7 @@
extension Concrete {
mutating func mutatingGeneric<T>(_ x: T) {}
+ mutating func mutatingGenericLabeled<T>(x: T) {}
mutating func mutatingGenericTwo<T, U>(_ x: T, _ y: U) {} // expected-note 5 {{'mutatingGenericTwo' declared here}}
mutating func mutatingGenericTuple<T, U>(_ x: (T, U)) {}
}
@@ -390,6 +408,11 @@
s.mutatingGeneric((3))
s.mutatingGeneric((3, 4))
+ s.mutatingGenericLabeled(x: 3)
+ s.mutatingGenericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ s.mutatingGenericLabeled(x: (3))
+ s.mutatingGenericLabeled(x: (3, 4))
+
s.mutatingGenericTwo(3, 4)
s.mutatingGenericTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -512,12 +535,19 @@
init(_ x: (Int, Int)) {}
}
+struct InitLabeledTuple {
+ init(x: (Int, Int)) {}
+}
+
do {
_ = InitTwo(3, 4)
_ = InitTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
_ = InitTuple(3, 4) // expected-error {{extra argument in call}}
_ = InitTuple((3, 4))
+
+ _ = InitLabeledTuple(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = InitLabeledTuple(x: (3, 4))
}
do {
@@ -556,6 +586,10 @@
subscript(_ x: (Int, Int)) -> Int { get { return 0 } set { } }
}
+struct SubscriptLabeledTuple {
+ subscript(x x: (Int, Int)) -> Int { get { return 0 } set { } }
+}
+
do {
let s1 = SubscriptTwo()
_ = s1[3, 4]
@@ -564,6 +598,10 @@
let s2 = SubscriptTuple()
_ = s2[3, 4] // expected-error {{extra argument in call}}
_ = s2[(3, 4)]
+
+ let s3 = SubscriptLabeledTuple()
+ _ = s3[x: 3, 4] // expected-error {{extra argument in call}}
+ _ = s3[x: (3, 4)]
}
do {
@@ -601,6 +639,7 @@
enum Enum {
case two(Int, Int) // expected-note 3 {{'two' declared here}}
case tuple((Int, Int))
+ case labeledTuple(x: (Int, Int))
}
do {
@@ -609,6 +648,9 @@
_ = Enum.tuple(3, 4) // expected-error {{extra argument in call}}
_ = Enum.tuple((3, 4))
+
+ _ = Enum.labeledTuple(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = Enum.labeledTuple(x: (3, 4))
}
do {
@@ -643,6 +685,7 @@
extension Generic {
func generic(_ x: T) {}
+ func genericLabeled(x: T) {}
func genericTwo(_ x: T, _ y: T) {} // expected-note 2 {{'genericTwo' declared here}}
func genericTuple(_ x: (T, T)) {}
}
@@ -653,6 +696,9 @@
s.generic(3.0)
s.generic((3.0))
+ s.genericLabeled(x: 3.0)
+ s.genericLabeled(x: (3.0))
+
s.genericTwo(3.0, 4.0)
s.genericTwo((3.0, 4.0)) // expected-error {{missing argument for parameter #2 in call}}
@@ -663,6 +709,9 @@
sTwo.generic(3.0, 4.0) // expected-error {{extra argument in call}}
sTwo.generic((3.0, 4.0))
+
+ sTwo.genericLabeled(x: 3.0, 4.0) // expected-error {{extra argument in call}}
+ sTwo.genericLabeled(x: (3.0, 4.0))
}
do {
@@ -717,6 +766,7 @@
extension Generic {
mutating func mutatingGeneric(_ x: T) {}
+ mutating func mutatingGenericLabeled(x: T) {}
mutating func mutatingGenericTwo(_ x: T, _ y: T) {} // expected-note 2 {{'mutatingGenericTwo' declared here}}
mutating func mutatingGenericTuple(_ x: (T, T)) {}
}
@@ -727,6 +777,9 @@
s.mutatingGeneric(3.0)
s.mutatingGeneric((3.0))
+ s.mutatingGenericLabeled(x: 3.0)
+ s.mutatingGenericLabeled(x: (3.0))
+
s.mutatingGenericTwo(3.0, 4.0)
s.mutatingGenericTwo((3.0, 4.0)) // expected-error {{missing argument for parameter #2 in call}}
@@ -737,6 +790,9 @@
sTwo.mutatingGeneric(3.0, 4.0) // expected-error {{extra argument in call}}
sTwo.mutatingGeneric((3.0, 4.0))
+
+ sTwo.mutatingGenericLabeled(x: 3.0, 4.0) // expected-error {{extra argument in call}}
+ sTwo.mutatingGenericLabeled(x: (3.0, 4.0))
}
do {
@@ -809,7 +865,7 @@
let sTwo = Generic<(Double, Double)>()
- sTwo.genericFunction(3.0, 4.0) // FIXME: Diagnoses in Swift 3 mode // expected-error {{extra argument in call}}
+ sTwo.genericFunction(3.0, 4.0)
sTwo.genericFunction((3.0, 4.0)) // Does not diagnose in Swift 3 mode
}
@@ -858,7 +914,7 @@
var sTwo = Generic<(Double, Double)>()
- sTwo.genericFunction(a, b) // FIXME: Diagnoses in Swift 3 mode // expected-error {{extra argument in call}}
+ sTwo.genericFunction(a, b)
sTwo.genericFunction((a, b)) // Does not diagnose in Swift 3 mode
sTwo.genericFunction(d) // Does not diagnose in Swift 3 mode
}
@@ -867,6 +923,10 @@
init(_ x: T) {}
}
+struct GenericInitLabeled<T> {
+ init(x: T) {}
+}
+
struct GenericInitTwo<T> {
init(_ x: T, _ y: T) {} // expected-note 8 {{'init' declared here}}
}
@@ -875,26 +935,42 @@
init(_ x: (T, T)) {}
}
+struct GenericInitLabeledTuple<T> {
+ init(x: (T, T)) {}
+}
+
do {
_ = GenericInit(3, 4)
_ = GenericInit((3, 4))
+ _ = GenericInitLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeled(x: (3, 4))
+
_ = GenericInitTwo(3, 4)
_ = GenericInitTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
_ = GenericInitTuple(3, 4) // expected-error {{extra argument in call}}
_ = GenericInitTuple((3, 4))
+
+ _ = GenericInitLabeledTuple(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeledTuple(x: (3, 4))
}
do {
_ = GenericInit<(Int, Int)>(3, 4)
_ = GenericInit<(Int, Int)>((3, 4)) // expected-error {{expression type 'GenericInit<(Int, Int)>' is ambiguous without more context}}
+ _ = GenericInitLabeled<(Int, Int)>(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeled<(Int, Int)>(x: (3, 4))
+
_ = GenericInitTwo<Int>(3, 4)
_ = GenericInitTwo<Int>((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
_ = GenericInitTuple<Int>(3, 4) // expected-error {{extra argument in call}}
_ = GenericInitTuple<Int>((3, 4))
+
+ _ = GenericInitLabeledTuple<Int>(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeledTuple<Int>(x: (3, 4))
}
do {
@@ -973,6 +1049,10 @@
subscript(_ x: T) -> Int { get { return 0 } set { } }
}
+struct GenericSubscriptLabeled<T> {
+ subscript(x x: T) -> Int { get { return 0 } set { } }
+}
+
struct GenericSubscriptTwo<T> {
subscript(_ x: T, _ y: T) -> Int { get { return 0 } set { } } // expected-note {{'subscript' declared here}}
}
@@ -981,11 +1061,19 @@
subscript(_ x: (T, T)) -> Int { get { return 0 } set { } }
}
+struct GenericSubscriptLabeledTuple<T> {
+ subscript(x x: (T, T)) -> Int { get { return 0 } set { } }
+}
+
do {
let s1 = GenericSubscript<(Double, Double)>()
_ = s1[3.0, 4.0]
_ = s1[(3.0, 4.0)] // expected-error {{expression type 'Int' is ambiguous without more context}}
+ let s1a = GenericSubscriptLabeled<(Double, Double)>()
+ _ = s1a [x: 3.0, 4.0] // expected-error {{extra argument in call}}
+ _ = s1a [x: (3.0, 4.0)]
+
let s2 = GenericSubscriptTwo<Double>()
_ = s2[3.0, 4.0]
_ = s2[(3.0, 4.0)] // expected-error {{missing argument for parameter #2 in call}}
@@ -993,6 +1081,10 @@
let s3 = GenericSubscriptTuple<Double>()
_ = s3[3.0, 4.0] // expected-error {{extra argument in call}}
_ = s3[(3.0, 4.0)]
+
+ let s3a = GenericSubscriptLabeledTuple<Double>()
+ _ = s3a[x: 3.0, 4.0] // expected-error {{extra argument in call}}
+ _ = s3a[x: (3.0, 4.0)]
}
do {
@@ -1039,6 +1131,7 @@
enum GenericEnum<T> {
case one(T)
+ case labeled(x: T)
case two(T, T) // expected-note 8 {{'two' declared here}}
case tuple((T, T))
}
@@ -1047,6 +1140,11 @@
_ = GenericEnum.one(3, 4)
_ = GenericEnum.one((3, 4))
+ _ = GenericEnum.labeled(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum.labeled(x: (3, 4))
+ _ = GenericEnum.labeled(3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum.labeled((3, 4)) // expected-error {{missing argument label 'x:' in call}}
+
_ = GenericEnum.two(3, 4)
_ = GenericEnum.two((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -1055,9 +1153,14 @@
}
do {
- _ = GenericEnum<(Int, Int)>.one(3, 4) // FIXME: Diagnoses in Swift 3 mode // expected-error {{extra argument in call}}
+ _ = GenericEnum<(Int, Int)>.one(3, 4)
_ = GenericEnum<(Int, Int)>.one((3, 4)) // Does not diagnose in Swift 3 mode
+ _ = GenericEnum<(Int, Int)>.labeled(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum<(Int, Int)>.labeled(x: (3, 4))
+ _ = GenericEnum<(Int, Int)>.labeled(3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum<(Int, Int)>.labeled((3, 4)) // expected-error {{missing argument label 'x:' in call}}
+
_ = GenericEnum<Int>.two(3, 4)
_ = GenericEnum<Int>.two((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -1143,6 +1246,7 @@
extension Protocol {
func requirement(_ x: Element) {}
+ func requirementLabeled(x: Element) {}
func requirementTwo(_ x: Element, _ y: Element) {} // expected-note 2 {{'requirementTwo' declared here}}
func requirementTuple(_ x: (Element, Element)) {}
}
@@ -1157,6 +1261,9 @@
s.requirement(3.0)
s.requirement((3.0))
+ s.requirementLabeled(x: 3.0)
+ s.requirementLabeled(x: (3.0))
+
s.requirementTwo(3.0, 4.0)
s.requirementTwo((3.0, 4.0)) // expected-error {{missing argument for parameter #2 in call}}
@@ -1167,6 +1274,9 @@
sTwo.requirement(3.0, 4.0) // expected-error {{extra argument in call}}
sTwo.requirement((3.0, 4.0))
+
+ sTwo.requirementLabeled(x: 3.0, 4.0) // expected-error {{extra argument in call}}
+ sTwo.requirementLabeled(x: (3.0, 4.0))
}
do {
diff --git a/test/Constraints/operator.swift b/test/Constraints/operator.swift
index 4d81dad..c37b202 100644
--- a/test/Constraints/operator.swift
+++ b/test/Constraints/operator.swift
@@ -132,3 +132,9 @@
}
struct S3 : P3, Equatable { }
+
+// rdar://problem/30220565
+func shrinkTooFar(_ : Double, closure : ()->()) {}
+func testShrinkTooFar() {
+ shrinkTooFar(0*0*0) {}
+}
diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift
index f5c6b99..3bc62bf 100644
--- a/test/Constraints/tuple_arguments.swift
+++ b/test/Constraints/tuple_arguments.swift
@@ -3,6 +3,7 @@
// See test/Compatibility/tuple_arguments.swift for the Swift 3 behavior.
func concrete(_ x: Int) {}
+func concreteLabeled(x: Int) {}
func concreteTwo(_ x: Int, _ y: Int) {} // expected-note 5 {{'concreteTwo' declared here}}
func concreteTuple(_ x: (Int, Int)) {}
@@ -10,6 +11,10 @@
concrete(3)
concrete((3))
+ concreteLabeled(x: 3)
+ concreteLabeled(x: (3))
+ concreteLabeled((x: 3)) // expected-error {{missing argument label 'x:' in call}}
+
concreteTwo(3, 4)
concreteTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -56,6 +61,7 @@
}
func generic<T>(_ x: T) {}
+func genericLabeled<T>(x: T) {}
func genericTwo<T, U>(_ x: T, _ y: U) {} // expected-note 5 {{'genericTwo' declared here}}
func genericTuple<T, U>(_ x: (T, U)) {}
@@ -65,6 +71,11 @@
generic((3))
generic((3, 4))
+ genericLabeled(x: 3)
+ genericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ genericLabeled(x: (3))
+ genericLabeled(x: (3, 4))
+
genericTwo(3, 4)
genericTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -234,6 +245,7 @@
extension Concrete {
func generic<T>(_ x: T) {}
+ func genericLabeled<T>(x: T) {}
func genericTwo<T, U>(_ x: T, _ y: U) {} // expected-note 5 {{'genericTwo' declared here}}
func genericTuple<T, U>(_ x: (T, U)) {}
}
@@ -246,6 +258,11 @@
s.generic((3))
s.generic((3, 4))
+ s.genericLabeled(x: 3)
+ s.genericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ s.genericLabeled(x: (3))
+ s.genericLabeled(x: (3, 4))
+
s.genericTwo(3, 4)
s.genericTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -362,6 +379,7 @@
extension Concrete {
mutating func mutatingGeneric<T>(_ x: T) {}
+ mutating func mutatingGenericLabeled<T>(x: T) {}
mutating func mutatingGenericTwo<T, U>(_ x: T, _ y: U) {} // expected-note 5 {{'mutatingGenericTwo' declared here}}
mutating func mutatingGenericTuple<T, U>(_ x: (T, U)) {}
}
@@ -374,6 +392,11 @@
s.mutatingGeneric((3))
s.mutatingGeneric((3, 4))
+ s.mutatingGenericLabeled(x: 3)
+ s.mutatingGenericLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ s.mutatingGenericLabeled(x: (3))
+ s.mutatingGenericLabeled(x: (3, 4))
+
s.mutatingGenericTwo(3, 4)
s.mutatingGenericTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -497,12 +520,19 @@
init(_ x: (Int, Int)) {}
}
+struct InitLabeledTuple {
+ init(x: (Int, Int)) {}
+}
+
do {
_ = InitTwo(3, 4)
_ = InitTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
_ = InitTuple(3, 4) // expected-error {{extra argument in call}}
_ = InitTuple((3, 4))
+
+ _ = InitLabeledTuple(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = InitLabeledTuple(x: (3, 4))
}
do {
@@ -541,6 +571,10 @@
subscript(_ x: (Int, Int)) -> Int { get { return 0 } set { } }
}
+struct SubscriptLabeledTuple {
+ subscript(x x: (Int, Int)) -> Int { get { return 0 } set { } }
+}
+
do {
let s1 = SubscriptTwo()
_ = s1[3, 4]
@@ -565,6 +599,10 @@
_ = s2[a, b] // expected-error {{extra argument in call}}
_ = s2[(a, b)]
_ = s2[d]
+
+ let s3 = SubscriptLabeledTuple()
+ _ = s3[x: 3, 4] // expected-error {{extra argument in call}}
+ _ = s3[x: (3, 4)]
}
do {
@@ -586,6 +624,7 @@
enum Enum {
case two(Int, Int) // expected-note 5 {{'two' declared here}}
case tuple((Int, Int))
+ case labeledTuple(x: (Int, Int))
}
do {
@@ -594,6 +633,9 @@
_ = Enum.tuple(3, 4) // expected-error {{extra argument in call}}
_ = Enum.tuple((3, 4))
+
+ _ = Enum.labeledTuple(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = Enum.labeledTuple(x: (3, 4))
}
do {
@@ -628,6 +670,7 @@
extension Generic {
func generic(_ x: T) {}
+ func genericLabeled(x: T) {}
func genericTwo(_ x: T, _ y: T) {} // expected-note 3 {{'genericTwo' declared here}}
func genericTuple(_ x: (T, T)) {}
}
@@ -638,6 +681,9 @@
s.generic(3.0)
s.generic((3.0))
+ s.genericLabeled(x: 3.0)
+ s.genericLabeled(x: (3.0))
+
s.genericTwo(3.0, 4.0)
s.genericTwo((3.0, 4.0)) // expected-error {{missing argument for parameter #2 in call}}
@@ -648,6 +694,9 @@
sTwo.generic(3.0, 4.0) // expected-error {{extra argument in call}}
sTwo.generic((3.0, 4.0))
+
+ sTwo.genericLabeled(x: 3.0, 4.0) // expected-error {{extra argument in call}}
+ sTwo.genericLabeled(x: (3.0, 4.0))
}
do {
@@ -702,6 +751,7 @@
extension Generic {
mutating func mutatingGeneric(_ x: T) {}
+ mutating func mutatingGenericLabeled(x: T) {}
mutating func mutatingGenericTwo(_ x: T, _ y: T) {} // expected-note 3 {{'mutatingGenericTwo' declared here}}
mutating func mutatingGenericTuple(_ x: (T, T)) {}
}
@@ -712,6 +762,9 @@
s.mutatingGeneric(3.0)
s.mutatingGeneric((3.0))
+ s.mutatingGenericLabeled(x: 3.0)
+ s.mutatingGenericLabeled(x: (3.0))
+
s.mutatingGenericTwo(3.0, 4.0)
s.mutatingGenericTwo((3.0, 4.0)) // expected-error {{missing argument for parameter #2 in call}}
@@ -722,6 +775,9 @@
sTwo.mutatingGeneric(3.0, 4.0) // expected-error {{extra argument in call}}
sTwo.mutatingGeneric((3.0, 4.0))
+
+ sTwo.mutatingGenericLabeled(x: 3.0, 4.0) // expected-error {{extra argument in call}}
+ sTwo.mutatingGenericLabeled(x: (3.0, 4.0))
}
do {
@@ -852,6 +908,10 @@
init(_ x: T) {}
}
+struct GenericInitLabeled<T> {
+ init(x: T) {}
+}
+
struct GenericInitTwo<T> {
init(_ x: T, _ y: T) {} // expected-note 10 {{'init' declared here}}
}
@@ -860,26 +920,42 @@
init(_ x: (T, T)) {}
}
+struct GenericInitLabeledTuple<T> {
+ init(x: (T, T)) {}
+}
+
do {
_ = GenericInit(3, 4) // expected-error {{extra argument in call}}
_ = GenericInit((3, 4))
+ _ = GenericInitLabeled(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeled(x: (3, 4))
+
_ = GenericInitTwo(3, 4)
_ = GenericInitTwo((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
_ = GenericInitTuple(3, 4) // expected-error {{extra argument in call}}
_ = GenericInitTuple((3, 4))
+
+ _ = GenericInitLabeledTuple(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeledTuple(x: (3, 4))
}
do {
_ = GenericInit<(Int, Int)>(3, 4) // expected-error {{extra argument in call}}
_ = GenericInit<(Int, Int)>((3, 4))
+ _ = GenericInitLabeled<(Int, Int)>(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeled<(Int, Int)>(x: (3, 4))
+
_ = GenericInitTwo<Int>(3, 4)
_ = GenericInitTwo<Int>((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
_ = GenericInitTuple<Int>(3, 4) // expected-error {{extra argument in call}}
_ = GenericInitTuple<Int>((3, 4))
+
+ _ = GenericInitLabeledTuple<Int>(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericInitLabeledTuple<Int>(x: (3, 4))
}
do {
@@ -958,10 +1034,18 @@
subscript(_ x: T) -> Int { get { return 0 } set { } }
}
+struct GenericSubscriptLabeled<T> {
+ subscript(x x: T) -> Int { get { return 0 } set { } }
+}
+
struct GenericSubscriptTwo<T> {
subscript(_ x: T, _ y: T) -> Int { get { return 0 } set { } } // expected-note {{'subscript' declared here}}
}
+struct GenericSubscriptLabeledTuple<T> {
+ subscript(x x: (T, T)) -> Int { get { return 0 } set { } }
+}
+
struct GenericSubscriptTuple<T> {
subscript(_ x: (T, T)) -> Int { get { return 0 } set { } }
}
@@ -971,6 +1055,10 @@
_ = s1[3.0, 4.0] // expected-error {{extra argument in call}}
_ = s1[(3.0, 4.0)]
+ let s1a = GenericSubscriptLabeled<(Double, Double)>()
+ _ = s1a [x: 3.0, 4.0] // expected-error {{extra argument in call}}
+ _ = s1a [x: (3.0, 4.0)]
+
let s2 = GenericSubscriptTwo<Double>()
_ = s2[3.0, 4.0]
_ = s2[(3.0, 4.0)] // expected-error {{missing argument for parameter #2 in call}}
@@ -978,6 +1066,10 @@
let s3 = GenericSubscriptTuple<Double>()
_ = s3[3.0, 4.0] // expected-error {{extra argument in call}}
_ = s3[(3.0, 4.0)]
+
+ let s3a = GenericSubscriptLabeledTuple<Double>()
+ _ = s3a[x: 3.0, 4.0] // expected-error {{extra argument in call}}
+ _ = s3a[x: (3.0, 4.0)]
}
do {
@@ -1024,6 +1116,7 @@
enum GenericEnum<T> {
case one(T)
+ case labeled(x: T)
case two(T, T) // expected-note 10 {{'two' declared here}}
case tuple((T, T))
}
@@ -1032,6 +1125,11 @@
_ = GenericEnum.one(3, 4) // expected-error {{extra argument in call}}
_ = GenericEnum.one((3, 4))
+ _ = GenericEnum.labeled(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum.labeled(x: (3, 4))
+ _ = GenericEnum.labeled(3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum.labeled((3, 4)) // expected-error {{missing argument label 'x:' in call}}
+
_ = GenericEnum.two(3, 4)
_ = GenericEnum.two((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -1043,6 +1141,11 @@
_ = GenericEnum<(Int, Int)>.one(3, 4) // expected-error {{extra argument in call}}
_ = GenericEnum<(Int, Int)>.one((3, 4))
+ _ = GenericEnum<(Int, Int)>.labeled(x: 3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum<(Int, Int)>.labeled(x: (3, 4))
+ _ = GenericEnum<(Int, Int)>.labeled(3, 4) // expected-error {{extra argument in call}}
+ _ = GenericEnum<(Int, Int)>.labeled((3, 4)) // expected-error {{missing argument label 'x:' in call}}
+
_ = GenericEnum<Int>.two(3, 4)
_ = GenericEnum<Int>.two((3, 4)) // expected-error {{missing argument for parameter #2 in call}}
@@ -1128,6 +1231,7 @@
extension Protocol {
func requirement(_ x: Element) {}
+ func requirementLabeled(x: Element) {}
func requirementTwo(_ x: Element, _ y: Element) {} // expected-note 3 {{'requirementTwo' declared here}}
func requirementTuple(_ x: (Element, Element)) {}
}
@@ -1141,6 +1245,9 @@
s.requirement(3.0)
s.requirement((3.0))
+
+ s.requirementLabeled(x: 3.0)
+ s.requirementLabeled(x: (3.0))
s.requirementTwo(3.0, 4.0)
s.requirementTwo((3.0, 4.0)) // expected-error {{missing argument for parameter #2 in call}}
@@ -1152,6 +1259,9 @@
sTwo.requirement(3.0, 4.0) // expected-error {{extra argument in call}}
sTwo.requirement((3.0, 4.0))
+
+ sTwo.requirementLabeled(x: 3.0, 4.0) // expected-error {{extra argument in call}}
+ sTwo.requirementLabeled(x: (3.0, 4.0))
}
do {
diff --git a/test/SILGen/closures.swift b/test/SILGen/closures.swift
index e910183..b654b8c 100644
--- a/test/SILGen/closures.swift
+++ b/test/SILGen/closures.swift
@@ -719,3 +719,26 @@
func r25993258() {
r25993258_helper { _ in () }
}
+
+// rdar://29810997
+//
+// Using a let from a closure in an init was causing the type-checker
+// to produce invalid AST: 'self.fn' was an l-value, but 'self' was already
+// loaded to make an r-value. This was ultimately because CSApply was
+// building the member reference correctly in the context of the closure,
+// where 'fn' is not settable, but CSGen / CSSimplify was processing it
+// in the general DC of the constraint system, i.e. the init, where
+// 'fn' *is* settable.
+func r29810997_helper(_ fn: (Int) -> Int) -> Int { return fn(0) }
+struct r29810997 {
+ private let fn: (Int) -> Int
+ private var x: Int
+
+ init(function: @escaping (Int) -> Int) {
+ fn = function
+ x = r29810997_helper { fn($0) }
+ }
+}
+
+// DI will turn this into a direct capture of the specific stored property.
+// CHECK-LABEL: sil hidden @_TF8closures16r29810997_helperFFSiSiSi : $@convention(thin) (@owned @callee_owned (Int) -> Int) -> Int
diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
index d4ddb5e..3464bc3 100644
--- a/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
+++ b/validation-test/Sema/type_checker_crashers_fixed/rdar27261929.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -typecheck -verify
+// RUN: %target-swift-frontend %s -typecheck
public enum R<V> {
case value(V)
@@ -14,7 +14,7 @@
public func test() -> P<I, [O]> {
return P<I, [O]> { input in
var output: [O] = []
- _ = R<([O], I)>.value(output, input) // expected-error{{extra argument in call}}
+ _ = R<([O], I)>.value(output, input)
return R<([O], I)>.value((output, input))
}
}
diff --git a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
index 5f8f536..67b7139 100644
--- a/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
+++ b/validation-test/compiler_crashers_fixed/26813-generic-enum-tuple-optional-payload.swift
@@ -6,7 +6,7 @@
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-// RUN: %target-swift-frontend %s -typecheck -verify
+// RUN: %target-swift-frontend %s -typecheck
// Issue found by https://github.com/austinzheng (Austin Zheng)
@@ -16,7 +16,7 @@
}
func foo() -> A<(String, String?)> {
- _ = A<(String, String?)>.Just("abc", "def") // expected-error{{extra argument in call}}
- _ = A.Just("abc", "def") // no error?
- return A.Just("abc", "def") // expected-error{{extra argument in call}}
+ _ = A<(String, String?)>.Just("abc", "def")
+ _ = A.Just("abc", "def")
+ return A.Just("abc", "def")
}