Skip to content

Commit d81f8db

Browse files
authored
Merge pull request swiftlang#75411 from tshortli/module-interface-lazy-typecheck-invalid-extension
ModuleInterface: Avoid crashing on invalid extensions in lazy typechecking mode
2 parents 38d9c9f + a621059 commit d81f8db

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_FRONTEND_MODULEINTERFACESUPPORT_H
1414
#define SWIFT_FRONTEND_MODULEINTERFACESUPPORT_H
1515

16+
#include "swift/AST/PrintOptions.h"
1617
#include "swift/Basic/LLVM.h"
1718
#include "swift/Basic/Version.h"
1819
#include "llvm/Support/Regex.h"

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "swift/Frontend/ModuleInterfaceSupport.h"
1314
#include "swift/AST/ASTContext.h"
1415
#include "swift/AST/ASTPrinter.h"
1516
#include "swift/AST/Decl.h"
@@ -20,13 +21,13 @@
2021
#include "swift/AST/Module.h"
2122
#include "swift/AST/ModuleNameLookup.h"
2223
#include "swift/AST/NameLookupRequests.h"
24+
#include "swift/AST/PrettyStackTrace.h"
2325
#include "swift/AST/ProtocolConformance.h"
2426
#include "swift/AST/TypeCheckRequests.h"
2527
#include "swift/AST/TypeRepr.h"
2628
#include "swift/Basic/Assertions.h"
2729
#include "swift/Basic/STLExtras.h"
2830
#include "swift/Frontend/Frontend.h"
29-
#include "swift/Frontend/ModuleInterfaceSupport.h"
3031
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
3132
#include "swift/SILOptimizer/PassManager/Passes.h"
3233
#include "swift/Serialization/SerializationOptions.h"
@@ -530,6 +531,7 @@ class InheritedProtocolCollector {
530531
/// protocols.
531532
void recordProtocols(InheritedTypes directlyInherited, const Decl *D,
532533
bool skipExtra = false) {
534+
PrettyStackTraceDecl stackTrace("recording protocols for", D);
533535
std::optional<AvailableAttrList> availableAttrs;
534536

535537
for (int i : directlyInherited.getIndices()) {
@@ -602,11 +604,19 @@ class InheritedProtocolCollector {
602604
///
603605
/// \sa recordProtocols
604606
static void collectProtocols(PerTypeMap &map, const Decl *D) {
607+
PrettyStackTraceDecl stackTrace("collecting protocols for", D);
605608
InheritedTypes directlyInherited = InheritedTypes(D);
606609
const NominalTypeDecl *nominal;
607610
const IterableDeclContext *memberContext;
608611

609612
auto shouldInclude = [](const ExtensionDecl *extension) {
613+
// In lazy typechecking mode we may be resolving the extended type for the
614+
// first time here, so we need to call getExtendedType() to cause
615+
// diagnostics to be emitted if necessary.
616+
(void)extension->getExtendedType();
617+
if (extension->isInvalid())
618+
return false;
619+
610620
if (extension->isConstrainedExtension()) {
611621
// Conditional conformances never apply to inherited protocols, nor
612622
// can they provide unconditional conformances that might be used in
@@ -615,9 +625,9 @@ class InheritedProtocolCollector {
615625
}
616626
return true;
617627
};
628+
618629
if ((nominal = dyn_cast<NominalTypeDecl>(D))) {
619630
memberContext = nominal;
620-
621631
} else if (auto *extension = dyn_cast<ExtensionDecl>(D)) {
622632
if (!shouldInclude(extension)) {
623633
return;
@@ -697,6 +707,9 @@ class InheritedProtocolCollector {
697707
const PrintOptions &printOptions,
698708
ModuleDecl *M,
699709
const NominalTypeDecl *nominal) const {
710+
PrettyStackTraceDecl stackTrace("printing synthesized extensions for",
711+
nominal);
712+
700713
if (ExtraProtocols.empty())
701714
return;
702715

@@ -881,6 +894,8 @@ const StringLiteral InheritedProtocolCollector::DummyProtocolName =
881894
bool swift::emitSwiftInterface(raw_ostream &out,
882895
ModuleInterfaceOptions const &Opts,
883896
ModuleDecl *M) {
897+
PrettyStackTraceDecl stackTrace("emitting swiftinterface for", M);
898+
884899
assert(M);
885900

886901
llvm::SmallSet<StringRef, 4> aliasModuleNamesTargets;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-emit-module-interface(%t/Test.swiftinterface) -module-name Test %s -experimental-lazy-typecheck -verify
4+
5+
extension DoesNotExist { // expected-error {{cannot find type 'DoesNotExist' in scope}}
6+
public func method() {}
7+
}

test/Serialization/lazy-typecheck-errors.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ public var varWithImplicitInvalidType = (1 as InvalidType)
3232
// expected-serialization-remark@-3 {{serialization skipped for invalid type}}
3333

3434
public var _: InvalidType
35+
36+
extension InvalidType {
37+
public func method() {}
38+
}

0 commit comments

Comments
 (0)