diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index 24bba5554ac12..e64c0e8a13e4d 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -360,6 +360,14 @@ class alignas(8) Expr { < (1 << NumCheckedCastKindBits), "unable to fit a CheckedCastKind in the given number of bits"); + class FunctionConversionExprBitfields { + friend class FunctionConversionExpr; + unsigned : NumImplicitConversionExprBits; + unsigned Flattening : 1; + }; + enum { NumFunctionConversionExprBits = NumImplicitConversionExprBits + 1 }; + static_assert(NumFunctionConversionExprBits <= 32, "fits in an unsigned"); + class CollectionUpcastConversionExprBitfields { friend class CollectionUpcastConversionExpr; unsigned : NumExprBits; @@ -413,6 +421,7 @@ class alignas(8) Expr { ApplyExprBitfields ApplyExprBits; CallExprBitfields CallExprBits; CheckedCastExprBitfields CheckedCastExprBits; + FunctionConversionExprBitfields FunctionConversionExprBits; CollectionUpcastConversionExprBitfields CollectionUpcastConversionExprBits; TupleShuffleExprBitfields TupleShuffleExprBits; ObjCSelectorExprBitfields ObjCSelectorExprBits; @@ -2761,8 +2770,22 @@ class UnresolvedTypeConversionExpr : public ImplicitConversionExpr { class FunctionConversionExpr : public ImplicitConversionExpr { public: FunctionConversionExpr(Expr *subExpr, Type type) - : ImplicitConversionExpr(ExprKind::FunctionConversion, subExpr, type) {} - + : ImplicitConversionExpr(ExprKind::FunctionConversion, subExpr, type) { + FunctionConversionExprBits.Flattening = false; + } + + /// Set whether this function conversion flattens an unapplied member + /// function. + void setFlattening() { + FunctionConversionExprBits.Flattening = true; + } + + /// Returns whether this function conversion flattens an unapplied member + /// function. + bool isFlattening() const { + return FunctionConversionExprBits.Flattening; + } + static bool classof(const Expr *E) { return E->getKind() == ExprKind::FunctionConversion; } diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index f5ed6b30c64f8..b3e467ba5757e 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -2297,6 +2297,16 @@ class AnyFunctionType : public TypeBase { return getExtInfo().throws(); } + unsigned getCurryLevel() const { + unsigned Level = 0; + const AnyFunctionType *function = this; + while ((function = function->getResult()->getAs())) + ++Level; + return Level; + } + + AnyFunctionType *getUncurriedFunction(); + /// Returns a new function type exactly like this one but with the ExtInfo /// replaced. AnyFunctionType *withExtInfo(ExtInfo info) const; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 40bd4c06c7843..1bf03ea815588 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3131,6 +3131,32 @@ AnyFunctionType *AnyFunctionType::withExtInfo(ExtInfo info) const { llvm_unreachable("unhandled function type"); } +AnyFunctionType *AnyFunctionType::getUncurriedFunction() { + assert(getCurryLevel() > 0 && "nothing to uncurry"); + + auto innerFunction = getResult()->castTo(); + SmallVector params{getInput()->getDesugaredType()}; + + if (auto tuple = dyn_cast(innerFunction->getInput().getPointer())) + params.append(tuple->getElements().begin(), tuple->getElements().end()); + else + params.push_back(innerFunction->getInput()->getDesugaredType()); + + auto inputType = TupleType::get(params, getASTContext()); + auto extInfo = + innerFunction->getExtInfo().withRepresentation(getRepresentation()); + + if (auto generic = getAs()) + return GenericFunctionType::get(generic->getGenericSignature(), inputType, + innerFunction->getResult(), extInfo); + + if (auto poly = getAs()) + return PolymorphicFunctionType::get(inputType, innerFunction->getResult(), + &poly->getGenericParams(), extInfo); + + return FunctionType::get(inputType, innerFunction->getResult(), extInfo); +} + FunctionType *FunctionType::get(Type Input, Type Result, const ExtInfo &Info) { auto properties = getFunctionRecursiveProperties(Input, Result); diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 3ace3309aeb5d..510a05886066a 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -1897,7 +1897,10 @@ class PrintExpr : public ExprVisitor { OS << ')'; } void visitFunctionConversionExpr(FunctionConversionExpr *E) { - printCommon(E, "function_conversion_expr") << '\n'; + printCommon(E, "function_conversion_expr"); + if (E->isFlattening()) + OS << " flattening"; + OS << '\n'; printRec(E->getSubExpr()); OS << ')'; } diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index 8c1b701690cfa..faf17cd80c715 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -1232,6 +1232,13 @@ class SILGenApply : public Lowering::ExprVisitor { } void visitFunctionConversionExpr(FunctionConversionExpr *e) { + // If this is a flattening function conversion, emit the expression + // directly. + if (e->isFlattening()) { + visitExpr(e); + return; + } + // FIXME: Check whether this function conversion requires us to build a // thunk. visit(e->getSubExpr()); diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index fda786bfe2324..56230a71c97e9 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -1257,7 +1257,8 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e, result = convertFunctionRepresentation(SGF, e, result, srcRepTy, srcTy); if (srcTy != destTy) - result = SGF.emitTransformedValue(e, result, srcTy, destTy); + result = + SGF.emitTransformedValue(e, result, srcTy, destTy, e->isFlattening()); if (destTy != destRepTy) result = convertFunctionRepresentation(SGF, e, result, destTy, destRepTy); diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index 5a3f69f019f42..49e864351cca1 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -1460,6 +1460,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction ManagedValue emitTransformedValue(SILLocation loc, ManagedValue input, CanType inputType, CanType outputType, + bool isFlattening = false, SGFContext ctx = SGFContext()); /// Most general form of the above. @@ -1468,6 +1469,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction CanType inputSubstType, AbstractionPattern outputOrigType, CanType outputSubstType, + bool isFlattening = false, SGFContext ctx = SGFContext()); RValue emitTransformedValue(SILLocation loc, RValue &&input, AbstractionPattern inputOrigType, diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index c72b4b0e10d07..21a791af43fb2 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -112,9 +112,11 @@ namespace { private: SILGenFunction &SGF; SILLocation Loc; + bool Flattening; public: - Transform(SILGenFunction &SGF, SILLocation loc) : SGF(SGF), Loc(loc) {} + Transform(SILGenFunction &SGF, SILLocation loc, bool flattening = false) + : SGF(SGF), Loc(loc), Flattening(flattening) {} virtual ~Transform() = default; /// Transform an arbitrary value. @@ -1252,7 +1254,7 @@ namespace { return SGF.emitTransformedValue(Loc, input, inputOrigType, inputSubstType, outputOrigType, outputSubstType, - context); + /*isFlattening=*/false, context); } /// Force the given result into the given initialization. @@ -2177,7 +2179,7 @@ void ResultPlanner::execute(ArrayRef innerDirectResults, Gen.emitTransformedValue(Loc, innerResult, op.InnerOrigType, op.InnerSubstType, op.OuterOrigType, op.OuterSubstType, - outerResultCtxt); + /*isFlattening=*/false, outerResultCtxt); // If the outer is indirect, force it into the context. if (outerIsIndirect) { @@ -2269,26 +2271,72 @@ void ResultPlanner::execute(ArrayRef innerDirectResults, /// \param inputSubstType Formal AST type of function value being thunked /// \param outputOrigType Abstraction pattern of the thunk /// \param outputSubstType Formal AST type of the thunk -static void buildThunkBody(SILGenFunction &gen, SILLocation loc, - AbstractionPattern inputOrigType, - CanAnyFunctionType inputSubstType, - AbstractionPattern outputOrigType, - CanAnyFunctionType outputSubstType) { +static void buildThunkBody( + SILGenFunction &gen, SILLocation loc, bool isFlattening, + AbstractionPattern inputOrigType, CanAnyFunctionType inputSubstType, + AbstractionPattern outputOrigType, CanAnyFunctionType outputSubstType) { PrettyStackTraceSILFunction stackTrace("emitting reabstraction thunk in", &gen.F); auto thunkType = gen.F.getLoweredFunctionType(); FullExpr scope(gen.Cleanups, CleanupLocation::get(loc)); - SmallVector params; + SmallVector paramsBuffer; // TODO: Could accept +0 arguments here when forwardFunctionArguments/ // emitApply can. - gen.collectThunkParams(loc, params, /*allowPlusZero*/ false); - - ManagedValue fnValue = params.pop_back_val(); + gen.collectThunkParams(loc, paramsBuffer, /*allowPlusZero*/ false); + ManagedValue fnValue = paramsBuffer.pop_back_val(); auto fnType = fnValue.getType().castTo(); assert(!fnType->isPolymorphic()); auto argTypes = fnType->getParameters(); + + ArrayRef params(paramsBuffer); + if (isFlattening) { + // Flatten an instance function type. + assert( + inputSubstType->getCurryLevel() - outputSubstType->getCurryLevel() == 1 && + "Invalid (un)currying"); + + SmallVector selfArg; + forwardFunctionArguments(gen, loc, fnType, params.front(), selfArg); + auto inner = gen.emitApplyWithRethrow(loc, fnValue.forward(gen), + /*substFnType*/ fnValue.getType(), + /*substitutions*/ {}, selfArg); + + // For the next steps update the variables by dropping the already applied + // first parameter (`self`) + params = params.slice(1); + fnValue = ManagedValue::forUnmanaged(inner); + fnType = fnValue.getType().castTo(); + argTypes = fnType->getParameters(); + inputOrigType = inputOrigType.getFunctionResultType(); + inputSubstType = cast(inputSubstType.getResult()); + + Type newOrigInput, newSubstInput; + auto origFunction = cast(outputOrigType.getType()); + if (auto origInput = dyn_cast(origFunction.getInput())) { + auto substInput = cast(outputSubstType.getInput()); + assert(origInput->getNumElements() == substInput->getNumElements() && + "invalid premise"); + newOrigInput = TupleType::get(origInput->getElements().slice(1), + gen.getASTContext()); + newSubstInput = TupleType::get(substInput->getElements().slice(1), + gen.getASTContext()); + } else { + // In this case `self` was the only parameter, which leaves us with an + // application of `Void` + assert(!dyn_cast(outputSubstType.getInput()) && + "invalid premise"); + newOrigInput = newSubstInput = TupleType::getEmpty(gen.getASTContext()); + } + + outputOrigType = AbstractionPattern(CanFunctionType::get( + newOrigInput->getCanonicalType(), origFunction.getResult(), + origFunction->getExtInfo())); + outputSubstType = CanFunctionType::get(newSubstInput->getCanonicalType(), + outputSubstType.getResult(), + outputSubstType->getExtInfo()); + } // Translate the argument values. Function parameters are // contravariant: we want to switch the direction of transformation @@ -2419,14 +2467,12 @@ CanSILFunctionType SILGenFunction::buildThunkType( } /// Create a reabstraction thunk. -static ManagedValue createThunk(SILGenFunction &gen, - SILLocation loc, - ManagedValue fn, - AbstractionPattern inputOrigType, - CanAnyFunctionType inputSubstType, - AbstractionPattern outputOrigType, - CanAnyFunctionType outputSubstType, - const TypeLowering &expectedTL) { +static ManagedValue createThunk( + SILGenFunction &gen, SILLocation loc, ManagedValue fn, + AbstractionPattern inputOrigType, CanAnyFunctionType inputSubstType, + AbstractionPattern outputOrigType, CanAnyFunctionType outputSubstType, + const TypeLowering &expectedTL, bool isFlattening) { + auto expectedType = expectedTL.getLoweredType().castTo(); // We can't do bridging here. @@ -2452,7 +2498,7 @@ static ManagedValue createThunk(SILGenFunction &gen, thunk->setContextGenericParams(gen.F.getContextGenericParams()); SILGenFunction thunkSGF(gen.SGM, *thunk); auto loc = RegularLocation::getAutoGeneratedLocation(); - buildThunkBody(thunkSGF, loc, + buildThunkBody(thunkSGF, loc, isFlattening, inputOrigType, inputSubstType, outputOrigType, outputSubstType); } @@ -2494,7 +2540,7 @@ ManagedValue Transform::transformFunction(ManagedValue fn, return createThunk(SGF, Loc, fn, inputOrigType, inputSubstType, outputOrigType, outputSubstType, - expectedTL); + expectedTL, Flattening); } // We do not, conversion is trivial. @@ -2535,7 +2581,7 @@ SILGenFunction::emitOrigToSubstValue(SILLocation loc, ManagedValue v, return emitTransformedValue(loc, v, origType, substType, AbstractionPattern(substType), substType, - ctxt); + /*isFlattening=*/false, ctxt); } /// Given a value with the abstraction patterns of the original formal @@ -2561,7 +2607,7 @@ SILGenFunction::emitSubstToOrigValue(SILLocation loc, ManagedValue v, return emitTransformedValue(loc, v, AbstractionPattern(substType), substType, origType, substType, - ctxt); + /*isFlattening=*/false, ctxt); } /// Given a value with the abstraction patterns of the substituted @@ -2594,10 +2640,12 @@ ManagedValue SILGenFunction::emitTransformedValue(SILLocation loc, ManagedValue v, CanType inputType, CanType outputType, + bool isFlattening, SGFContext ctxt) { return emitTransformedValue(loc, v, AbstractionPattern(inputType), inputType, - AbstractionPattern(outputType), outputType); + AbstractionPattern(outputType), outputType, + isFlattening, ctxt); } ManagedValue @@ -2606,8 +2654,9 @@ SILGenFunction::emitTransformedValue(SILLocation loc, ManagedValue v, CanType inputSubstType, AbstractionPattern outputOrigType, CanType outputSubstType, + bool isFlattening, SGFContext ctxt) { - return Transform(*this, loc).transform(v, + return Transform(*this, loc, isFlattening).transform(v, inputOrigType, inputSubstType, outputOrigType, diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 6ce577170fba4..50fdac8b1ce36 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -1024,7 +1024,16 @@ namespace { Expr *result = new (context) DotSyntaxBaseIgnoredExpr(base, dotLoc, ref); closeExistential(result, /*force=*/openedExistential); - return result; + + if (!isa(member)) + return result; + + auto newTy = result->getType() + ->castTo() + ->getUncurriedFunction(); + auto conversion = new FunctionConversionExpr(result, newTy); + conversion->setFlattening(); + return conversion; } else { assert((!baseIsInstance || member->isInstanceMember()) && "can't call a static method on an instance"); @@ -4637,6 +4646,8 @@ static bool isReferenceToMetatypeMember(Expr *expr) { return dotIgnored->getLHS()->getType()->is(); if (auto dotSyntax = dyn_cast(expr)) return dotSyntax->getBase()->getType()->is(); + if (auto conversion = dyn_cast(expr)) + return isReferenceToMetatypeMember(conversion->getSubExpr()); return false; } @@ -6952,4 +6963,3 @@ Expr *Solution::convertOptionalToBool(Expr *expr, isSomeExpr->setType(tc.lookupBoolType(cs.DC)); return isSomeExpr; } - diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 92652ec2565f5..f9f2e86022569 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1024,8 +1024,8 @@ namespace { auto memberLocator = CS.getConstraintLocator(expr, ConstraintLocator::Member); auto tv = CS.createTypeVariable(memberLocator, TVO_CanBindToLValue); - - OverloadChoice choice(base->getType(), decl, /*isSpecialized=*/false, CS); + + OverloadChoice choice(base->getType(), decl, CS); auto locator = CS.getConstraintLocator(expr, ConstraintLocator::Member); CS.addBindOverloadConstraint(tv, choice, locator); return tv; @@ -1114,8 +1114,7 @@ namespace { // a known subscript here. This might be cleaner if we split off a new // UnresolvedSubscriptExpr from SubscriptExpr. if (decl) { - OverloadChoice choice(base->getType(), decl, /*isSpecialized=*/false, - CS); + OverloadChoice choice(base->getType(), decl, CS); CS.addBindOverloadConstraint(fnTy, choice, subscriptMemberLocator); } else { CS.addValueMemberConstraint(baseTy, Context.Id_subscript, @@ -1312,10 +1311,9 @@ namespace { // Create an overload choice referencing this declaration and immediately // resolve it. This records the overload for use later. auto tv = CS.createTypeVariable(locator, TVO_CanBindToLValue); - CS.resolveOverload(locator, tv, - OverloadChoice(Type(), E->getDecl(), - E->isSpecialized(), CS)); - + CS.resolveOverload(locator, tv, OverloadChoice(Type(), E->getDecl(), CS, + E->isSpecialized())); + if (E->getDecl()->getType() && !E->getDecl()->getType()->getAs()) { CS.setFavoredType(E, E->getDecl()->getType().getPointer()); @@ -1377,9 +1375,8 @@ namespace { if (decls[i]->isInvalid()) continue; - choices.push_back(OverloadChoice(Type(), decls[i], - expr->isSpecialized(), - CS)); + choices.push_back( + OverloadChoice(Type(), decls[i], CS, expr->isSpecialized())); } // If there are no valid overloads, give up. diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 93d7590eaaa08..e9d7697e38228 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -889,6 +889,13 @@ ConstraintSystem::SolutionKind ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2, TypeMatchKind kind, unsigned flags, ConstraintLocatorBuilder locator) { + if (flags & TMF_FlattenFunction) { + // If we want a flattened function, remove a level of currying and continue. + return matchFunctionTypes( + func1->getUncurriedFunction()->castTo(), func2, kind, + flags & ~TMF_FlattenFunction, locator); + } + // An @autoclosure function type can be a subtype of a // non-@autoclosure function type. if (func1->isAutoClosure() != func2->isAutoClosure() && @@ -2842,9 +2849,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName, } } } - - result.addViable(OverloadChoice(baseTy, ctor, - /*isSpecialized=*/false, *this)); + + result.addViable(OverloadChoice(baseTy, ctor, *this)); } @@ -2885,9 +2891,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName, TC.validateDecl(candidate.first, true); if (candidate.first->isInvalid()) return result.markErrorAlreadyDiagnosed(); - - result.addViable(OverloadChoice(baseTy, candidate.first, - /*isSpecialized=*/false)); + + result.addViable(OverloadChoice(baseTy, candidate.first)); } return result; @@ -2994,19 +2999,24 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName, } } + bool isFlattened = + isMetatype && cand->isInstanceMember() && isa(cand); + // If we're looking into an existential type, check whether this // result was found via dynamic lookup. if (isDynamicLookup) { assert(cand->getDeclContext()->isTypeContext() && "Dynamic lookup bug"); // We found this declaration via dynamic lookup, record it as such. - result.addViable(OverloadChoice::getDeclViaDynamic(baseTy, cand)); + result.addViable( + OverloadChoice::getDeclViaDynamic(baseTy, cand, isFlattened)); return; } // If we have a bridged type, we found this declaration via bridging. if (isBridged) { - result.addViable(OverloadChoice::getDeclViaBridge(bridgedType, cand)); + result.addViable( + OverloadChoice::getDeclViaBridge(bridgedType, cand, isFlattened)); return; } @@ -3017,11 +3027,11 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName, ovlBaseTy = MetatypeType::get(baseTy->castTo() ->getInstanceType() ->getAnyOptionalObjectType()); - result.addViable(OverloadChoice::getDeclViaUnwrappedOptional(ovlBaseTy, - cand)); + result.addViable(OverloadChoice::getDeclViaUnwrappedOptional( + ovlBaseTy, cand, isFlattened)); } else { - result.addViable(OverloadChoice(ovlBaseTy, cand, - /*isSpecialized=*/false, *this)); + result.addViable(OverloadChoice(ovlBaseTy, cand, *this, + /*isSpecialized=*/false, isFlattened)); } }; @@ -4331,9 +4341,10 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) { return result; } - return matchTypes(constraint.getFirstType(), constraint.getSecondType(), - matchKind, - TMF_None, constraint.getLocator()); + return matchTypes( + constraint.getFirstType(), constraint.getSecondType(), matchKind, + constraint.isFunctionFlattening() ? TMF_FlattenFunction : TMF_None, + constraint.getLocator()); } case ConstraintKind::ApplicableFunction: diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp index 6e5935e9feda2..95576006ef54f 100644 --- a/lib/Sema/Constraint.cpp +++ b/lib/Sema/Constraint.cpp @@ -27,24 +27,23 @@ using namespace swift; using namespace constraints; Constraint::Constraint(ConstraintKind kind, ArrayRef constraints, - ConstraintLocator *locator, + ConstraintLocator *locator, ArrayRef typeVars) - : Kind(kind), HasRestriction(false), HasFix(false), IsActive(false), - RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()), - Nested(constraints), Locator(locator) -{ + : Kind(kind), HasRestriction(false), HasFix(false), IsActive(false), + RememberChoice(false), IsFavored(false), IsFunctionFlattening(false), + NumTypeVariables(typeVars.size()), Nested(constraints), Locator(locator) { assert(kind == ConstraintKind::Disjunction); std::uninitialized_copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); } -Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, +Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, DeclName Member, ConstraintLocator *locator, ArrayRef typeVars) - : Kind(Kind), HasRestriction(false), HasFix(false), IsActive(false), - RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()), - Types { First, Second, Member }, Locator(locator) -{ + : Kind(Kind), HasRestriction(false), HasFix(false), IsActive(false), + RememberChoice(false), IsFavored(false), IsFunctionFlattening(false), + NumTypeVariables(typeVars.size()), Types{First, Second, Member}, + Locator(locator) { switch (Kind) { case ConstraintKind::Bind: case ConstraintKind::Equal: @@ -100,26 +99,24 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); } -Constraint::Constraint(Type type, OverloadChoice choice, +Constraint::Constraint(Type type, OverloadChoice choice, ConstraintLocator *locator, ArrayRef typeVars) - : Kind(ConstraintKind::BindOverload), - HasRestriction(false), HasFix(false), IsActive(false), - RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()), - Overload{type, choice}, Locator(locator) -{ + : Kind(ConstraintKind::BindOverload), HasRestriction(false), HasFix(false), + IsActive(false), RememberChoice(false), IsFavored(false), + IsFunctionFlattening(false), NumTypeVariables(typeVars.size()), + Overload{type, choice}, Locator(locator) { std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); } -Constraint::Constraint(ConstraintKind kind, +Constraint::Constraint(ConstraintKind kind, ConversionRestrictionKind restriction, Type first, Type second, ConstraintLocator *locator, ArrayRef typeVars) - : Kind(kind), Restriction(restriction), - HasRestriction(true), HasFix(false), IsActive(false), - RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()), - Types{ first, second, Identifier() }, Locator(locator) -{ + : Kind(kind), Restriction(restriction), HasRestriction(true), HasFix(false), + IsActive(false), RememberChoice(false), IsFavored(false), + IsFunctionFlattening(false), NumTypeVariables(typeVars.size()), + Types{first, second, Identifier()}, Locator(locator) { assert(!first.isNull()); assert(!second.isNull()); std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); @@ -128,12 +125,11 @@ Constraint::Constraint(ConstraintKind kind, Constraint::Constraint(ConstraintKind kind, Fix fix, Type first, Type second, ConstraintLocator *locator, ArrayRef typeVars) - : Kind(kind), TheFix(fix.getKind()), FixData(fix.getData()), - HasRestriction(false), HasFix(true), - IsActive(false), RememberChoice(false), IsFavored(false), - NumTypeVariables(typeVars.size()), - Types{ first, second, Identifier() }, Locator(locator) -{ + : Kind(kind), TheFix(fix.getKind()), FixData(fix.getData()), + HasRestriction(false), HasFix(true), IsActive(false), + RememberChoice(false), IsFavored(false), IsFunctionFlattening(false), + NumTypeVariables(typeVars.size()), Types{first, second, Identifier()}, + Locator(locator) { assert(!first.isNull()); assert(!second.isNull()); std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin()); diff --git a/lib/Sema/Constraint.h b/lib/Sema/Constraint.h index 739e7f10973c7..9c4e76b190824 100644 --- a/lib/Sema/Constraint.h +++ b/lib/Sema/Constraint.h @@ -319,6 +319,8 @@ class Constraint final : public llvm::ilist_node, /// in its disjunction. unsigned IsFavored : 1; + unsigned IsFunctionFlattening : 1; + /// The number of type variables referenced by this constraint. /// /// The type variables themselves are tail-allocated. @@ -446,6 +448,9 @@ class Constraint final : public llvm::ilist_node, /// this constraint. bool shouldRememberChoice() const { return RememberChoice; } + void setFunctionFlattening() { IsFunctionFlattening = true; } + bool isFunctionFlattening() const { return IsFunctionFlattening; } + /// Retrieve the set of type variables referenced by this constraint. ArrayRef getTypeVariables() const { return {getTrailingObjects(), NumTypeVariables}; diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 284aaebdc9def..321c4dd1bd1cf 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -1430,6 +1430,9 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator, = getTypeOfMemberReference(choice.getBaseType(), choice.getDecl(), isTypeReference, isDynamicResult, locator, base, nullptr); + + if (choice.isFlattened()) + refType = refType->castTo()->getUncurriedFunction(); } else { std::tie(openedFullType, refType) = getTypeOfReference(choice.getDecl(), isTypeReference, diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index d3c3b3918ea90..9da46418dc4ee 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -65,7 +65,7 @@ namespace constraints { class SavedTypeVariableBinding { /// \brief The type variable and type variable options. llvm::PointerIntPair TypeVarAndOptions; - + /// \brief The parent or fixed type. llvm::PointerUnion ParentOrFixed; @@ -157,12 +157,12 @@ class TypeVariableType::Implementation { friend class constraints::SavedTypeVariableBinding; public: - + /// \brief If this type variable is an opened literal expression, keep track /// of the associated literal conformance for optimization and diagnostic /// purposes. ProtocolDecl *literalConformanceProto = nullptr; - + explicit Implementation(constraints::ConstraintLocator *locator, unsigned options) : Options(options), locator(locator), @@ -198,19 +198,19 @@ class TypeVariableType::Implementation { constraints::ConstraintGraphNode *getGraphNode() const { return GraphNode; } /// Set the corresponding node in the constraint graph. - void setGraphNode(constraints::ConstraintGraphNode *newNode) { - GraphNode = newNode; + void setGraphNode(constraints::ConstraintGraphNode *newNode) { + GraphNode = newNode; } /// Retrieve the index into the constraint graph's list of type variables. - unsigned getGraphIndex() const { + unsigned getGraphIndex() const { assert(GraphNode && "Graph node isn't set"); - return GraphIndex; + return GraphIndex; } /// Set the index into the constraint graph's list of type variables. void setGraphIndex(unsigned newIndex) { GraphIndex = newIndex; } - + /// \brief Check whether this type variable either has a representative that /// is not itself or has a fixed type binding. bool hasRepresentativeOrFixed() const { @@ -458,7 +458,7 @@ enum ScoreKind { SK_ArrayPointerConversion, /// A conversion to an empty existential type ('Any' or '{}'). SK_EmptyExistentialConversion, - + SK_LastScoreKind = SK_EmptyExistentialConversion, }; @@ -575,7 +575,7 @@ class Solution { /// \brief The set of type bindings. llvm::SmallDenseMap typeBindings; - + /// \brief The set of overload choices along with their types. llvm::SmallDenseMap overloadChoices; @@ -773,7 +773,7 @@ struct ResolvedOverloadSetListItem { unsigned alignment = alignof(ResolvedOverloadSetListItem)); }; - + /// Identifies a specific conversion from @@ -789,7 +789,7 @@ typedef llvm::ilist ConstraintList; enum class ConstraintSystemFlags { /// Whether we allow the solver to attempt fixes to the system. AllowFixes = 0x01, - + /// Set if the client prefers fixits to be in the form of force unwrapping /// or optional chaining to return an optional. PreferForceUnwrapToOptional = 0x02, @@ -804,53 +804,53 @@ struct MemberLookupResult { /// This result indicates that we cannot begin to solve this, because the /// base expression is a type variable. Unsolved, - + /// This result indicates that the member reference is erroneous, but was /// already diagnosed. Don't emit another error. ErrorAlreadyDiagnosed, - + /// This result indicates that the lookup produced candidate lists, /// potentially of viable results, potentially of error candidates, and /// potentially empty lists, indicating that there were no matches. HasResults } OverallResult; - + /// This is a list of viable candidates that were matched. /// SmallVector ViableCandidates; - + /// If there is a favored candidate in the viable list, this indicates its /// index. unsigned FavoredChoice = ~0U; - - + + /// This enum tracks reasons why a candidate is not viable. enum UnviableReason { /// Argument labels don't match. UR_LabelMismatch, - + /// This uses a type like Self in its signature that cannot be used on an /// existential box. UR_UnavailableInExistential, - + /// This is an instance member being accessed through something of metatype /// type. UR_InstanceMemberOnType, - + /// This is a static/class member being accessed through an instance. UR_TypeMemberOnInstance, - + /// This is a mutating member, being used on an rvalue. UR_MutatingMemberOnRValue, - + /// The getter for this subscript or computed property is mutating and we /// only have an rvalue base. This is more specific than the former one. UR_MutatingGetterOnRValue, - + /// The member is inaccessible (e.g. a private member in another file). UR_Inaccessible, }; - + /// This is a list of considered, but rejected, candidates, along with a /// reason for their rejection. SmallVector, 4> UnviableCandidates; @@ -861,23 +861,23 @@ struct MemberLookupResult { OverallResult = ErrorAlreadyDiagnosed; return *this; } - + void addViable(OverloadChoice candidate) { ViableCandidates.push_back(candidate); } - + void addUnviable(ValueDecl *VD, UnviableReason reason) { UnviableCandidates.push_back({VD, reason}); } - + OverloadChoice *getFavoredChoice() { if (FavoredChoice == ~0U) return nullptr; return &ViableCandidates[FavoredChoice]; } - + }; - - + + /// \brief Describes a system of constraints on type variables, the /// solution of which assigns concrete types to each of the type variables. /// Constraint systems are typically generated given an (untyped) expression. @@ -886,7 +886,7 @@ class ConstraintSystem { TypeChecker &TC; DeclContext *DC; ConstraintSystemOptions Options; - + friend class Fix; friend class OverloadChoice; friend class ConstraintGraph; @@ -913,7 +913,7 @@ class ConstraintSystem { /// \brief Counter for type variables introduced. unsigned TypeCounter = 0; - + /// \brief The expression being solved has exceeded the solver's memory /// threshold. bool expressionExceededThreshold = false; @@ -952,7 +952,7 @@ class ConstraintSystem { TypeLoc contextualType; Expr *contextualTypeNode = nullptr; ContextualTypePurpose contextualTypePurpose = CTP_Unused; - + /// \brief The set of constraint restrictions used to reach the /// current constraint system. /// @@ -1006,7 +1006,7 @@ class ConstraintSystem { ConstraintSystem &CS; /// Old value of DebugConstraintSolver. - /// FIXME: Move the "debug constraint solver" bit into the constraint + /// FIXME: Move the "debug constraint solver" bit into the constraint /// system itself. bool OldDebugConstraintSolver; @@ -1046,7 +1046,7 @@ class ConstraintSystem { /// /// This will be non-null when we're actively solving the constraint /// system, and carries temporary state related to the current path - /// we're exploring. + /// we're exploring. SolverState *solverState = nullptr; struct ArgumentLabelState { @@ -1177,8 +1177,8 @@ class ConstraintSystem { /// diagnostic for it and returning true. If the fixit hint turned out to be /// bogus, this returns false and doesn't emit anything. bool applySolutionFix(Expr *expr, const Solution &solution, unsigned fixNo); - - + + /// \brief Restore the type variable bindings to what they were before /// we attempted to solve this constraint system. /// @@ -1226,14 +1226,14 @@ class ConstraintSystem { ArrayRef getTypeVariables() const { return TypeVariables; } - + TypeBase* getFavoredType(Expr *E) { return this->FavoredTypes[E]; } void setFavoredType(Expr *E, TypeBase *T) { this->FavoredTypes[E] = T; } - + void setContextualType(Expr *E, TypeLoc T, ContextualTypePurpose purpose) { contextualTypeNode = E; contextualType = T; @@ -1258,7 +1258,7 @@ class ConstraintSystem { ContextualTypePurpose getContextualTypePurpose() const { return contextualTypePurpose; } - + /// \brief Retrieve the constraint locator for the given anchor and /// path, uniqued. ConstraintLocator * @@ -1306,7 +1306,7 @@ class ConstraintSystem { /// \brief Log and record the application of the fix. Return true iff any /// subsequent solution would be worse than the best known solution. bool recordFix(Fix fix, ConstraintLocatorBuilder locator); - + /// \brief Try to salvage the constraint system by applying (speculative) /// fixes to the underlying expression. /// @@ -1324,7 +1324,7 @@ class ConstraintSystem { /// invalid, emit a detailed error about the condition. void diagnoseAssignmentFailure(Expr *dest, Type destTy, SourceLoc equalLoc); - + /// \brief Mine the active and inactive constraints in the constraint /// system to generate a plausible diagnosis of why the system could not be /// solved. @@ -1364,7 +1364,7 @@ class ConstraintSystem { /// Add a constraint that binds an overload set to a specific choice. void addBindOverloadConstraint(Type boundTy, OverloadChoice choice, ConstraintLocator *locator) { - addConstraint(Constraint::createBindOverload(*this, boundTy, choice, + addConstraint(Constraint::createBindOverload(*this, boundTy, choice, locator)); } @@ -1398,7 +1398,7 @@ class ConstraintSystem { baseTy, Type(), DeclName(), locator)); } - + /// \brief Remove an inactive constraint from the current constraint graph. void removeInactiveConstraint(Constraint *constraint) { CG.removeConstraint(constraint); @@ -1414,11 +1414,11 @@ class ConstraintSystem { /// /// \param locator The location used to describe this member access. /// - /// \param options Options to be supplied to type variable creation if + /// \param options Options to be supplied to type variable creation if /// a new type is created. /// /// \returns the type variable representing the member type. - TypeVariableType *getMemberType(TypeVariableType *baseTypeVar, + TypeVariableType *getMemberType(TypeVariableType *baseTypeVar, AssociatedTypeDecl *assocType, ConstraintLocatorBuilder locator, unsigned options); @@ -1457,7 +1457,7 @@ class ConstraintSystem { /// /// \param type The type to simplify. /// - /// \param typeVar Will receive the type variable at which simplification + /// \param typeVar Will receive the type variable at which simplification /// stopped, which has no fixed type. /// /// \param wantRValue Whether this routine should look through @@ -1475,7 +1475,7 @@ class ConstraintSystem { /// \param type The fixed type to which the type variable will be bound. /// /// \param updateState Whether to update the state based on this binding. - /// False when we're only assigning a type as part of reconstructing + /// False when we're only assigning a type as part of reconstructing /// a complete solution from partial solutions. void assignFixedType(TypeVariableType *typeVar, Type type, bool updateState = true); @@ -1484,7 +1484,7 @@ class ConstraintSystem { // necessary to ensure that the type in question is materializable in a // viable solution. void setMustBeMaterializableRecursive(Type type); - + /// \brief Determine if the type in question is an Array. bool isArrayType(Type t); @@ -1721,13 +1721,15 @@ class ConstraintSystem { /// Indicates that we are applying a fix. TMF_ApplyingFix = 0x02, - + /// Indicates we're matching an operator parameter. TMF_ApplyingOperatorParameter = 0x4, - + /// Indicates we're unwrapping an optional type for a value-to-optional /// conversion. TMF_UnwrappingOptional = 0x8, + + TMF_FlattenFunction = 0x10, }; private: @@ -1846,7 +1848,7 @@ class ConstraintSystem { /// type equivalence requirements aren't introduced between comparisons. Type simplifyType(Type type, llvm::SmallPtrSet &substituting); - + /// \brief Attempt to simplify the given construction constraint. /// /// \param valueType The type being constructed. @@ -1857,10 +1859,10 @@ class ConstraintSystem { /// /// \param flags Flags that indicate how the constraint should be /// simplified. - /// + /// /// \param locator Locator describing where this construction /// occurred. - SolutionKind simplifyConstructionConstraint(Type valueType, + SolutionKind simplifyConstructionConstraint(Type valueType, FunctionType *fnType, unsigned flags, ConstraintLocator *locator); @@ -1898,7 +1900,7 @@ class ConstraintSystem { /// \brief Attempt to simplify the given member constraint. SolutionKind simplifyMemberConstraint(const Constraint &constraint); - + /// \brief Attempt to simplify the optional object constraint. SolutionKind simplifyOptionalObjectConstraint(const Constraint &constraint); @@ -1913,7 +1915,7 @@ class ConstraintSystem { /// \brief Attempt to simplify the given class constraint. SolutionKind simplifyClassConstraint(const Constraint &constraint); - + /// \brief Attempt to simplify the given bridge constraint. SolutionKind simplifyBridgedToObjectiveCConstraint(const Constraint &constraint); @@ -2057,12 +2059,12 @@ class ConstraintSystem { /// expression, producing a fully type-checked expression. Expr *applySolutionShallow(const Solution &solution, Expr *expr, bool suppressDiagnostics); - + /// \brief Obtain the specializations computed for a type variable. This is /// useful when emitting diagnostics for computed type variables. void getComputedBindings(TypeVariableType *tvt, SmallVectorImpl &bindings); - + /// Extract the base type from an array or slice type. /// \param type The array type to inspect. /// \returns the base type of the array. @@ -2072,18 +2074,18 @@ class ConstraintSystem { /// \param type The set type to inspect. /// \returns the base type of the set. Type getBaseTypeForSetType(TypeBase *type); - + /// \brief Set whether or not the expression being solved is too complex and /// has exceeded the solver's memory threshold. void setExpressionTooComplex(bool tc) { expressionExceededThreshold = tc; } - + /// \brief Reorder the disjunctive clauses for a given expression to /// increase the likelihood that a favored constraint will be successfully /// resolved before any others. void optimizeConstraints(Expr *e); - + /// \brief Determine if the expression being solved has exceeded the solver's /// memory threshold. bool getExpressionTooComplex() { diff --git a/lib/Sema/OverloadChoice.cpp b/lib/Sema/OverloadChoice.cpp index 8eb4d4754142d..5b21f25439571 100644 --- a/lib/Sema/OverloadChoice.cpp +++ b/lib/Sema/OverloadChoice.cpp @@ -23,11 +23,14 @@ using namespace swift; using namespace constraints; -OverloadChoice::OverloadChoice( - Type base, ValueDecl *value, bool isSpecialized, ConstraintSystem &CS) - : BaseAndBits(base, isSpecialized ? IsSpecializedBit : 0) { +OverloadChoice::OverloadChoice(Type base, ValueDecl *value, + ConstraintSystem &CS, bool isSpecialized, + bool isFlattened) + : BaseAndBits(base, isSpecialized ? IsSpecializedBit : 0), + IsFlattened(isFlattened) { assert((reinterpret_cast(value) & (uintptr_t)0x03) == 0 && "Badly aligned decl"); - + assert((!isFlattened || isa(value)) && + "can only flatten function decls"); DeclOrKind = reinterpret_cast(value); } diff --git a/lib/Sema/OverloadChoice.h b/lib/Sema/OverloadChoice.h index 53d19c03be889..35c1890c26b2e 100644 --- a/lib/Sema/OverloadChoice.h +++ b/lib/Sema/OverloadChoice.h @@ -21,6 +21,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/ErrorHandling.h" #include "swift/AST/Availability.h" +#include "swift/AST/Decl.h" #include "swift/AST/Type.h" #include "swift/AST/Types.h" @@ -75,7 +76,7 @@ class OverloadChoice { /// optional context type, turning a "Decl" kind into /// "DeclViaUnwrappedOptional". IsUnwrappedOptionalBit = 0x04, - + // IsBridged and IsUnwrappedOptional are mutually exclusive, so there is // room for another mutually exclusive OverloadChoiceKind to be packed into // those two bits. @@ -91,23 +92,26 @@ class OverloadChoice { /// overload choice kind shifted by 1 with the low bit set. uintptr_t DeclOrKind; + bool IsFlattened; + public: OverloadChoice() - : BaseAndBits(nullptr, 0), DeclOrKind() {} - - OverloadChoice( - Type base, ValueDecl *value, bool isSpecialized, ConstraintSystem &CS); - - OverloadChoice(Type base, TypeDecl *type, bool isSpecialized) - : BaseAndBits(base, isSpecialized ? IsSpecializedBit : 0) { - assert((reinterpret_cast(type) & (uintptr_t)0x03) == 0 - && "Badly aligned decl"); + : BaseAndBits(nullptr, 0), DeclOrKind(), IsFlattened(false) {} + + OverloadChoice(Type base, ValueDecl *value, ConstraintSystem &CS, + bool isSpecialized = false, bool isFlattened = false); + + OverloadChoice(Type base, TypeDecl *type, bool isSpecialized = false) + : BaseAndBits(base, isSpecialized ? IsSpecializedBit : 0), + IsFlattened(false) { + assert((reinterpret_cast(type) & (uintptr_t)0x03) == 0 && + "Badly aligned decl"); DeclOrKind = reinterpret_cast(type) | 0x01; } OverloadChoice(Type base, OverloadChoiceKind kind) : BaseAndBits(base, 0), - DeclOrKind((uintptr_t)kind << 2 | (uintptr_t)0x03) + DeclOrKind((uintptr_t)kind << 2 | (uintptr_t)0x03), IsFlattened(false) { assert(base && "Must have a base type for overload choice"); assert(kind != OverloadChoiceKind::Decl && @@ -122,37 +126,47 @@ class OverloadChoice { : BaseAndBits(base, 0), DeclOrKind(((uintptr_t)index + (uintptr_t)OverloadChoiceKind::TupleIndex) << 2 - | (uintptr_t)0x03) { + | (uintptr_t)0x03), IsFlattened(false) { assert(base->getRValueType()->is() && "Must have tuple type"); } /// Retrieve an overload choice for a declaration that was found via /// dynamic lookup. - static OverloadChoice getDeclViaDynamic(Type base, ValueDecl *value) { + static OverloadChoice getDeclViaDynamic(Type base, ValueDecl *value, bool isFlattened = false) { + assert((!isFlattened || isa(value)) && + "can only flatten function decls"); OverloadChoice result; result.BaseAndBits.setPointer(base); result.DeclOrKind = reinterpret_cast(value) | 0x02; + result.IsFlattened = isFlattened; return result; } /// Retrieve an overload choice for a declaration that was found via /// bridging to an Objective-C class. - static OverloadChoice getDeclViaBridge(Type base, ValueDecl *value) { + static OverloadChoice getDeclViaBridge(Type base, ValueDecl *value, + bool isFlattened = false) { + assert((!isFlattened || isa(value)) && + "can only flatten function decls"); OverloadChoice result; result.BaseAndBits.setPointer(base); result.BaseAndBits.setInt(IsBridgedBit); result.DeclOrKind = reinterpret_cast(value); + result.IsFlattened = isFlattened; return result; } /// Retrieve an overload choice for a declaration that was found /// by unwrapping an optional context type. - static OverloadChoice getDeclViaUnwrappedOptional(Type base, - ValueDecl *value) { + static OverloadChoice getDeclViaUnwrappedOptional(Type base, ValueDecl *value, + bool isFlattened = false) { + assert((!isFlattened || isa(value)) && + "can only flatten function decls"); OverloadChoice result; result.BaseAndBits.setPointer(base); result.BaseAndBits.setInt(IsUnwrappedOptionalBit); result.DeclOrKind = reinterpret_cast(value); + result.IsFlattened = isFlattened; return result; } @@ -166,18 +180,22 @@ class OverloadChoice { bool isSpecialized() const { return BaseAndBits.getInt() & IsSpecializedBit; } - + + bool isFlattened() const { + return IsFlattened; + } + /// \brief Determines the kind of overload choice this is. OverloadChoiceKind getKind() const { switch (DeclOrKind & 0x03) { - case 0x00: + case 0x00: if (BaseAndBits.getInt() & IsBridgedBit) return OverloadChoiceKind::DeclViaBridge; if (BaseAndBits.getInt() & IsUnwrappedOptionalBit) return OverloadChoiceKind::DeclViaUnwrappedOptional; return OverloadChoiceKind::Decl; - + case 0x01: return OverloadChoiceKind::TypeDecl; case 0x02: return OverloadChoiceKind::DeclViaDynamic; case 0x03: { diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 892257c1e74cf..03cdf96b65a3f 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -2388,8 +2388,14 @@ bool TypeChecker::convertToType(Expr *&expr, Type type, DeclContext *dc, // If there is a type that we're expected to convert to, add the conversion // constraint. - cs.addConstraint(ConstraintKind::ExplicitConversion, expr->getType(), type, - cs.getConstraintLocator(expr)); + auto constraint = Constraint::create(cs, ConstraintKind::ExplicitConversion, + expr->getType(), type, DeclName(), + cs.getConstraintLocator(expr)); + // An unapplied member function wants a flattened function type. + if (auto ignored = dyn_cast(expr)) + if (isa(ignored->getLHS())) + constraint->setFunctionFlattening(); + cs.addConstraint(constraint); if (getLangOpts().DebugConstraintSolver) { auto &log = Context.TypeCheckerDebug->getStream(); diff --git a/test/1_stdlib/Renames.swift b/test/1_stdlib/Renames.swift index c4a9206c8ea32..3c7711022819d 100644 --- a/test/1_stdlib/Renames.swift +++ b/test/1_stdlib/Renames.swift @@ -219,8 +219,8 @@ func _HashedCollection(x: Dictionary, i: Dictionary.Index, k: func _ImplicitlyUnwrappedOptional(x: ImplicitlyUnwrappedOptional) { _ = ImplicitlyUnwrappedOptional() // expected-error {{'init()' is unavailable: Please use nil literal instead.}} {{none}} - try! _ = ImplicitlyUnwrappedOptional.map(x)() { _ in true } // expected-error {{'map' is unavailable: Has been removed in Swift 3.}} - try! _ = ImplicitlyUnwrappedOptional.flatMap(x)() { _ in true } // expected-error {{'flatMap' is unavailable: Has been removed in Swift 3.}} + try! _ = ImplicitlyUnwrappedOptional.map(x) { _ in true } // expected-error {{'map' is unavailable: Has been removed in Swift 3.}} + try! _ = ImplicitlyUnwrappedOptional.flatMap(x) { _ in true } // expected-error {{'flatMap' is unavailable: Has been removed in Swift 3.}} // FIXME: No way to call map and flatMap as method? // _ = (x as ImplicitlyUnwrappedOptional).map { _ in true } // xpected-error {{}} {{none}} // _ = (x as ImplicitlyUnwrappedOptional).flatMap { _ in true } // xpected-error {{}} {{none}} diff --git a/test/1_stdlib/UnsafePointer.swift.gyb b/test/1_stdlib/UnsafePointer.swift.gyb index 0705a8a0abfb0..3b5102c9a2731 100644 --- a/test/1_stdlib/UnsafePointer.swift.gyb +++ b/test/1_stdlib/UnsafePointer.swift.gyb @@ -246,8 +246,8 @@ class Missile { func checkPointerCorrectness(_ check: Check, _ withMissiles: Bool = false, - _ f: (UnsafeMutablePointer) -> - (UnsafeMutablePointer, count: Int) -> Void) { + _ f: (UnsafeMutablePointer, + UnsafeMutablePointer, count: Int) -> Void) { let ptr = UnsafeMutablePointer.allocate(capacity: 4) switch check { case .RightOverlap: @@ -256,7 +256,7 @@ func checkPointerCorrectness(_ check: Check, if withMissiles { (ptr + 2).initialize(to: Missile(3)) } - f(ptr + 1)(ptr, count: 2) + f(ptr + 1, ptr, count: 2) expectEqual(1, ptr[1].number) expectEqual(2, ptr[2].number) case .LeftOverlap: @@ -265,7 +265,7 @@ func checkPointerCorrectness(_ check: Check, } (ptr + 1).initialize(to: Missile(2)) (ptr + 2).initialize(to: Missile(3)) - f(ptr)(ptr + 1, count: 2) + f(ptr, ptr + 1, count: 2) expectEqual(2, ptr[0].number) expectEqual(3, ptr[1].number) case .Disjoint: @@ -275,7 +275,7 @@ func checkPointerCorrectness(_ check: Check, } (ptr + 2).initialize(to: Missile(2)) (ptr + 3).initialize(to: Missile(3)) - f(ptr)(ptr + 2, count: 2) + f(ptr, ptr + 2, count: 2) expectEqual(2, ptr[0].number) expectEqual(3, ptr[1].number) // backwards @@ -286,26 +286,28 @@ func checkPointerCorrectness(_ check: Check, (ptr2 + 2).initialize(to: Missile(2)) (ptr2 + 3).initialize(to: Missile(3)) } - f(ptr2 + 2)(ptr2, count: 2) + f(ptr2 + 2, ptr2, count: 2) expectEqual(0, ptr2[2].number) expectEqual(1, ptr2[3].number) } } func checkPtr( - _ f: ((UnsafeMutablePointer) -> (UnsafeMutablePointer, count: Int) -> Void), + _ f: ((UnsafeMutablePointer, + UnsafeMutablePointer, count: Int) -> Void), _ m: Bool ) -> (Check) -> Void { return { checkPointerCorrectness($0, m, f) } } func checkPtr( - _ f: ((UnsafeMutablePointer) -> (UnsafePointer, count: Int) -> Void), + _ f: ((UnsafeMutablePointer, + UnsafePointer, count: Int) -> Void), _ m: Bool ) -> (Check) -> Void { return { - checkPointerCorrectness($0, m) { destPtr in - return { f(destPtr)(UnsafeMutablePointer($0), count: $1) } + checkPointerCorrectness($0, m) { destPtr, srcPtr, count in + f(destPtr, UnsafeMutablePointer(srcPtr), count: count) } } } diff --git a/test/1_stdlib/UnsafeRawPointer.swift b/test/1_stdlib/UnsafeRawPointer.swift index 9ee370229b9fb..a5a0c335725a7 100644 --- a/test/1_stdlib/UnsafeRawPointer.swift +++ b/test/1_stdlib/UnsafeRawPointer.swift @@ -148,53 +148,55 @@ enum Check { } func checkRawPointerCorrectness(_ check: Check, - _ f: (UnsafeMutableRawPointer) -> (as: Int.Type, from: UnsafeMutablePointer, count: Int) -> UnsafeMutablePointer) { + _ f: (UnsafeMutableRawPointer, + as: Int.Type, from: UnsafeMutablePointer, count: Int) + -> UnsafeMutablePointer) { let ptr = UnsafeMutablePointer.allocate(capacity: 4) switch check { case .RightOverlap: ptr.initialize(to: 1) (ptr + 1).initialize(to: 2) - _ = f(UnsafeMutableRawPointer(ptr + 1))(as: Int.self, from: ptr, count: 2) + _ = f(UnsafeMutableRawPointer(ptr + 1), as: Int.self, from: ptr, count: 2) expectEqual(1, ptr[1]) expectEqual(2, ptr[2]) case .LeftOverlap: (ptr + 1).initialize(to: 2) (ptr + 2).initialize(to: 3) - _ = f(UnsafeMutableRawPointer(ptr))(as: Int.self, from: ptr + 1, count: 2) + _ = f(UnsafeMutableRawPointer(ptr), as: Int.self, from: ptr + 1, count: 2) expectEqual(2, ptr[0]) expectEqual(3, ptr[1]) case .Disjoint: (ptr + 2).initialize(to: 2) (ptr + 3).initialize(to: 3) - _ = f(UnsafeMutableRawPointer(ptr))(as: Int.self, from: ptr + 2, count: 2) + _ = f(UnsafeMutableRawPointer(ptr), as: Int.self, from: ptr + 2, count: 2) expectEqual(2, ptr[0]) expectEqual(3, ptr[1]) // backwards let ptr2 = UnsafeMutablePointer.allocate(capacity: 4) ptr2.initialize(to: 0) (ptr2 + 1).initialize(to: 1) - _ = f(UnsafeMutableRawPointer(ptr2 + 2))(as: Int.self, from: ptr2, count: 2) + _ = f(UnsafeMutableRawPointer(ptr2 + 2), as: Int.self, from: ptr2, count: 2) expectEqual(0, ptr2[2]) expectEqual(1, ptr2[3]) } } func checkPtr( - _ f: ((UnsafeMutableRawPointer) - -> (as: Int.Type, from: UnsafeMutablePointer, count: Int) + _ f: ((UnsafeMutableRawPointer, + as: Int.Type, from: UnsafeMutablePointer, count: Int) -> UnsafeMutablePointer) ) -> (Check) -> Void { return { checkRawPointerCorrectness($0, f) } } func checkPtr( - _ f: ((UnsafeMutableRawPointer) - -> (as: Int.Type, from: UnsafePointer, count: Int) + _ f: ((UnsafeMutableRawPointer, + as: Int.Type, from: UnsafePointer, count: Int) -> UnsafeMutablePointer) ) -> (Check) -> Void { return { - checkRawPointerCorrectness($0) { destPtr in - return { f(destPtr)(as: $0, from: UnsafeMutablePointer($1), count: $2) } + checkRawPointerCorrectness($0) { destPtr, type, srcPtr, count in + f(destPtr, as: type, from: UnsafeMutablePointer(srcPtr), count: count) } } } diff --git a/test/ClangModules/objc_parse.swift b/test/ClangModules/objc_parse.swift index 923409273f77b..078c247c23160 100644 --- a/test/ClangModules/objc_parse.swift +++ b/test/ClangModules/objc_parse.swift @@ -373,7 +373,8 @@ func testPreferClassMethodToCurriedInstanceMethod(_ obj: NSObject) { // FIXME: We shouldn't need the ": Bool" type annotation here. // let _: Bool = NSObject.isEqual(obj) - _ = NSObject.isEqual(obj) as (NSObject!) -> Bool // no-warning + _ = NSObject.isEqual as (NSObject, NSObject) -> Bool // no-warning + _ = obj.isEqual as (NSObject!) -> Bool } @@ -598,4 +599,3 @@ func testNSUInteger(_ obj: NSUIntegerTests, uint: UInt, int: Int) { let num = NSNumber(value: uint) let _: String = num.uintValue // expected-error {{cannot convert value of type 'UInt' to specified type 'String'}} } - diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index 0ba8807ca0e49..8ed05eec20219 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -205,7 +205,8 @@ func validateSaveButton(_ text: String) { // QoI: poor diagnostic when calling a class method via a metatype class r20201968C { func blah() { - r20201968C.blah() // expected-error {{use of instance member 'blah' on type 'r20201968C'; did you mean to use a value of type 'r20201968C' instead?}} + r20201968C.blah() // FIXME-error {{use of instance member 'blah' on type 'r20201968C'; did you mean to use a value of type 'r20201968C' instead?}} + // expected-error @-1 {{missing argument for parameter #1 in call}} } } @@ -363,8 +364,8 @@ f8(b: 1.0) // expected-error {{cannot convert value of type 'Double' to class CurriedClass { func method1() {} - func method2(_ a: Int) -> (b : Int) -> () { return { b in () } } - func method3(_ a: Int, b : Int) {} + func method2(_ a: Int) -> (b: Int) -> () { return { b in () } } + func method3(_ a: Int, b: Int) {} } let c = CurriedClass() @@ -379,29 +380,28 @@ c.method2(1)(b: 2.0) // expected-error {{cannot convert value of type 'Double' t c.method2(1.0)(b: 2) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} c.method2(1.0)(b: 2.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} -CurriedClass.method1(c)() -_ = CurriedClass.method1(c) -CurriedClass.method1(c)(1) // expected-error {{argument passed to call that takes no arguments}} -CurriedClass.method1(2.0)(1) // expected-error {{use of instance member 'method1' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} - -CurriedClass.method2(c)(32)(b: 1) -_ = CurriedClass.method2(c) -_ = CurriedClass.method2(c)(32) -_ = CurriedClass.method2(1,2) // expected-error {{use of instance member 'method2' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} -CurriedClass.method2(c)(1.0)(b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} -CurriedClass.method2(c)(1)(b: 1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} -CurriedClass.method2(c)(2)(c: 1.0) // expected-error {{incorrect argument label in call (have 'c:', expected 'b:')}} - -CurriedClass.method3(c)(32, b: 1) -_ = CurriedClass.method3(c) -_ = CurriedClass.method3(c)(1, 2) // expected-error {{missing argument label 'b:' in call}} {{32-32=b: }} -_ = CurriedClass.method3(c)(1, b: 2)(32) // expected-error {{cannot call value of non-function type '()'}} -_ = CurriedClass.method3(1, 2) // expected-error {{use of instance member 'method3' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} -CurriedClass.method3(c)(1.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} -CurriedClass.method3(c)(1) // expected-error {{missing argument for parameter 'b' in call}} - -CurriedClass.method3(c)(c: 1.0) // expected-error {{missing argument for parameter 'b' in call}} - +CurriedClass.method1(c) +CurriedClass.method1(c, 1) // expected-error {{extra argument in call}} +CurriedClass.method1(2.0)(1) // FIXME-error {{use of instance member 'method1' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} +// expected-error @-1 {{cannot convert value of type 'Double' to expected argument type 'CurriedClass'}} + +CurriedClass.method2(c, 32)(b: 1) +_ = CurriedClass.method2(c, 32) +_ = CurriedClass.method2(1,2) // FIXME-error {{use of instance member 'method2' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} +// expected-error @-1 {{cannot convert value of type 'Int' to expected argument type 'CurriedClass'}} +CurriedClass.method2(c, 1.0)(b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +CurriedClass.method2(c, 1)(b: 1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +CurriedClass.method2(c, 2)(c: 1.0) // expected-error {{incorrect argument label in call (have 'c:', expected 'b:')}} + +CurriedClass.method3(c, 32, b: 1) +_ = CurriedClass.method3(c, 1, 2) // expected-error {{missing argument label 'b:' in call}} {{32-32=b: }} +_ = CurriedClass.method3(c, 1, b: 2)(32) // expected-error {{cannot call value of non-function type '()'}} +_ = CurriedClass.method3(1, 2) // FIXME-error {{use of instance member 'method3' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} +// expected-error @-1 {{missing argument for parameter 'b' in call}} +CurriedClass.method3(c, 1.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +CurriedClass.method3(c, 1) // expected-error {{missing argument for parameter 'b' in call}} + +CurriedClass.method3(c, c: 1.0) // expected-error {{missing argument for parameter 'b' in call}} extension CurriedClass { func f() { @@ -419,15 +419,12 @@ extension CurriedClass { } // QoI: "Extra argument" error when accidentally currying a method -CurriedClass.m1(2, b: 42) // expected-error {{use of instance member 'm1' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} - +CurriedClass.m1(2, b: 42) // FIXME-error {{use of instance member 'm1' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} +// expected-error @-1 {{missing argument for parameter #2 in call}} // QoI: Confusing error message when calling an instance method as a class method -CurriedClass.m2(12) // expected-error {{use of instance member 'm2' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} - - - - +CurriedClass.m2(12) // FIXME-error {{use of instance member 'm2' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} +// expected-error @-1 {{missing argument for parameter #2 in call}} // Incorrect diagnostic for failed member lookups within closures passed as arguments ("(_) -> _") func ident(_ t: T) -> T {} diff --git a/test/Constraints/existential_metatypes.swift b/test/Constraints/existential_metatypes.swift index 14db40095e508..220c6cf8ed417 100644 --- a/test/Constraints/existential_metatypes.swift +++ b/test/Constraints/existential_metatypes.swift @@ -83,5 +83,6 @@ class Something { func testP3(_ p: P3, something: Something) { - p.withP3(Something.takeP3(something)) + p.withP3(something.takeP3) + p.withP3 { Something.takeP3(something, $0) } } diff --git a/test/Constraints/lvalues.swift b/test/Constraints/lvalues.swift index 4352b412de3b8..34233578daa59 100644 --- a/test/Constraints/lvalues.swift +++ b/test/Constraints/lvalues.swift @@ -148,7 +148,7 @@ struct FooStruct { } func testFooStruct() { - FooStruct.instanceFunc0(FooStruct())() + FooStruct.instanceFunc0(FooStruct()) } // Don't load from explicit lvalues. @@ -232,4 +232,3 @@ func r23331567(_ fn: (x: inout Int) -> Void) { fn(x: &a) } r23331567 { $0 += 1 } - diff --git a/test/Constraints/members.swift b/test/Constraints/members.swift index f6e504d03de40..fcc794ccda040 100644 --- a/test/Constraints/members.swift +++ b/test/Constraints/members.swift @@ -25,7 +25,7 @@ var i : Int var x : X var yf : Y -func g0(_: (inout X) -> (Float) -> ()) {} +func g0(_: (inout X, Float) -> ()) {} _ = x.f0(i) x.f0(i).f1(i) @@ -193,30 +193,27 @@ func generic(_ t: T) { let _: () -> () = id(T.tum) // Instance member of archetype metatype - let _: (T) -> (Int) -> () = id(T.bar) - let _: (Int) -> () = id(T.bar(t)) + let _: (T, Int) -> () = id(T.bar) + let _: () = id(T.bar(t, 0)) _ = t.mut // expected-error{{partial application of 'mutating' method is not allowed}} _ = t.tum // expected-error{{static member 'tum' cannot be used on instance of type 'T'}} // Instance member of extension returning Self) - let _: (T) -> () -> T = id(T.returnSelfInstance) - let _: () -> T = id(T.returnSelfInstance(t)) - let _: T = id(T.returnSelfInstance(t)()) + let _: (T) -> T = id(T.returnSelfInstance) + let _: T = id(T.returnSelfInstance(t)) let _: () -> T = id(t.returnSelfInstance) let _: T = id(t.returnSelfInstance()) - let _: (T) -> (Bool) -> T? = id(T.returnSelfOptionalInstance) - let _: (Bool) -> T? = id(T.returnSelfOptionalInstance(t)) - let _: T? = id(T.returnSelfOptionalInstance(t)(false)) + let _: (T, Bool) -> T? = id(T.returnSelfOptionalInstance) + let _: T? = id(T.returnSelfOptionalInstance(t, false)) let _: (Bool) -> T? = id(t.returnSelfOptionalInstance) let _: T? = id(t.returnSelfOptionalInstance(true)) - let _: (T) -> (Bool) -> T! = id(T.returnSelfIUOInstance) - let _: (Bool) -> T! = id(T.returnSelfIUOInstance(t)) - let _: T! = id(T.returnSelfIUOInstance(t)(true)) + let _: (T, Bool) -> T! = id(T.returnSelfIUOInstance) + let _: T! = id(T.returnSelfIUOInstance(t, true)) let _: (Bool) -> T! = id(t.returnSelfIUOInstance) let _: T! = id(t.returnSelfIUOInstance(true)) @@ -238,9 +235,8 @@ func genericClassP(_ t: T) { let _: () = id(t.bas(0)) // Instance member of archetype metatype) - let _: (T) -> (Int) -> () = id(T.bas) - let _: (Int) -> () = id(T.bas(t)) - let _: () = id(T.bas(t)(1)) + let _: (T, Int) -> () = id(T.bas) + let _: () = id(T.bas(t, 1)) } //// @@ -273,14 +269,12 @@ func staticExistential(_ p: P.Type, pp: P.Protocol) { _ = P() // expected-error{{protocol type 'P' cannot be instantiated}} // Instance member of metatype - let _: (P) -> (Int) -> () = P.bar - let _: (Int) -> () = P.bar(ppp) - P.bar(ppp)(5) + let _: (P, Int) -> () = P.bar + P.bar(ppp, 5) // Instance member of metatype value - let _: (P) -> (Int) -> () = pp.bar - let _: (Int) -> () = pp.bar(ppp) - pp.bar(ppp)(5) + let _: (P, Int) -> () = pp.bar + pp.bar(ppp, 5) // Static member of existential metatype value let _: () -> () = p.tum @@ -319,9 +313,10 @@ func existentialClassP(_ p: ClassP) { let _: () = id(p.bas(0)) // Instance member of existential metatype) - let _: (ClassP) -> (Int) -> () = id(ClassP.bas) - let _: (Int) -> () = id(ClassP.bas(p)) - let _: () = id(ClassP.bas(p)(1)) + let _: (ClassP, Int) -> () = id(ClassP.bas) + let _: (Int) -> () = id(p.bas) + let _: (Int) -> () = id({ ClassP.bas(p, $0) }) + let _: () = id(ClassP.bas(p, 1)) } // Partial application of curried protocol methods @@ -377,7 +372,7 @@ class InstanceOrClassMethod { func testPreferClassMethodToCurriedInstanceMethod(_ obj: InstanceOrClassMethod) { let result = InstanceOrClassMethod.method(obj) let _: Bool = result // no-warning - let _: () -> Bool = InstanceOrClassMethod.method(obj) + let _: Bool = InstanceOrClassMethod.method(obj) } protocol Numeric { @@ -557,4 +552,3 @@ enum SomeErrorType { return nil } } - diff --git a/test/Generics/function_defs.swift b/test/Generics/function_defs.swift index 15bd40c9d81f0..1a73fb5d2e885 100644 --- a/test/Generics/function_defs.swift +++ b/test/Generics/function_defs.swift @@ -116,11 +116,11 @@ func testOverload(_ ovl: Ovl, ovl2: Ovl, var f3ovl_2 : (Ovl) -> Ovl = ovl2.f3 var f3ovl_3 : (Ovl) -> Ovl = other.f3 // expected-error{{ambiguous reference to member 'f3'}} - var f3i_unbound : (Ovl) -> (Int) -> Int = Ovl.f3 - var f3f_unbound : (Ovl) -> (Float) -> Float = Ovl.f3 - var f3f_unbound2 : (OtherOvl) -> (Float) -> Float = OtherOvl.f3 - var f3ovl_unbound_1 : (Ovl) -> (Ovl) -> Ovl = Ovl.f3 - var f3ovl_unbound_2 : (OtherOvl) -> (OtherOvl) -> OtherOvl = OtherOvl.f3 + var f3i_unbound : (Ovl, Int) -> Int = Ovl.f3 + var f3f_unbound : (Ovl, Float) -> Float = Ovl.f3 + var f3f_unbound2 : (OtherOvl, Float) -> Float = OtherOvl.f3 + var f3ovl_unbound_1 : (Ovl, Ovl) -> Ovl = Ovl.f3 + var f3ovl_unbound_2 : (OtherOvl, OtherOvl) -> OtherOvl = OtherOvl.f3 } //===----------------------------------------------------------------------===// diff --git a/test/Generics/generic_types.swift b/test/Generics/generic_types.swift index 712024fd7d8b4..1ddbc245cf7f8 100644 --- a/test/Generics/generic_types.swift +++ b/test/Generics/generic_types.swift @@ -125,8 +125,8 @@ i = xi.g() i = yi.f() // expected-error{{static member 'f' cannot be used on instance of type 'YI' (aka 'YT')}} i = yi.g() -var xif : (XI) -> () -> Int = XI.g -var gif : (YI) -> () -> Int = YI.g +var xif : (XI) -> Int = XI.g +var gif : (YI) -> Int = YI.g var ii : (Int, Int) = xi.prop ii = yi.prop diff --git a/test/IDE/complete_value_expr.swift b/test/IDE/complete_value_expr.swift index e8e729e7c9965..1f82aeb117ea9 100644 --- a/test/IDE/complete_value_expr.swift +++ b/test/IDE/complete_value_expr.swift @@ -13,9 +13,13 @@ // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CF3 | FileCheck %s -check-prefix=CF3 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CF4 | FileCheck %s -check-prefix=CF4 -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_FUNC_0 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_FUNC_0 -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_FUNC_1 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_FUNC_1 -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_FUNC_2 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_FUNC_2 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNAPPLIED_FUNC_0 | FileCheck %s -check-prefix=UNAPPLIED_FUNC_0 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNAPPLIED_FUNC_1 | FileCheck %s -check-prefix=UNAPPLIED_FUNC_1 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNAPPLIED_FUNC_2 | FileCheck %s -check-prefix=UNAPPLIED_FUNC_2 + +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=FLATTENED_APPLIED_FUNC_0 | FileCheck %s -check-prefix=FLATTENED_APPLIED_FUNC_0 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=FLATTENED_APPLIED_FUNC_1 | FileCheck %s -check-prefix=FLATTENED_APPLIED_FUNC_1 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=FLATTENED_APPLIED_FUNC_2 | FileCheck %s -check-prefix=FLATTENED_APPLIED_FUNC_2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_VARARG_FUNC_0 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_VARARG_FUNC_0 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_VARARG_FUNC_1 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_VARARG_FUNC_1 @@ -24,10 +28,15 @@ // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_OVERLOADED_FUNC_1 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_OVERLOADED_FUNC_1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_OVERLOADED_FUNC_2 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_OVERLOADED_FUNC_2 -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_CURRIED_FUNC_1 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_CURRIED_FUNC_1 -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_CURRIED_FUNC_2 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_CURRIED_FUNC_2 -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_CURRIED_FUNC_3 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_CURRIED_FUNC_3 -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IMPLICITLY_CURRIED_CURRIED_FUNC_4 | FileCheck %s -check-prefix=IMPLICITLY_CURRIED_CURRIED_FUNC_4 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNAPPLIED_CURRIED_FUNC_1 | FileCheck %s -check-prefix=UNAPPLIED_CURRIED_FUNC_1 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNAPPLIED_CURRIED_FUNC_2 | FileCheck %s -check-prefix=UNAPPLIED_CURRIED_FUNC_2 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNAPPLIED_CURRIED_FUNC_3 | FileCheck %s -check-prefix=UNAPPLIED_CURRIED_FUNC_3 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNAPPLIED_CURRIED_FUNC_4 | FileCheck %s -check-prefix=UNAPPLIED_CURRIED_FUNC_4 + +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=FLATTENED_CURRIED_FUNC_1 | FileCheck %s -check-prefix=FLATTENED_CURRIED_FUNC_1 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=FLATTENED_CURRIED_FUNC_2 | FileCheck %s -check-prefix=FLATTENED_CURRIED_FUNC_2 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=FLATTENED_CURRIED_FUNC_3 | FileCheck %s -check-prefix=FLATTENED_CURRIED_FUNC_3 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=FLATTENED_CURRIED_FUNC_4 | FileCheck %s -check-prefix=FLATTENED_CURRIED_FUNC_4 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IN_SWITCH_CASE_1 | FileCheck %s -check-prefix=IN_SWITCH_CASE // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IN_SWITCH_CASE_2 | FileCheck %s -check-prefix=IN_SWITCH_CASE @@ -240,26 +249,26 @@ struct FooStruct { } mutating - func curriedVoidFunc1()() {} + func curriedVoidFunc1() -> () -> Void {} mutating - func curriedVoidFunc2()(a: Int) {} + func curriedVoidFunc2() -> (Int) -> Void {} mutating - func curriedVoidFunc3(_ a: Int)() {} + func curriedVoidFunc3(_ a: Int) -> () -> Void {} mutating - func curriedVoidFunc4(_ a: Int)(b: Int) {} + func curriedVoidFunc4(_ a: Int) -> (Int) -> Void {} mutating - func curriedVoidFunc5(_ a: Int)(b: Int, _: (Float, Double)) {} + func curriedVoidFunc5(_ a: Int) -> (Int, (Float, Double)) -> Void {} mutating - func curriedStringFunc1()() -> String {} + func curriedStringFunc1() -> () -> String {} mutating - func curriedStringFunc2()(a: Int) -> String {} + func curriedStringFunc2() -> (Int) -> String {} mutating - func curriedStringFunc3(_ a: Int)() -> String {} + func curriedStringFunc3(_ a: Int) -> () -> String {} mutating - func curriedStringFunc4(_ a: Int)(b: Int) -> String {} + func curriedStringFunc4(_ a: Int) -> (Int) -> String {} mutating - func curriedStringFunc5(_ a: Int)(b: Int, _: (Float, Double)) -> String {} + func curriedStringFunc5(_ a: Int) -> (Int, (Float, Double)) -> String {} mutating func selectorVoidFunc1(_ a: Int, b x: Float) {} @@ -350,15 +359,15 @@ var fooObject: FooStruct // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: overloadedInstanceFunc2({#(x): Double#})[#Int#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: builderFunc1({#(a): Int#})[#FooStruct#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc1()[#() -> Void#]{{; name=.+$}} -// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc2()[#(a: Int) -> Void#]{{; name=.+$}} +// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc2()[#(Int) -> Void#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc3({#(a): Int#})[#() -> Void#]{{; name=.+$}} -// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc4({#(a): Int#})[#(b: Int) -> Void#]{{; name=.+$}} -// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc5({#(a): Int#})[#(b: Int, (Float, Double)) -> Void#]{{; name=.+$}} +// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc4({#(a): Int#})[#(Int) -> Void#]{{; name=.+$}} +// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc5({#(a): Int#})[#(Int, (Float, Double)) -> Void#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc1()[#() -> String#]{{; name=.+$}} -// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc2()[#(a: Int) -> String#]{{; name=.+$}} +// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc2()[#(Int) -> String#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc3({#(a): Int#})[#() -> String#]{{; name=.+$}} -// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc4({#(a): Int#})[#(b: Int) -> String#]{{; name=.+$}} -// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc5({#(a): Int#})[#(b: Int, (Float, Double)) -> String#]{{; name=.+$}} +// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc4({#(a): Int#})[#(Int) -> String#]{{; name=.+$}} +// FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc5({#(a): Int#})[#(Int, (Float, Double)) -> String#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: selectorVoidFunc1({#(a): Int#}, {#b: Float#})[#Void#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: selectorVoidFunc2({#(a): Int#}, {#b: Float#}, {#c: Double#})[#Void#]{{; name=.+$}} // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: selectorVoidFunc3({#(a): Int#}, {#b: (Float, Double)#})[#Void#]{{; name=.+$}} @@ -395,15 +404,15 @@ var fooObject: FooStruct // FOO_OBJECT_NO_DOT-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Double#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}, {#Int#}][#Double#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc1()[#() -> Void#]{{; name=.+$}} -// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc2()[#(a: Int) -> Void#]{{; name=.+$}} +// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc2()[#(Int) -> Void#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc3({#(a): Int#})[#() -> Void#]{{; name=.+$}} -// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc4({#(a): Int#})[#(b: Int) -> Void#]{{; name=.+$}} -// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc5({#(a): Int#})[#(b: Int, (Float, Double)) -> Void#]{{; name=.+$}} +// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc4({#(a): Int#})[#(Int) -> Void#]{{; name=.+$}} +// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc5({#(a): Int#})[#(Int, (Float, Double)) -> Void#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc1()[#() -> String#]{{; name=.+$}} -// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc2()[#(a: Int) -> String#]{{; name=.+$}} +// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc2()[#(Int) -> String#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc3({#(a): Int#})[#() -> String#]{{; name=.+$}} -// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc4({#(a): Int#})[#(b: Int) -> String#]{{; name=.+$}} -// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc5({#(a): Int#})[#(b: Int, (Float, Double)) -> String#]{{; name=.+$}} +// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc4({#(a): Int#})[#(Int) -> String#]{{; name=.+$}} +// FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc5({#(a): Int#})[#(Int, (Float, Double)) -> String#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .selectorVoidFunc1({#(a): Int#}, {#b: Float#})[#Void#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .selectorVoidFunc2({#(a): Int#}, {#b: Float#}, {#c: Double#})[#Void#]{{; name=.+$}} // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .selectorVoidFunc3({#(a): Int#}, {#b: (Float, Double)#})[#Void#]{{; name=.+$}} @@ -435,15 +444,15 @@ var fooObject: FooStruct // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: overloadedInstanceFunc2({#self: &FooStruct#})[#(Double) -> Int#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: builderFunc1({#self: &FooStruct#})[#(Int) -> FooStruct#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc1({#self: &FooStruct#})[#() -> () -> Void#]{{; name=.+$}} -// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc2({#self: &FooStruct#})[#() -> (a: Int) -> Void#]{{; name=.+$}} +// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc2({#self: &FooStruct#})[#() -> (Int) -> Void#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc3({#self: &FooStruct#})[#(Int) -> () -> Void#]{{; name=.+$}} -// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc4({#self: &FooStruct#})[#(Int) -> (b: Int) -> Void#]{{; name=.+$}} -// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc5({#self: &FooStruct#})[#(Int) -> (b: Int, (Float, Double)) -> Void#]{{; name=.+$}} +// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc4({#self: &FooStruct#})[#(Int) -> (Int) -> Void#]{{; name=.+$}} +// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedVoidFunc5({#self: &FooStruct#})[#(Int) -> (Int, (Float, Double)) -> Void#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc1({#self: &FooStruct#})[#() -> () -> String#]{{; name=.+$}} -// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc2({#self: &FooStruct#})[#() -> (a: Int) -> String#]{{; name=.+$}} +// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc2({#self: &FooStruct#})[#() -> (Int) -> String#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc3({#self: &FooStruct#})[#(Int) -> () -> String#]{{; name=.+$}} -// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc4({#self: &FooStruct#})[#(Int) -> (b: Int) -> String#]{{; name=.+$}} -// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc5({#self: &FooStruct#})[#(Int) -> (b: Int, (Float, Double)) -> String#]{{; name=.+$}} +// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc4({#self: &FooStruct#})[#(Int) -> (Int) -> String#]{{; name=.+$}} +// FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: curriedStringFunc5({#self: &FooStruct#})[#(Int) -> (Int, (Float, Double)) -> String#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: selectorVoidFunc1({#self: &FooStruct#})[#(Int, b: Float) -> Void#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: selectorVoidFunc2({#self: &FooStruct#})[#(Int, b: Float, c: Double) -> Void#]{{; name=.+$}} // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: selectorVoidFunc3({#self: &FooStruct#})[#(Int, b: (Float, Double)) -> Void#]{{; name=.+$}} @@ -492,15 +501,15 @@ var fooObject: FooStruct // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .overloadedInstanceFunc2({#self: &FooStruct#})[#(Double) -> Int#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .builderFunc1({#self: &FooStruct#})[#(Int) -> FooStruct#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc1({#self: &FooStruct#})[#() -> () -> Void#]{{; name=.+$}} -// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc2({#self: &FooStruct#})[#() -> (a: Int) -> Void#]{{; name=.+$}} +// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc2({#self: &FooStruct#})[#() -> (Int) -> Void#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc3({#self: &FooStruct#})[#(Int) -> () -> Void#]{{; name=.+$}} -// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc4({#self: &FooStruct#})[#(Int) -> (b: Int) -> Void#]{{; name=.+$}} -// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc5({#self: &FooStruct#})[#(Int) -> (b: Int, (Float, Double)) -> Void#]{{; name=.+$}} +// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc4({#self: &FooStruct#})[#(Int) -> (Int) -> Void#]{{; name=.+$}} +// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedVoidFunc5({#self: &FooStruct#})[#(Int) -> (Int, (Float, Double)) -> Void#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc1({#self: &FooStruct#})[#() -> () -> String#]{{; name=.+$}} -// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc2({#self: &FooStruct#})[#() -> (a: Int) -> String#]{{; name=.+$}} +// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc2({#self: &FooStruct#})[#() -> (Int) -> String#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc3({#self: &FooStruct#})[#(Int) -> () -> String#]{{; name=.+$}} -// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc4({#self: &FooStruct#})[#(Int) -> (b: Int) -> String#]{{; name=.+$}} -// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc5({#self: &FooStruct#})[#(Int) -> (b: Int, (Float, Double)) -> String#]{{; name=.+$}} +// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc4({#self: &FooStruct#})[#(Int) -> (Int) -> String#]{{; name=.+$}} +// FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .curriedStringFunc5({#self: &FooStruct#})[#(Int) -> (Int, (Float, Double)) -> String#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .selectorVoidFunc1({#self: &FooStruct#})[#(Int, b: Float) -> Void#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .selectorVoidFunc2({#self: &FooStruct#})[#(Int, b: Float, c: Double) -> Void#]{{; name=.+$}} // FOO_STRUCT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .selectorVoidFunc3({#self: &FooStruct#})[#(Int, b: (Float, Double)) -> Void#]{{; name=.+$}} @@ -577,7 +586,7 @@ func testCurriedFunc() { fooObject.curriedVoidFunc2()#^CF2^# // CF2: Begin completions -// CF2-NEXT: Pattern/ExprSpecific: ({#a: Int#})[#Void#]{{; name=.+$}} +// CF2-NEXT: Pattern/ExprSpecific: ({#Int#})[#Void#]{{; name=.+$}} // CF2-NEXT: End completions fooObject.curriedVoidFunc3(42)#^CF3^# @@ -587,39 +596,52 @@ func testCurriedFunc() { fooObject.curriedVoidFunc4(42)#^CF4^# // CF4: Begin completions -// CF4-NEXT: Pattern/ExprSpecific: ({#b: Int#})[#Void#]{{; name=.+$}} +// CF4-NEXT: Pattern/ExprSpecific: ({#Int#})[#Void#]{{; name=.+$}} // CF4-NEXT: End completions } -func testImplicitlyCurriedFunc(_ fs: inout FooStruct) { - FooStruct.instanceFunc0(&fs)#^IMPLICITLY_CURRIED_FUNC_0^# -// IMPLICITLY_CURRIED_FUNC_0: Begin completions -// IMPLICITLY_CURRIED_FUNC_0-NEXT: Pattern/ExprSpecific: ()[#Void#]{{; name=.+$}} -// IMPLICITLY_CURRIED_FUNC_0-NEXT: End completions +func testUnappliedFlattenedFunctions(_ fs: inout FooStruct) { + FooStruct.instanceFunc0#^UNAPPLIED_FUNC_0^# +// UNAPPLIED_FUNC_0: Begin completions +// UNAPPLIED_FUNC_0-NEXT: Pattern/ExprSpecific: ({#&(self): FooStruct#})[#Void#]{{; name=.+$}} +// UNAPPLIED_FUNC_0-NEXT: End completions + + FooStruct.instanceFunc1#^UNAPPLIED_FUNC_1^# +// UNAPPLIED_FUNC_1: Begin completions +// UNAPPLIED_FUNC_1-NEXT: Pattern/ExprSpecific: ({#&FooStruct#}, {#Int#})[#Void#]{{; name=.+$}} +// UNAPPLIED_FUNC_1-NEXT: End completions + + FooStruct.instanceFunc2#^UNAPPLIED_FUNC_2^# +// UNAPPLIED_FUNC_2: Begin completions +// UNAPPLIED_FUNC_2-NEXT: Pattern/ExprSpecific: ({#&FooStruct#}, {#Int#}, {#b: &Double#})[#Void#]{{; name=.+$}} +// UNAPPLIED_FUNC_2-NEXT: End completions + + FooStruct.instanceFunc0(&fs)#^FLATTENED_APPLIED_FUNC_0^# +// FLATTENED_APPLIED_FUNC_0: found code completion token +// FLATTENED_APPLIED_FUNC_0-NOT: Begin completions - FooStruct.instanceFunc1(&fs)#^IMPLICITLY_CURRIED_FUNC_1^# -// IMPLICITLY_CURRIED_FUNC_1: Begin completions -// IMPLICITLY_CURRIED_FUNC_1-NEXT: Pattern/ExprSpecific: ({#Int#})[#Void#]{{; name=.+$}} -// IMPLICITLY_CURRIED_FUNC_1-NEXT: End completions + FooStruct.instanceFunc1(&fs, 42)#^FLATTENED_APPLIED_FUNC_1^# +// FLATTENED_APPLIED_FUNC_1: found code completion token +// FLATTENED_APPLIED_FUNC_1-NOT: Begin completions - FooStruct.instanceFunc2(&fs)#^IMPLICITLY_CURRIED_FUNC_2^# -// IMPLICITLY_CURRIED_FUNC_2: Begin completions -// IMPLICITLY_CURRIED_FUNC_2-NEXT: Pattern/ExprSpecific: ({#Int#}, {#b: &Double#})[#Void#]{{; name=.+$}} -// IMPLICITLY_CURRIED_FUNC_2-NEXT: End completions + var d = 0.42 + FooStruct.instanceFunc2(&fs, 42, &d)#^FLATTENED_APPLIED_FUNC_2^# +// FLATTENED_APPLIED_FUNC_2: found code completion token +// FLATTENED_APPLIED_FUNC_2-NOT: Begin completions - FooStruct.varargInstanceFunc0(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_0^# + FooStruct.varargInstanceFunc0#^IMPLICITLY_CURRIED_VARARG_FUNC_0^# // IMPLICITLY_CURRIED_VARARG_FUNC_0: Begin completions -// IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: Pattern/ExprSpecific: ({#Int...#})[#Void#]{{; name=.+$}} +// IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: Pattern/ExprSpecific: ({#&FooStruct#}, {#Int...#})[#Void#]{{; name=.+$}} // IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: End completions - FooStruct.varargInstanceFunc1(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_1^# + FooStruct.varargInstanceFunc1#^IMPLICITLY_CURRIED_VARARG_FUNC_1^# // IMPLICITLY_CURRIED_VARARG_FUNC_1: Begin completions -// IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: Pattern/ExprSpecific: ({#Float#}, {#v: Int...#})[#Void#]{{; name=.+$}} +// IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: Pattern/ExprSpecific: ({#&FooStruct#}, {#Float#}, {#v: Int...#})[#Void#]{{; name=.+$}} // IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: End completions - FooStruct.varargInstanceFunc2(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_2^# + FooStruct.varargInstanceFunc2#^IMPLICITLY_CURRIED_VARARG_FUNC_2^# // IMPLICITLY_CURRIED_VARARG_FUNC_2: Begin completions -// IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: Pattern/ExprSpecific: ({#Float#}, {#b: Double#}, {#v: Int...#})[#Void#]{{; name=.+$}} +// IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: Pattern/ExprSpecific: ({#&FooStruct#}, {#Float#}, {#b: Double#}, {#v: Int...#})[#Void#]{{; name=.+$}} // IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: End completions // This call is ambiguous, and the expression is invalid. @@ -634,25 +656,45 @@ func testImplicitlyCurriedFunc(_ fs: inout FooStruct) { // IMPLICITLY_CURRIED_OVERLOADED_FUNC_2: found code completion token // IMPLICITLY_CURRIED_OVERLOADED_FUNC_2-NOT: Begin completions - FooStruct.curriedVoidFunc1(&fs)#^IMPLICITLY_CURRIED_CURRIED_FUNC_1^# -// IMPLICITLY_CURRIED_CURRIED_FUNC_1: Begin completions -// IMPLICITLY_CURRIED_CURRIED_FUNC_1-NEXT: Pattern/ExprSpecific: ()[#() -> ()#]{{; name=.+$}} -// IMPLICITLY_CURRIED_CURRIED_FUNC_1-NEXT: End completions + FooStruct.curriedVoidFunc1#^UNAPPLIED_CURRIED_FUNC_1^# +// UNAPPLIED_CURRIED_FUNC_1: Begin completions +// UNAPPLIED_CURRIED_FUNC_1-NEXT: Pattern/ExprSpecific: ({#&(self): FooStruct#})[#() -> Void#]{{; name=.+$}} +// UNAPPLIED_CURRIED_FUNC_1-NEXT: End completions + + FooStruct.curriedVoidFunc2#^UNAPPLIED_CURRIED_FUNC_2^# +// UNAPPLIED_CURRIED_FUNC_2: Begin completions +// UNAPPLIED_CURRIED_FUNC_2-NEXT: Pattern/ExprSpecific: ({#&(self): FooStruct#})[#(Int) -> Void#]{{; name=.+$}} +// UNAPPLIED_CURRIED_FUNC_2-NEXT: End completions + + FooStruct.curriedVoidFunc3#^UNAPPLIED_CURRIED_FUNC_3^# +// UNAPPLIED_CURRIED_FUNC_3: Begin completions +// UNAPPLIED_CURRIED_FUNC_3-NEXT: Pattern/ExprSpecific: ({#&FooStruct#}, {#Int#})[#() -> Void#]{{; name=.+$}} +// UNAPPLIED_CURRIED_FUNC_3-NEXT: End completions + + FooStruct.curriedVoidFunc4#^UNAPPLIED_CURRIED_FUNC_4^# +// UNAPPLIED_CURRIED_FUNC_4: Begin completions +// UNAPPLIED_CURRIED_FUNC_4-NEXT: Pattern/ExprSpecific: ({#&FooStruct#}, {#Int#})[#(Int) -> Void#]{{; name=.+$}} +// UNAPPLIED_CURRIED_FUNC_4-NEXT: End completions + + FooStruct.curriedVoidFunc1(&fs)#^FLATTENED_CURRIED_FUNC_1^# +// FLATTENED_CURRIED_FUNC_1: Begin completions +// FLATTENED_CURRIED_FUNC_1-NEXT: Pattern/ExprSpecific: ()[#Void#]{{; name=.+$}} +// FLATTENED_CURRIED_FUNC_1-NEXT: End completions - FooStruct.curriedVoidFunc2(&fs)#^IMPLICITLY_CURRIED_CURRIED_FUNC_2^# -// IMPLICITLY_CURRIED_CURRIED_FUNC_2: Begin completions -// IMPLICITLY_CURRIED_CURRIED_FUNC_2-NEXT: Pattern/ExprSpecific: ()[#(a: Int) -> ()#]{{; name=.+$}} -// IMPLICITLY_CURRIED_CURRIED_FUNC_2-NEXT: End completions + FooStruct.curriedVoidFunc2(&fs)#^FLATTENED_CURRIED_FUNC_2^# +// FLATTENED_CURRIED_FUNC_2: Begin completions +// FLATTENED_CURRIED_FUNC_2-NEXT: Pattern/ExprSpecific: ({#Int#})[#Void#]{{; name=.+$}} +// FLATTENED_CURRIED_FUNC_2-NEXT: End completions - FooStruct.curriedVoidFunc3(&fs)#^IMPLICITLY_CURRIED_CURRIED_FUNC_3^# -// IMPLICITLY_CURRIED_CURRIED_FUNC_3: Begin completions -// IMPLICITLY_CURRIED_CURRIED_FUNC_3-NEXT: Pattern/ExprSpecific: ({#Int#})[#() -> ()#]{{; name=.+$}} -// IMPLICITLY_CURRIED_CURRIED_FUNC_3-NEXT: End completions + FooStruct.curriedVoidFunc3(&fs, 42)#^FLATTENED_CURRIED_FUNC_3^# +// FLATTENED_CURRIED_FUNC_3: Begin completions +// FLATTENED_CURRIED_FUNC_3-NEXT: Pattern/ExprSpecific: ()[#Void#]{{; name=.+$}} +// FLATTENED_CURRIED_FUNC_3-NEXT: End completions - FooStruct.curriedVoidFunc4(&fs)#^IMPLICITLY_CURRIED_CURRIED_FUNC_4^# -// IMPLICITLY_CURRIED_CURRIED_FUNC_4: Begin completions -// IMPLICITLY_CURRIED_CURRIED_FUNC_4-NEXT: Pattern/ExprSpecific: ({#Int#})[#(b: Int) -> ()#]{{; name=.+$}} -// IMPLICITLY_CURRIED_CURRIED_FUNC_4-NEXT: End completions + FooStruct.curriedVoidFunc4(&fs, 42)#^FLATTENED_CURRIED_FUNC_4^# +// FLATTENED_CURRIED_FUNC_4: Begin completions +// FLATTENED_CURRIED_FUNC_4-NEXT: Pattern/ExprSpecific: ({#Int#})[#Void#]{{; name=.+$}} +// FLATTENED_CURRIED_FUNC_4-NEXT: End completions } //===--- @@ -903,7 +945,7 @@ func testInsideCurriedFunctionCall1() { var a = FooStruct() a.curriedVoidFunc4(42)(#^INSIDE_CURRIED_FUNCTION_CALL_1^# // INSIDE_CURRIED_FUNCTION_CALL_1: Begin completions -// INSIDE_CURRIED_FUNCTION_CALL_1-DAG: Pattern/ExprSpecific: ['(']{#b: Int#})[#Void#]{{; name=.+$}} +// INSIDE_CURRIED_FUNCTION_CALL_1-DAG: Pattern/ExprSpecific: ['(']{#Int#})[#Void#]{{; name=.+$}} // INSIDE_CURRIED_FUNCTION_CALL_1: End completions } diff --git a/test/Interpreter/currying_protocols.swift b/test/Interpreter/currying_protocols.swift index da225d874e5bc..7a343a8eea997 100644 --- a/test/Interpreter/currying_protocols.swift +++ b/test/Interpreter/currying_protocols.swift @@ -41,26 +41,23 @@ final class Archimedes : Gymnast { //// func genericOlympicGames(_ g1: T) -> T { - let f1: (T) -> (Double) -> T = T.backflip - let f2: (Double) -> T = f1(g1) - let g2: T = f2(180) + let f1: (T, Double) -> T = T.backflip + let g2: T = f1(g1, 180) let f3: (Double) -> T = g2.backflip let g3: T = f3(360) - let f4: (T) -> () -> (Medal) -> T = T.compete - let f5: () -> (Medal) -> T = f4(g3) - let f6: (Medal) -> T = f5() - let g4: T = f6(Medal.Silver) + let f4: (T) -> (Medal) -> T = T.compete + let f5: (Medal) -> T = f4(g3) + let g4: T = f5(Medal.Silver) let f7: () -> (Medal) -> T = g4.compete let f8: (Medal) -> T = f7() let g5: T = f8(Medal.Gold) - let f9: (T) -> () -> (Steroids) -> () = T.scandal - let f10: () -> (Steroids) -> () = f9(g5) - let f11: (Steroids) -> () = f10() - f11(Steroids()) + let f9: (T) -> (Steroids) -> () = T.scandal + let f10: (Steroids) -> () = f9(g5) + f10(Steroids()) let f12: () -> (Steroids) -> () = g5.scandal let f13: (Steroids) -> () = f12() diff --git a/test/NameBinding/name_lookup.swift b/test/NameBinding/name_lookup.swift index 29089c5aa5e22..84c0c21657d2b 100644 --- a/test/NameBinding/name_lookup.swift +++ b/test/NameBinding/name_lookup.swift @@ -223,12 +223,12 @@ class ThisDerived1 : ThisBase1 { self.baseInstanceVar = 42 // expected-error {{member 'baseInstanceVar' cannot be used on type 'ThisDerived1'}} self.baseProp = 42 // expected-error {{member 'baseProp' cannot be used on type 'ThisDerived1'}} self.baseFunc0() // expected-error {{missing argument}} - self.baseFunc0(ThisBase1())() // expected-error {{'(ThisBase1) -> () -> ()' is not convertible to '(ThisDerived1) -> () -> ()'}} - - self.baseFunc0(ThisDerived1())() - self.baseFunc1(42) // expected-error {{cannot convert value of type 'Int' to expected argument type 'ThisBase1'}} - self.baseFunc1(ThisBase1())(42) // expected-error {{'(ThisBase1) -> (Int) -> ()' is not convertible to '(ThisDerived1) -> (Int) -> ()'}} - self.baseFunc1(ThisDerived1())(42) + self.baseFunc0(ThisBase1()) // expected-error {{'(ThisBase1) -> ()' is not convertible to '(ThisDerived1) -> ()'}} + + self.baseFunc0(ThisDerived1()) + self.baseFunc1(42) // FIXME: expected-error {{missing argument for parameter #2 in call}} + self.baseFunc1(ThisBase1(), 42) // expected-error {{'(ThisBase1, Int) -> ()' is not convertible to '(ThisDerived1, Int) -> ()'}} + self.baseFunc1(ThisDerived1(), 42) self[0] = 42.0 // expected-error {{instance member 'subscript' cannot be used on type 'ThisDerived1'}} self.baseStaticVar = 42 self.baseStaticProp = 42 @@ -253,8 +253,8 @@ class ThisDerived1 : ThisBase1 { self.derivedInstanceVar = 42 // expected-error {{member 'derivedInstanceVar' cannot be used on type 'ThisDerived1'}} self.derivedProp = 42 // expected-error {{member 'derivedProp' cannot be used on type 'ThisDerived1'}} self.derivedFunc0() // expected-error {{missing argument}} - self.derivedFunc0(ThisBase1())() // expected-error {{cannot convert value of type 'ThisBase1' to expected argument type 'ThisDerived1'}} - self.derivedFunc0(ThisDerived1())() + self.derivedFunc0(ThisBase1()) // expected-error {{cannot convert value of type 'ThisBase1' to expected argument type 'ThisDerived1'}} + self.derivedFunc0(ThisDerived1()) self.derivedStaticVar = 42 self.derivedStaticProp = 42 self.derivedStaticFunc0() @@ -292,9 +292,9 @@ class ThisDerived1 : ThisBase1 { super.baseInstanceVar = 42 // expected-error {{member 'baseInstanceVar' cannot be used on type 'ThisBase1'}} super.baseProp = 42 // expected-error {{member 'baseProp' cannot be used on type 'ThisBase1'}} super.baseFunc0() // expected-error {{missing argument}} - super.baseFunc0(ThisBase1())() - super.baseFunc1(42) // expected-error {{cannot convert value of type 'Int' to expected argument type 'ThisBase1'}} - super.baseFunc1(ThisBase1())(42) + super.baseFunc0(ThisBase1()) + super.baseFunc1(42) // FIXME: expected-error {{missing argument for parameter #2 in call}} + super.baseFunc1(ThisBase1(), 42) super[0] = 42.0 // expected-error {{instance member 'subscript' cannot be used on type 'ThisBase1'}} super.baseStaticVar = 42 super.baseStaticProp = 42 @@ -302,7 +302,7 @@ class ThisDerived1 : ThisBase1 { super.baseExtProp = 42 // expected-error {{member 'baseExtProp' cannot be used on type 'ThisBase1'}} super.baseExtFunc0() // expected-error {{missing argument}} - super.baseExtStaticVar = 42 + super.baseExtStaticVar = 42 super.baseExtStaticProp = 42 // expected-error {{member 'baseExtStaticProp' cannot be used on type 'ThisBase1'}} super.baseExtStaticFunc0() @@ -457,13 +457,13 @@ protocol MyProto { // struct DefaultArgumentFromExtension { - func g(_ x: (DefaultArgumentFromExtension) -> () -> () = f) { + func g(_ x: (DefaultArgumentFromExtension) -> () = f) { let f = 42 var x2 = x - x2 = f // expected-error{{cannot assign value of type 'Int' to type '(DefaultArgumentFromExtension) -> () -> ()'}} + x2 = f // expected-error{{cannot assign value of type 'Int' to type '(DefaultArgumentFromExtension) -> ()'}} _ = x2 } - var x : (DefaultArgumentFromExtension) -> () -> () = f + var x : (DefaultArgumentFromExtension) -> () = f } extension DefaultArgumentFromExtension { func f() {} @@ -480,8 +480,9 @@ struct MyStruct { // QoI: poor diagnostic initializing a variable with a non-class func class Test19935319 { - let i = getFoo() // expected-error {{cannot use instance member 'getFoo' within property initializer; property initializers run before 'self' is available}} - + // FIXME-error @+1 {{cannot use instance member 'getFoo' within property initializer; property initializers run before 'self' is available}} + let i = getFoo() // expected-error {{missing argument for parameter #1 in call}} + func getFoo() -> Int {} } @@ -492,7 +493,8 @@ class rdar27013358 { return 2 } init(defaulted value: Int = defaultValue) {} // expected-error {{cannot use instance member 'defaultValue' as a default parameter}} - init(another value: Int = returnTwo()) {} // expected-error {{cannot use instance member 'returnTwo' as a default parameter}} + // FIXME-error @+1 {{cannot use instance member 'returnTwo' as a default parameter}} + init(another value: Int = returnTwo()) {} // expected-error {{missing argument for parameter #1 in call}} } // QoI: ivar default initializer cannot reference other default initialized ivars? @@ -500,4 +502,3 @@ class r23904262 { let x = 1 let y = x // expected-error {{cannot use instance member 'x' within property initializer; property initializers run before 'self' is available}} } - diff --git a/test/SILGen/cf_members.swift b/test/SILGen/cf_members.swift index bfeea910851bb..f967ba5054bdd 100644 --- a/test/SILGen/cf_members.swift +++ b/test/SILGen/cf_members.swift @@ -65,8 +65,8 @@ public func foo(_ x: Double) { z = c(x) // CHECK: [[THUNK:%.*]] = function_ref [[THUNK_NAME]] // CHECK: thin_to_thick_function [[THUNK]] - let d: (Struct1) -> (Double) -> Struct1 = Struct1.translate(radians:) - z = d(z)(x) + let d: (Struct1, Double) -> Struct1 = Struct1.translate(radians:) + z = d(z, x) // TODO: If we implement SE-0042, this should thunk the value Struct1 param // to a const* param to the underlying C symbol. @@ -90,7 +90,7 @@ public func foo(_ x: Double) { // CHECK: thin_to_thick_function [[THUNK]] let g = Struct1.scale // CHECK: [[ZVAL:%.*]] = load [[Z]] - z = g(z)(x) + z = g(z, x) // TODO: If we implement SE-0042, this should directly reference the // underlying C function. @@ -166,8 +166,8 @@ public func foo(_ x: Double) { z.selfComesLast(x: x) let k: (Double) -> () = z.selfComesLast(x:) k(x) - let l: (Struct1) -> (Double) -> () = Struct1.selfComesLast(x:) - l(z)(x) + let l: (Struct1, Double) -> () = Struct1.selfComesLast(x:) + l(z, x) // TODO: If we implement SE-0042, this should thunk to reorder the arguments. // let m: @convention(c) (Struct1, Double) -> () = Struct1.selfComesLast(x:) @@ -179,9 +179,8 @@ public func foo(_ x: Double) { z.selfComesThird(a: y, b: 0, x: x) let n: (Int32, Float, Double) -> () = z.selfComesThird(a:b:x:) n(y, 0, x) - let o: (Struct1) -> (Int32, Float, Double) -> () - = Struct1.selfComesThird(a:b:x:) - o(z)(y, 0, x) + let o: (Struct1, Int32, Float, Double) -> () = Struct1.selfComesThird(a:b:x:) + o(z, y, 0, x) // TODO: If we implement SE-0042, this should thunk to reorder the arguments. // let p: @convention(c) (Struct1, Int, Float, Double) -> () @@ -239,8 +238,8 @@ public func bar(_ x: Double) { let a: (Double) -> CCPowerSupply = CCPowerSupply.init(watts:) let _ = a(x) - let b: (CCRefrigerator) -> () -> () = CCRefrigerator.open - b(fridge)() + let b: (CCRefrigerator) -> () = CCRefrigerator.open + b(fridge) let c = fridge.open c() } diff --git a/test/SILGen/functions.swift b/test/SILGen/functions.swift index 8b875e690a4c0..9d7470c715fb2 100644 --- a/test/SILGen/functions.swift +++ b/test/SILGen/functions.swift @@ -130,7 +130,7 @@ func calls(_ i:Int, j:Int, k:Int) { // CHECK: [[THUNK:%.*]] = function_ref @_TFV9functions10SomeStruct6method{{.*}} // CHECK: [[THUNK_THICK:%.*]] = thin_to_thick_function [[THUNK]] var stm1 = SomeStruct.method - stm1(&st)(i) + stm1(&st, i) // -- Curry 'self' onto method argument lists dispatched using class_method. @@ -149,17 +149,14 @@ func calls(_ i:Int, j:Int, k:Int) { // CHECK: apply [[METHOD]]([[I]], [[C]]) c.method(i) - // -- Curry 'self' onto unapplied methods dispatched using class_method. - // CHECK: [[METHOD_CURRY_THUNK:%.*]] = function_ref @_TFC9functions9SomeClass6method{{.*}} - // CHECK: apply [[METHOD_CURRY_THUNK]] - var cm1 = SomeClass.method(c) - cm1(i) - + // CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @_TFC9functions9SomeClass6methodFBi64_T_ : $@convention(thin) (@owned SomeClass) -> @owned @callee_owned (Builtin.Int64) -> () + // CHECK: [[FUNC_THICK:%[0-9]+]] = thin_to_thick_function [[FUNC_THIN]] + // CHECK: [[THUNK:%[0-9]+]] = function_ref @_TTRXFo_oC9functions9SomeClass{{.*}} : $@convention(thin) (@owned SomeClass, Builtin.Int64, @owned @callee_owned (@owned SomeClass) -> @owned @callee_owned (Builtin.Int64) -> ()) -> () + // CHECK: [[METHOD:%[0-9]+]] = partial_apply [[THUNK]]([[FUNC_THICK]]) // CHECK: [[C:%[0-9]+]] = load [[CADDR]] - // CHECK: [[METHOD:%[0-9]+]] = class_method [[C]] : {{.*}}, #SomeClass.method!1 // CHECK: [[I:%[0-9]+]] = load [[IADDR]] - // CHECK: apply [[METHOD]]([[I]], [[C]]) - SomeClass.method(c)(i) + // CHECK: apply [[METHOD]]([[C]], [[I]]) + SomeClass.method(c, i) // -- Curry the Type onto static method argument lists. diff --git a/test/SILGen/guaranteed_self.swift b/test/SILGen/guaranteed_self.swift index 28ed628464a47..e5784bb7562a3 100644 --- a/test/SILGen/guaranteed_self.swift +++ b/test/SILGen/guaranteed_self.swift @@ -390,11 +390,11 @@ class D: C { } } -func S_curryThunk(_ s: S) -> ((S) -> (Int) -> ()/*, Int -> ()*/) { +func S_curryThunk(_ s: S) -> ((S, Int) -> ()/*, (Int) -> ()*/) { return (S.foo /*, s.foo*/) } -func AO_curryThunk(_ ao: AO) -> ((AO) -> (Int) -> ()/*, Int -> ()*/) { +func AO_curryThunk(_ ao: AO) -> ((AO, Int) -> ()/*, (Int) -> ()*/) { return (AO.foo /*, ao.foo*/) } diff --git a/test/SILGen/objc_protocols.swift b/test/SILGen/objc_protocols.swift index 639bdb3f48570..5b27c36fa8416 100644 --- a/test/SILGen/objc_protocols.swift +++ b/test/SILGen/objc_protocols.swift @@ -48,13 +48,15 @@ func objc_generic_partial_apply(_ x: T) { // CHECK: [[FN:%.*]] = function_ref @_TTOFP14objc_protocols9NSRuncing5runceFT_CSo8NSObject // CHECK-NEXT: [[METHOD:%.*]] = partial_apply [[FN]]() - // CHECK-NEXT: strong_release [[METHOD]] + // CHECK: [[THUNK:%.*]] = function_ref @_TTRGRx14objc_protocols9NSRuncing + // CHECK-NEXT: [[METHOD_FLAT:%.*]] = partial_apply [[THUNK]]([[METHOD]] + // CHECK-NEXT: strong_release [[METHOD_FLAT]] _ = T.runce // CHECK: [[FN:%.*]] = function_ref @_TTOZFP14objc_protocols9NSRuncing5minceFT_CSo8NSObject // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick T.Type // CHECK-NEXT: [[METHOD:%.*]] = apply [[FN]]([[METATYPE]]) - // CHECK-NEXT: strong_release [[METHOD:%.*]] + // CHECK-NEXT: strong_release [[METHOD]] _ = T.mince } diff --git a/test/SILGen/partial_apply_generic.swift b/test/SILGen/partial_apply_generic.swift index ac9612def3ac3..eecce9385165d 100644 --- a/test/SILGen/partial_apply_generic.swift +++ b/test/SILGen/partial_apply_generic.swift @@ -45,19 +45,22 @@ func getInstanceFunc1(t: T) -> () -> () { // CHECK-NEXT: return // CHECK-LABEL: sil hidden @_TF21partial_apply_generic16getInstanceFunc2 -func getInstanceFunc2(t: T) -> (T) -> () -> () { +func getInstanceFunc2(t: T) -> (T) -> () { // CHECK: [[REF:%.*]] = function_ref @_TFP21partial_apply_generic3Foo12instanceFunc // CHECK-NEXT: partial_apply [[REF]]( +// CHECK: [[THUNK:%.*]] = function_ref @_TTRGRx21partial_apply_generic3Foo +// CHECK-NEXT: partial_apply [[THUNK]]( return T.instanceFunc // CHECK-NEXT: destroy_addr %0 : $* // CHECK-NEXT: return } // CHECK-LABEL: sil hidden @_TF21partial_apply_generic16getInstanceFunc3 -func getInstanceFunc3(t: T.Type) -> (T) -> () -> () { +func getInstanceFunc3(t: T.Type) -> (T) -> () { // CHECK: [[REF:%.*]] = function_ref @_TFP21partial_apply_generic3Foo12instanceFunc // CHECK-NEXT: partial_apply [[REF]]( +// CHECK: [[THUNK:%.*]] = function_ref @_TTRGRx21partial_apply_generic3Foo +// CHECK-NEXT: partial_apply [[THUNK]]( return t.instanceFunc // CHECK-NEXT: return } - diff --git a/test/TypeCoercion/overload_member.swift b/test/TypeCoercion/overload_member.swift index ce1f5e7bc1055..69363b42a3c07 100644 --- a/test/TypeCoercion/overload_member.swift +++ b/test/TypeCoercion/overload_member.swift @@ -42,7 +42,7 @@ func test_method_overload_coerce(_ a: A, x: inout X, y: inout Y, z: Z) { func test_method_value_coerce(_ a: A) { var _ : (X) -> X = a.f - var _ : (A) -> (X) -> X = A.f + var _ : (A, X) -> X = A.f } func test_static_method_overload(_ a: A, x: X, y: Y) { @@ -70,9 +70,9 @@ func test_mixed_overload(_ a: A, x: X, y: Y) { var x1 = a.mixed(x: x) x1 = x var y1 = a.mixed(y: y) // expected-error{{incorrect argument label in call (have 'y:', expected 'x:')}} - + A.mixed(x) // expected-error{{missing argument label 'y:' in call}} - var x2 = A.mixed(a)(x: x) + var x2 = A.mixed(a, x: x) x2 = x var y2 = A.mixed(y: y) y2 = y @@ -90,7 +90,7 @@ func test_mixed_method_value_coerce(_ a: A) { var _ : (X) -> X = a.mixed var _ : (Y) -> Y = A.mixed var _ : (Y) -> Y = a.mixed; // expected-error{{cannot convert value of type '(x: X) -> X' to specified type '(Y) -> Y'}} - var _ : (A) -> (X) -> X = A.mixed + var _ : (A, X) -> X = A.mixed } extension A { @@ -119,8 +119,8 @@ extension A { func test_method_value_coerce() { var _ : (X) -> X = f - var _ : (A) -> (X) -> X = A.f - var _ : (A) -> (X) -> X = A.f + var _ : (A, X) -> X = A.f + var _ : (A, X) -> X = A.f } func test_mixed_overload_coerce(x: inout X, y: Y, z: Z) { @@ -132,7 +132,7 @@ extension A { var _ : (X) -> X = mixed var _ : (Y) -> Y = mixed; // expected-error{{cannot convert value of type '(x: X) -> X' to specified type '(Y) -> Y'}} var _ : (Y) -> Y = mixed; // expected-error{{cannot convert value of type '(x: X) -> X' to specified type '(Y) -> Y'}} - var _ : (A) -> (X) -> X = A.mixed + var _ : (A, X) -> X = A.mixed } class func test_method_overload_static(x: X, y: Y, z: Z) { @@ -158,7 +158,7 @@ extension A { class func test_mixed_overload_static(a: A, x: X, y: Y) { mixed(x) // expected-error{{missing argument label 'y:' in call}} - var x2 = mixed(a)(x: x) + var x2 = mixed(a, x: x) x2 = x var y2 = mixed(y: y) y2 = y @@ -172,13 +172,13 @@ extension A { class func test_mixed_method_value_coerce_static() { var _ : (Y) -> Y = mixed - var _ : (A) -> (X) -> X = mixed + var _ : (A, X) -> X = mixed } } var clams : X -struct WeirdIvarLookupBehavior { +struct WeirdIvarLookupBehavior { var clams : Y func f() { diff --git a/test/decl/enum/enumtest.swift b/test/decl/enum/enumtest.swift index c65ee6a0b5774..ee876902a80ea 100644 --- a/test/decl/enum/enumtest.swift +++ b/test/decl/enum/enumtest.swift @@ -215,7 +215,7 @@ func f() { // Test that we can get the "address of a member". var _ : () -> () = UnionTest1.baz - var _ : (UnionTest1) -> () -> () = UnionTest1.bar + var _ : (UnionTest1) -> () = UnionTest1.bar } func union_error(_ a: ZeroOneTwoThree) { diff --git a/test/expr/unary/selector/fixits.swift b/test/expr/unary/selector/fixits.swift index a6a34e54ad6f5..f2615f173dd0c 100644 --- a/test/expr/unary/selector/fixits.swift +++ b/test/expr/unary/selector/fixits.swift @@ -72,8 +72,8 @@ func testDeprecatedStringLiteralSelector() { _ = "method3" as Selector // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-28=#selector(Foo.method3)}} // Overloaded cases - _ = "overloadedWithInt:" as Selector // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-39=#selector(Bar.overloaded(_:) as (Bar) -> (Int) -> ())}} - _ = "overloadedWithString:" as Selector // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-42=#selector(Bar.overloaded(_:) as (Bar) -> (String) -> ())}} + _ = "overloadedWithInt:" as Selector // FIXME-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-39=#selector(Bar.overloaded(_:) as (Bar) -> (Int) -> ())}} + _ = "overloadedWithString:" as Selector // FIXME-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-42=#selector(Bar.overloaded(_:) as (Bar) -> (String) -> ())}} _ = "staticOverloadedWithInt:" as Selector // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-45=#selector(Bar.staticOverloaded(_:) as (Int) -> ())}} _ = "staticOverloadedWithString:" as Selector // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-48=#selector(Bar.staticOverloaded(_:) as (String) -> ())}} @@ -85,7 +85,7 @@ func testDeprecatedStringLiteralSelector() { // We need coercion here because we asked for a selector from an // instance method with the same name as (but a different selector // from) a static method. - _ = "theInstanceOne:" as Selector // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-36=#selector(Bar.staticOrNonStatic2(_:) as (Bar) -> (Int) -> ())}} + _ = "theInstanceOne:" as Selector // FIXME-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-36=#selector(Bar.staticOrNonStatic2(_:) as (Bar) -> (Int) -> ())}} // Note: from Foundation _ = "initWithArray:" as Selector // expected-warning{{use of string literal for Objective-C selectors is deprecated; use '#selector' instead}}{{7-35=#selector(NSSet.init(array:))}} diff --git a/validation-test/compiler_crashers_2_fixed/0011-rdar20985062.swift b/validation-test/compiler_crashers_2_fixed/0011-rdar20985062.swift index f460e3d3eef79..7085d3a17031a 100644 --- a/validation-test/compiler_crashers_2_fixed/0011-rdar20985062.swift +++ b/validation-test/compiler_crashers_2_fixed/0011-rdar20985062.swift @@ -8,7 +8,7 @@ class A { func accept(_ t: T.Type, _ value: inout T) {} -typealias TheType = (A) -> ([(x: Int, y: Double)]) -> () +typealias TheType = (A, [(x: Int, y: Double)]) -> () var curried = A.foo accept(TheType.self, &curried)