Skip to content

Commit bbe9867

Browse files
authored
Merge pull request swiftlang#28442 from slavapestov/revert-sf-synthesized-decls
Revert "Eagerly TypeCheck Synthesized Decls"
2 parents 3aa7082 + 2cada3b commit bbe9867

File tree

7 files changed

+51
-26
lines changed

7 files changed

+51
-26
lines changed

include/swift/AST/SourceFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ class SourceFile final : public FileUnit {
147147
/// A set of synthesized declarations that need to be type checked.
148148
llvm::SmallVector<Decl *, 8> SynthesizedDecls;
149149

150+
/// We might perform type checking on the same source file more than once,
151+
/// if its the main file or a REPL instance, so keep track of the last
152+
/// checked synthesized declaration to avoid duplicating work.
153+
unsigned LastCheckedSynthesizedDecl = 0;
154+
150155
/// A mapping from Objective-C selectors to the methods that have
151156
/// those selectors.
152157
llvm::DenseMap<ObjCSelector, llvm::TinyPtrVector<AbstractFunctionDecl *>>

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,10 +1251,7 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) {
12511251
C, StaticSpellingKind::None, hashValuePat, /*InitExpr*/ nullptr,
12521252
parentDC);
12531253

1254-
// If any of the members we synthesized didn't typecheck, bail out.
1255-
if (derived.addMembersToConformanceContext({hashValueDecl, patDecl})) {
1256-
return nullptr;
1257-
}
1254+
derived.addMembersToConformanceContext({hashValueDecl, patDecl});
12581255

12591256
return hashValueDecl;
12601257
}

lib/Sema/DerivedConformances.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/Pattern.h"
1818
#include "swift/AST/ParameterList.h"
1919
#include "swift/AST/ProtocolConformance.h"
20+
#include "swift/AST/SourceFile.h"
2021
#include "swift/AST/Types.h"
2122
#include "swift/ClangImporter/ClangModule.h"
2223
#include "DerivedConformances.h"
@@ -35,16 +36,15 @@ DeclContext *DerivedConformance::getConformanceContext() const {
3536
return cast<DeclContext>(ConformanceDecl);
3637
}
3738

38-
bool DerivedConformance::addMembersToConformanceContext(
39+
void DerivedConformance::addMembersToConformanceContext(
3940
ArrayRef<Decl *> children) {
4041
auto IDC = cast<IterableDeclContext>(ConformanceDecl);
41-
bool anyInvalid = false;
42+
auto *SF = ConformanceDecl->getDeclContext()->getParentSourceFile();
4243
for (auto child : children) {
4344
IDC->addMember(child);
44-
TypeChecker::typeCheckDecl(child);
45-
anyInvalid |= child->isInvalid();
45+
if (SF)
46+
SF->SynthesizedDecls.push_back(child);
4647
}
47-
return anyInvalid;
4848
}
4949

5050
Type DerivedConformance::getProtocolType() const {
@@ -285,28 +285,38 @@ DerivedConformance::createSelfDeclRef(AbstractFunctionDecl *fn) {
285285
AccessorDecl *DerivedConformance::
286286
addGetterToReadOnlyDerivedProperty(VarDecl *property,
287287
Type propertyContextType) {
288+
auto getter =
289+
declareDerivedPropertyGetter(property, propertyContextType);
290+
291+
property->setImplInfo(StorageImplInfo::getImmutableComputed());
292+
property->setAccessors(SourceLoc(), {getter}, SourceLoc());
293+
294+
return getter;
295+
}
296+
297+
AccessorDecl *
298+
DerivedConformance::declareDerivedPropertyGetter(VarDecl *property,
299+
Type propertyContextType) {
288300
auto &C = property->getASTContext();
289301
auto parentDC = property->getDeclContext();
290302
ParameterList *params = ParameterList::createEmpty(C);
291303

292304
Type propertyInterfaceType = property->getInterfaceType();
293-
294-
auto getter = AccessorDecl::create(C,
305+
306+
auto getterDecl = AccessorDecl::create(C,
295307
/*FuncLoc=*/SourceLoc(), /*AccessorKeywordLoc=*/SourceLoc(),
296308
AccessorKind::Get, property,
297309
/*StaticLoc=*/SourceLoc(), StaticSpellingKind::None,
298310
/*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
299311
/*GenericParams=*/nullptr, params,
300312
TypeLoc::withoutLoc(propertyInterfaceType), parentDC);
301-
getter->setImplicit();
302-
getter->setIsTransparent(false);
313+
getterDecl->setImplicit();
314+
getterDecl->setIsTransparent(false);
303315

304-
getter->copyFormalAccessFrom(property);
316+
getterDecl->copyFormalAccessFrom(property);
305317

306-
property->setImplInfo(StorageImplInfo::getImmutableComputed());
307-
property->setAccessors(SourceLoc(), {getter}, SourceLoc());
308318

309-
return getter;
319+
return getterDecl;
310320
}
311321

312322
std::pair<VarDecl *, PatternBindingDecl *>

lib/Sema/DerivedConformances.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ class DerivedConformance {
4646
DeclContext *getConformanceContext() const;
4747

4848
/// Add \c children as members of the context that declares the conformance.
49-
///
50-
/// \returns True if any of the added members were found to be invalid after type
51-
/// checking.
52-
bool addMembersToConformanceContext(ArrayRef<Decl *> children);
49+
void addMembersToConformanceContext(ArrayRef<Decl *> children);
5350

5451
/// Get the declared type of the protocol that this is conformance is for.
5552
Type getProtocolType() const;
@@ -200,7 +197,12 @@ class DerivedConformance {
200197
/// Add a getter to a derived property. The property becomes read-only.
201198
static AccessorDecl *
202199
addGetterToReadOnlyDerivedProperty(VarDecl *property,
203-
Type propertyContextType);
200+
Type propertyContextType);
201+
202+
/// Declare a getter for a derived property.
203+
/// The getter will not be added to the property yet.
204+
static AccessorDecl *declareDerivedPropertyGetter(VarDecl *property,
205+
Type propertyContextType);
204206

205207
/// Build a reference to the 'self' decl of a derived function.
206208
static DeclRefExpr *createSelfDeclRef(AbstractFunctionDecl *fn);

lib/Sema/TypeCheckDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,6 @@ bool TypeChecker::isAvailabilitySafeForConformance(
15501550
// Returns 'nullptr' if this is the setter's 'newValue' parameter;
15511551
// otherwise, returns the corresponding parameter of the subscript
15521552
// declaration.
1553-
15541553
static ParamDecl *getOriginalParamFromAccessor(AbstractStorageDecl *storage,
15551554
AccessorDecl *accessor,
15561555
ParamDecl *param) {

lib/Sema/TypeChecker.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ static void bindExtensions(SourceFile &SF) {
289289

290290
static void typeCheckFunctionsAndExternalDecls(SourceFile &SF, TypeChecker &TC) {
291291
unsigned currentFunctionIdx = 0;
292+
unsigned currentSynthesizedDecl = SF.LastCheckedSynthesizedDecl;
292293
do {
293294
// Type check the body of each of the function in turn. Note that outside
294295
// functions must be visited before nested functions for type-checking to
@@ -300,7 +301,18 @@ static void typeCheckFunctionsAndExternalDecls(SourceFile &SF, TypeChecker &TC)
300301

301302
TypeChecker::typeCheckAbstractFunctionBody(AFD);
302303
}
303-
} while (currentFunctionIdx < TC.definedFunctions.size());
304+
305+
// Type check synthesized functions and their bodies.
306+
for (unsigned n = SF.SynthesizedDecls.size();
307+
currentSynthesizedDecl != n;
308+
++currentSynthesizedDecl) {
309+
auto decl = SF.SynthesizedDecls[currentSynthesizedDecl];
310+
TypeChecker::typeCheckDecl(decl);
311+
}
312+
313+
} while (currentFunctionIdx < TC.definedFunctions.size() ||
314+
currentSynthesizedDecl < SF.SynthesizedDecls.size());
315+
304316

305317
for (AbstractFunctionDecl *FD : llvm::reverse(TC.definedFunctions)) {
306318
TypeChecker::computeCaptures(FD);

test/Sema/enum_conformance_synthesis.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func customHashable() {
6161
enum InvalidCustomHashable {
6262
case A, B
6363

64-
var hashValue: String { return "" } // expected-note 2 {{previously declared here}}
64+
var hashValue: String { return "" } // expected-note {{previously declared here}}
6565
}
6666
func ==(x: InvalidCustomHashable, y: InvalidCustomHashable) -> String {
6767
return ""
@@ -72,7 +72,7 @@ func invalidCustomHashable() {
7272
s = InvalidCustomHashable.A.hashValue
7373
_ = s
7474
var _: Int = InvalidCustomHashable.A.hashValue
75-
InvalidCustomHashable.A.hash(into: &hasher) // expected-error {{value of type 'InvalidCustomHashable' has no member 'hash'}}
75+
InvalidCustomHashable.A.hash(into: &hasher)
7676
}
7777

7878
// Check use of an enum's synthesized members before the enum is actually declared.

0 commit comments

Comments
 (0)