Skip to content

Commit 2efbeb3

Browse files
authored
Merge pull request #21451 from CodaFi/logicd
[SR-8272] Drop the last remnants of LogicValue
2 parents 335fe49 + 426fe88 commit 2efbeb3

23 files changed

+61
-241
lines changed

include/swift/AST/KnownIdentifiers.def

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ IDENTIFIER(appendInterpolation)
175175
IDENTIFIER_WITH_NAME(dollarInterpolation, "$interpolation")
176176
IDENTIFIER(arrayLiteral)
177177
IDENTIFIER(dictionaryLiteral)
178-
IDENTIFIER_(getBuiltinLogicValue)
179178
IDENTIFIER(className)
180179

181180
IDENTIFIER_(ErrorType)

lib/AST/ASTVerifier.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ class Verifier : public ASTWalker {
996996
case StmtConditionElement::CK_Boolean: {
997997
auto *E = elt.getBoolean();
998998
if (shouldVerifyChecked(E))
999-
checkSameType(E->getType(), BuiltinIntegerType::get(1, Ctx),
999+
checkSameType(E->getType(), Ctx.getBoolDecl()->getDeclaredType(),
10001000
"condition type");
10011001
break;
10021002
}
@@ -2070,8 +2070,8 @@ class Verifier : public ASTWalker {
20702070
PrettyStackTraceExpr debugStack(Ctx, "verifying IfExpr", E);
20712071

20722072
auto condTy = E->getCondExpr()->getType();
2073-
if (!condTy->isBuiltinIntegerType(1)) {
2074-
Out << "IfExpr condition is not an i1\n";
2073+
if (!condTy->isBool()) {
2074+
Out << "IfExpr condition is not Bool\n";
20752075
abort();
20762076
}
20772077

lib/SILGen/SILGenDecl.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -696,9 +696,12 @@ copyOrInitValueInto(SILGenFunction &SGF, SILLocation loc,
696696
getUnmanagedValue();
697697
}
698698

699+
assert(testBool->getType().getASTType()->isBool());
700+
auto i1Value = SGF.emitUnwrapIntegerResult(loc, testBool);
701+
699702
SILBasicBlock *contBB = SGF.B.splitBlockForFallthrough();
700703
auto falseBB = SGF.Cleanups.emitBlockForCleanups(getFailureDest(), loc);
701-
SGF.B.createCondBranch(loc, testBool, contBB, falseBB);
704+
SGF.B.createCondBranch(loc, i1Value, contBB, falseBB);
702705

703706
SGF.B.setInsertionPoint(contBB);
704707
}
@@ -995,13 +998,7 @@ copyOrInitValueInto(SILGenFunction &SGF, SILLocation loc,
995998
assert(isInit && "Only initialization is supported for refutable patterns");
996999

9971000
// Extract the i1 from the Bool struct.
998-
StructDecl *BoolStruct = cast<StructDecl>(SGF.getASTContext().getBoolDecl());
999-
auto Members = BoolStruct->lookupDirect(SGF.getASTContext().Id_value_);
1000-
assert(Members.size() == 1 &&
1001-
"Bool should have only one property with name '_value'");
1002-
auto Member = dyn_cast<VarDecl>(Members[0]);
1003-
assert(Member &&"Bool should have a property with name '_value' of type Int1");
1004-
auto *i1Val = SGF.B.createStructExtract(loc, value.forward(SGF), Member);
1001+
auto i1Value = SGF.emitUnwrapIntegerResult(loc, value.forward(SGF));
10051002

10061003
// Branch on the boolean based on whether we're testing for true or false.
10071004
SILBasicBlock *trueBB = SGF.B.splitBlockForFallthrough();
@@ -1010,7 +1007,7 @@ copyOrInitValueInto(SILGenFunction &SGF, SILLocation loc,
10101007

10111008
if (!pattern->getValue())
10121009
std::swap(trueBB, falseBB);
1013-
SGF.B.createCondBranch(loc, i1Val, trueBB, falseBB);
1010+
SGF.B.createCondBranch(loc, i1Value, trueBB, falseBB);
10141011
SGF.B.setInsertionPoint(contBB);
10151012
}
10161013

@@ -1264,6 +1261,7 @@ void SILGenFunction::emitStmtCondition(StmtCondition Cond, JumpDest FalseDest,
12641261
// Evaluate the condition as an i1 value (guaranteed by Sema).
12651262
FullExpr Scope(Cleanups, CleanupLocation(expr));
12661263
booleanTestValue = emitRValue(expr).forwardAsSingleValue(*this, expr);
1264+
booleanTestValue = emitUnwrapIntegerResult(expr, booleanTestValue);
12671265
booleanTestLoc = expr;
12681266
break;
12691267
}

lib/SILGen/SILGenForeignError.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -281,25 +281,6 @@ void SILGenFunction::emitForeignErrorBlock(SILLocation loc,
281281
emitThrow(loc, error);
282282
}
283283

284-
/// Unwrap a value of a wrapped integer type to get at the juicy
285-
/// Builtin.IntegerN value within.
286-
static SILValue emitUnwrapIntegerResult(SILGenFunction &SGF,
287-
SILLocation loc,
288-
SILValue value) {
289-
// This is a loop because we want to handle types that wrap integer types,
290-
// like ObjCBool (which may be Bool or Int8).
291-
while (!value->getType().is<BuiltinIntegerType>()) {
292-
auto structDecl = value->getType().getStructOrBoundGenericStruct();
293-
assert(structDecl && "value for error result wasn't of struct type!");
294-
assert(std::next(structDecl->getStoredProperties().begin())
295-
== structDecl->getStoredProperties().end());
296-
auto property = *structDecl->getStoredProperties().begin();
297-
value = SGF.B.createStructExtract(loc, value, property);
298-
}
299-
300-
return value;
301-
}
302-
303284
/// Perform a foreign error check by testing whether the call result is zero.
304285
/// The call result is otherwise ignored.
305286
static void
@@ -312,7 +293,7 @@ emitResultIsZeroErrorCheck(SILGenFunction &SGF, SILLocation loc,
312293
}
313294

314295
SILValue resultValue =
315-
emitUnwrapIntegerResult(SGF, loc, result.getUnmanagedValue());
296+
SGF.emitUnwrapIntegerResult(loc, result.getUnmanagedValue());
316297
auto resultType = resultValue->getType().getASTType();
317298

318299
if (!resultType->isBuiltinIntegerType(1)) {

lib/SILGen/SILGenFunction.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,3 +687,19 @@ Optional<ASTNode> SILGenFunction::getPGOParent(ASTNode Node) const {
687687
return SP->getPGOParent(Node);
688688
return None;
689689
}
690+
691+
SILValue SILGenFunction::emitUnwrapIntegerResult(SILLocation loc,
692+
SILValue value) {
693+
// This is a loop because we want to handle types that wrap integer types,
694+
// like ObjCBool (which may be Bool or Int8).
695+
while (!value->getType().is<BuiltinIntegerType>()) {
696+
auto structDecl = value->getType().getStructOrBoundGenericStruct();
697+
assert(structDecl && "value for error result wasn't of struct type!");
698+
assert(std::next(structDecl->getStoredProperties().begin())
699+
== structDecl->getStoredProperties().end());
700+
auto property = *structDecl->getStoredProperties().begin();
701+
value = B.createStructExtract(loc, value, property);
702+
}
703+
704+
return value;
705+
}

lib/SILGen/SILGenFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
13431343
SILValue semanticValue,
13441344
SILType storageType);
13451345

1346+
SILValue emitUnwrapIntegerResult(SILLocation loc, SILValue value);
1347+
13461348
/// Load an r-value out of the given address. This does not handle
13471349
/// reabstraction or bridging. If that is needed, use the other emit load
13481350
/// entry point.

lib/SILGen/SILGenPattern.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,9 @@ void PatternMatchEmission::emitGuardBranch(SILLocation loc, Expr *guard,
12101210
testBool = SGF.emitRValueAsSingleValue(guard).getUnmanagedValue();
12111211
}
12121212

1213-
SGF.B.createCondBranch(loc, testBool, trueBB, falseBB);
1213+
// Extract the i1 from the Bool struct.
1214+
auto i1Value = SGF.emitUnwrapIntegerResult(loc, testBool);
1215+
SGF.B.createCondBranch(loc, i1Value, trueBB, falseBB);
12141216

12151217
SGF.B.setInsertionPoint(falseBB);
12161218
failure(loc);
@@ -2250,15 +2252,8 @@ emitBoolDispatch(ArrayRef<RowToSpecialize> rows, ConsumableManagedValue src,
22502252
SILValue srcValue = src.getFinalManagedValue().forward(SGF);
22512253

22522254
// Extract the i1 from the Bool struct.
2253-
StructDecl *BoolStruct = cast<StructDecl>(Context.getBoolDecl());
2254-
auto Members = BoolStruct->lookupDirect(Context.Id_value_);
2255-
assert(Members.size() == 1 &&
2256-
"Bool should have only one property with name '_value'");
2257-
auto Member = dyn_cast<VarDecl>(Members[0]);
2258-
assert(Member &&"Bool should have a property with name '_value' of type Int1");
2259-
auto *ETI = SGF.B.createStructExtract(loc, srcValue, Member);
2260-
2261-
SGF.B.createSwitchValue(loc, SILValue(ETI), defaultBB, caseBBs);
2255+
auto i1Value = SGF.emitUnwrapIntegerResult(loc, srcValue);
2256+
SGF.B.createSwitchValue(loc, i1Value, defaultBB, caseBBs);
22622257

22632258
// Okay, now emit all the cases.
22642259
for (unsigned i = 0, e = caseInfos.size(); i != e; ++i) {

lib/SILGen/SILGenStmt.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,15 +232,14 @@ Condition SILGenFunction::emitCondition(Expr *E, bool invertValue,
232232
assert(B.hasValidInsertionPoint() &&
233233
"emitting condition at unreachable point");
234234

235-
// Sema forces conditions to have Builtin.i1 type, which guarantees this.
235+
// Sema forces conditions to have Bool type, which guarantees this.
236236
SILValue V;
237237
{
238238
FullExpr Scope(Cleanups, CleanupLocation(E));
239239
V = emitRValue(E).forwardAsSingleValue(*this, E);
240240
}
241-
assert(V->getType().castTo<BuiltinIntegerType>()->isFixedWidth(1));
242-
243-
return emitCondition(V, E, invertValue, contArgs, NumTrueTaken,
241+
auto i1Value = emitUnwrapIntegerResult(E, V);
242+
return emitCondition(i1Value, E, invertValue, contArgs, NumTrueTaken,
244243
NumFalseTaken);
245244
}
246245

@@ -525,16 +524,16 @@ void StmtEmitter::visitPoundAssertStmt(PoundAssertStmt *stmt) {
525524
SGF.emitRValueAsSingleValue(stmt->getCondition()).getUnmanagedValue();
526525
}
527526

528-
// Sema forces conditions to have Builtin.i1 type.
529-
assert(condition->getType().castTo<BuiltinIntegerType>()->isFixedWidth(1));
527+
// Extract the i1 from the Bool struct.
528+
auto i1Value = SGF.emitUnwrapIntegerResult(stmt, condition);
530529

531530
SILValue message = SGF.B.createStringLiteral(
532531
stmt, stmt->getMessage(), StringLiteralInst::Encoding::UTF8);
533532

534533
auto resultType = SGF.getASTContext().TheEmptyTupleType;
535534
SGF.B.createBuiltin(
536535
stmt, SGF.getASTContext().getIdentifier("poundAssert"),
537-
SGF.getLoweredType(resultType), {}, {condition, message});
536+
SGF.getLoweredType(resultType), {}, {i1Value, message});
538537
}
539538

540539
namespace {

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3143,10 +3143,7 @@ namespace {
31433143
auto resultTy = simplifyType(cs.getType(expr));
31443144
cs.setType(expr, resultTy);
31453145

3146-
// Convert the condition to a logic value.
3147-
auto cond
3148-
= solution.convertBooleanTypeToBuiltinI1(expr->getCondExpr(),
3149-
cs.getConstraintLocator(expr));
3146+
auto cond = cs.coerceToRValue(expr->getCondExpr());
31503147
expr->setCondExpr(cond);
31513148

31523149
// Coerce the then/else branches to the common type.
@@ -8011,81 +8008,6 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
80118008
return result;
80128009
}
80138010

8014-
Expr *
8015-
Solution::convertBooleanTypeToBuiltinI1(Expr *expr,
8016-
ConstraintLocator *locator) const {
8017-
auto &cs = getConstraintSystem();
8018-
8019-
// Load lvalues here.
8020-
expr = cs.coerceToRValue(expr);
8021-
8022-
auto &tc = cs.getTypeChecker();
8023-
auto &ctx = tc.Context;
8024-
8025-
auto type = cs.getType(expr);
8026-
8027-
// We allow UnresolvedType <c $T for all $T, so we might end up here
8028-
// in diagnostics. Just bail out.
8029-
if (type->is<UnresolvedType>())
8030-
return expr;
8031-
8032-
// Look for the builtin name. If we don't have it, we need to call the
8033-
// general name via the witness table.
8034-
NameLookupOptions lookupOptions = defaultMemberLookupOptions;
8035-
if (isa<AbstractFunctionDecl>(cs.DC))
8036-
lookupOptions |= NameLookupFlags::KnownPrivate;
8037-
auto members = tc.lookupMember(cs.DC, type,
8038-
tc.Context.Id_getBuiltinLogicValue,
8039-
lookupOptions);
8040-
8041-
// Find the builtin method.
8042-
if (members.size() != 1) {
8043-
tc.diagnose(expr->getLoc(), diag::broken_bool);
8044-
return expr;
8045-
}
8046-
auto *builtinMethod = dyn_cast<FuncDecl>(members[0].getValueDecl());
8047-
if (!builtinMethod) {
8048-
tc.diagnose(expr->getLoc(), diag::broken_bool);
8049-
return expr;
8050-
}
8051-
8052-
// The method is not generic, so there are no substitutions.
8053-
tc.validateDeclForNameLookup(builtinMethod);
8054-
auto builtinMethodType = builtinMethod->getInterfaceType()
8055-
->castTo<FunctionType>();
8056-
8057-
// Form an unbound reference to the builtin method.
8058-
auto *declRef = new (ctx) DeclRefExpr(builtinMethod,
8059-
DeclNameLoc(expr->getLoc()),
8060-
/*Implicit=*/true);
8061-
declRef->setFunctionRefKind(FunctionRefKind::DoubleApply);
8062-
cs.setType(declRef, builtinMethodType);
8063-
8064-
auto getType = [&](const Expr *E) -> Type {
8065-
return cs.getType(E);
8066-
};
8067-
8068-
// Apply 'self' to get the method value.
8069-
auto *methodRef = new (ctx) DotSyntaxCallExpr(declRef,
8070-
SourceLoc(),
8071-
expr);
8072-
cs.setType(methodRef, builtinMethodType->getResult());
8073-
8074-
// Apply the empty argument list to get the final result.
8075-
auto *result = CallExpr::createImplicit(ctx, methodRef,
8076-
{ }, { }, getType);
8077-
cs.setType(result, builtinMethodType->getResult()
8078-
->castTo<FunctionType>()->getResult());
8079-
cs.setType(result->getArg(), ctx.TheEmptyTupleType);
8080-
8081-
if (!cs.getType(result)->isBuiltinIntegerType(1)) {
8082-
tc.diagnose(expr->getLoc(), diag::broken_bool);
8083-
return result;
8084-
}
8085-
8086-
return result;
8087-
}
8088-
80898011
Expr *Solution::convertOptionalToBool(Expr *expr,
80908012
ConstraintLocator *locator) const {
80918013
auto &cs = getConstraintSystem();

lib/Sema/CSGen.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3315,22 +3315,6 @@ namespace {
33153315
continue;
33163316
}
33173317

3318-
// Strip off 'Bool' to 'Builtin.Int1' conversion. Otherwise, we'll have
3319-
// to handle multiple ways of type-checking.
3320-
if (expr->isImplicit()) {
3321-
if (auto call = dyn_cast<CallExpr>(expr)) {
3322-
if (auto DSCE = dyn_cast<DotSyntaxCallExpr>(call->getFn())) {
3323-
auto RefD = DSCE->getFn()->getReferencedDecl().getDecl();
3324-
if (RefD->getBaseName() == TC.Context.Id_getBuiltinLogicValue &&
3325-
RefD->getDeclContext()->getSelfNominalTypeDecl() ==
3326-
TC.Context.getBoolDecl()) {
3327-
expr = DSCE->getBase();
3328-
continue;
3329-
}
3330-
}
3331-
}
3332-
}
3333-
33343318
// Remove any semantic expression injected by typechecking.
33353319
if (auto CE = dyn_cast<CollectionExpr>(expr)) {
33363320
CE->setSemanticExpr(nullptr);

lib/Sema/ConstraintSystem.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -636,19 +636,6 @@ class Solution {
636636
bool ignoreTopLevelInjection = false,
637637
Optional<Pattern*> typeFromPattern = None) const;
638638

639-
/// Convert the given expression to a logic value.
640-
///
641-
/// This operation cannot fail.
642-
///
643-
/// \param expr The expression to coerce. The type of this expression
644-
/// must conform to the LogicValue protocol.
645-
///
646-
/// \param locator Locator used to describe the location of this expression.
647-
///
648-
/// \returns the expression converted to a logic value (Builtin i1).
649-
Expr *convertBooleanTypeToBuiltinI1(Expr *expr,
650-
ConstraintLocator *locator) const;
651-
652639
/// Convert the given optional-producing expression to a Bool
653640
/// indicating whether the optional has a value.
654641
///

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,10 +2699,9 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
26992699
}
27002700

27012701
bool TypeChecker::typeCheckCondition(Expr *&expr, DeclContext *dc) {
2702-
// If this expression is already typechecked and has an i1 type, then it has
2703-
// already got its conversion from Boolean back to i1. Just re-typecheck
2704-
// it.
2705-
if (expr->getType() && expr->getType()->isBuiltinIntegerType(1)) {
2702+
// If this expression is already typechecked and has type Bool, then just
2703+
// re-typecheck it.
2704+
if (expr->getType() && expr->getType()->isBool()) {
27062705
auto resultTy = typeCheckExpression(expr, dc);
27072706
return !resultTy;
27082707
}
@@ -2728,19 +2727,6 @@ bool TypeChecker::typeCheckCondition(Expr *&expr, DeclContext *dc) {
27282727
cs.getConstraintLocator(expr));
27292728
return false;
27302729
}
2731-
2732-
// Convert the result to a Builtin.i1.
2733-
Expr *appliedSolution(constraints::Solution &solution,
2734-
Expr *expr) override {
2735-
auto &cs = solution.getConstraintSystem();
2736-
2737-
auto converted =
2738-
solution.convertBooleanTypeToBuiltinI1(expr,
2739-
cs.getConstraintLocator(OrigExpr));
2740-
cs.setExprTypes(converted);
2741-
return converted;
2742-
}
2743-
27442730
};
27452731

27462732
ConditionListener listener;

stdlib/public/core/Bool.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,6 @@ extension Bool : _ExpressibleByBuiltinBooleanLiteral, ExpressibleByBooleanLitera
170170
}
171171
}
172172

173-
extension Bool {
174-
// This is a magic entry point known to the compiler.
175-
@_transparent
176-
public // COMPILER_INTRINSIC
177-
func _getBuiltinLogicValue() -> Builtin.Int1 {
178-
return _value
179-
}
180-
}
181-
182173
extension Bool : CustomStringConvertible {
183174
/// A textual representation of the Boolean value.
184175
@inlinable

0 commit comments

Comments
 (0)