Skip to content

Commit 51e272e

Browse files
committed
---
yaml --- r: 322509 b: refs/heads/tensorflow-next c: d9afc65 h: refs/heads/master i: 322507: 4f5fe5a
1 parent eecdcd1 commit 51e272e

File tree

15 files changed

+382
-121
lines changed

15 files changed

+382
-121
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1461,4 +1461,4 @@ refs/heads/master-rebranch: 86e95c23aa0d37f24ec138b7853146c1cead2e40
14611461
refs/heads/rdar-53901732: 9bd06af3284e18a109cdbf9aa59d833b24eeca7b
14621462
refs/heads/revert-26776-subst-always-returns-a-type: 1b8e18fdd391903a348970a4c848995d4cdd789c
14631463
refs/heads/tensorflow-merge: 8b854f62f80d4476cb383d43c4aac2001dde3cec
1464-
refs/heads/tensorflow-next: ba8d6406550d38797155fca636ee757558e4c07b
1464+
refs/heads/tensorflow-next: d9afc650dc2721f9301cc489d2a1dc009df34525

branches/tensorflow-next/include/swift/AST/Expr.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,6 +2206,7 @@ class TupleExpr final : public Expr,
22062206
class CollectionExpr : public Expr {
22072207
SourceLoc LBracketLoc;
22082208
SourceLoc RBracketLoc;
2209+
ConcreteDeclRef Initializer;
22092210

22102211
Expr *SemanticExpr = nullptr;
22112212

@@ -2282,6 +2283,14 @@ class CollectionExpr : public Expr {
22822283
e->getKind() <= ExprKind::Last_CollectionExpr;
22832284
}
22842285

2286+
/// Retrieve the initializer that will be used to construct the 'array'
2287+
/// literal from the result of the initializer.
2288+
ConcreteDeclRef getInitializer() const { return Initializer; }
2289+
2290+
/// Set the initializer that will be used to construct the 'array' literal.
2291+
void setInitializer(ConcreteDeclRef initializer) {
2292+
Initializer = initializer;
2293+
}
22852294
};
22862295

22872296
/// An array literal expression [a, b, c].
@@ -2312,6 +2321,8 @@ class ArrayExpr final : public CollectionExpr,
23122321
static bool classof(const Expr *e) {
23132322
return e->getKind() == ExprKind::Array;
23142323
}
2324+
2325+
Type getElementType();
23152326
};
23162327

23172328
/// A dictionary literal expression [a : x, b : y, c : z].

branches/tensorflow-next/lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,8 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
20682068
}
20692069
void visitArrayExpr(ArrayExpr *E) {
20702070
printCommon(E, "array_expr");
2071+
PrintWithColorRAII(OS, LiteralValueColor) << " initializer=";
2072+
E->getInitializer().dump(PrintWithColorRAII(OS, LiteralValueColor).getOS());
20712073
for (auto elt : E->getElements()) {
20722074
OS << '\n';
20732075
printRec(elt);

branches/tensorflow-next/lib/AST/Expr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,19 @@ ArrayExpr *ArrayExpr::create(ASTContext &C, SourceLoc LBracketLoc,
14891489
return new (Mem) ArrayExpr(LBracketLoc, Elements, CommaLocs, RBracketLoc, Ty);
14901490
}
14911491

1492+
Type ArrayExpr::getElementType() {
1493+
auto init = getInitializer();
1494+
if (!init)
1495+
return Type();
1496+
1497+
auto *decl = cast<ConstructorDecl>(init.getDecl());
1498+
return decl->getMethodInterfaceType()
1499+
->getAs<AnyFunctionType>()
1500+
->getParams()[0]
1501+
.getPlainType()
1502+
.subst(init.getSubstitutions());
1503+
}
1504+
14921505
DictionaryExpr *DictionaryExpr::create(ASTContext &C, SourceLoc LBracketLoc,
14931506
ArrayRef<Expr*> Elements,
14941507
ArrayRef<SourceLoc> CommaLocs,

branches/tensorflow-next/lib/IDE/ExprContextAnalysis.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,12 @@ class ExprContextAnalyzer {
588588
analyzeApplyExpr(Parent);
589589
break;
590590
}
591+
case ExprKind::Array: {
592+
if (auto type = ParsedExpr->getType()) {
593+
recordPossibleType(type);
594+
}
595+
break;
596+
}
591597
case ExprKind::Assign: {
592598
auto *AE = cast<AssignExpr>(Parent);
593599

@@ -744,6 +750,7 @@ class ExprContextAnalyzer {
744750
case ExprKind::PrefixUnary:
745751
case ExprKind::Assign:
746752
case ExprKind::Subscript:
753+
case ExprKind::Array:
747754
return true;
748755
case ExprKind::Tuple: {
749756
auto ParentE = Parent.getAsExpr();

branches/tensorflow-next/lib/SILGen/RValue.h

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -308,42 +308,6 @@ class RValue {
308308
/// be returned. Otherwise, an object will be returned. So this is a
309309
/// convenient way to determine if an RValue needs an address.
310310
SILType getLoweredImplodedTupleType(SILGenFunction &SGF) const &;
311-
312-
/// Rewrite the type of this r-value.
313-
void rewriteType(CanType newType) & {
314-
#ifndef NDEBUG
315-
static const auto areSimilarTypes = [](CanType l, CanType r) {
316-
if (l == r) return true;
317-
318-
// Allow function types to disagree about 'noescape'.
319-
if (auto lf = dyn_cast<FunctionType>(l)) {
320-
if (auto rf = dyn_cast<FunctionType>(r)) {
321-
auto lParams = lf.getParams();
322-
auto rParams = rf.getParams();
323-
return AnyFunctionType::equalParams(lParams, rParams) &&
324-
lf.getResult() == rf.getResult() &&
325-
lf->getExtInfo().withNoEscape(false) ==
326-
rf->getExtInfo().withNoEscape(false);
327-
}
328-
}
329-
return false;
330-
};
331-
332-
static const auto isSingleElementTuple = [](CanType type, CanType eltType) {
333-
if (auto tupleType = dyn_cast<TupleType>(type)) {
334-
return tupleType->getNumElements() == 1 &&
335-
areSimilarTypes(tupleType.getElementType(0), eltType);
336-
}
337-
return false;
338-
};
339-
340-
// We only allow a very modest set of changes to a type.
341-
assert(areSimilarTypes(newType, type) ||
342-
isSingleElementTuple(newType, type) ||
343-
isSingleElementTuple(type, newType));
344-
#endif
345-
type = newType;
346-
}
347311

348312
/// Emit an equivalent value with independent ownership.
349313
RValue copy(SILGenFunction &SGF, SILLocation loc) const &;

branches/tensorflow-next/lib/SILGen/SILGenApply.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5635,20 +5635,7 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) {
56355635
}
56365636
}
56375637

5638-
// Helper routine to add an argument label if we need one.
5639-
auto relabelArgument = [&](ConcreteDeclRef callee, RValue &arg) {
5640-
auto name = callee.getDecl()->getFullName();
5641-
auto argLabels = name.getArgumentNames();
5642-
if (argLabels.size() == 1 && !argLabels[0].empty() &&
5643-
!isa<TupleType>(arg.getType())) {
5644-
Type newType = TupleType::get({TupleTypeElt(arg.getType(), argLabels[0])},
5645-
getASTContext());
5646-
arg.rewriteType(newType->getCanonicalType());
5647-
}
5648-
};
5649-
56505638
// Call the builtin initializer.
5651-
relabelArgument(builtinInit, builtinLiteralArgs);
56525639
RValue builtinLiteral =
56535640
emitApplyAllocatingInitializer(literal, builtinInit,
56545641
std::move(builtinLiteralArgs),
@@ -5659,7 +5646,6 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) {
56595646
if (!init) return builtinLiteral;
56605647

56615648
// Otherwise, perform the second initialization step.
5662-
relabelArgument(init, builtinLiteral);
56635649
RValue result = emitApplyAllocatingInitializer(literal, init,
56645650
std::move(builtinLiteral),
56655651
literal->getType(), C);
@@ -6189,14 +6175,9 @@ void SILGenFunction::emitSetAccessor(SILLocation loc, SILDeclRef set,
61896175
values.addArbitrary(std::move(setValue));
61906176

61916177
if (!subscriptIndices.isNull()) {
6192-
unsigned paramIndex = 1;
61936178
for (auto &component : std::move(subscriptIndices).getSources()) {
6194-
auto param = accessType.getParams()[paramIndex++];
6195-
auto paramType = param.getParameterType();
6196-
61976179
auto argLoc = component.getKnownRValueLocation();
61986180
RValue &&arg = std::move(component).asKnownRValue(*this);
6199-
arg.rewriteType(paramType);
62006181
values.add(argLoc, std::move(arg));
62016182
}
62026183
}

branches/tensorflow-next/lib/SILGen/SILGenExpr.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ namespace {
462462
RValue visitKeyPathExpr(KeyPathExpr *E, SGFContext C);
463463
RValue visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E,
464464
SGFContext C);
465-
RValue visitCollectionExpr(CollectionExpr *E, SGFContext C);
465+
RValue visitArrayExpr(ArrayExpr *E, SGFContext C);
466+
RValue visitDictionaryExpr(DictionaryExpr *E, SGFContext C);
466467
RValue visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *E,
467468
SGFContext C);
468469
RValue visitInjectIntoOptionalExpr(InjectIntoOptionalExpr *E, SGFContext C);
@@ -3601,7 +3602,64 @@ visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E, SGFContext C) {
36013602
llvm_unreachable("Unhandled MagicIdentifierLiteralExpr in switch.");
36023603
}
36033604

3604-
RValue RValueEmitter::visitCollectionExpr(CollectionExpr *E, SGFContext C) {
3605+
RValue RValueEmitter::visitArrayExpr(ArrayExpr *E, SGFContext C) {
3606+
auto loc = SILLocation(E);
3607+
ArgumentScope scope(SGF, loc);
3608+
3609+
CanType elementType = E->getElementType()->getCanonicalType();
3610+
CanType arrayTy = ArraySliceType::get(elementType)->getCanonicalType();
3611+
VarargsInfo varargsInfo =
3612+
emitBeginVarargs(SGF, loc, elementType, arrayTy,
3613+
E->getNumElements(), {});
3614+
3615+
// Cleanups for any elements that have been initialized so far.
3616+
SmallVector<CleanupHandle, 8> cleanups;
3617+
3618+
for (unsigned index : range(E->getNumElements())) {
3619+
auto destAddr = varargsInfo.getBaseAddress();
3620+
if (index != 0) {
3621+
SILValue indexValue = SGF.B.createIntegerLiteral(
3622+
loc, SILType::getBuiltinWordType(SGF.getASTContext()), index);
3623+
destAddr = SGF.B.createIndexAddr(loc, destAddr, indexValue);
3624+
}
3625+
auto &destTL = varargsInfo.getBaseTypeLowering();
3626+
// Create a dormant cleanup for the value in case we exit before the
3627+
// full array has been constructed.
3628+
3629+
CleanupHandle destCleanup = CleanupHandle::invalid();
3630+
if (!destTL.isTrivial()) {
3631+
destCleanup = SGF.enterDestroyCleanup(destAddr);
3632+
SGF.Cleanups.setCleanupState(destCleanup, CleanupState::Dormant);
3633+
cleanups.push_back(destCleanup);
3634+
}
3635+
3636+
TemporaryInitialization init(destAddr, destCleanup);
3637+
3638+
ArgumentSource(E->getElements()[index])
3639+
.forwardInto(SGF, varargsInfo.getBaseAbstractionPattern(), &init,
3640+
destTL);
3641+
}
3642+
3643+
// Kill the per-element cleanups. The array will take ownership of them.
3644+
for (auto destCleanup : cleanups)
3645+
SGF.Cleanups.setCleanupState(destCleanup, CleanupState::Dead);
3646+
3647+
RValue arg(SGF, loc, arrayTy,
3648+
emitEndVarargs(SGF, loc, std::move(varargsInfo)));
3649+
3650+
arg = scope.popPreservingValue(std::move(arg));
3651+
3652+
// If we're building an array, we don't have to call the initializer;
3653+
// we've already built one.
3654+
if (arrayTy->isEqual(E->getType()))
3655+
return arg;
3656+
3657+
// Call the builtin initializer.
3658+
return SGF.emitApplyAllocatingInitializer(
3659+
loc, E->getInitializer(), std::move(arg), E->getType(), C);
3660+
}
3661+
3662+
RValue RValueEmitter::visitDictionaryExpr(DictionaryExpr *E, SGFContext C) {
36053663
return visit(E->getSemanticExpr(), C);
36063664
}
36073665

branches/tensorflow-next/lib/Sema/CSApply.cpp

Lines changed: 10 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,71 +2782,23 @@ namespace {
27822782
ConformanceCheckFlags::InExpression);
27832783
assert(conformance && "Type does not conform to protocol?");
27842784

2785-
// Call the witness that builds the array literal.
2786-
// FIXME: callWitness() may end up re-doing some work we already did
2787-
// to convert the array literal elements to the element type. It would
2788-
// be nicer to re-use them.
2789-
2790-
// FIXME: This location info is bogus.
2791-
Expr *typeRef = TypeExpr::createImplicitHack(expr->getLoc(), arrayTy,
2792-
tc.Context);
2793-
cs.cacheExprTypes(typeRef);
2794-
27952785
DeclName name(tc.Context, DeclBaseName::createConstructor(),
27962786
{ tc.Context.Id_arrayLiteral });
27972787

2798-
// Coerce the array elements to be rvalues, so that other type-checker
2799-
// code that attempts to peephole the AST doesn't have to re-load the
2800-
// elements (and break the invariant that lvalue nodes only get their
2801-
// access kind set once).
2802-
for (auto &element : expr->getElements()) {
2803-
element = cs.coerceToRValue(element);
2804-
}
2805-
2806-
// Restructure the argument to provide the appropriate labels in the
2807-
// tuple.
2808-
SmallVector<TupleTypeElt, 4> typeElements;
2809-
SmallVector<Identifier, 4> names;
2810-
bool first = true;
2811-
for (auto elt : expr->getElements()) {
2812-
if (first) {
2813-
typeElements.push_back(TupleTypeElt(cs.getType(elt),
2814-
tc.Context.Id_arrayLiteral));
2815-
names.push_back(tc.Context.Id_arrayLiteral);
2788+
ConcreteDeclRef witness =
2789+
findNamedWitnessImpl(tc, dc, arrayTy->getRValueType(), arrayProto,
2790+
name, diag::array_protocol_broken, conformance);
2791+
if (!witness || !isa<AbstractFunctionDecl>(witness.getDecl()))
2792+
return nullptr;
2793+
expr->setInitializer(witness);
28162794

2817-
first = false;
2818-
continue;
2819-
}
2795+
auto elementType = expr->getElementType();
28202796

2821-
typeElements.push_back(cs.getType(elt));
2822-
names.push_back(Identifier());
2797+
for (auto &element : expr->getElements()) {
2798+
element = coerceToType(element, elementType,
2799+
cs.getConstraintLocator(element));
28232800
}
28242801

2825-
Type argType = TupleType::get(typeElements, tc.Context);
2826-
assert(isa<TupleType>(argType.getPointer()));
2827-
2828-
Expr *arg =
2829-
TupleExpr::create(tc.Context, SourceLoc(),
2830-
expr->getElements(),
2831-
names,
2832-
{ },
2833-
SourceLoc(), /*HasTrailingClosure=*/false,
2834-
/*Implicit=*/true,
2835-
argType);
2836-
2837-
cs.cacheExprTypes(arg);
2838-
2839-
cs.setExprTypes(typeRef);
2840-
cs.setExprTypes(arg);
2841-
2842-
Expr *result = tc.callWitness(typeRef, dc, arrayProto, *conformance,
2843-
name, arg, diag::array_protocol_broken);
2844-
if (!result)
2845-
return nullptr;
2846-
2847-
cs.cacheExprTypes(result);
2848-
2849-
expr->setSemanticExpr(result);
28502802
return expr;
28512803
}
28522804

branches/tensorflow-next/test/IDE/complete_unresolved_members.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,12 +368,12 @@ func f() -> SomeEnum1 {
368368
return .#^UNRESOLVED_27^#
369369
}
370370

371-
let TopLevelVar1 = OptionSetTaker7([.#^UNRESOLVED_28^#], Op2: [.Option4])
371+
let TopLevelVar1 = OptionSetTaker7([.#^UNRESOLVED_28^#], [.Option4])
372372

373373
let TopLevelVar2 = OptionSetTaker1([.#^UNRESOLVED_29^#])
374374

375-
let TopLevelVar3 = OptionSetTaker7([.Option1], Op2: [.#^UNRESOLVED_30^#])
376-
let TopLevelVar4 = OptionSetTaker7([.Option1], Op2: [.Option4, .#^UNRESOLVED_31^#])
375+
let TopLevelVar3 = OptionSetTaker7([.Option1], [.#^UNRESOLVED_30^#])
376+
let TopLevelVar4 = OptionSetTaker7([.Option1], [.Option4, .#^UNRESOLVED_31^#])
377377

378378
let _: [SomeEnum1] = [.#^UNRESOLVED_32^#]
379379
let _: [SomeEnum1] = [.South, .#^UNRESOLVED_33^#]

branches/tensorflow-next/test/Interpreter/arrays.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,25 @@ test()
161161
let mdaPerf = [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]]
162162
print(mdaPerf)
163163
// CHECK: {{\[}}[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]]
164+
165+
class Deinitable {
166+
deinit {
167+
print("deinit called")
168+
}
169+
}
170+
171+
enum E : Error {
172+
case error
173+
}
174+
175+
func throwingFunc() throws -> Deinitable {
176+
throw E.error
177+
}
178+
179+
do {
180+
let array = try [Deinitable(), throwingFunc()]
181+
} catch {
182+
// CHECK: deinit called
183+
// CHECK: error thrown
184+
print("error thrown")
185+
}

0 commit comments

Comments
 (0)