Skip to content

Commit 66abd32

Browse files
authored
Merge pull request #69456 from tshortli/serialization-lazy-typecheck-custom-attr
Serialization: Resolve type of CustomAttr before serializing
2 parents 3c244c3 + 33edb66 commit 66abd32

File tree

7 files changed

+55
-2
lines changed

7 files changed

+55
-2
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
957957
unsigned getAttachedMacroDiscriminator(DeclBaseName macroName, MacroRole role,
958958
const CustomAttr *attr) const;
959959

960+
/// Returns the resolved type for the give custom attribute attached to this
961+
/// declaration.
962+
Type getResolvedCustomAttrType(CustomAttr *attr) const;
963+
960964
/// Determines if this declaration is exposed to clients of the module it is
961965
/// defined in. For example, `public` declarations are exposed to clients.
962966
bool isExposedToClients() const;

lib/AST/Decl.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,29 @@ unsigned Decl::getAttachedMacroDiscriminator(DeclBaseName macroName,
493493
macroName);
494494
}
495495

496+
Type Decl::getResolvedCustomAttrType(CustomAttr *attr) const {
497+
if (auto ty = attr->getType())
498+
return ty;
499+
500+
auto dc = getDeclContext();
501+
auto *nominal = evaluateOrDefault(
502+
getASTContext().evaluator, CustomAttrNominalRequest{attr, dc}, nullptr);
503+
if (!nominal)
504+
return Type();
505+
506+
CustomAttrTypeKind kind;
507+
if (nominal->isGlobalActor()) {
508+
kind = CustomAttrTypeKind::GlobalActor;
509+
} else if (nominal->getAttrs().hasAttribute<PropertyWrapperAttr>()) {
510+
kind = CustomAttrTypeKind::PropertyWrapper;
511+
} else {
512+
kind = CustomAttrTypeKind::NonGeneric;
513+
}
514+
515+
return evaluateOrDefault(getASTContext().evaluator,
516+
CustomAttrTypeRequest{attr, dc, kind}, Type());
517+
}
518+
496519
bool Decl::isExposedToClients() const {
497520
return DeclExportabilityVisitor().visit(this);
498521
}

lib/Serialization/Serialization.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3023,7 +3023,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
30233023
if (D->getResolvedMacro(const_cast<CustomAttr *>(theAttr)))
30243024
return;
30253025

3026-
auto typeID = S.addTypeRef(theAttr->getType());
3026+
auto typeID = S.addTypeRef(
3027+
D->getResolvedCustomAttrType(const_cast<CustomAttr *>(theAttr)));
30273028
if (!typeID && !S.allowCompilerErrors()) {
30283029
llvm::PrettyStackTraceString message("CustomAttr has no type");
30293030
abort();

test/Inputs/lazy_typecheck.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ public protocol PublicProto {
9696
func req() throws -> Int
9797
}
9898

99+
@MainActor public protocol MainActorProtocol {
100+
func req() throws -> Int
101+
}
102+
99103
protocol InternalProto {
100104
func goodReq() -> Int // expected-note 2 {{protocol requires function 'goodReq()' with type '() -> Int'; add a stub for conformance}}
101105
func badReq() -> DoesNotExist // expected-error {{cannot find type 'DoesNotExist' in scope}}
@@ -118,6 +122,10 @@ public struct PublicStruct {
118122
return true // expected-error {{cannot convert return expression of type 'Bool' to return type 'Int'}}
119123
}
120124

125+
@MainActor public func publicMainActorMethod() -> Int {
126+
return true // expected-error {{cannot convert return expression of type 'Bool' to return type 'Int'}}
127+
}
128+
121129
public static func publicStaticMethod() {
122130
_ = DoesNotExist() // expected-error {{cannot find 'DoesNotExist' in scope}}
123131
}

test/Inputs/lazy_typecheck_client.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ struct ConformsToPublicProto: PublicProto {
77
func req() -> Int { return 1 }
88
}
99

10+
struct ConformsToMainActorProto: MainActorProtocol {
11+
func req() -> Int { return 1 }
12+
}
13+
1014
func testGlobalFunctions() {
1115
_ = publicFunc()
1216
_ = publicFuncWithDefaultArg()
@@ -78,6 +82,12 @@ func testConformances() {
7882
}
7983
}
8084

85+
@MainActor
86+
func testMainActorConstraint() {
87+
let _: ConformsToMainActorProto = ConformsToMainActorProto()
88+
let _: Int = PublicStruct(x: 5).publicMainActorMethod()
89+
}
90+
8191
// FIXME: This conformance ought to be included to verify that a redundant
8292
// conformance diagnostic is emitted.
8393
// However, it turns out that the mechanism implemented by

test/ModuleInterface/lazy-typecheck.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
// CHECK: func req() throws -> Swift.Int
4242
// CHECK: }
4343
// CHECK: #endif
44+
// CHECK: @MainActor public protocol MainActorProtocol {
45+
// CHECK: func req() throws -> Swift.Int
46+
// CHECK: }
4447
// CHECK: public struct PublicStruct {
4548
// CHECK: public var publicProperty: Swift.Int
4649
// CHECK: public var publicPropertyInferredType: Swift.String
@@ -54,6 +57,7 @@
5457
// CHECK-NEXT: }
5558
// CHECK: public init(x: Swift.Int)
5659
// CHECK: public func publicMethod() -> Swift.Int
60+
// CHECK: @MainActor public func publicMainActorMethod() -> Swift.Int
5761
// CHECK: public static func publicStaticMethod()
5862
// CHECK: }
5963
// CHECK: public struct PublicGenericStruct<T> {

test/TBD/lazy-typecheck.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ exports:
9292
'_$s14lazy_typecheck12PublicStructV14publicPropertySivpMV',
9393
'_$s14lazy_typecheck12PublicStructV14publicPropertySivs',
9494
'_$s14lazy_typecheck12PublicStructV18publicStaticMethodyyFZ',
95-
'_$s14lazy_typecheck12PublicStructV1xACSi_tcfC', '_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvM',
95+
'_$s14lazy_typecheck12PublicStructV1xACSi_tcfC', '_$s14lazy_typecheck12PublicStructV21publicMainActorMethodSiyF',
96+
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvM',
9697
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvg',
9798
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvpMV',
9899
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvs',
@@ -113,6 +114,8 @@ exports:
113114
'_$s14lazy_typecheck13inlinableFuncSiyF', '_$s14lazy_typecheck15publicGlobalVarSivM',
114115
'_$s14lazy_typecheck15publicGlobalVarSivg', '_$s14lazy_typecheck15publicGlobalVarSivs',
115116
'_$s14lazy_typecheck16EmptyPublicProtoMp', '_$s14lazy_typecheck16EmptyPublicProtoTL',
117+
'_$s14lazy_typecheck17MainActorProtocolMp', '_$s14lazy_typecheck17MainActorProtocolP3reqSiyKFTj',
118+
'_$s14lazy_typecheck17MainActorProtocolP3reqSiyKFTq', '_$s14lazy_typecheck17MainActorProtocolTL',
116119
'_$s14lazy_typecheck18PublicDerivedClassC1xACSi_tcfC', '_$s14lazy_typecheck18PublicDerivedClassC1xACSi_tcfc',
117120
'_$s14lazy_typecheck18PublicDerivedClassCMa', '_$s14lazy_typecheck18PublicDerivedClassCMm',
118121
'_$s14lazy_typecheck18PublicDerivedClassCMn', '_$s14lazy_typecheck18PublicDerivedClassCMo',

0 commit comments

Comments
 (0)