Skip to content

Commit 019520b

Browse files
authored
Merge pull request #85740 from hamishknight/out-of-place
Rework emission of EditorPlaceholderExprs
2 parents 95d0fd6 + 3a3e8df commit 019520b

File tree

13 files changed

+95
-97
lines changed

13 files changed

+95
-97
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,8 +2370,6 @@ NOTE(note_no_in_class_init_3plus,none,
23702370
(Identifier, Identifier, Identifier, bool))
23712371
ERROR(missing_unimplemented_init_runtime,none,
23722372
"standard library error: missing _unimplementedInitializer", ())
2373-
ERROR(missing_undefined_runtime,none,
2374-
"standard library error: missing _undefined", ())
23752373

23762374
ERROR(inherited_default_value_not_in_designated_constructor,none,
23772375
"default value inheritance via 'super' is only valid on the parameters of "

include/swift/AST/Expr.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5764,14 +5764,13 @@ class EditorPlaceholderExpr : public Expr {
57645764
SourceLoc Loc;
57655765
TypeRepr *PlaceholderTy;
57665766
TypeRepr *ExpansionTyR;
5767-
Expr *SemanticExpr;
57685767

57695768
public:
57705769
EditorPlaceholderExpr(Identifier Placeholder, SourceLoc Loc,
57715770
TypeRepr *PlaceholderTy, TypeRepr *ExpansionTyR)
57725771
: Expr(ExprKind::EditorPlaceholder, /*Implicit=*/false),
57735772
Placeholder(Placeholder), Loc(Loc), PlaceholderTy(PlaceholderTy),
5774-
ExpansionTyR(ExpansionTyR), SemanticExpr(nullptr) {}
5773+
ExpansionTyR(ExpansionTyR) {}
57755774

57765775
Identifier getPlaceholder() const { return Placeholder; }
57775776
SourceRange getSourceRange() const { return Loc; }
@@ -5783,9 +5782,6 @@ class EditorPlaceholderExpr : public Expr {
57835782
static bool classof(const Expr *E) {
57845783
return E->getKind() == ExprKind::EditorPlaceholder;
57855784
}
5786-
5787-
Expr *getSemanticExpr() const { return SemanticExpr; }
5788-
void setSemanticExpr(Expr *SE) { SemanticExpr = SE; }
57895785
};
57905786

57915787
/// A LazyInitializerExpr is used to embed an existing typechecked

include/swift/AST/KnownDecls.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,6 @@ FUNC_DECL(ModifyAtReferenceWritableKeyPath, "_modifyAtReferenceWritableKeyPath")
9191
FUNC_DECL(Swap, "swap")
9292

9393
FUNC_DECL(UnimplementedInitializer, "_unimplementedInitializer")
94-
FUNC_DECL(Undefined, "_undefined")
94+
FUNC_DECL(UndefinedEditorPlaceholder, "_undefinedEditorPlaceholder")
9595

9696
#undef FUNC_DECL

include/swift/Sema/ConstraintLocator.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ enum ContextualTypePurpose : uint8_t {
8383

8484
CTP_ExprPattern, ///< `~=` operator application associated with expression
8585
/// pattern.
86-
87-
CTP_CannotFail, ///< Conversion can never fail. abort() if it does.
8886
};
8987

9088
namespace constraints {

lib/AST/ASTDumper.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4430,9 +4430,6 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, Label>,
44304430
if (ExpTyR && ExpTyR != TyR) {
44314431
printRec(ExpTyR, Label::optional("type_repr_for_expansion"));
44324432
}
4433-
if (auto *SE = E->getSemanticExpr()) {
4434-
printRec(SE, Label::always("semantic_expr"));
4435-
}
44364433
printFoot();
44374434
}
44384435
void visitLazyInitializerExpr(LazyInitializerExpr *E, Label label) {

lib/AST/ASTWalker.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -599,23 +599,6 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
599599
// Exprs
600600
//===--------------------------------------------------------------------===//
601601

602-
// A macro for handling the "semantic expressions" that are common
603-
// on sugared expression nodes like string interpolation. The
604-
// semantic expression is set up by type-checking to include all the
605-
// other children as sub-expressions, so if it exists, we should
606-
// just bypass the rest of the visitation.
607-
#define HANDLE_SEMANTIC_EXPR(NODE) \
608-
do { \
609-
if (Expr *_semanticExpr = NODE->getSemanticExpr()) { \
610-
if ((_semanticExpr = doIt(_semanticExpr))) { \
611-
NODE->setSemanticExpr(_semanticExpr); \
612-
} else { \
613-
return nullptr; \
614-
} \
615-
return NODE; \
616-
} \
617-
} while (false)
618-
619602
Expr *visitErrorExpr(ErrorExpr *E) {
620603
if (auto *origExpr = E->getOriginalExpr()) {
621604
auto *newOrigExpr = doIt(origExpr);
@@ -1267,7 +1250,6 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
12671250
}
12681251

12691252
Expr *visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) {
1270-
HANDLE_SEMANTIC_EXPR(E);
12711253
return E;
12721254
}
12731255

lib/SILGen/SILGenExpr.cpp

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,9 @@ namespace {
499499
emitFunctionCvtFromExecutionCallerToGlobalActor(FunctionConversionExpr *E,
500500
SGFContext C);
501501

502+
/// Helper to emit a value of arbitrary type in an unreachable codepath.
503+
RValue emitUnreachableValue(SILLocation loc, CanType ty);
504+
502505
RValue visitActorIsolationErasureExpr(ActorIsolationErasureExpr *E,
503506
SGFContext C);
504507
RValue visitExtractFunctionIsolationExpr(ExtractFunctionIsolationExpr *E,
@@ -2136,6 +2139,32 @@ RValue RValueEmitter::emitFunctionCvtFromExecutionCallerToGlobalActor(
21362139
return RValue(SGF, e, destType, result);
21372140
}
21382141

2142+
RValue RValueEmitter::emitUnreachableValue(SILLocation loc, CanType ty) {
2143+
ASSERT(!SGF.B.hasValidInsertionPoint() && "Must be unreachable");
2144+
2145+
// Continue code generation in a block with no predecessors.
2146+
// Whatever code is emitted here is guaranteed to be removed by SIL passes.
2147+
SGF.B.emitBlock(SGF.createBasicBlock());
2148+
2149+
// Since the type is uninhabited, use a SILUndef of so that we can return
2150+
// some sort of RValue from this API.
2151+
auto &lowering = SGF.getTypeLowering(ty);
2152+
auto loweredTy = lowering.getLoweredType();
2153+
auto undef = SILUndef::get(SGF.F, loweredTy);
2154+
2155+
// Create an alloc initialized with contents from the undefined addr type.
2156+
// It seems pack addresses do not satisfy isPlusOneOrTrivial, so we need an
2157+
// actual allocation.
2158+
if (loweredTy.isAddress()) {
2159+
auto resultAddr = SGF.emitTemporaryAllocation(loc, loweredTy);
2160+
SGF.emitSemanticStore(loc, undef, resultAddr, lowering, IsInitialization);
2161+
return RValue(SGF, loc, ty, SGF.emitManagedRValueWithCleanup(resultAddr));
2162+
}
2163+
2164+
// Otherwise, if it's not an address, just emit the undef value itself.
2165+
return RValue(SGF, loc, ty, ManagedValue::forRValueWithoutOwnership(undef));
2166+
}
2167+
21392168
RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
21402169
SGFContext C) {
21412170
CanAnyFunctionType srcType =
@@ -2660,28 +2689,7 @@ RValue RValueEmitter::visitUnreachableExpr(UnreachableExpr *E, SGFContext C) {
26602689
// Emit the expression, followed by an unreachable.
26612690
SGF.emitIgnoredExpr(E->getSubExpr());
26622691
SGF.B.createUnreachable(E);
2663-
2664-
// Continue code generation in a block with no predecessors.
2665-
// Whatever code is emitted here is guaranteed to be removed by SIL passes.
2666-
SGF.B.emitBlock(SGF.createBasicBlock());
2667-
2668-
// Since the type is uninhabited, use a SILUndef of so that we can return
2669-
// some sort of RValue from this API.
2670-
auto &lowering = SGF.getTypeLowering(E->getType());
2671-
auto loweredTy = lowering.getLoweredType();
2672-
auto undef = SILUndef::get(SGF.F, loweredTy);
2673-
2674-
// Create an alloc initialized with contents from the undefined addr type.
2675-
// It seems pack addresses do not satisfy isPlusOneOrTrivial, so we need an
2676-
// actual allocation.
2677-
if (loweredTy.isAddress()) {
2678-
auto resultAddr = SGF.emitTemporaryAllocation(E, loweredTy);
2679-
SGF.emitSemanticStore(E, undef, resultAddr, lowering, IsInitialization);
2680-
return RValue(SGF, E, SGF.emitManagedRValueWithCleanup(resultAddr));
2681-
}
2682-
2683-
// Otherwise, if it's not an address, just emit the undef value itself.
2684-
return RValue(SGF, E, ManagedValue::forRValueWithoutOwnership(undef));
2692+
return emitUnreachableValue(E, E->getType()->getCanonicalType());
26852693
}
26862694

26872695
static SILValue getArrayBuffer(SILValue array, SILGenFunction &SGF, SILLocation loc) {
@@ -3477,7 +3485,21 @@ visitObjectLiteralExpr(ObjectLiteralExpr *E, SGFContext C) {
34773485

34783486
RValue RValueEmitter::
34793487
visitEditorPlaceholderExpr(EditorPlaceholderExpr *E, SGFContext C) {
3480-
return visit(E->getSemanticExpr(), C);
3488+
if (auto *undefinedFn = SGF.getASTContext().getUndefinedEditorPlaceholder()) {
3489+
auto args = SGF.emitSourceLocationArgs(E->getLoc(), E);
3490+
SGF.emitApplyOfLibraryIntrinsic(E, undefinedFn, SubstitutionMap(),
3491+
{
3492+
args.filenameStartPointer,
3493+
args.filenameLength,
3494+
args.filenameIsAscii,
3495+
args.line,
3496+
},
3497+
SGFContext());
3498+
} else {
3499+
SGF.B.createUnconditionalFail(E, "attempt to evaluate editor placeholder");
3500+
}
3501+
SGF.B.createUnreachable(E);
3502+
return emitUnreachableValue(E, E->getType()->getCanonicalType());
34813503
}
34823504

34833505
RValue RValueEmitter::visitObjCSelectorExpr(ObjCSelectorExpr *e, SGFContext C) {

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4782,34 +4782,7 @@ namespace {
47824782
}
47834783

47844784
Expr *visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) {
4785-
simplifyExprType(E);
4786-
auto valueType = cs.getType(E);
4787-
4788-
// Synthesize a call to _undefined() of appropriate type.
4789-
FuncDecl *undefinedDecl = ctx.getUndefined();
4790-
if (!undefinedDecl) {
4791-
ctx.Diags.diagnose(E->getLoc(), diag::missing_undefined_runtime);
4792-
return nullptr;
4793-
}
4794-
DeclRefExpr *fnRef = new (ctx) DeclRefExpr(undefinedDecl, DeclNameLoc(),
4795-
/*Implicit=*/true);
4796-
fnRef->setFunctionRefInfo(FunctionRefInfo::singleBaseNameApply());
4797-
4798-
StringRef msg = "attempt to evaluate editor placeholder";
4799-
Expr *argExpr = new (ctx) StringLiteralExpr(msg, E->getLoc(),
4800-
/*implicit*/true);
4801-
4802-
auto *argList = ArgumentList::forImplicitUnlabeled(ctx, {argExpr});
4803-
Expr *callExpr = CallExpr::createImplicit(ctx, fnRef, argList);
4804-
4805-
auto resultTy = TypeChecker::typeCheckExpression(
4806-
callExpr, dc, /*contextualInfo=*/{valueType, CTP_CannotFail});
4807-
assert(resultTy && "Conversion cannot fail!");
4808-
(void)resultTy;
4809-
4810-
cs.cacheExprTypes(callExpr);
4811-
E->setSemanticExpr(callExpr);
4812-
return E;
4785+
return simplifyExprType(E);
48134786
}
48144787

48154788
Expr *visitObjCSelectorExpr(ObjCSelectorExpr *E) {
@@ -9616,7 +9589,6 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
96169589
case CTP_SubscriptAssignSource:
96179590
case CTP_Condition:
96189591
case CTP_WrappedProperty:
9619-
case CTP_CannotFail:
96209592
case CTP_SingleValueStmtBranch:
96219593
result.setExpr(rewrittenExpr);
96229594
break;

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,6 @@ GenericArgumentsMismatchFailure::getDiagnosticFor(
864864
case CTP_ThrowStmt:
865865
case CTP_ForEachSequence:
866866
case CTP_Unused:
867-
case CTP_CannotFail:
868867
case CTP_YieldByReference:
869868
case CTP_EnumCaseRawValue:
870869
case CTP_ExprPattern:
@@ -973,7 +972,7 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
973972

974973
case ConstraintLocator::ContextualType: {
975974
auto purpose = getContextualTypePurpose();
976-
assert(!(purpose == CTP_Unused || purpose == CTP_CannotFail));
975+
assert(purpose != CTP_Unused);
977976

978977
// If this is call to a closure e.g. `let _: A = { B() }()`
979978
// let's point diagnostic to its result.
@@ -2949,9 +2948,7 @@ static std::optional<Diag<Type>>
29492948
getContextualNilDiagnostic(ContextualTypePurpose CTP) {
29502949
switch (CTP) {
29512950
case CTP_Unused:
2952-
case CTP_CannotFail:
2953-
llvm_unreachable("These contextual type purposes cannot fail with a "
2954-
"conversion type specified!");
2951+
llvm_unreachable("Expected a contextual purpose");
29552952
case CTP_Initialization:
29562953
return diag::cannot_convert_initializer_value_nil;
29572954

@@ -3749,7 +3746,6 @@ ContextualFailure::getDiagnosticFor(ContextualTypePurpose context,
37493746
case CTP_ThrowStmt:
37503747
case CTP_ForEachSequence:
37513748
case CTP_Unused:
3752-
case CTP_CannotFail:
37533749
case CTP_YieldByReference:
37543750
case CTP_ExprPattern:
37553751
break;

lib/Sema/CSSimplify.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16680,7 +16680,6 @@ void ConstraintSystem::addContextualConversionConstraint(
1668016680

1668116681
case CTP_ArrayElement:
1668216682
case CTP_AssignSource:
16683-
case CTP_CannotFail:
1668416683
case CTP_Condition:
1668516684
case CTP_Unused:
1668616685
case CTP_YieldByValue:

0 commit comments

Comments
 (0)