Skip to content

Commit a8d831f

Browse files
authored
Merge pull request #16278 from slavapestov/simpler-string-literals
Sema: Eliminate typeCheckExpression() calls from convertLiteralInPlace()
2 parents d5b98a0 + e24fbbb commit a8d831f

File tree

6 files changed

+78
-72
lines changed

6 files changed

+78
-72
lines changed

docs/SIL.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2881,7 +2881,7 @@ reference-counted types, this can produce a different value from the operand
28812881
if the block is copied from the stack to the heap.
28822882

28832883
copy_block_without_escaping
2884-
``````````
2884+
```````````````````````````
28852885
::
28862886

28872887
sil-instruction :: 'copy_block_without_escaping' sil-operand 'withoutEscaping' sil-operand

lib/SILGen/SILGenApply.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4541,6 +4541,8 @@ static RValue emitApplyAllocatingInitializer(SILGenFunction &SGF,
45414541
callee.emplace(Callee::forWitnessMethod(
45424542
SGF, selfMetaVal.getType().getSwiftRValueType(),
45434543
initRef, subs, loc));
4544+
} else if (getMethodDispatch(ctor) == MethodDispatch::Class) {
4545+
callee.emplace(Callee::forClassMethod(SGF, initRef, subs, loc));
45444546
} else {
45454547
callee.emplace(Callee::forDirect(SGF, initRef, subs, loc));
45464548
}
@@ -4550,7 +4552,7 @@ static RValue emitApplyAllocatingInitializer(SILGenFunction &SGF,
45504552
// For an inheritable initializer, determine whether we'll need to adjust the
45514553
// result type.
45524554
bool requiresDowncast = false;
4553-
if (ctor->isInheritable() && overriddenSelfType) {
4555+
if (ctor->isRequired() && overriddenSelfType) {
45544556
CanType substResultType = substFormalType;
45554557
for (unsigned i : range(ctor->getNumParameterLists())) {
45564558
(void)i;

lib/Sema/CSApply.cpp

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,14 @@ ConcreteDeclRef findNamedWitnessImpl(
166166

167167
// For a type with dependent conformance, just return the requirement from
168168
// the protocol. There are no protocol conformance tables.
169-
if (!conformance->isConcrete())
170-
return requirement;
169+
if (!conformance->isConcrete()) {
170+
auto subMap = SubstitutionMap::getProtocolSubstitutions(proto, type,
171+
*conformance);
172+
SmallVector<Substitution, 2> subs;
173+
proto->getGenericSignature()->getSubstitutions(subMap, subs);
174+
return ConcreteDeclRef(tc.Context, requirement, subs);
175+
}
176+
171177
auto concrete = conformance->getConcrete();
172178
return concrete->getWitnessDeclRef(requirement, &tc);
173179
}
@@ -7286,31 +7292,13 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
72867292
return nullptr;
72877293

72887294
// Form a reference to the builtin conversion function.
7289-
// FIXME: Bogus location info.
7290-
Expr *base = TypeExpr::createImplicitHack(literal->getLoc(), type,
7291-
tc.Context);
7292-
7293-
Expr *unresolvedDot = new (tc.Context) UnresolvedDotExpr(
7294-
base, SourceLoc(),
7295-
witness.getDecl()->getFullName(),
7296-
DeclNameLoc(base->getEndLoc()),
7297-
/*Implicit=*/true);
7298-
(void)tc.typeCheckExpression(unresolvedDot, dc);
7299-
7300-
cs.cacheExprTypes(unresolvedDot);
7301-
7302-
ConcreteDeclRef builtinRef = unresolvedDot->getReferencedDecl();
7303-
if (!builtinRef) {
7304-
tc.diagnose(base->getLoc(), brokenBuiltinProtocolDiag);
7305-
return nullptr;
7306-
}
73077295

73087296
// Set the builtin initializer.
73097297
if (auto stringLiteral = dyn_cast<StringLiteralExpr>(literal))
7310-
stringLiteral->setBuiltinInitializer(builtinRef);
7298+
stringLiteral->setBuiltinInitializer(witness);
73117299
else {
73127300
cast<MagicIdentifierLiteralExpr>(literal)
7313-
->setBuiltinInitializer(builtinRef);
7301+
->setBuiltinInitializer(witness);
73147302
}
73157303

73167304
// The literal expression has this type.
@@ -7350,30 +7338,11 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
73507338
if (!witness || !isa<AbstractFunctionDecl>(witness.getDecl()))
73517339
return nullptr;
73527340

7353-
// Form a reference to the conversion function.
7354-
// FIXME: Bogus location info.
7355-
Expr *base = TypeExpr::createImplicitHack(literal->getLoc(), type,
7356-
tc.Context);
7357-
7358-
Expr *unresolvedDot = new (tc.Context) UnresolvedDotExpr(
7359-
base, SourceLoc(),
7360-
witness.getDecl()->getFullName(),
7361-
DeclNameLoc(base->getEndLoc()),
7362-
/*Implicit=*/true);
7363-
(void)tc.typeCheckExpression(unresolvedDot, dc);
7364-
cs.cacheExprTypes(unresolvedDot);
7365-
7366-
ConcreteDeclRef ref = unresolvedDot->getReferencedDecl();
7367-
if (!ref) {
7368-
tc.diagnose(base->getLoc(), brokenProtocolDiag);
7369-
return nullptr;
7370-
}
7371-
73727341
// Set the initializer.
73737342
if (auto stringLiteral = dyn_cast<StringLiteralExpr>(literal))
7374-
stringLiteral->setInitializer(ref);
7343+
stringLiteral->setInitializer(witness);
73757344
else
7376-
cast<MagicIdentifierLiteralExpr>(literal)->setInitializer(ref);
7345+
cast<MagicIdentifierLiteralExpr>(literal)->setInitializer(witness);
73777346

73787347
// The literal expression has this type.
73797348
cs.setType(literal, type);

test/SILGen/generic_literals.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-swift-emit-silgen -enable-sil-ownership %s | %FileCheck %s
22

3-
// CHECK-LABEL: sil hidden @$S16generic_literals0A14IntegerLiteral1xyx_ts013ExpressibleBycD0RzlF
3+
// CHECK-LABEL: sil hidden @$S16generic_literals0A14IntegerLiteral1xyx_ts013ExpressibleBycD0RzlF : $@convention(thin) <T where T : ExpressibleByIntegerLiteral> (@in_guaranteed T) -> () {
44
func genericIntegerLiteral<T : ExpressibleByIntegerLiteral>(x: T) {
55
var x = x
66
// CHECK: [[ADDR:%.*]] = alloc_stack $T
@@ -16,7 +16,7 @@ func genericIntegerLiteral<T : ExpressibleByIntegerLiteral>(x: T) {
1616
x = 17
1717
}
1818

19-
// CHECK-LABEL: sil hidden @$S16generic_literals0A15FloatingLiteral{{[_0-9a-zA-Z]*}}F
19+
// CHECK-LABEL: sil hidden @$S16generic_literals0A15FloatingLiteral1xyx_ts018ExpressibleByFloatD0RzlF : $@convention(thin) <T where T : ExpressibleByFloatLiteral> (@in_guaranteed T) -> () {
2020
func genericFloatingLiteral<T : ExpressibleByFloatLiteral>(x: T) {
2121
var x = x
2222
// CHECK: [[TVAL:%.*]] = alloc_stack $T
@@ -31,3 +31,20 @@ func genericFloatingLiteral<T : ExpressibleByFloatLiteral>(x: T) {
3131

3232
x = 2.5
3333
}
34+
35+
// CHECK-LABEL: sil hidden @$S16generic_literals0A13StringLiteral1xyx_ts013ExpressibleBycD0RzlF : $@convention(thin) <T where T : ExpressibleByStringLiteral> (@in_guaranteed T) -> () {
36+
37+
func genericStringLiteral<T : ExpressibleByStringLiteral>(x: T) {
38+
var x = x
39+
// CHECK: [[LIT_VALUE:%.*]] = string_literal utf8 "hello"
40+
// CHECK: [[TSTR_META:%.*]] = metatype $@thick T.StringLiteralType.Type
41+
// CHECK: [[STR_VAL:%.*]] = alloc_stack $T.StringLiteralType
42+
// CHECK: [[BUILTIN_CONV:%.*]] = witness_method $T.StringLiteralType, #_ExpressibleByBuiltinStringLiteral.init!allocator.1
43+
// CHECK: apply [[BUILTIN_CONV]]<T.StringLiteralType>([[STR_VAL]], [[LIT_VALUE]], {{.*}}, [[TSTR_META]]) : $@convention(witness_method: _ExpressibleByBuiltinStringLiteral) <τ_0_0 where τ_0_0 : _ExpressibleByBuiltinStringLiteral> (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thick τ_0_0.Type) -> @out τ_0_0
44+
// CHECK: [[TMETA:%.*]] = metatype $@thick T.Type
45+
// CHECK: [[TVAL:%.*]] = alloc_stack $T
46+
// CHECK: [[CONV:%.*]] = witness_method $T, #ExpressibleByStringLiteral.init!allocator.1
47+
// CHECK: apply [[CONV]]<T>([[TVAL]], [[STR_VAL]], [[TMETA]]) : $@convention(witness_method: ExpressibleByStringLiteral) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in τ_0_0.StringLiteralType, @thick τ_0_0.Type) -> @out τ_0_0
48+
49+
x = "hello"
50+
}

test/SILGen/literals.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %target-swift-emit-silgen -enable-sil-ownership %s | %FileCheck %s
2+
3+
func takesOptionalFunction(_: (() -> ())?) {}
4+
5+
struct CustomNull : ExpressibleByNilLiteral {
6+
init(nilLiteral: ()) {}
7+
}
8+
9+
func takesANull(_: CustomNull) {}
10+
11+
// CHECK-LABEL: sil hidden @$S8literals4testyyF : $@convention(thin) () -> ()
12+
func test() {
13+
// CHECK: [[NIL:%.*]] = enum $Optional<@callee_guaranteed () -> ()>, #Optional.none!enumelt
14+
// CHECK: [[FN:%.*]] = function_ref @$S8literals21takesOptionalFunctionyyyycSgF
15+
// CHECK: apply [[FN]]([[NIL]])
16+
_ = takesOptionalFunction(nil)
17+
18+
// CHECK: [[METATYPE:%.*]] = metatype $@thin CustomNull.Type
19+
// CHECK: [[NIL_FN:%.*]] = function_ref @$S8literals10CustomNullV10nilLiteralACyt_tcfC
20+
// CHECK: [[NIL:%.*]] = apply [[NIL_FN]]([[METATYPE]])
21+
// CHECK: [[FN:%.*]] = function_ref @$S8literals10takesANullyyAA10CustomNullVF
22+
// CHECK: apply [[FN]]([[NIL]])
23+
_ = takesANull(nil)
24+
}
25+
26+
class CustomStringClass : ExpressibleByStringLiteral {
27+
required init(stringLiteral value: String) {}
28+
required init(extendedGraphemeClusterLiteral value: String) {}
29+
required init(unicodeScalarLiteral value: String) {}
30+
}
31+
32+
class CustomStringSubclass : CustomStringClass {}
33+
34+
// CHECK-LABEL: sil hidden @$S8literals27returnsCustomStringSubclassAA0cdE0CyF : $@convention(thin) () -> @owned CustomStringSubclass
35+
// CHECK: [[METATYPE:%.*]] = metatype $@thick CustomStringSubclass.Type
36+
// CHECK: [[UPCAST:%.*]] = upcast [[METATYPE]] : $@thick CustomStringSubclass.Type to $@thick CustomStringClass.Type
37+
// CHECK: [[CTOR:%.*]] = class_method [[UPCAST]] : $@thick CustomStringClass.Type, #CustomStringClass.init!allocator.1 : (CustomStringClass.Type) -> (String) -> CustomStringClass, $@convention(method) (@owned String, @thick CustomStringClass.Type) -> @owned CustomStringClass
38+
// CHECK: [[RESULT:%.*]] = apply [[CTOR]]({{%.*}}, [[UPCAST]])
39+
// CHECK: [[DOWNCAST:%.*]] = unchecked_ref_cast [[RESULT]] : $CustomStringClass to $CustomStringSubclass
40+
// CHECK: return [[DOWNCAST]]
41+
func returnsCustomStringSubclass() -> CustomStringSubclass {
42+
return "hello world"
43+
}

test/SILGen/nil_literal.swift

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)