Skip to content

[WIP][Sema][stdlib] Remove _getBuiltinLogicValue #21285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion include/swift/AST/KnownIdentifiers.def
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ IDENTIFIER(appendInterpolation)
IDENTIFIER_WITH_NAME(dollarInterpolation, "$interpolation")
IDENTIFIER(arrayLiteral)
IDENTIFIER(dictionaryLiteral)
IDENTIFIER_(getBuiltinLogicValue)
IDENTIFIER(className)

IDENTIFIER_(ErrorType)
Expand Down
56 changes: 19 additions & 37 deletions lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3164,9 +3164,8 @@ namespace {
cs.setType(expr, resultTy);

// Convert the condition to a logic value.
auto cond
= solution.convertBooleanTypeToBuiltinI1(expr->getCondExpr(),
cs.getConstraintLocator(expr));
auto cond = solution.getBoolValue(expr->getCondExpr(),
cs.getConstraintLocator(expr));
expr->setCondExpr(cond);

// Coerce the then/else branches to the common type.
Expand Down Expand Up @@ -8023,9 +8022,7 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
return result;
}

Expr *
Solution::convertBooleanTypeToBuiltinI1(Expr *expr,
ConstraintLocator *locator) const {
Expr *Solution::getBoolValue(Expr *expr, ConstraintLocator *locator) const {
auto &cs = getConstraintSystem();

// Load lvalues here.
Expand All @@ -8041,55 +8038,40 @@ Solution::convertBooleanTypeToBuiltinI1(Expr *expr,
if (type->is<UnresolvedType>())
return expr;

// Look for the builtin name. If we don't have it, we need to call the
// Look for the property name. If we don't have it, we need to call the
// general name via the witness table.
NameLookupOptions lookupOptions = defaultMemberLookupOptions;
if (isa<AbstractFunctionDecl>(cs.DC))
lookupOptions |= NameLookupFlags::KnownPrivate;
auto members = tc.lookupMember(cs.DC, type,
tc.Context.Id_getBuiltinLogicValue,
ctx.Id_value_,
lookupOptions);

// Find the builtin method.
// Find the _value property
if (members.size() != 1) {
tc.diagnose(expr->getLoc(), diag::broken_bool);
return expr;
}
auto *builtinMethod = dyn_cast<FuncDecl>(members[0].getValueDecl());
if (!builtinMethod) {

auto *value = dyn_cast<VarDecl>(members[0].getValueDecl());
if (!value) {
tc.diagnose(expr->getLoc(), diag::broken_bool);
return expr;
}

// The method is not generic, so there are no substitutions.
tc.validateDeclForNameLookup(builtinMethod);
auto builtinMethodType = builtinMethod->getInterfaceType()
->castTo<FunctionType>();

// Form an unbound reference to the builtin method.
auto *declRef = new (ctx) DeclRefExpr(builtinMethod,
DeclNameLoc(expr->getLoc()),
/*Implicit=*/true);
declRef->setFunctionRefKind(FunctionRefKind::DoubleApply);
cs.setType(declRef, builtinMethodType);

auto getType = [&](const Expr *E) -> Type {
return cs.getType(E);
};
// This property is not generic, so there are no substitutions.
tc.validateDeclForNameLookup(value);
auto builtinType = value->getValueInterfaceType();

// Apply 'self' to get the method value.
auto *methodRef = new (ctx) DotSyntaxCallExpr(declRef,
SourceLoc(),
expr);
cs.setType(methodRef, builtinMethodType->getResult());
// Form a reference to Bool._value
auto *result = new (ctx) MemberRefExpr(expr, expr->getLoc(),
ConcreteDeclRef(value),
DeclNameLoc(expr->getLoc()),
/*implicit*/ true);

// Apply the empty argument list to get the final result.
auto *result = CallExpr::createImplicit(ctx, methodRef,
{ }, { }, getType);
cs.setType(result, builtinMethodType->getResult()
->castTo<FunctionType>()->getResult());
cs.setType(result->getArg(), ctx.TheEmptyTupleType);
cs.setType(result, builtinType);

// Ensure the property has a type Builtin.Int1
if (!cs.getType(result)->isBuiltinIntegerType(1)) {
tc.diagnose(expr->getLoc(), diag::broken_bool);
return result;
Expand Down
15 changes: 6 additions & 9 deletions lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3316,15 +3316,12 @@ namespace {
// Strip off 'Bool' to 'Builtin.Int1' conversion. Otherwise, we'll have
// to handle multiple ways of type-checking.
if (expr->isImplicit()) {
if (auto call = dyn_cast<CallExpr>(expr)) {
if (auto DSCE = dyn_cast<DotSyntaxCallExpr>(call->getFn())) {
auto RefD = DSCE->getFn()->getReferencedDecl().getDecl();
if (RefD->getBaseName() == TC.Context.Id_getBuiltinLogicValue &&
RefD->getDeclContext()->getSelfNominalTypeDecl() ==
TC.Context.getBoolDecl()) {
expr = DSCE->getBase();
continue;
}
if (auto mfe = dyn_cast<MemberRefExpr>(expr)) {
auto member = mfe->getMember().getDecl();
if (member->getBaseName() == TC.Context.Id_value_ &&
member->getDeclContext() == TC.Context.getBoolDecl()) {
expr = mfe->getBase();
continue;
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,7 @@ class Solution {
/// \param locator Locator used to describe the location of this expression.
///
/// \returns the expression converted to a logic value (Builtin i1).
Expr *convertBooleanTypeToBuiltinI1(Expr *expr,
ConstraintLocator *locator) const;
Expr *getBoolValue(Expr *expr, ConstraintLocator *locator) const;

/// Convert the given optional-producing expression to a Bool
/// indicating whether the optional has a value.
Expand Down
3 changes: 1 addition & 2 deletions lib/Sema/TypeCheckConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2758,8 +2758,7 @@ bool TypeChecker::typeCheckCondition(Expr *&expr, DeclContext *dc) {
auto &cs = solution.getConstraintSystem();

auto converted =
solution.convertBooleanTypeToBuiltinI1(expr,
cs.getConstraintLocator(OrigExpr));
solution.getBoolValue(expr, cs.getConstraintLocator(OrigExpr));
cs.setExprTypes(converted);
return converted;
}
Expand Down
13 changes: 2 additions & 11 deletions stdlib/public/core/Bool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
/// have a consistent type interface.
@_fixed_layout
public struct Bool {
@usableFromInline
internal var _value: Builtin.Int1

public var _value: Builtin.Int1

/// Creates an instance initialized to `false`.
///
Expand Down Expand Up @@ -170,15 +170,6 @@ extension Bool : _ExpressibleByBuiltinBooleanLiteral, ExpressibleByBooleanLitera
}
}

extension Bool {
// This is a magic entry point known to the compiler.
@_transparent
public // COMPILER_INTRINSIC
func _getBuiltinLogicValue() -> Builtin.Int1 {
return _value
}
}

extension Bool : CustomStringConvertible {
/// A textual representation of the Boolean value.
@inlinable
Expand Down
2 changes: 1 addition & 1 deletion test/DebugInfo/patternmatching.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func classifyPoint2(_ p: (Double, Double)) {

switch p {
case (let x, let y) where
// CHECK: call {{.*}}double {{.*}}return_same{{.*}}, !dbg ![[LOC1:.*]]
// CHECK: fcmp oeq double {{.*}}, {{.*}}, !dbg ![[LOC1:.*]]
// CHECK: br {{.*}}, label {{.*}}, label {{.*}}, !dbg ![[LOC1]]
// CHECK: call{{.*}}markUsed{{.*}}, !dbg ![[LOC3:.*]]
// CHECK: ![[LOC1]] = !DILocation(line: [[@LINE+1]],
Expand Down
2 changes: 1 addition & 1 deletion test/NameBinding/reference-dependencies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ struct Sentinel2 {}
// CHECK-DAG: - !private ["s33ExpressibleByUnicodeScalarLiteralP", ""]
// CHECK-DAG: - !private ["Sx", "Stride"]
// CHECK-DAG: - !private ["Sa", "reduce"]
// CHECK-DAG: - !private ["Sb", "_getBuiltinLogicValue"]
// CHECK-DAG: - !private ["Sb", "_value"]
// CHECK-DAG: - ["Sb", "InnerToBool"]
// CHECK-DAG: - !private ["4main17OtherFileIntArrayV", "deinit"]
// CHECK-DAG: - !private ["4main18OtherFileOuterTypeV", "InnerType"]
Expand Down
4 changes: 2 additions & 2 deletions test/PCMacro/else.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ if (a) {

// CHECK: [8:1-8:14] pc before
// CHECK-NEXT: [8:1-8:14] pc after
// CHECK-NEXT: [9:1-9:7] pc before
// CHECK-NEXT: [9:1-9:7] pc after
// CHECK-NEXT: [9:1-9:6] pc before
// CHECK-NEXT: [9:1-9:6] pc after
// CHECK-NEXT: [11:3-11:7] pc before
// CHECK-NEXT: [11:3-11:7] pc after
// CHECK-NEXT: [12:3-12:4] pc before
Expand Down
4 changes: 2 additions & 2 deletions test/PCMacro/if.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if (a) {

// CHECK: [8:1-8:13] pc before
// CHECK-NEXT: [8:1-8:13] pc after
// CHECK-NEXT: [9:1-9:7] pc before
// CHECK-NEXT: [9:1-9:7] pc after
// CHECK-NEXT: [9:1-9:6] pc before
// CHECK-NEXT: [9:1-9:6] pc after
// CHECK-NEXT: [10:3-10:4] pc before
// CHECK-NEXT: [10:3-10:4] pc after
26 changes: 13 additions & 13 deletions test/Parse/if_expr.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
// CHECK: (func_decl{{.*}}"r13756261(_:_:)"
func r13756261(_ x: Bool, _ y: Int) -> Int {
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (declref_expr
// CHECK: (declref_expr
return (x) ? y : (x) ? y : (x) ? y : y
Expand All @@ -18,13 +18,13 @@ func r13756261(_ x: Bool, _ y: Int) -> Int {
// CHECK: (func_decl{{.*}}"r13756221(_:_:)"
func r13756221(_ x: Bool, _ y: Int) -> Int {
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (declref_expr
// CHECK: (declref_expr
return (x) ? y
Expand All @@ -36,11 +36,11 @@ func r13756221(_ x: Bool, _ y: Int) -> Int {
// CHECK: (func_decl{{.*}}"telescoping_if(_:_:)"
func telescoping_if(_ x: Bool, _ y: Int) -> Int {
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (declref_expr
// CHECK: (declref_expr
// CHECK: (declref_expr
Expand Down Expand Up @@ -91,11 +91,11 @@ func prec_below(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
// CHECK: (binary_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (binary_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (binary_expr
// CHECK: (declref_expr
// CHECK: (declref_expr
Expand All @@ -109,14 +109,14 @@ func prec_equal(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
// CHECK: (binary_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (binary_expr
// CHECK: (declref_expr
// CHECK: (declref_expr
// CHECK: (binary_expr
// CHECK: (declref_expr
// CHECK: (if_expr
// CHECK: (call_expr
// CHECK: (member_ref_expr
// CHECK: (binary_expr
// CHECK: (declref_expr
// CHECK: (declref_expr
Expand Down
2 changes: 1 addition & 1 deletion test/Profiler/coverage_label.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func foo() { // CHECK-DAG: [[@LINE]]:12 -> [[@LINE+19]]:2 : 0
}

label2: do { // CHECK-DAG: [[@LINE]]:14 -> [[@LINE+7]]:4 : 0
x += 3 // CHECK-DAG: [[@LINE+1]]:11 -> [[@LINE+1]]:17 : 0
x += 3 // CHECK-DAG: [[@LINE+1]]:11 -> [[@LINE+1]]:16 : 0
while (true) { // CHECK-DAG: [[@LINE]]:18 -> [[@LINE+3]]:6 : 1
x += 4
break label2 // Note: This exit affects the condition counter expr @ L15.
Expand Down
2 changes: 1 addition & 1 deletion test/Profiler/coverage_toplevel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ func f1() {}
var i : Int32 = 0

// CHECK: sil_coverage_map{{.*}}__tlcd_line:[[@LINE+2]]:1
// CHECK: [[@LINE+1]]:7 -> [[@LINE+1]]:15 : (0 + 1)
// CHECK: [[@LINE+1]]:7 -> [[@LINE+1]]:11 : (0 + 1)
while (i < 10) {
i += 1
}
Expand Down
22 changes: 11 additions & 11 deletions test/Profiler/coverage_while.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ func eoo() {
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_while.foo
func foo() -> Int32 {
var x : Int32 = 0
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:17 : (0 + 1)
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:13 : (0 + 1)
while (x < 10) {
x += 1
}

// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:22 : (0 + 2)
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:19 : (0 + 2)
while ((x - 1) > 0) {
x -= 1
if (x % 2 == 0) { continue }
}

// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:18 : ((0 + 4) - 5)
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:13 : ((0 + 4) - 5)
while (x < 100) {
x += 1
if (x == 10) { break }
}

// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:18 : ((0 + 6) - 9)
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:13 : ((0 + 6) - 9)
while (x < 100) {
x += 1
while (true) { break }
Expand All @@ -45,10 +45,10 @@ func foo() -> Int32 {
// CHECK: [[@LINE+1]]:10 -> [[@LINE+4]]:4 : 10
repeat {
x -= 1
// CHECK: [[@LINE+1]]:11 -> [[@LINE+1]]:16 : 10
// CHECK: [[@LINE+1]]:11 -> [[@LINE+1]]:14 : 10
} while x > 0

// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:18 : ((0 + 11) - 12)
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:13 : ((0 + 11) - 12)
while (x < 100) {
if (x == 40) { // CHECK: [[@LINE]]:18 -> [[@LINE+2]]:6 : 12
return x
Expand All @@ -57,7 +57,7 @@ func foo() -> Int32 {
}

var y : Int32? = 2
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:15 : ((0 + 13) - 12)
// CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:12 : ((0 + 13) - 12)
while x > 30, let _ = y {
y = nil
}
Expand All @@ -76,21 +76,21 @@ func goo() {

repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+2]]:4 : [[RWS1:[0-9]+]]
x += 1
} while x < 10 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : [[RWS1]]
} while x < 10 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:14 : [[RWS1]]

repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+5]]:4 : [[RWS2:[0-9]+]]
x += 1
if (x % 2 == 0) { // CHECK-DAG: [[@LINE]]:21 -> [[@LINE+2]]:6 : [[CONT1:[0-9]+]]
continue
} // CHECK-DAG: [[@LINE]]:6 -> [[@LINE+1]]:4 : ([[RWS2]] - [[CONT1]])
} while x < 20 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : [[RWS2]]
} while x < 20 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:14 : [[RWS2]]

repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+5]]:4 : [[RWS3:[0-9]+]]
x += 1
if (x % 2 == 0) { // CHECK-DAG: [[@LINE]]:21 -> [[@LINE+2]]:6 : [[BRK1:[0-9]+]]
break
} // CHECK-DAG: [[@LINE]]:6 -> [[@LINE+1]]:4 : ([[RWS3]] - [[BRK1]])
} while x < 30 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : ([[RWS3]] - [[BRK1]])
} while x < 30 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:14 : ([[RWS3]] - [[BRK1]])

repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+10]]:4 : [[RWS4:[0-9]+]]
x += 1
Expand All @@ -102,7 +102,7 @@ func goo() {
break
} // CHECK-DAG: [[@LINE]]:6 -> [[@LINE+2]]:4 : (([[RWS4]] - [[CONT2]]) - [[BRK2]])
x += 1
} while x < 40 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:17 : ([[RWS4]] - [[BRK2]])
} while x < 40 // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:14 : ([[RWS4]] - [[BRK2]])

repeat { // CHECK-DAG: [[@LINE]]:10 -> [[@LINE+1]]:4 : [[RWS5:[0-9]+]]
} while false // CHECK-DAG: [[@LINE]]:11 -> [[@LINE]]:16 : [[RWS5]]
Expand Down
Loading