Skip to content

Commit 63bf579

Browse files
Merge pull request #4658 from swiftwasm/main
[pull] swiftwasm from main
2 parents 94e856e + 025a6fc commit 63bf579

16 files changed

+222
-37
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,12 @@ FIXIT(insert_closure_return_type_placeholder,
288288
NOTE(use_of_anon_closure_param,none,
289289
"anonymous closure parameter %0 is used here", (Identifier))
290290

291-
ERROR(incorrect_explicit_closure_result,none,
291+
ERROR(incorrect_explicit_closure_result_vs_contextual_type,none,
292292
"declared closure result %0 is incompatible with contextual type %1",
293293
(Type, Type))
294+
ERROR(incorrect_explicit_closure_result_vs_return_type,none,
295+
"declared closure result %0 is incompatible with return type %1",
296+
(Type, Type))
294297

295298
ERROR(unsupported_closure_attr,none,
296299
"%select{attribute |}0 '%1' is not supported on a closure",

include/swift/Sema/ConstraintLocatorPathElts.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ SIMPLE_LOCATOR_PATH_ELT(AutoclosureResult)
5454
/// The result of a closure.
5555
SIMPLE_LOCATOR_PATH_ELT(ClosureResult)
5656

57+
/// FIXME: Misleading name: this locator is used only for single-expression
58+
/// closure returns.
59+
///
5760
/// The type of a closure body.
5861
CUSTOM_LOCATOR_PATH_ELT(ClosureBody)
5962

lib/ClangImporter/ImportDecl.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,12 +2189,31 @@ namespace {
21892189

21902190
Impl.markUnavailable(MD, "use .pointee property");
21912191
MD->overwriteAccess(AccessLevel::Private);
2192+
} else if (cxxOperatorKind ==
2193+
clang::OverloadedOperatorKind::OO_PlusPlus) {
2194+
auto selfTy = result->getSelfInterfaceType();
2195+
auto returnTy =
2196+
MD->getResultInterfaceType()->getAnyPointerElementType();
2197+
if (cxxMethod->param_empty() &&
2198+
selfTy->getCanonicalType() == returnTy->getCanonicalType()) {
2199+
// This is a pre-increment operator. We synthesize a
2200+
// non-mutating function called `successor() -> Self`.
2201+
FuncDecl *successorFunc = synthesizer.makeSuccessorFunc(MD);
2202+
result->addMember(successorFunc);
2203+
2204+
Impl.markUnavailable(MD, "use .successor()");
2205+
} else {
2206+
Impl.markUnavailable(MD, "unable to create .successor() func");
2207+
}
2208+
MD->overwriteAccess(AccessLevel::Private);
21922209
}
21932210
// Check if this method _is_ an overloaded operator but is not a
2194-
// call / subscript / dereference. Those 3 operators do not need
2195-
// static versions.
2211+
// call / subscript / dereference / increment. Those
2212+
// operators do not need static versions.
21962213
else if (cxxOperatorKind !=
21972214
clang::OverloadedOperatorKind::OO_None &&
2215+
cxxOperatorKind !=
2216+
clang::OverloadedOperatorKind::OO_PlusPlus &&
21982217
cxxOperatorKind !=
21992218
clang::OverloadedOperatorKind::OO_Call &&
22002219
cxxOperatorKind !=

lib/ClangImporter/ImportName.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,6 +1854,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
18541854
case clang::OverloadedOperatorKind::OO_LessLess:
18551855
case clang::OverloadedOperatorKind::OO_GreaterGreater:
18561856
case clang::OverloadedOperatorKind::OO_EqualEqual:
1857+
case clang::OverloadedOperatorKind::OO_PlusPlus:
18571858
case clang::OverloadedOperatorKind::OO_ExclaimEqual:
18581859
case clang::OverloadedOperatorKind::OO_LessEqual:
18591860
case clang::OverloadedOperatorKind::OO_GreaterEqual:

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ SwiftDeclSynthesizer::createVarWithPattern(DeclContext *dc, Identifier name,
144144
VarDecl::Introducer introducer,
145145
bool isImplicit, AccessLevel access,
146146
AccessLevel setterAccess) {
147-
ASTContext &ctx = ImporterImpl.SwiftContext;
147+
ASTContext &ctx = dc->getASTContext();
148148

149149
// Create a variable to store the underlying value.
150150
auto var = new (ctx) VarDecl(
@@ -1720,6 +1720,97 @@ VarDecl *SwiftDeclSynthesizer::makeDereferencedPointeeProperty(
17201720
return result;
17211721
}
17221722

1723+
// MARK: C++ increment operator
1724+
1725+
/// Synthesizer callback for a successor function.
1726+
///
1727+
/// \code
1728+
/// var __copy: Self
1729+
/// __copy = self
1730+
/// __copy.__operatorPlusPlus()
1731+
/// return __copy
1732+
/// \endcode
1733+
static std::pair<BraceStmt *, bool>
1734+
synthesizeSuccessorFuncBody(AbstractFunctionDecl *afd, void *context) {
1735+
auto successorDecl = cast<FuncDecl>(afd);
1736+
auto incrementImpl = static_cast<FuncDecl *>(context);
1737+
1738+
ASTContext &ctx = successorDecl->getASTContext();
1739+
auto emptyTupleTy = TupleType::getEmpty(ctx);
1740+
auto returnTy = successorDecl->getResultInterfaceType();
1741+
1742+
auto selfDecl = successorDecl->getImplicitSelfDecl();
1743+
auto selfRefExpr = new (ctx) DeclRefExpr(selfDecl, DeclNameLoc(),
1744+
/*implicit*/ true);
1745+
selfRefExpr->setType(selfDecl->getInterfaceType());
1746+
1747+
// Create a `__copy` variable.
1748+
VarDecl *copyDecl = nullptr;
1749+
PatternBindingDecl *patternDecl = nullptr;
1750+
std::tie(copyDecl, patternDecl) = SwiftDeclSynthesizer::createVarWithPattern(
1751+
successorDecl, ctx.getIdentifier("__copy"), returnTy,
1752+
VarDecl::Introducer::Var,
1753+
/*isImplicit*/ true, AccessLevel::Public, AccessLevel::Public);
1754+
1755+
auto copyRefLValueExpr = new (ctx) DeclRefExpr(copyDecl, DeclNameLoc(),
1756+
/*implicit*/ true);
1757+
copyRefLValueExpr->setType(LValueType::get(copyDecl->getInterfaceType()));
1758+
1759+
auto inoutCopyExpr = new (ctx) InOutExpr(
1760+
SourceLoc(), copyRefLValueExpr,
1761+
successorDecl->mapTypeIntoContext(copyDecl->getValueInterfaceType()),
1762+
/*isImplicit*/ true);
1763+
inoutCopyExpr->setType(InOutType::get(copyDecl->getInterfaceType()));
1764+
1765+
// Copy `self` to `__copy`.
1766+
auto copyAssignExpr = new (ctx) AssignExpr(copyRefLValueExpr, SourceLoc(),
1767+
selfRefExpr, /*implicit*/ true);
1768+
copyAssignExpr->setType(emptyTupleTy);
1769+
1770+
// Call `operator++`.
1771+
auto incrementExpr = createAccessorImplCallExpr(incrementImpl, inoutCopyExpr);
1772+
1773+
auto copyRefRValueExpr = new (ctx) DeclRefExpr(copyDecl, DeclNameLoc(),
1774+
/*implicit*/ true);
1775+
copyRefRValueExpr->setType(copyDecl->getInterfaceType());
1776+
1777+
auto returnStmt = new (ctx) ReturnStmt(SourceLoc(), copyRefRValueExpr,
1778+
/*implicit*/ true);
1779+
1780+
auto body = BraceStmt::create(ctx, SourceLoc(),
1781+
{
1782+
copyDecl,
1783+
patternDecl,
1784+
copyAssignExpr,
1785+
incrementExpr,
1786+
returnStmt,
1787+
},
1788+
SourceLoc());
1789+
return {body, /*isTypeChecked*/ true};
1790+
}
1791+
1792+
FuncDecl *SwiftDeclSynthesizer::makeSuccessorFunc(FuncDecl *incrementFunc) {
1793+
auto &ctx = ImporterImpl.SwiftContext;
1794+
auto dc = incrementFunc->getDeclContext();
1795+
1796+
auto returnTy = incrementFunc->getImplicitSelfDecl()->getInterfaceType();
1797+
1798+
auto nameId = ctx.getIdentifier("successor");
1799+
auto *params = ParameterList::createEmpty(ctx);
1800+
DeclName name(ctx, DeclBaseName(nameId), params);
1801+
1802+
auto result = FuncDecl::createImplicit(
1803+
ctx, StaticSpellingKind::None, name, SourceLoc(),
1804+
/*Async*/ false, /*Throws*/ false,
1805+
/*GenericParams*/ nullptr, params, returnTy, dc);
1806+
1807+
result->setAccess(AccessLevel::Public);
1808+
result->setIsDynamic(false);
1809+
result->setBodySynthesizer(synthesizeSuccessorFuncBody, incrementFunc);
1810+
1811+
return result;
1812+
}
1813+
17231814
// MARK: C++ arithmetic operators
17241815

17251816
static std::pair<BraceStmt *, bool>

lib/ClangImporter/SwiftDeclSynthesizer.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ class SwiftDeclSynthesizer {
5151
: ImporterImpl(Impl) {}
5252

5353
/// Create a typedpattern(namedpattern(decl))
54-
Pattern *createTypedNamedPattern(VarDecl *decl);
54+
static Pattern *createTypedNamedPattern(VarDecl *decl);
55+
56+
/// Create a var member for this struct, along with its pattern binding, and
57+
/// add it as a member.
58+
static std::pair<VarDecl *, PatternBindingDecl *>
59+
createVarWithPattern(DeclContext *dc, Identifier name, Type ty,
60+
VarDecl::Introducer introducer, bool isImplicit,
61+
AccessLevel access, AccessLevel setterAccess);
5562

5663
/// Create a new named constant with the given value.
5764
///
@@ -272,6 +279,10 @@ class SwiftDeclSynthesizer {
272279
/// \return computed property declaration
273280
VarDecl *makeDereferencedPointeeProperty(FuncDecl *dereferenceFunc);
274281

282+
/// Given a C++ pre-increment operator (`operator++()`). create a non-mutating
283+
/// function `successor() -> Self`.
284+
FuncDecl *makeSuccessorFunc(FuncDecl *incrementFunc);
285+
275286
FuncDecl *makeOperator(FuncDecl *operatorMethod,
276287
clang::CXXMethodDecl *clangOperator);
277288

@@ -280,13 +291,6 @@ class SwiftDeclSynthesizer {
280291

281292
private:
282293
Type getConstantLiteralType(Type type, ConstantConvertKind convertKind);
283-
284-
/// Create a var member for this struct, along with its pattern binding, and
285-
/// add it as a member.
286-
std::pair<VarDecl *, PatternBindingDecl *>
287-
createVarWithPattern(DeclContext *dc, Identifier name, Type ty,
288-
VarDecl::Introducer introducer, bool isImplicit,
289-
AccessLevel access, AccessLevel setterAccess);
290294
};
291295

292296
} // namespace swift

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9189,12 +9189,13 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
91899189
return None;
91909190

91919191
if (isDebugMode()) {
9192-
// If we had partially type-checked expressions, lets print
9193-
// fully type-checked expression after processDelayed is done.
9194-
if (needsPostProcessing) {
9192+
// If we had partially type-checked expressions, lets print
9193+
// fully type-checked target after processDelayed is done.
9194+
auto node = target.getAsASTNode();
9195+
if (node && needsPostProcessing) {
91959196
auto &log = llvm::errs();
9196-
log << "---Fully type-checked expression---\n";
9197-
resultTarget->getAsExpr()->dump(log);
9197+
log << "---Fully type-checked target---\n";
9198+
node.dump(log);
91989199
log << "\n";
91999200
}
92009201
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,17 +2335,32 @@ bool ContextualFailure::diagnoseAsError() {
23352335
auto toType = getToType();
23362336

23372337
Diag<Type, Type> diagnostic;
2338-
switch (path.back().getKind()) {
2338+
2339+
const auto lastPathEltKind = path.back().getKind();
2340+
switch (lastPathEltKind) {
23392341
case ConstraintLocator::ClosureBody:
23402342
case ConstraintLocator::ClosureResult: {
23412343
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
23422344
if (closure->hasExplicitResultType() &&
23432345
closure->getExplicitResultTypeRepr()) {
23442346
auto resultRepr = closure->getExplicitResultTypeRepr();
2345-
emitDiagnosticAt(resultRepr->getStartLoc(),
2346-
diag::incorrect_explicit_closure_result, fromType,
2347-
toType)
2348-
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2347+
2348+
if (lastPathEltKind == ConstraintLocator::ClosureBody) {
2349+
// The conflict is between the return type and the declared result type.
2350+
emitDiagnosticAt(resultRepr->getStartLoc(),
2351+
diag::incorrect_explicit_closure_result_vs_return_type,
2352+
toType, fromType)
2353+
.fixItReplace(resultRepr->getSourceRange(), fromType.getString());
2354+
} else {
2355+
// The conflict is between the declared result type and the
2356+
// contextual type.
2357+
emitDiagnosticAt(
2358+
resultRepr->getStartLoc(),
2359+
diag::incorrect_explicit_closure_result_vs_contextual_type,
2360+
fromType, toType)
2361+
.fixItReplace(resultRepr->getSourceRange(), toType.getString());
2362+
}
2363+
23492364
return true;
23502365
}
23512366

stdlib/public/Concurrency/DispatchGlobalExecutor.inc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424

2525
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
2626
#include <dispatch/dispatch.h>
27-
#if !defined(_WIN32)
27+
#if defined(_WIN32)
28+
#include <Windows.h>
29+
#else
2830
#include <dlfcn.h>
2931
#endif
3032
#endif

test/Constraints/closures.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ func rdar52204414() {
997997
let _: () -> Void = { return 42 }
998998
// expected-error@-1 {{cannot convert value of type 'Int' to closure result type 'Void'}}
999999
let _ = { () -> Void in return 42 }
1000-
// expected-error@-1 {{declared closure result 'Int' is incompatible with contextual type 'Void'}}
1000+
// expected-error@-1 {{declared closure result 'Void' is incompatible with return type 'Int'}} {{19-23=Int}}
10011001
}
10021002

10031003
// SR-12291 - trailing closure is used as an argument to the last (positionally) parameter.

test/Driver/static-stdlib-linux-lld.swift

Lines changed: 0 additions & 12 deletions
This file was deleted.

test/Interop/Cxx/operators/Inputs/member-inline.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ struct LoadableIntWrapper {
1919
int operator()(int x, int y) {
2020
return value + x * y;
2121
}
22+
23+
LoadableIntWrapper &operator++() {
24+
value++;
25+
return *this;
26+
}
2227
};
2328

2429
struct LoadableBoolWrapper {
@@ -43,6 +48,26 @@ struct AddressOnlyIntWrapper {
4348
int operator()(int x, int y) {
4449
return value + x * y;
4550
}
51+
52+
AddressOnlyIntWrapper &operator++() {
53+
value++;
54+
return *this;
55+
}
56+
AddressOnlyIntWrapper operator++(int) {
57+
// This shouldn't be called, since we only support pre-increment operators.
58+
return AddressOnlyIntWrapper(-777);
59+
}
60+
};
61+
62+
struct HasPostIncrementOperator {
63+
HasPostIncrementOperator operator++(int) {
64+
return HasPostIncrementOperator();
65+
}
66+
};
67+
68+
struct HasPreIncrementOperatorWithAnotherReturnType {
69+
int value = 0;
70+
const int &operator++() { return value; }
4671
};
4772

4873
struct HasDeletedOperator {

test/Interop/Cxx/operators/member-inline-module-interface.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %target-swift-ide-test -print-module -module-to-print=MemberInline -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s
22

33
// CHECK: struct LoadableIntWrapper {
4+
// CHECK: func successor() -> LoadableIntWrapper
45
// CHECK: static func - (lhs: inout LoadableIntWrapper, rhs: LoadableIntWrapper) -> LoadableIntWrapper
56
// CHECK: mutating func callAsFunction() -> Int32
67
// CHECK: mutating func callAsFunction(_ x: Int32) -> Int32

test/Interop/Cxx/operators/member-inline-typechecker.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,9 @@ let nonTrivialValueByVal = nonTrivialIntArrayByVal[1]
4040
var diffTypesArrayByVal = DifferentTypesArrayByVal()
4141
let diffTypesResultIntByVal: Int32 = diffTypesArrayByVal[0]
4242
let diffTypesResultDoubleByVal: Double = diffTypesArrayByVal[0.5]
43+
44+
let postIncrement = HasPostIncrementOperator()
45+
postIncrement.successor() // expected-error {{value of type 'HasPostIncrementOperator' has no member 'successor'}}
46+
47+
let anotherReturnType = HasPreIncrementOperatorWithAnotherReturnType()
48+
anotherReturnType.successor() // expected-error {{value of type 'HasPreIncrementOperatorWithAnotherReturnType' has no member 'successor'}}

0 commit comments

Comments
 (0)