From 68e09d64fdb6a3265002ae7753803cfcce98be91 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 17 Jan 2020 00:10:29 -0300 Subject: [PATCH 1/6] [CSFix] Creating object literal module import fix --- lib/Sema/CSDiagnostics.cpp | 50 ++++++++++++++++++++++++++++++++++++++ lib/Sema/CSDiagnostics.h | 9 +++++++ lib/Sema/CSFix.cpp | 25 +++++++++++++++++++ lib/Sema/CSFix.h | 21 ++++++++++++++++ lib/Sema/CSSimplify.cpp | 17 +++++++++++-- 5 files changed, 120 insertions(+), 2 deletions(-) diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index dbe3a5b7dc0f4..eefacdb127dc6 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -6038,3 +6038,53 @@ bool UnableToInferClosureReturnType::diagnoseAsError() { return true; } + +static std::tuple +getImportModuleAndDefaultType(const ASTContext &ctx, ProtocolDecl *protocol) { + const auto &target = ctx.LangOpts.Target; + if (protocol == + ctx.getProtocol(KnownProtocolKind::ExpressibleByColorLiteral)) { + if (target.isMacOSX()) { + return std::make_tuple("AppKit", "NSColor"); + } else if (target.isiOS() || target.isTvOS()) { + return std::make_tuple("UIKit", "UIColor"); + } + } else if (protocol == + ctx.getProtocol(KnownProtocolKind::ExpressibleByImageLiteral)) { + if (target.isMacOSX()) { + return std::make_tuple("AppKit", "NSImage"); + } else if (target.isiOS() || target.isTvOS()) { + return std::make_tuple("UIKit", "UIImage"); + } + } else if (protocol == + ctx.getProtocol( + KnownProtocolKind::ExpressibleByFileReferenceLiteral)) { + return std::make_tuple("Foundation", "URL"); + } + return std::make_tuple("", ""); +} + +bool UnableToInferProtocolLiteralType::diagnoseAsError() { + auto *locator = getLocator(); + auto &cs = getConstraintSystem(); + auto *expr = cast(locator->getAnchor()); + + auto &ctx = cs.getASTContext(); + auto protocol = TypeChecker::getLiteralProtocol(ctx, expr); + assert(protocol); + auto plainName = expr->getLiteralKindPlainName(); + + StringRef importModule; + StringRef importDefaultTypeName; + std::tie(importModule, importDefaultTypeName) = + getImportModuleAndDefaultType(ctx, protocol); + + emitDiagnostic(expr->getLoc(), diag::object_literal_default_type_missing, + plainName); + if (!importModule.empty()) { + emitDiagnostic(expr->getLoc(), diag::object_literal_resolve_import, + importModule, importDefaultTypeName, plainName); + } + + return true; +} diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h index a94be81e1c36a..cbe28453808e1 100644 --- a/lib/Sema/CSDiagnostics.h +++ b/lib/Sema/CSDiagnostics.h @@ -1926,6 +1926,15 @@ class UnableToInferClosureReturnType final : public FailureDiagnostic { bool diagnoseAsError(); }; +class UnableToInferProtocolLiteralType final : public FailureDiagnostic { +public: + UnableToInferProtocolLiteralType(ConstraintSystem &cs, + ConstraintLocator *locator) + : FailureDiagnostic(cs, locator) {} + + bool diagnoseAsError(); +}; + } // end namespace constraints } // end namespace swift diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp index 21abf55ddd143..b9c269f60f43c 100644 --- a/lib/Sema/CSFix.cpp +++ b/lib/Sema/CSFix.cpp @@ -1168,3 +1168,28 @@ SpecifyClosureReturnType::create(ConstraintSystem &cs, ConstraintLocator *locator) { return new (cs.getAllocator()) SpecifyClosureReturnType(cs, locator); } + +bool SpecifyObjectLiteralTypeImport::diagnose(bool asNote) const { + auto &cs = getConstraintSystem(); + UnableToInferProtocolLiteralType failure(cs, getLocator()); + return failure.diagnose(asNote); +} + +SpecifyObjectLiteralTypeImport * +SpecifyObjectLiteralTypeImport::attempt(ConstraintSystem &cs, + ConstraintLocator *locator) { + // FIXME: ArgumentMismatchFailure is currently used from CSDiag, meaning + // we could endup emiting this diagnostic duplicated. + if (cs.Options.contains(ConstraintSystemFlags::SubExpressionDiagnostics)) + return nullptr; + + auto *anchor = locator->getAnchor(); + if (!isa(anchor)) + return nullptr; + + // * The object literal has no contextual type + if (cs.getContextualType()) + return nullptr; + + return new (cs.getAllocator()) SpecifyObjectLiteralTypeImport(cs, locator); +} diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h index d8550f6ef09a9..6276f40ec86fb 100644 --- a/lib/Sema/CSFix.h +++ b/lib/Sema/CSFix.h @@ -235,6 +235,11 @@ enum class FixKind : uint8_t { /// Closure return type has to be explicitly specified because it can't be /// inferred in current context e.g. because it's a multi-statement closure. SpecifyClosureReturnType, + + /// Object literal type coudn't be infered because the module where it's + /// protocol type was not imported. + SpecifyObjectLiteralTypeImport, + }; class ConstraintFix { @@ -1633,6 +1638,22 @@ class SpecifyClosureReturnType final : public ConstraintFix { ConstraintLocator *locator); }; +class SpecifyObjectLiteralTypeImport final : public ConstraintFix { + SpecifyObjectLiteralTypeImport(ConstraintSystem &cs, ConstraintLocator *locator) + : ConstraintFix(cs, FixKind::SpecifyObjectLiteralTypeImport, locator) {} + +public: + std::string getName() const { + return "specify object literal protocol type import"; + } + + bool diagnose(bool asNote = false) const; + + static SpecifyObjectLiteralTypeImport *attempt(ConstraintSystem &cs, + ConstraintLocator *locator); + +}; + } // end namespace constraints } // end namespace swift diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index aa4b80319b932..ebbcc8b4c7794 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -1027,7 +1027,18 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments( argsWithLabels, params, paramInfo, argInfo->HasTrailingClosure, cs.shouldAttemptFixes(), listener, parameterBindings)) return cs.getTypeMatchFailure(locator); - + + if (!callee) { + // If we couldn't find a callee, diagnose and maybe suggest + // import a module. + if (cs.shouldAttemptFixes()) { + if (auto *fix = SpecifyObjectLiteralTypeImport::attempt(cs, loc)) { + if (cs.recordFix(fix)) + return cs.getTypeMatchFailure(locator); + } + } + } + auto extraArguments = listener.getExtraneousArguments(); if (!extraArguments.empty()) { if (RemoveExtraneousArguments::isMinMaxNameShadowing(cs, locator)) @@ -1047,6 +1058,7 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments( return cs.getTypeMatchFailure(locator); } } + } // If this application is part of an operator, then we allow an implicit @@ -8739,7 +8751,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint( case FixKind::UseValueTypeOfRawRepresentative: case FixKind::ExplicitlyConstructRawRepresentable: case FixKind::SpecifyBaseTypeForContextualMember: - case FixKind::CoerceToCheckedCast: { + case FixKind::CoerceToCheckedCast: + case FixKind::SpecifyObjectLiteralTypeImport: { return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved; } From b53da3247a2fde88d242309f14fbb4c17c746174 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 17 Jan 2020 00:13:32 -0300 Subject: [PATCH 2/6] [ConstraintLocator] Minor indentation fixes --- lib/Sema/ConstraintLocator.cpp | 2 +- lib/Sema/ConstraintLocatorPathElts.def | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/Sema/ConstraintLocator.cpp b/lib/Sema/ConstraintLocator.cpp index bba1582f764df..8c5fcfe594be6 100644 --- a/lib/Sema/ConstraintLocator.cpp +++ b/lib/Sema/ConstraintLocator.cpp @@ -470,7 +470,7 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) const { auto branchElt = elt.castTo(); out << (branchElt.forThen() ? "'then'" : "'else'") << " branch of a ternary operator"; - break; + break; } } out << ']'; diff --git a/lib/Sema/ConstraintLocatorPathElts.def b/lib/Sema/ConstraintLocatorPathElts.def index 54912bbfa9953..88a8e9c7eff57 100644 --- a/lib/Sema/ConstraintLocatorPathElts.def +++ b/lib/Sema/ConstraintLocatorPathElts.def @@ -135,11 +135,12 @@ CUSTOM_LOCATOR_PATH_ELT(ProtocolRequirement) /// Type parameter requirements. ABSTRACT_LOCATOR_PATH_ELT(AnyRequirement) - /// The Nth conditional requirement in the parent locator's conformance. - CUSTOM_LOCATOR_PATH_ELT(ConditionalRequirement) - /// A single requirement placed on the type parameters. - CUSTOM_LOCATOR_PATH_ELT(TypeParameterRequirement) +/// The Nth conditional requirement in the parent locator's conformance. +CUSTOM_LOCATOR_PATH_ELT(ConditionalRequirement) + +/// A single requirement placed on the type parameters. +CUSTOM_LOCATOR_PATH_ELT(TypeParameterRequirement) /// RValue adjustment. SIMPLE_LOCATOR_PATH_ELT(RValueAdjustment) @@ -155,11 +156,12 @@ CUSTOM_LOCATOR_PATH_ELT(SynthesizedArgument) /// Tuple elements. ABSTRACT_LOCATOR_PATH_ELT(AnyTupleElement) - /// A tuple element referenced by position. - CUSTOM_LOCATOR_PATH_ELT(TupleElement) - /// A tuple element referenced by name. - CUSTOM_LOCATOR_PATH_ELT(NamedTupleElement) +/// A tuple element referenced by position. +CUSTOM_LOCATOR_PATH_ELT(TupleElement) + +/// A tuple element referenced by name. +CUSTOM_LOCATOR_PATH_ELT(NamedTupleElement) /// An unresolved member. SIMPLE_LOCATOR_PATH_ELT(UnresolvedMember) From 94dd355604b5e452d4f9282592de06c469cd7748 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 17 Jan 2020 00:14:01 -0300 Subject: [PATCH 3/6] [CSDiag] Remove FailureDiagnosis:: visitObjectLiteralExpr from CSDiag --- lib/Sema/CSDiag.cpp | 69 ---------------------------------- lib/Sema/ConstraintLocator.cpp | 2 +- 2 files changed, 1 insertion(+), 70 deletions(-) diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp index acb50536c105d..96ee39f27578a 100644 --- a/lib/Sema/CSDiag.cpp +++ b/lib/Sema/CSDiag.cpp @@ -239,7 +239,6 @@ class FailureDiagnosis :public ASTVisitor{ bool visitTryExpr(TryExpr *E); bool visitUnresolvedDotExpr(UnresolvedDotExpr *UDE); - bool visitObjectLiteralExpr(ObjectLiteralExpr *E); bool visitApplyExpr(ApplyExpr *AE); bool visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *E); @@ -1722,74 +1721,6 @@ visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *E) { return false; } -/// When an object literal fails to typecheck because its protocol's -/// corresponding default type has not been set in the global namespace (e.g. -/// _ColorLiteralType), suggest that the user import the appropriate module for -/// the target. -bool FailureDiagnosis::visitObjectLiteralExpr(ObjectLiteralExpr *E) { - // Type check the argument first. - auto protocol = TypeChecker::getLiteralProtocol(CS.getASTContext(), E); - if (!protocol) - return false; - auto constrName = - TypeChecker::getObjectLiteralConstructorName(CS.getASTContext(), E); - assert(constrName); - auto *constr = dyn_cast_or_null( - protocol->getSingleRequirement(constrName)); - if (!constr) - return false; - auto paramType = TypeChecker::getObjectLiteralParameterType(E, constr); - if (!typeCheckChildIndependently( - E->getArg(), paramType, CTP_CallArgument)) - return true; - - // Conditions for showing this diagnostic: - // * The object literal protocol's default type is unimplemented - if (TypeChecker::getDefaultType(protocol, CS.DC)) - return false; - // * The object literal has no contextual type - if (CS.getContextualType()) - return false; - - // Figure out what import to suggest. - auto &Ctx = CS.getASTContext(); - const auto &target = Ctx.LangOpts.Target; - StringRef importModule; - StringRef importDefaultTypeName; - if (protocol == Ctx.getProtocol(KnownProtocolKind::ExpressibleByColorLiteral)) { - if (target.isMacOSX()) { - importModule = "AppKit"; - importDefaultTypeName = "NSColor"; - } else if (target.isiOS() || target.isTvOS()) { - importModule = "UIKit"; - importDefaultTypeName = "UIColor"; - } - } else if (protocol == Ctx.getProtocol( - KnownProtocolKind::ExpressibleByImageLiteral)) { - if (target.isMacOSX()) { - importModule = "AppKit"; - importDefaultTypeName = "NSImage"; - } else if (target.isiOS() || target.isTvOS()) { - importModule = "UIKit"; - importDefaultTypeName = "UIImage"; - } - } else if (protocol == Ctx.getProtocol( - KnownProtocolKind::ExpressibleByFileReferenceLiteral)) { - importModule = "Foundation"; - importDefaultTypeName = "URL"; - } - - // Emit the diagnostic. - const auto plainName = E->getLiteralKindPlainName(); - Ctx.Diags.diagnose(E->getLoc(), diag::object_literal_default_type_missing, - plainName); - if (!importModule.empty()) { - Ctx.Diags.diagnose(E->getLoc(), diag::object_literal_resolve_import, - importModule, importDefaultTypeName, plainName); - } - return true; -} - bool FailureDiagnosis::diagnoseMemberFailures( Expr *E, Expr *baseExpr, ConstraintKind lookupKind, DeclNameRef memberName, FunctionRefKind funcRefKind, ConstraintLocator *locator, diff --git a/lib/Sema/ConstraintLocator.cpp b/lib/Sema/ConstraintLocator.cpp index 8c5fcfe594be6..bba1582f764df 100644 --- a/lib/Sema/ConstraintLocator.cpp +++ b/lib/Sema/ConstraintLocator.cpp @@ -470,7 +470,7 @@ void ConstraintLocator::dump(SourceManager *sm, raw_ostream &out) const { auto branchElt = elt.castTo(); out << (branchElt.forThen() ? "'then'" : "'else'") << " branch of a ternary operator"; - break; + break; } } out << ']'; From 716e11f575608751b6bb9ddc3a2de37c64d99ed0 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 21 Jan 2020 20:39:44 -0300 Subject: [PATCH 4/6] [Constraint System] Recording SpecifyObjectLiteralTypeImport fix when attempting literal result type variable binding and handle object literal in MissingArgumentsFailure --- lib/Sema/CSBindings.cpp | 7 +++ lib/Sema/CSDiagnostics.cpp | 59 ++++++++++++++------------ lib/Sema/CSFix.cpp | 17 +------- lib/Sema/CSFix.h | 9 ++-- lib/Sema/CSGen.cpp | 3 +- lib/Sema/CSSimplify.cpp | 14 +----- lib/Sema/ConstraintLocatorPathElts.def | 18 ++++---- 7 files changed, 57 insertions(+), 70 deletions(-) diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index a3a15f49035ca..c3b3de33f5399 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -1045,6 +1045,13 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const { cs.DefaultedConstraints.push_back(srcLocator); if (type->isHole()) { + if (auto * OLE = dyn_cast(srcLocator->getAnchor())) { + auto *fix = SpecifyObjectLiteralTypeImport::create( + cs, TypeVar->getImpl().getLocator()); + if (cs.recordFix(fix)) + return true; + } + if (auto *GP = TypeVar->getImpl().getGenericParameter()) { auto path = dstLocator->getPath(); // Drop `generic parameter` locator element so that all missing diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index eefacdb127dc6..f1b0e5d3eef03 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -3882,7 +3882,7 @@ bool MissingArgumentsFailure::diagnoseSingleMissingArgument() const { auto *anchor = getRawAnchor(); if (!(isa(anchor) || isa(anchor) || - isa(anchor))) + isa(anchor) || isa(anchor))) return false; if (SynthesizedArgs.size() != 1) @@ -4219,6 +4219,9 @@ MissingArgumentsFailure::getCallInfo(Expr *anchor) const { } else if (auto *SE = dyn_cast(anchor)) { return std::make_tuple(SE, SE->getIndex(), SE->getNumArguments(), SE->hasTrailingClosure()); + } else if (auto *OLE = dyn_cast(anchor)) { + return std::make_tuple(OLE, OLE->getArg(), OLE->getNumArguments(), + OLE->hasTrailingClosure()); } return std::make_tuple(nullptr, nullptr, 0, false); @@ -6039,46 +6042,48 @@ bool UnableToInferClosureReturnType::diagnoseAsError() { return true; } -static std::tuple -getImportModuleAndDefaultType(const ASTContext &ctx, ProtocolDecl *protocol) { +static std::pair +getImportModuleAndDefaultType(const ASTContext &ctx, ObjectLiteralExpr *expr) { const auto &target = ctx.LangOpts.Target; - if (protocol == - ctx.getProtocol(KnownProtocolKind::ExpressibleByColorLiteral)) { - if (target.isMacOSX()) { - return std::make_tuple("AppKit", "NSColor"); - } else if (target.isiOS() || target.isTvOS()) { - return std::make_tuple("UIKit", "UIColor"); + + switch (expr->getLiteralKind()) { + case ObjectLiteralExpr::colorLiteral: { + if (target.isMacOSX()) { + return std::make_pair("AppKit", "NSColor"); + } else if (target.isiOS() || target.isTvOS()) { + return std::make_pair("UIKit", "UIColor"); + } + break; } - } else if (protocol == - ctx.getProtocol(KnownProtocolKind::ExpressibleByImageLiteral)) { - if (target.isMacOSX()) { - return std::make_tuple("AppKit", "NSImage"); - } else if (target.isiOS() || target.isTvOS()) { - return std::make_tuple("UIKit", "UIImage"); + + case ObjectLiteralExpr::imageLiteral: { + if (target.isMacOSX()) { + return std::make_pair("AppKit", "NSImage"); + } else if (target.isiOS() || target.isTvOS()) { + return std::make_pair("UIKit", "UIImage"); + } + break; + } + + case ObjectLiteralExpr::fileLiteral: { + return std::make_pair("Foundation", "URL"); } - } else if (protocol == - ctx.getProtocol( - KnownProtocolKind::ExpressibleByFileReferenceLiteral)) { - return std::make_tuple("Foundation", "URL"); } - return std::make_tuple("", ""); + + return std::make_pair("", ""); } bool UnableToInferProtocolLiteralType::diagnoseAsError() { - auto *locator = getLocator(); auto &cs = getConstraintSystem(); - auto *expr = cast(locator->getAnchor()); - auto &ctx = cs.getASTContext(); - auto protocol = TypeChecker::getLiteralProtocol(ctx, expr); - assert(protocol); - auto plainName = expr->getLiteralKindPlainName(); + auto *expr = cast(getLocator()->getAnchor()); StringRef importModule; StringRef importDefaultTypeName; std::tie(importModule, importDefaultTypeName) = - getImportModuleAndDefaultType(ctx, protocol); + getImportModuleAndDefaultType(ctx, expr); + auto plainName = expr->getLiteralKindPlainName(); emitDiagnostic(expr->getLoc(), diag::object_literal_default_type_missing, plainName); if (!importModule.empty()) { diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp index b9c269f60f43c..e15edfc72284e 100644 --- a/lib/Sema/CSFix.cpp +++ b/lib/Sema/CSFix.cpp @@ -1176,20 +1176,7 @@ bool SpecifyObjectLiteralTypeImport::diagnose(bool asNote) const { } SpecifyObjectLiteralTypeImport * -SpecifyObjectLiteralTypeImport::attempt(ConstraintSystem &cs, - ConstraintLocator *locator) { - // FIXME: ArgumentMismatchFailure is currently used from CSDiag, meaning - // we could endup emiting this diagnostic duplicated. - if (cs.Options.contains(ConstraintSystemFlags::SubExpressionDiagnostics)) - return nullptr; - - auto *anchor = locator->getAnchor(); - if (!isa(anchor)) - return nullptr; - - // * The object literal has no contextual type - if (cs.getContextualType()) - return nullptr; - +SpecifyObjectLiteralTypeImport::create(ConstraintSystem &cs, + ConstraintLocator *locator) { return new (cs.getAllocator()) SpecifyObjectLiteralTypeImport(cs, locator); } diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h index 6276f40ec86fb..8eea9a40590ad 100644 --- a/lib/Sema/CSFix.h +++ b/lib/Sema/CSFix.h @@ -236,8 +236,9 @@ enum class FixKind : uint8_t { /// inferred in current context e.g. because it's a multi-statement closure. SpecifyClosureReturnType, - /// Object literal type coudn't be infered because the module where it's - /// protocol type was not imported. + /// Object literal type coudn't be infered because the module where + /// the default type that implements the associated literal protocol + /// is declared was not imported. SpecifyObjectLiteralTypeImport, }; @@ -1649,8 +1650,8 @@ class SpecifyObjectLiteralTypeImport final : public ConstraintFix { bool diagnose(bool asNote = false) const; - static SpecifyObjectLiteralTypeImport *attempt(ConstraintSystem &cs, - ConstraintLocator *locator); + static SpecifyObjectLiteralTypeImport *create(ConstraintSystem &cs, + ConstraintLocator *locator); }; diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 259ced6a8037d..7078c4cc45af1 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1277,7 +1277,8 @@ namespace { auto tv = CS.createTypeVariable(exprLoc, TVO_PrefersSubtypeBinding | - TVO_CanBindToNoEscape); + TVO_CanBindToNoEscape | + TVO_CanBindToHole); CS.addConstraint(ConstraintKind::LiteralConformsTo, tv, protocol->getDeclaredType(), diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index ebbcc8b4c7794..6f5a94ca3c851 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -1027,18 +1027,7 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments( argsWithLabels, params, paramInfo, argInfo->HasTrailingClosure, cs.shouldAttemptFixes(), listener, parameterBindings)) return cs.getTypeMatchFailure(locator); - - if (!callee) { - // If we couldn't find a callee, diagnose and maybe suggest - // import a module. - if (cs.shouldAttemptFixes()) { - if (auto *fix = SpecifyObjectLiteralTypeImport::attempt(cs, loc)) { - if (cs.recordFix(fix)) - return cs.getTypeMatchFailure(locator); - } - } - } - + auto extraArguments = listener.getExtraneousArguments(); if (!extraArguments.empty()) { if (RemoveExtraneousArguments::isMinMaxNameShadowing(cs, locator)) @@ -1058,7 +1047,6 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments( return cs.getTypeMatchFailure(locator); } } - } // If this application is part of an operator, then we allow an implicit diff --git a/lib/Sema/ConstraintLocatorPathElts.def b/lib/Sema/ConstraintLocatorPathElts.def index 88a8e9c7eff57..54912bbfa9953 100644 --- a/lib/Sema/ConstraintLocatorPathElts.def +++ b/lib/Sema/ConstraintLocatorPathElts.def @@ -135,12 +135,11 @@ CUSTOM_LOCATOR_PATH_ELT(ProtocolRequirement) /// Type parameter requirements. ABSTRACT_LOCATOR_PATH_ELT(AnyRequirement) + /// The Nth conditional requirement in the parent locator's conformance. + CUSTOM_LOCATOR_PATH_ELT(ConditionalRequirement) -/// The Nth conditional requirement in the parent locator's conformance. -CUSTOM_LOCATOR_PATH_ELT(ConditionalRequirement) - -/// A single requirement placed on the type parameters. -CUSTOM_LOCATOR_PATH_ELT(TypeParameterRequirement) + /// A single requirement placed on the type parameters. + CUSTOM_LOCATOR_PATH_ELT(TypeParameterRequirement) /// RValue adjustment. SIMPLE_LOCATOR_PATH_ELT(RValueAdjustment) @@ -156,12 +155,11 @@ CUSTOM_LOCATOR_PATH_ELT(SynthesizedArgument) /// Tuple elements. ABSTRACT_LOCATOR_PATH_ELT(AnyTupleElement) + /// A tuple element referenced by position. + CUSTOM_LOCATOR_PATH_ELT(TupleElement) -/// A tuple element referenced by position. -CUSTOM_LOCATOR_PATH_ELT(TupleElement) - -/// A tuple element referenced by name. -CUSTOM_LOCATOR_PATH_ELT(NamedTupleElement) + /// A tuple element referenced by name. + CUSTOM_LOCATOR_PATH_ELT(NamedTupleElement) /// An unresolved member. SIMPLE_LOCATOR_PATH_ELT(UnresolvedMember) From f07e21b4833c7d421724745195e8245cc5d61279 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 21 Jan 2020 20:40:55 -0300 Subject: [PATCH 5/6] [tests] Updating test/Sema/object_literals_ios and test/Sema/object_literals_macos --- test/Sema/object_literals_ios.swift | 2 +- test/Sema/object_literals_osx.swift | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Sema/object_literals_ios.swift b/test/Sema/object_literals_ios.swift index 7585a96d0122b..225d7a165df0f 100644 --- a/test/Sema/object_literals_ios.swift +++ b/test/Sema/object_literals_ios.swift @@ -7,7 +7,7 @@ struct S: _ExpressibleByColorLiteral { let y: S = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1) let y2 = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1) // expected-error{{could not infer type of color literal}} expected-note{{import UIKit to use 'UIColor' as the default color literal type}} -let y3 = #colorLiteral(red: 1, bleen: 0, grue: 0, alpha: 1) // expected-error{{cannot convert value of type '(red: Int, bleen: Int, grue: Int, alpha: Int)' to expected argument type '(red: Float, green: Float, blue: Float, alpha: Float)'}} +let y3 = #colorLiteral(red: 1, bleen: 0, grue: 0, alpha: 1) // expected-error{{incorrect argument labels in call (have 'red:bleen:grue:alpha:', expected 'red:green:blue:alpha:')}} expected-error{{could not infer type of color literal}} expected-note{{import AppKit to use 'NSColor' as the default color literal type}} struct I: _ExpressibleByImageLiteral { init(imageLiteralResourceName: String) {} diff --git a/test/Sema/object_literals_osx.swift b/test/Sema/object_literals_osx.swift index 965dd8e1ca597..b49c28989f9bd 100644 --- a/test/Sema/object_literals_osx.swift +++ b/test/Sema/object_literals_osx.swift @@ -7,7 +7,7 @@ struct S: _ExpressibleByColorLiteral { let y: S = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1) let y2 = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1) // expected-error{{could not infer type of color literal}} expected-note{{import AppKit to use 'NSColor' as the default color literal type}} -let y3 = #colorLiteral(red: 1, bleen: 0, grue: 0, alpha: 1) // expected-error{{cannot convert value of type '(red: Int, bleen: Int, grue: Int, alpha: Int)' to expected argument type '(red: Float, green: Float, blue: Float, alpha: Float)'}} +let y3 = #colorLiteral(red: 1, bleen: 0, grue: 0, alpha: 1) // expected-error{{incorrect argument labels in call (have 'red:bleen:grue:alpha:', expected 'red:green:blue:alpha:')}} expected-error{{could not infer type of color literal}} expected-note{{import AppKit to use 'NSColor' as the default color literal type}} struct I: _ExpressibleByImageLiteral { init(imageLiteralResourceName: String) {} @@ -23,7 +23,7 @@ struct Path: _ExpressibleByFileReferenceLiteral { let p1: Path = #fileLiteral(resourceName: "what.txt") let p2 = #fileLiteral(resourceName: "what.txt") // expected-error{{could not infer type of file reference literal}} expected-note{{import Foundation to use 'URL' as the default file reference literal type}} -let text = #fileLiteral(resourceName: "TextFile.txt").relativeString! // expected-error{{type of expression is ambiguous without more context}} +let text = #fileLiteral(resourceName: "TextFile.txt").relativeString! // expected-error{{could not infer type of file reference literal}} expected-note{{import Foundation to use 'URL' as the default file reference literal type}} // rdar://problem/49861813 -#fileLiteral() // expected-error {{cannot convert value of type '()' to expected argument type '(resourceName: String)'}} +#fileLiteral() // expected-error{{missing argument for parameter 'resourceName' in call}} expected-error{{could not infer type of file reference literal}} expected-note{{import Foundation to use 'URL' as the default file reference literal type}} From e598f6118e0fd297f25c0dde9a8ff05c156f6f0b Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Tue, 21 Jan 2020 20:55:08 -0300 Subject: [PATCH 6/6] [ConstraintSystem] Improve check for record SpecifyObjectLiteralTypeImport and fix string description --- lib/Sema/CSBindings.cpp | 13 ++++++------- lib/Sema/CSFix.h | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index c3b3de33f5399..f7a4ac736135f 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -1045,13 +1045,6 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const { cs.DefaultedConstraints.push_back(srcLocator); if (type->isHole()) { - if (auto * OLE = dyn_cast(srcLocator->getAnchor())) { - auto *fix = SpecifyObjectLiteralTypeImport::create( - cs, TypeVar->getImpl().getLocator()); - if (cs.recordFix(fix)) - return true; - } - if (auto *GP = TypeVar->getImpl().getGenericParameter()) { auto path = dstLocator->getPath(); // Drop `generic parameter` locator element so that all missing @@ -1066,6 +1059,12 @@ bool TypeVariableBinding::attempt(ConstraintSystem &cs) const { cs, TypeVar->getImpl().getLocator()); if (cs.recordFix(fix)) return true; + } else if (auto *OLE = dyn_cast_or_null( + srcLocator->getAnchor())) { + auto *fix = SpecifyObjectLiteralTypeImport::create( + cs, TypeVar->getImpl().getLocator()); + if (cs.recordFix(fix)) + return true; } } } diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h index 8eea9a40590ad..05959c8ddbaf4 100644 --- a/lib/Sema/CSFix.h +++ b/lib/Sema/CSFix.h @@ -1645,7 +1645,7 @@ class SpecifyObjectLiteralTypeImport final : public ConstraintFix { public: std::string getName() const { - return "specify object literal protocol type import"; + return "import required module to gain access to a default literal type"; } bool diagnose(bool asNote = false) const;