Skip to content

Commit a895020

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents 1474ea2 + c3ea110 commit a895020

20 files changed

+184
-91
lines changed

cmake/modules/StandaloneOverlay.cmake

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ set(SWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS "9.0" CACHE STRING "")
2121
set(SWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS "2.0" CACHE STRING "")
2222
set(SWIFT_ENABLE_PARSEABLE_MODULE_INTERFACES TRUE)
2323

24-
set(SWIFT_SOURCE_DIR "${SWIFT_SOURCE_ROOT}/src/swift" CACHE PATH "")
24+
set(SWIFT_SOURCE_DIR "${SWIFT_SOURCE_ROOT}/swift" CACHE PATH "")
2525
set(SWIFT_NATIVE_SWIFT_TOOLS_PATH "${TOOLCHAIN_DIR}/usr/bin" CACHE PATH "")
2626
set(SWIFT_SDKS ${SWIFT_HOST_VARIANT_SDK})
2727

28-
find_package(LLVM CONFIG REQUIRED NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
29-
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}" "${PROJECT_SOURCE_DIR}/../../../../cmake/modules")
28+
list(APPEND CMAKE_MODULE_PATH
29+
"${SWIFT_SOURCE_ROOT}/llvm/cmake/modules"
30+
"${PROJECT_SOURCE_DIR}/../../../../cmake/modules")
3031

3132
set(SWIFT_DARWIN_XCRUN_TOOLCHAIN "XcodeDefault" CACHE STRING
3233
"The name of the toolchain to pass to 'xcrun'")

include/swift/Frontend/PrintingDiagnosticConsumer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/DiagnosticConsumer.h"
2323

2424
#include "llvm/Support/raw_ostream.h"
25+
#include "llvm/Support/Process.h"
2526

2627
namespace swift {
2728

@@ -42,6 +43,7 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer {
4243

4344
void forceColors() {
4445
ForceColors = true;
46+
llvm::sys::Process::UseANSIEscapeCodes(true);
4547
}
4648

4749
bool didErrorOccur() {

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,8 @@ addCommonInvocationArguments(std::vector<std::string> &invocationArgStrs,
716716
invocationArgStrs.push_back(importerOpts.IndexStorePath);
717717
}
718718

719+
invocationArgStrs.push_back("-fansi-escape-codes");
720+
719721
for (auto extraArg : importerOpts.ExtraArgs) {
720722
invocationArgStrs.push_back(extraArg);
721723
}
@@ -876,7 +878,6 @@ ClangImporter::create(ASTContext &ctx,
876878
// Clang expects this to be like an actual command line. So we need to pass in
877879
// "clang" for argv[0]
878880
invocationArgStrs.push_back("clang");
879-
880881
switch (importerOpts.Mode) {
881882
case ClangImporterOptions::Modes::Normal:
882883
getNormalInvocationArguments(invocationArgStrs, ctx, importerOpts);

lib/Sema/CSDiagnostics.cpp

Lines changed: 109 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -549,16 +549,67 @@ bool MemberAccessOnOptionalBaseFailure::diagnoseAsError() {
549549
resultIsOptional, SourceRange());
550550
}
551551

552-
// Suggest a default value via ?? <default value>
553-
static void offerDefaultValueUnwrapFixit(TypeChecker &TC, DeclContext *DC, Expr *expr, Expr *rootExpr) {
554-
auto diag =
555-
TC.diagnose(expr->getLoc(), diag::unwrap_with_default_value);
552+
Optional<AnyFunctionType::Param>
553+
MissingOptionalUnwrapFailure::getOperatorParameterFor(Expr *expr) const {
554+
auto *parentExpr = findParentExpr(expr);
555+
if (!parentExpr)
556+
return None;
557+
558+
auto getArgIdx = [](TupleExpr *tuple, Expr *argExpr) -> unsigned {
559+
for (unsigned i = 0, n = tuple->getNumElements(); i != n; ++i) {
560+
if (tuple->getElement(i) == argExpr)
561+
return i;
562+
}
563+
llvm_unreachable("argument is not in enclosing tuple?!");
564+
};
565+
566+
auto *tupleExpr = dyn_cast<TupleExpr>(parentExpr);
567+
if (!(tupleExpr && tupleExpr->isImplicit()))
568+
return None;
569+
570+
parentExpr = findParentExpr(tupleExpr);
571+
if (!(parentExpr && isa<ApplyExpr>(parentExpr)))
572+
return None;
573+
574+
auto &cs = getConstraintSystem();
575+
auto *fnExpr = cast<ApplyExpr>(parentExpr)->getFn();
576+
if (auto overload =
577+
getOverloadChoiceIfAvailable(cs.getConstraintLocator(fnExpr))) {
578+
if (auto *decl = overload->choice.getDecl()) {
579+
if (!decl->isOperator())
580+
return None;
581+
582+
auto *fnType = overload->openedType->castTo<FunctionType>();
583+
return fnType->getParams()[getArgIdx(tupleExpr, expr)];
584+
}
585+
}
586+
587+
return None;
588+
}
589+
590+
void MissingOptionalUnwrapFailure::offerDefaultValueUnwrapFixIt(
591+
DeclContext *DC, Expr *expr) const {
592+
auto *anchor = getAnchor();
593+
594+
// If anchor is an explicit address-of, or expression which produces
595+
// an l-value (e.g. first argument of `+=` operator), let's not
596+
// suggest default value here because that would produce r-value type.
597+
if (isa<InOutExpr>(anchor))
598+
return;
556599

600+
if (auto param = getOperatorParameterFor(anchor)) {
601+
if (param->isInOut())
602+
return;
603+
}
604+
605+
auto diag = emitDiagnostic(expr->getLoc(), diag::unwrap_with_default_value);
606+
607+
auto &TC = getTypeChecker();
557608
// Figure out what we need to parenthesize.
558609
bool needsParensInside =
559-
exprNeedsParensBeforeAddingNilCoalescing(TC, DC, expr);
610+
exprNeedsParensBeforeAddingNilCoalescing(TC, DC, expr);
560611
bool needsParensOutside =
561-
exprNeedsParensAfterAddingNilCoalescing(TC, DC, expr, rootExpr);
612+
exprNeedsParensAfterAddingNilCoalescing(TC, DC, expr, getParentExpr());
562613

563614
llvm::SmallString<2> insertBefore;
564615
llvm::SmallString<32> insertAfter;
@@ -580,8 +631,8 @@ static void offerDefaultValueUnwrapFixit(TypeChecker &TC, DeclContext *DC, Expr
580631
}
581632

582633
// Suggest a force-unwrap.
583-
static void offerForceUnwrapFixit(ConstraintSystem &CS, Expr *expr) {
584-
auto diag = CS.TC.diagnose(expr->getLoc(), diag::unwrap_with_force_value);
634+
void MissingOptionalUnwrapFailure::offerForceUnwrapFixIt(Expr *expr) const {
635+
auto diag = emitDiagnostic(expr->getLoc(), diag::unwrap_with_force_value);
585636

586637
// If expr is optional as the result of an optional chain and this last
587638
// dot isn't a member returning optional, then offer to force the last
@@ -590,7 +641,7 @@ static void offerForceUnwrapFixit(ConstraintSystem &CS, Expr *expr) {
590641
if (auto dotExpr =
591642
dyn_cast<UnresolvedDotExpr>(optionalChain->getSubExpr())) {
592643
auto bind = dyn_cast<BindOptionalExpr>(dotExpr->getBase());
593-
if (bind && !CS.getType(dotExpr)->getOptionalObjectType()) {
644+
if (bind && !getType(dotExpr)->getOptionalObjectType()) {
594645
diag.fixItReplace(SourceRange(bind->getLoc()), "!");
595646
return;
596647
}
@@ -601,7 +652,7 @@ static void offerForceUnwrapFixit(ConstraintSystem &CS, Expr *expr) {
601652
diag.fixItInsertAfter(expr->getEndLoc(), "!");
602653
} else {
603654
diag.fixItInsert(expr->getStartLoc(), "(")
604-
.fixItInsertAfter(expr->getEndLoc(), ")!");
655+
.fixItInsertAfter(expr->getEndLoc(), ")!");
605656
}
606657
}
607658

@@ -622,8 +673,38 @@ class VarDeclMultipleReferencesChecker : public ASTWalker {
622673
int referencesCount() { return count; }
623674
};
624675

625-
static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Expr *rootExpr, Type baseType,
626-
Type unwrappedType) {
676+
bool MissingOptionalUnwrapFailure::diagnoseAsError() {
677+
if (hasComplexLocator())
678+
return false;
679+
680+
auto *anchor = getAnchor();
681+
682+
if (auto assignExpr = dyn_cast<AssignExpr>(anchor))
683+
anchor = assignExpr->getSrc();
684+
685+
auto *unwrappedExpr = anchor->getValueProvidingExpr();
686+
687+
if (auto *tryExpr = dyn_cast<OptionalTryExpr>(unwrappedExpr)) {
688+
bool isSwift5OrGreater = getASTContext().isSwiftVersionAtLeast(5);
689+
auto subExprType = getType(tryExpr->getSubExpr());
690+
bool subExpressionIsOptional = (bool)subExprType->getOptionalObjectType();
691+
692+
if (isSwift5OrGreater && subExpressionIsOptional) {
693+
// Using 'try!' won't change the type for a 'try?' with an optional
694+
// sub-expr under Swift 5+, so just report that a missing unwrap can't be
695+
// handled here.
696+
return false;
697+
}
698+
699+
emitDiagnostic(tryExpr->getTryLoc(), diag::missing_unwrap_optional_try,
700+
getType(anchor)->getRValueType())
701+
.fixItReplace({tryExpr->getTryLoc(), tryExpr->getQuestionLoc()},
702+
"try!");
703+
return true;
704+
}
705+
706+
auto baseType = getBaseType();
707+
auto unwrappedType = getUnwrappedType();
627708

628709
assert(!baseType->hasTypeVariable() &&
629710
"Base type must not be a type variable");
@@ -633,15 +714,14 @@ static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Expr *rootExpr, Typ
633714
if (!baseType->getOptionalObjectType())
634715
return false;
635716

636-
CS.TC.diagnose(expr->getLoc(), diag::optional_not_unwrapped, baseType,
637-
unwrappedType);
717+
emitDiagnostic(unwrappedExpr->getLoc(), diag::optional_not_unwrapped,
718+
baseType, unwrappedType);
638719

639720
// If the expression we're unwrapping is the only reference to a
640721
// local variable whose type isn't explicit in the source, then
641722
// offer unwrapping fixits on the initializer as well.
642-
if (auto declRef = dyn_cast<DeclRefExpr>(expr)) {
723+
if (auto declRef = dyn_cast<DeclRefExpr>(unwrappedExpr)) {
643724
if (auto varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
644-
645725
bool singleUse = false;
646726
AbstractFunctionDecl *AFD = nullptr;
647727
if (auto contextDecl = varDecl->getDeclContext()->getAsDecl()) {
@@ -658,69 +738,37 @@ static bool diagnoseUnwrap(ConstraintSystem &CS, Expr *expr, Expr *rootExpr, Typ
658738

659739
Expr *initializer = varDecl->getParentInitializer();
660740
if (auto declRefExpr = dyn_cast<DeclRefExpr>(initializer)) {
661-
if (declRefExpr->getDecl()->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
662-
CS.TC.diagnose(declRefExpr->getLoc(), diag::unwrap_iuo_initializer,
741+
if (declRefExpr->getDecl()
742+
->getAttrs()
743+
.hasAttribute<ImplicitlyUnwrappedOptionalAttr>()) {
744+
emitDiagnostic(declRefExpr->getLoc(), diag::unwrap_iuo_initializer,
663745
baseType);
664746
}
665747
}
666748

667749
auto fnTy = AFD->getInterfaceType()->castTo<AnyFunctionType>();
668-
bool voidReturn = fnTy->getResult()->isEqual(TupleType::getEmpty(CS.DC->getASTContext()));
750+
bool voidReturn =
751+
fnTy->getResult()->isEqual(TupleType::getEmpty(getASTContext()));
669752

670-
auto diag = CS.TC.diagnose(varDecl->getLoc(), diag::unwrap_with_guard);
753+
auto diag = emitDiagnostic(varDecl->getLoc(), diag::unwrap_with_guard);
671754
diag.fixItInsert(binding->getStartLoc(), "guard ");
672755
if (voidReturn) {
673756
diag.fixItInsertAfter(binding->getEndLoc(), " else { return }");
674757
} else {
675758
diag.fixItInsertAfter(binding->getEndLoc(), " else { return <"
676-
"#default value#" "> }");
759+
"#default value#"
760+
"> }");
677761
}
678762
diag.flush();
679763

680-
offerDefaultValueUnwrapFixit(CS.TC, varDecl->getDeclContext(),
681-
initializer, rootExpr);
682-
offerForceUnwrapFixit(CS, initializer);
764+
offerDefaultValueUnwrapFixIt(varDecl->getDeclContext(), initializer);
765+
offerForceUnwrapFixIt(initializer);
683766
}
684767
}
685768
}
686769

687-
offerDefaultValueUnwrapFixit(CS.TC, CS.DC, expr, rootExpr);
688-
offerForceUnwrapFixit(CS, expr);
689-
return true;
690-
}
691-
692-
bool MissingOptionalUnwrapFailure::diagnoseAsError() {
693-
if (hasComplexLocator())
694-
return false;
695-
696-
auto *anchor = getAnchor();
697-
auto *rootExpr = getParentExpr();
698-
699-
if (auto assignExpr = dyn_cast<AssignExpr>(anchor))
700-
anchor = assignExpr->getSrc();
701-
702-
auto *unwrapped = anchor->getValueProvidingExpr();
703-
auto type = getType(anchor)->getRValueType();
704-
705-
auto *tryExpr = dyn_cast<OptionalTryExpr>(unwrapped);
706-
if (!tryExpr) {
707-
return diagnoseUnwrap(getConstraintSystem(), unwrapped, rootExpr, getBaseType(),
708-
getUnwrappedType());
709-
}
710-
711-
bool isSwift5OrGreater = getTypeChecker().getLangOpts().isSwiftVersionAtLeast(5);
712-
auto subExprType = getType(tryExpr->getSubExpr());
713-
bool subExpressionIsOptional = (bool)subExprType->getOptionalObjectType();
714-
715-
716-
if (isSwift5OrGreater && subExpressionIsOptional) {
717-
// Using 'try!' won't change the type for a 'try?' with an optional sub-expr
718-
// under Swift 5+, so just report that a missing unwrap can't be handled here.
719-
return false;
720-
}
721-
722-
emitDiagnostic(tryExpr->getTryLoc(), diag::missing_unwrap_optional_try, type)
723-
.fixItReplace({tryExpr->getTryLoc(), tryExpr->getQuestionLoc()}, "try!");
770+
offerDefaultValueUnwrapFixIt(getDC(), unwrappedExpr);
771+
offerForceUnwrapFixIt(unwrappedExpr);
724772
return true;
725773
}
726774

lib/Sema/CSDiagnostics.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,15 @@ class MissingOptionalUnwrapFailure final : public FailureDiagnostic {
565565
Type getUnwrappedType() const {
566566
return resolveType(UnwrappedType, /*reconstituteSugar=*/true);
567567
}
568+
569+
/// Suggest a default value via `?? <default value>`
570+
void offerDefaultValueUnwrapFixIt(DeclContext *DC, Expr *expr) const;
571+
/// Suggest a force optional unwrap via `!`
572+
void offerForceUnwrapFixIt(Expr *expr) const;
573+
574+
/// Determine whether given expression is an argument used in the
575+
/// operator invocation, and if so return corresponding parameter.
576+
Optional<AnyFunctionType::Param> getOperatorParameterFor(Expr *expr) const;
568577
};
569578

570579
/// Diagnose errors associated with rvalues in positions

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,6 +1925,16 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
19251925

19261926
auto &elt = path.back();
19271927
switch (elt.getKind()) {
1928+
case ConstraintLocator::LValueConversion:
1929+
case ConstraintLocator::ApplyArgToParam: {
1930+
if (lhs->getOptionalObjectType() && !rhs->getOptionalObjectType()) {
1931+
conversionsOrFixes.push_back(
1932+
ForceOptional::create(cs, lhs, lhs->getOptionalObjectType(),
1933+
cs.getConstraintLocator(locator)));
1934+
}
1935+
break;
1936+
}
1937+
19281938
case ConstraintLocator::FunctionArgument: {
19291939
auto *argLoc = cs.getConstraintLocator(
19301940
locator.withPathElement(LocatorPathElt::getSynthesizedArgument(0)));

test/Constraints/optional.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,15 @@ func sr_9893_2(cString: UnsafePointer<CChar>) {
333333
}
334334
}
335335
}
336+
337+
// rdar://problem/47776586 - Diagnostic refers to '&' which is not present in the source code
338+
func rdar47776586() {
339+
func foo(_: inout Int) {}
340+
var x: Int? = 0
341+
foo(&x) // expected-error {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
342+
// expected-note@-1 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} {{7-7=(}} {{9-9=)!}}
343+
344+
var dict = [1: 2]
345+
dict[1] += 1 // expected-error {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
346+
// expected-note@-1 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}} {{10-10=!}}
347+
}

test/Driver/Inputs/crash-after-generating-pch.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@
1010
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1111

1212
import os
13+
import platform
1314
import signal
1415
import sys
1516

1617
assert sys.argv[1] == '-frontend'
1718

1819
if '-emit-pch' not in sys.argv:
19-
os.kill(os.getpid(), signal.SIGKILL)
20+
if platform.system() == 'Windows':
21+
exit(-2)
22+
else:
23+
os.kill(os.getpid(), signal.SIGKILL)
2024

2125
outputFile = sys.argv[sys.argv.index('-o') + 1]
2226

test/Driver/batch_mode.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Windows does not support batch-mode yet
2-
// XFAIL: win32
2+
// XFAIL: windows
33
//
44
// RUN: %empty-directory(%t)
55
// RUN: touch %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/file-04.swift %t/file-05.swift

test/Driver/batch_mode_aux_file_order.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Batch-mode is not supported on Windows yet
2-
// XFAIL: win32
2+
// XFAIL: windows
33
//
44
// When multiple additional-outputs on the same command-line are no longer
55
// supported (i.e. when we've moved to mandatory use of output file maps for

0 commit comments

Comments
 (0)