Serialization: Resolve type of CustomAttr before serializing.

This fixing a crash during serialization when lazy typechecking is enabled.

Resolves rdar://117442955
This commit is contained in:
Allan Shortlidge
2023-10-26 15:17:30 -07:00
parent a94d22e017
commit 33edb6642d
7 changed files with 55 additions and 2 deletions

View File

@@ -957,6 +957,10 @@ public:
unsigned getAttachedMacroDiscriminator(DeclBaseName macroName, MacroRole role,
const CustomAttr *attr) const;
/// Returns the resolved type for the give custom attribute attached to this
/// declaration.
Type getResolvedCustomAttrType(CustomAttr *attr) const;
/// Determines if this declaration is exposed to clients of the module it is
/// defined in. For example, `public` declarations are exposed to clients.
bool isExposedToClients() const;

View File

@@ -493,6 +493,29 @@ unsigned Decl::getAttachedMacroDiscriminator(DeclBaseName macroName,
macroName);
}
Type Decl::getResolvedCustomAttrType(CustomAttr *attr) const {
if (auto ty = attr->getType())
return ty;
auto dc = getDeclContext();
auto *nominal = evaluateOrDefault(
getASTContext().evaluator, CustomAttrNominalRequest{attr, dc}, nullptr);
if (!nominal)
return Type();
CustomAttrTypeKind kind;
if (nominal->isGlobalActor()) {
kind = CustomAttrTypeKind::GlobalActor;
} else if (nominal->getAttrs().hasAttribute<PropertyWrapperAttr>()) {
kind = CustomAttrTypeKind::PropertyWrapper;
} else {
kind = CustomAttrTypeKind::NonGeneric;
}
return evaluateOrDefault(getASTContext().evaluator,
CustomAttrTypeRequest{attr, dc, kind}, Type());
}
bool Decl::isExposedToClients() const {
return DeclExportabilityVisitor().visit(this);
}

View File

@@ -3024,7 +3024,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
if (D->getResolvedMacro(const_cast<CustomAttr *>(theAttr)))
return;
auto typeID = S.addTypeRef(theAttr->getType());
auto typeID = S.addTypeRef(
D->getResolvedCustomAttrType(const_cast<CustomAttr *>(theAttr)));
if (!typeID && !S.allowCompilerErrors()) {
llvm::PrettyStackTraceString message("CustomAttr has no type");
abort();

View File

@@ -96,6 +96,10 @@ public protocol PublicProto {
func req() throws -> Int
}
@MainActor public protocol MainActorProtocol {
func req() throws -> Int
}
protocol InternalProto {
func goodReq() -> Int // expected-note 2 {{protocol requires function 'goodReq()' with type '() -> Int'; add a stub for conformance}}
func badReq() -> DoesNotExist // expected-error {{cannot find type 'DoesNotExist' in scope}}
@@ -118,6 +122,10 @@ public struct PublicStruct {
return true // expected-error {{cannot convert return expression of type 'Bool' to return type 'Int'}}
}
@MainActor public func publicMainActorMethod() -> Int {
return true // expected-error {{cannot convert return expression of type 'Bool' to return type 'Int'}}
}
public static func publicStaticMethod() {
_ = DoesNotExist() // expected-error {{cannot find 'DoesNotExist' in scope}}
}

View File

@@ -7,6 +7,10 @@ struct ConformsToPublicProto: PublicProto {
func req() -> Int { return 1 }
}
struct ConformsToMainActorProto: MainActorProtocol {
func req() -> Int { return 1 }
}
func testGlobalFunctions() {
_ = publicFunc()
_ = publicFuncWithDefaultArg()
@@ -78,6 +82,12 @@ func testConformances() {
}
}
@MainActor
func testMainActorConstraint() {
let _: ConformsToMainActorProto = ConformsToMainActorProto()
let _: Int = PublicStruct(x: 5).publicMainActorMethod()
}
// FIXME: This conformance ought to be included to verify that a redundant
// conformance diagnostic is emitted.
// However, it turns out that the mechanism implemented by

View File

@@ -41,6 +41,9 @@
// CHECK: func req() throws -> Swift.Int
// CHECK: }
// CHECK: #endif
// CHECK: @MainActor public protocol MainActorProtocol {
// CHECK: func req() throws -> Swift.Int
// CHECK: }
// CHECK: public struct PublicStruct {
// CHECK: public var publicProperty: Swift.Int
// CHECK: public var publicPropertyInferredType: Swift.String
@@ -54,6 +57,7 @@
// CHECK-NEXT: }
// CHECK: public init(x: Swift.Int)
// CHECK: public func publicMethod() -> Swift.Int
// CHECK: @MainActor public func publicMainActorMethod() -> Swift.Int
// CHECK: public static func publicStaticMethod()
// CHECK: }
// CHECK: public struct PublicGenericStruct<T> {

View File

@@ -92,7 +92,8 @@ exports:
'_$s14lazy_typecheck12PublicStructV14publicPropertySivpMV',
'_$s14lazy_typecheck12PublicStructV14publicPropertySivs',
'_$s14lazy_typecheck12PublicStructV18publicStaticMethodyyFZ',
'_$s14lazy_typecheck12PublicStructV1xACSi_tcfC', '_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvM',
'_$s14lazy_typecheck12PublicStructV1xACSi_tcfC', '_$s14lazy_typecheck12PublicStructV21publicMainActorMethodSiyF',
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvM',
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvg',
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvpMV',
'_$s14lazy_typecheck12PublicStructV21publicWrappedPropertySdvs',
@@ -113,6 +114,8 @@ exports:
'_$s14lazy_typecheck13inlinableFuncSiyF', '_$s14lazy_typecheck15publicGlobalVarSivM',
'_$s14lazy_typecheck15publicGlobalVarSivg', '_$s14lazy_typecheck15publicGlobalVarSivs',
'_$s14lazy_typecheck16EmptyPublicProtoMp', '_$s14lazy_typecheck16EmptyPublicProtoTL',
'_$s14lazy_typecheck17MainActorProtocolMp', '_$s14lazy_typecheck17MainActorProtocolP3reqSiyKFTj',
'_$s14lazy_typecheck17MainActorProtocolP3reqSiyKFTq', '_$s14lazy_typecheck17MainActorProtocolTL',
'_$s14lazy_typecheck18PublicDerivedClassC1xACSi_tcfC', '_$s14lazy_typecheck18PublicDerivedClassC1xACSi_tcfc',
'_$s14lazy_typecheck18PublicDerivedClassCMa', '_$s14lazy_typecheck18PublicDerivedClassCMm',
'_$s14lazy_typecheck18PublicDerivedClassCMn', '_$s14lazy_typecheck18PublicDerivedClassCMo',