Skip to content

Commit d8cfe03

Browse files
authored
Merge pull request #61501 from xedin/type-wrappers-add-wrapped-type
[AST/Sema] TypeWrappers: Extend implementation to support wrapped type
2 parents f656a76 + a82d8a5 commit d8cfe03

17 files changed

+1059
-518
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3926,9 +3926,13 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
39263926
NominalTypeDecl *getTypeWrapperStorageDecl() const;
39273927

39283928
/// If this declaration is a type wrapper, retrieve
3929-
/// its required initializer - `init(storage:)`.
3929+
/// its required initializer - `init(storageWrapper:)`.
39303930
ConstructorDecl *getTypeWrapperInitializer() const;
39313931

3932+
/// Get an initializer that accepts a type wrapper instance to
3933+
/// initialize the wrapped type.
3934+
ConstructorDecl *getTypeWrappedTypeStorageInitializer() const;
3935+
39323936
/// Get a memberwise initializer that could be used to instantiate a
39333937
/// type wrapped type.
39343938
ConstructorDecl *getTypeWrappedTypeMemberwiseInitializer() const;

include/swift/AST/DiagnosticsSema.def

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6604,21 +6604,30 @@ ERROR(type_wrapper_attribute_not_allowed_here,none,
66046604
"type wrapper attribute %0 can only be applied to a class, struct",
66056605
(Identifier))
66066606

6607-
ERROR(type_wrapper_requires_a_single_generic_param,none,
6608-
"type wrapper has to declare a single generic parameter "
6609-
"for underlying storage type", ())
6607+
ERROR(type_wrapper_requires_two_generic_params,none,
6608+
"type wrapper has to declare two generic parameters: "
6609+
"wrapped and storage types", ())
66106610

66116611
ERROR(cannot_use_multiple_type_wrappers,none,
66126612
"type %0 cannot use more than one type wrapper", ())
66136613

66146614
ERROR(type_wrapper_requires_memberwise_init,none,
66156615
"type wrapper type %0 does not contain a required initializer"
6616-
" - init(memberwise:)",
6616+
" - init(for:storage:)",
66176617
(DeclName))
66186618

6619+
ERROR(cannot_overload_type_wrapper_initializer,none,
6620+
"cannot overload type wrapper initializer 'init(for:storage:)'", ())
6621+
6622+
ERROR(cannot_declare_type_wrapper_init_with_invalid_first_param,none,
6623+
"first parameter of type wrapper initializer should be wrapped type - %0", (Type))
6624+
6625+
ERROR(cannot_declare_type_wrapper_init_with_invalid_second_param,none,
6626+
"second parameter of type wrapper initializer should be storage type - %0", (Type))
6627+
66196628
ERROR(type_wrapper_requires_subscript,none,
66206629
"type wrapper type %0 does not contain a required subscript"
6621-
" - subscript(storedKeyPath:)",
6630+
" - subscript(propertyKeyPath:storageKeyPath:)",
66226631
(DeclName))
66236632

66246633
ERROR(type_wrapper_requires_readonly_subscript,none,
@@ -6635,9 +6644,13 @@ NOTE(add_type_wrapper_subscript_stub_note,none,
66356644
ERROR(type_wrapper_failable_init,none,
66366645
"type wrapper initializer %0 cannot be failable", (DeclName))
66376646

6638-
ERROR(type_wrapper_invalid_subscript_param_type, none,
6639-
"type wrapper subscript expects a key path parameter type (got: %0)",
6640-
(Type))
6647+
ERROR(type_wrapper_subscript_invalid_parameter_type,none,
6648+
"type wrapper subscript parameter %0 expects type %1 (got: %2)",
6649+
(Identifier, Type, Type))
6650+
6651+
ERROR(type_wrapper_subscript_invalid_keypath_parameter,none,
6652+
"type wrapper subscript parameter %0 expects a key path (got: %1)",
6653+
(Identifier, Type))
66416654

66426655
ERROR(type_wrapper_type_requirement_not_accessible,none,
66436656
"%select{private|fileprivate|internal|public|open}0 %1 %2 cannot have "

include/swift/AST/KnownIdentifiers.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,11 @@ IDENTIFIER_WITH_NAME(builderSelf, "$builderSelf")
311311

312312
// Type wrappers
313313
IDENTIFIER_WITH_NAME(TypeWrapperStorage, "$Storage")
314-
IDENTIFIER_WITH_NAME(TypeWrapperProperty, "$_storage")
314+
IDENTIFIER_WITH_NAME(TypeWrapperProperty, "$storage")
315315
IDENTIFIER(storageKeyPath)
316-
IDENTIFIER(memberwise)
316+
IDENTIFIER(propertyKeyPath)
317+
IDENTIFIER(wrappedSelf)
318+
IDENTIFIER(storageWrapper)
317319
IDENTIFIER_WITH_NAME(localStorageVar, "_storage")
318320

319321
// Attribute options

include/swift/AST/TypeCheckRequests.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3588,7 +3588,7 @@ class GetTypeWrapperStorage
35883588
bool isCached() const { return true; }
35893589
};
35903590

3591-
/// Inject or get `$_storage` property which is used to route accesses through
3591+
/// Inject or get `$storage` property which is used to route accesses through
35923592
/// to all stored properties of a type that has a type wrapper.
35933593
class GetTypeWrapperProperty
35943594
: public SimpleRequest<GetTypeWrapperProperty, VarDecl *(NominalTypeDecl *),
@@ -3689,17 +3689,17 @@ class SynthesizeTypeWrappedTypeMemberwiseInitializer
36893689
bool isCached() const { return true; }
36903690
};
36913691

3692-
class SynthesizeTypeWrappedTypeMemberwiseInitializerBody
3693-
: public SimpleRequest<SynthesizeTypeWrappedTypeMemberwiseInitializerBody,
3694-
BraceStmt *(ConstructorDecl *),
3692+
class SynthesizeTypeWrappedTypeStorageWrapperInitializer
3693+
: public SimpleRequest<SynthesizeTypeWrappedTypeStorageWrapperInitializer,
3694+
ConstructorDecl *(NominalTypeDecl *),
36953695
RequestFlags::Cached> {
36963696
public:
36973697
using SimpleRequest::SimpleRequest;
36983698

36993699
private:
37003700
friend SimpleRequest;
37013701

3702-
BraceStmt *evaluate(Evaluator &evaluator, ConstructorDecl *) const;
3702+
ConstructorDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *) const;
37033703

37043704
public:
37053705
bool isCached() const { return true; }

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,8 @@ SWIFT_REQUEST(TypeChecker, IsPropertyAccessedViaTypeWrapper,
431431
SWIFT_REQUEST(TypeChecker, SynthesizeTypeWrappedTypeMemberwiseInitializer,
432432
ConstructorDecl *(NominalTypeDecl *),
433433
Cached, NoLocationInfo)
434-
SWIFT_REQUEST(TypeChecker, SynthesizeTypeWrappedTypeMemberwiseInitializerBody,
435-
BraceStmt *(ConstructorDecl *),
434+
SWIFT_REQUEST(TypeChecker, SynthesizeTypeWrappedTypeStorageWrapperInitializer,
435+
ConstructorDecl *(NominalTypeDecl *),
436436
Cached, NoLocationInfo)
437437
SWIFT_REQUEST(TypeChecker, SynthesizeLocalVariableForTypeWrapperStorage,
438438
VarDecl *(ConstructorDecl *),

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ namespace {
459459
/// corresponds to `self`.
460460
void injectActorHops();
461461

462-
/// Injects `self.$storage = .init(memberwise: $Storage(...))`
462+
/// Injects `self.$storage = .init(storage: $Storage(...))`
463463
/// assignment instructions into the function after each point
464464
/// where `_storage` becomes fully initialized via `assign_by_wrapper`.
465465
/// This is only necessary only for user-defined initializers of a
@@ -1117,7 +1117,7 @@ void LifetimeChecker::injectTypeWrapperStorageInitalization() {
11171117
auto storageType = F.getLoweredType(
11181118
ctor->mapTypeIntoContext(storageDecl->getDeclaredInterfaceType()));
11191119

1120-
// Argument value to use in call to <TypeWrapper>.init(memberwise:)
1120+
// Argument value to use in call to <TypeWrapper>.init(storage:)
11211121
SILValue storageObj = allocStack(storageType);
11221122

11231123
// let storageObj = $Storage(<destructured _storage tuple>)
@@ -1253,7 +1253,7 @@ void LifetimeChecker::injectTypeWrapperStorageInitalization() {
12531253
StoreOwnershipQualifier::Init);
12541254
}
12551255

1256-
// self.$storage = <TypeWrapper>(memberwise: storageObj))
1256+
// self.$storage = <TypeWrapper>(storage: storageObj))
12571257
{
12581258
bool isClass = isa<ClassDecl>(parentType);
12591259

@@ -1291,6 +1291,11 @@ void LifetimeChecker::injectTypeWrapperStorageInitalization() {
12911291
loc, selfRef, parentType->getTypeWrapperProperty());
12921292
}
12931293

1294+
auto wrappedType = MetatypeType::get(self->getType().getASTType(),
1295+
MetatypeRepresentation::Thick);
1296+
auto wrappedMetatype =
1297+
b.createMetatype(loc, F.getLoweredType(wrappedType));
1298+
12941299
auto typeWrapperType =
12951300
b.createMetatype(loc, F.getLoweredType(MetatypeType::get(
12961301
storagePropRef->getType().getASTType())));
@@ -1305,14 +1310,17 @@ void LifetimeChecker::injectTypeWrapperStorageInitalization() {
13051310
wrapperInitArgs.push_back(*localWrapperObj);
13061311
}
13071312

1313+
wrapperInitArgs.push_back(wrappedMetatype);
13081314
wrapperInitArgs.push_back(storageObj);
13091315
wrapperInitArgs.push_back(typeWrapperType);
13101316

1311-
// <wrapper-var> = <TypeWrapper>.init(memberwise: tmpStorage)
1317+
// <wrapper-var> = <TypeWrapper>.init(storage: tmpStorage)
13121318
auto wrapperInitResult = b.createApply(
13131319
loc, typeWrapperInitRef,
13141320
SubstitutionMap::get(typeWrapperInit->getGenericSignature(),
1315-
/*substitutions=*/{storageType.getASTType()},
1321+
/*substitutions=*/
1322+
{wrappedType->getMetatypeInstanceType(),
1323+
storageType.getASTType()},
13161324
/*conformances=*/{}),
13171325
wrapperInitArgs);
13181326

0 commit comments

Comments
 (0)