Skip to content

Commit 3f97af7

Browse files
author
John Holdsworth
committed
Switch back to @_marker protocol to differentiate ASCII literals.
1 parent c234ef4 commit 3f97af7

File tree

7 files changed

+17
-71
lines changed

7 files changed

+17
-71
lines changed

include/swift/AST/KnownProtocols.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByStringInterpolation, "StringLiteral
150150
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByStringLiteral, "StringLiteralType", true)
151151
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByNilLiteral, nullptr, false)
152152
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByUnicodeScalarLiteral, "UnicodeScalarType", true)
153+
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByASCIIScalarLiteral, "UnicodeScalarType", true)
153154

154155
EXPRESSIBLE_BY_LITERAL_PROTOCOL_(ExpressibleByColorLiteral, "_ColorLiteralType", true)
155156
EXPRESSIBLE_BY_LITERAL_PROTOCOL_(ExpressibleByImageLiteral, "_ImageLiteralType", true)

lib/IRGen/GenMeta.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6532,6 +6532,7 @@ SpecialProtocol irgen::getSpecialProtocolID(ProtocolDecl *P) {
65326532
case KnownProtocolKind::ExpressibleByStringLiteral:
65336533
case KnownProtocolKind::ExpressibleByNilLiteral:
65346534
case KnownProtocolKind::ExpressibleByUnicodeScalarLiteral:
6535+
case KnownProtocolKind::ExpressibleByASCIIScalarLiteral:
65356536
case KnownProtocolKind::ExpressibleByColorLiteral:
65366537
case KnownProtocolKind::ExpressibleByImageLiteral:
65376538
case KnownProtocolKind::ExpressibleByFileReferenceLiteral:

lib/Sema/TypeChecker.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ ProtocolDecl *TypeChecker::getLiteralProtocol(ASTContext &Context, Expr *expr) {
103103
if (const auto *SLE = dyn_cast<StringLiteralExpr>(expr)) {
104104
if (SLE->isSingleUnicodeScalar())
105105
return TypeChecker::getProtocol(
106-
Context, expr->getLoc(),
106+
Context, expr->getLoc(), SLE->getValue().size() == 1 ?
107+
KnownProtocolKind::ExpressibleByASCIIScalarLiteral :
107108
KnownProtocolKind::ExpressibleByUnicodeScalarLiteral);
108109

109110
if (SLE->isSingleExtendedGraphemeCluster())

stdlib/public/core/CompilerProtocols.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,9 @@ public protocol ExpressibleByBooleanLiteral {
394394
init(booleanLiteral value: BooleanLiteralType)
395395
}
396396

397+
/// Used to differentiate string literals containing only a single ASCII character
398+
@_marker public protocol ExpressibleByASCIIScalarLiteral {}
399+
397400
public protocol _ExpressibleByBuiltinUnicodeScalarLiteral {
398401
init(_builtinUnicodeScalarLiteral value: Builtin.Int32)
399402
}
@@ -415,7 +418,7 @@ public protocol _ExpressibleByBuiltinUnicodeScalarLiteral {
415418
///
416419
/// To add `ExpressibleByUnicodeScalarLiteral` conformance to your custom type,
417420
/// implement the required initializer.
418-
public protocol ExpressibleByUnicodeScalarLiteral {
421+
public protocol ExpressibleByUnicodeScalarLiteral: ExpressibleByASCIIScalarLiteral {
419422
/// A type that represents a Unicode scalar literal.
420423
///
421424
/// Valid types for `UnicodeScalarLiteralType` are `Unicode.Scalar`,

stdlib/public/core/UnicodeScalar.swift

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -380,72 +380,12 @@ extension UInt64 {
380380
}
381381
}
382382

383-
/// Extends `UInt8` to allow direct comparisons with double quoted literals.
384-
extension UInt8 {
385-
/// Returns a Boolean indicating whether the `UInt8` is equal to the provided Unicode scalar.
386-
///
387-
/// - Parameters:
388-
/// - i: The `UInt8` value to compare.
389-
/// - s: The Unicode scalar to compare against.
390-
/// - Returns: `true` when the `UInt8` is equal to the provided Unicode scalar; otherwise, `false`.
391-
@_transparent @_alwaysEmitIntoClient
392-
public static func == (i: Self, s: Unicode.Scalar) -> Bool {
393-
return i == UInt8(ascii: s)
394-
}
395-
396-
/// Returns a Boolean indicating whether the `UInt8` is not equal to the provided Unicode scalar.
397-
@_transparent @_alwaysEmitIntoClient
398-
public static func != (i: Self, s: Unicode.Scalar) -> Bool {
399-
return i != UInt8(ascii: s)
400-
}
401-
402-
/// Enables pattern matching of Unicode scalars in switch statements.
403-
@_transparent @_alwaysEmitIntoClient
404-
public static func ~= (s: Unicode.Scalar, i: Self) -> Bool {
405-
return i == UInt8(ascii: s)
406-
}
407-
}
383+
extension UInt8: ExpressibleByASCIIScalarLiteral,
384+
_ExpressibleByBuiltinUnicodeScalarLiteral {
408385

409-
/// Extends `Optional<UInt8>` to allow direct comparisons with double quoted literals.
410-
extension UInt8? {
411-
/// Returns a Boolean value indicating whether the optional `UInt8` is equal to the provided Unicode scalar.
412-
///
413-
/// - Parameters:
414-
/// - i: The optional `UInt8` value to compare.
415-
/// - s: The Unicode scalar to compare against.
416-
/// - Returns: `true` if the optional `UInt8` is equal to the provided Unicode scalar; otherwise, `false`.
417386
@_transparent @_alwaysEmitIntoClient
418-
public static func == (i: Self, s: Unicode.Scalar) -> Bool {
419-
return i == UInt8(ascii: s)
420-
}
421-
422-
/// Returns a Boolean value indicating whether the optional `UInt8` is not equal to the provided Unicode scalar.
423-
@_transparent @_alwaysEmitIntoClient
424-
public static func != (i: Self, s: Unicode.Scalar) -> Bool {
425-
return i != UInt8(ascii: s)
426-
}
427-
428-
/// Allows pattern matching of Unicode scalars in switch statements.
429-
@_transparent @_alwaysEmitIntoClient
430-
public static func ~= (s: Unicode.Scalar, i: Self) -> Bool {
431-
return i == UInt8(ascii: s)
432-
}
433-
}
434-
435-
/// Extends `Array` where Element is a FixedWidthInteger, providing initialization from a string of Unicode scalars.
436-
@_unavailableInEmbedded
437-
extension Array where Element: FixedWidthInteger {
438-
/// Initializes an array of Integers with Unicode scalars represented by the provided string.
439-
///
440-
/// - Parameter scalars: A string containing Unicode scalars.
441-
@inlinable @_alwaysEmitIntoClient @_unavailableInEmbedded
442-
public init(scalars: String) {
443-
#if os(Linux) || os(iOS) || os(tvOS)
444-
// How to avoid the function body being type checked for embedded?
445-
self.init(scalars.unicodeScalars.map { Element(unicode: $0) })
446-
#else
447-
self.init(scalars.utf16.map { Element($0) })
448-
#endif
387+
public init(_builtinUnicodeScalarLiteral value: Builtin.Int32) {
388+
self = UInt8(UInt32(value))
449389
}
450390
}
451391

test/stdlib/UnicodeScalarDiagnostics.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ func test_UnicodeScalarDoesNotImplementArithmetic(_ us: UnicodeScalar, i: Int) {
99
var a1 = "a" + "b" // OK
1010
isString(&a1)
1111
// We don't check for the overload choices list on the overload note match because they may change on different platforms.
12-
let a2 = "a" - "b" // expected-error {{binary operator '-' cannot be applied to two 'String' operands}}
13-
let a3 = "a" * "b" // expected-error {{binary operator '*' cannot be applied to two 'String' operands}}
14-
let a4 = "a" / "b" // expected-error {{binary operator '/' cannot be applied to two 'String' operands}}
12+
let a2 = "a" - "b"
13+
let a3 = "a" * "b"
14+
let a4 = "a" / "b"
1515

1616
let b1 = us + us // expected-error {{binary operator '+' cannot be applied to two 'UnicodeScalar' (aka 'Unicode.Scalar') operands}}
1717
let b2 = us - us // expected-error {{binary operator '-' cannot be applied to two 'UnicodeScalar' (aka 'Unicode.Scalar') operands}}

test/stmt/typed_throws.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ func testDoCatchMultiErrorType() {
8080
do {
8181
try doSomething()
8282
try doHomework()
83-
} catch .failed { // expected-error{{expression pattern of type 'Unicode.Scalar' cannot match values of type 'any Error}}
84-
// expected-error@-1{{type 'Unicode.Scalar' has no member 'failed'}}
83+
} catch .failed { // expected-error{{type 'any Error' has no member 'failed'}}
84+
8585
} catch {
8686
let _: Int = error // expected-error{{cannot convert value of type 'any Error' to specified type 'Int'}}
8787
}

0 commit comments

Comments
 (0)