Skip to content

Commit 18569e5

Browse files
authored
Merge pull request #16963 from DougGregor/evaluator-type-checker
[Type checker] Use the request-evaluator in the type checker.
2 parents 570ed72 + 89032e4 commit 18569e5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+661
-224
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "llvm/Support/DataTypes.h"
2121
#include "swift/AST/ClangModuleLoader.h"
22+
#include "swift/AST/Evaluator.h"
2223
#include "swift/AST/Identifier.h"
2324
#include "swift/AST/SearchPathOptions.h"
2425
#include "swift/AST/Type.h"
@@ -218,6 +219,9 @@ class ASTContext final {
218219
/// Diags - The diagnostics engine.
219220
DiagnosticEngine &Diags;
220221

222+
/// The request-evaluator that is used to process various requests.
223+
Evaluator evaluator;
224+
221225
/// The set of top-level modules we have loaded.
222226
/// This map is used for iteration, therefore it's a MapVector and not a
223227
/// DenseMap.

include/swift/AST/Decl.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,9 @@ class ExtensionDecl final : public GenericContext, public Decl,
16611661

16621662
void setInherited(MutableArrayRef<TypeLoc> i) { Inherited = i; }
16631663

1664+
/// Retrieve one of the types listed in the "inherited" clause.
1665+
Type getInheritedType(unsigned index) const;
1666+
16641667
/// Whether we have fully checked the extension.
16651668
bool hasValidSignature() const {
16661669
return hasValidationStarted() && !isBeingValidated();
@@ -2496,6 +2499,9 @@ class TypeDecl : public ValueDecl {
24962499
MutableArrayRef<TypeLoc> getInherited() { return Inherited; }
24972500
ArrayRef<TypeLoc> getInherited() const { return Inherited; }
24982501

2502+
/// Retrieve one of the types listed in the "inherited" clause.
2503+
Type getInheritedType(unsigned index) const;
2504+
24992505
/// Whether we already type-checked the inheritance clause.
25002506
bool checkedInheritanceClause() const {
25012507
return Bits.TypeDecl.CheckedInheritanceClause;
@@ -3162,6 +3168,8 @@ class EnumDecl final : public NominalTypeDecl {
31623168
} LazySemanticInfo;
31633169

31643170
friend class IterativeTypeChecker;
3171+
friend class EnumRawTypeRequest;
3172+
friend class TypeChecker;
31653173

31663174
public:
31673175
EnumDecl(SourceLoc EnumLoc, Identifier Name, SourceLoc NameLoc,
@@ -3278,14 +3286,11 @@ class EnumDecl final : public NominalTypeDecl {
32783286
}
32793287

32803288
/// Determine whether this enum declares a raw type in its inheritance clause.
3281-
bool hasRawType() const {
3282-
return (bool)LazySemanticInfo.RawType.getPointer();
3283-
}
3289+
bool hasRawType() const { return (bool)getRawType(); }
3290+
32843291
/// Retrieve the declared raw type of the enum from its inheritance clause,
32853292
/// or null if it has none.
3286-
Type getRawType() const {
3287-
return LazySemanticInfo.RawType.getPointer();
3288-
}
3293+
Type getRawType() const;
32893294

32903295
/// Set the raw type of the enum from its inheritance clause.
32913296
void setRawType(Type rawType) {
@@ -3413,6 +3418,8 @@ class ClassDecl final : public NominalTypeDecl {
34133418
} LazySemanticInfo;
34143419

34153420
friend class IterativeTypeChecker;
3421+
friend class SuperclassTypeRequest;
3422+
friend class TypeChecker;
34163423

34173424
public:
34183425
ClassDecl(SourceLoc ClassLoc, Identifier Name, SourceLoc NameLoc,
@@ -3428,7 +3435,7 @@ class ClassDecl final : public NominalTypeDecl {
34283435
bool hasSuperclass() const { return (bool)getSuperclass(); }
34293436

34303437
/// Retrieve the superclass of this class, or null if there is no superclass.
3431-
Type getSuperclass() const { return LazySemanticInfo.Superclass.getPointer(); }
3438+
Type getSuperclass() const;
34323439

34333440
/// Retrieve the ClassDecl for the superclass of this class, or null if there
34343441
/// is no superclass.

include/swift/AST/Evaluator.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ class Evaluator {
107107
/// diagnostics will be emitted.
108108
DiagnosticEngine &diags;
109109

110+
/// Whether to diagnose cycles or ignore them completely.
111+
bool shouldDiagnoseCycles;
112+
110113
/// A vector containing all of the active evaluation requests, which
111114
/// is treated as a stack and is used to detect cycles.
112115
llvm::SetVector<AnyRequest> activeRequests;
@@ -128,7 +131,7 @@ class Evaluator {
128131
public:
129132
/// Construct a new evaluator that can emit cyclic-dependency
130133
/// diagnostics through the given diagnostics engine.
131-
Evaluator(DiagnosticEngine &diags);
134+
Evaluator(DiagnosticEngine &diags, bool shouldDiagnoseCycles);
132135

133136
/// Evaluate the given request and produce its result,
134137
/// consulting/populating the cache as required.

include/swift/AST/LazyResolver.h

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,19 @@ class LazyResolver {
7171
/// Resolve the "is Objective-C" bit for the given declaration.
7272
virtual void resolveIsObjC(ValueDecl *VD) = 0;
7373

74-
/// Resolve the types in the inheritance clause of the given
75-
/// declaration context, which will be a type declaration or
76-
/// extension declaration.
77-
virtual void resolveInheritanceClause(
78-
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl) = 0;
79-
80-
/// Resolve the superclass of the given class.
81-
virtual void resolveSuperclass(ClassDecl *classDecl) = 0;
74+
/// Retrieve the superclass of the given class.
75+
virtual Type getSuperclass(const ClassDecl *classDecl) = 0;
8276

8377
/// Resolve the raw type of the given enum.
84-
virtual void resolveRawType(EnumDecl *enumDecl) = 0;
78+
virtual Type getRawType(EnumDecl *enumDecl) = 0;
79+
80+
/// Get a specific inherited type from the given declaration.
81+
virtual Type getInheritedType(
82+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
83+
unsigned index) = 0;
8584

86-
/// Resolve the inherited protocols of a given protocol.
87-
virtual void resolveInheritedProtocols(ProtocolDecl *protocol) = 0;
85+
/// Resolve the trailing where clause of the given protocol in-place.
86+
virtual void resolveTrailingWhereClause(ProtocolDecl *proto) = 0;
8887

8988
/// Bind an extension to its extended type.
9089
virtual void bindExtension(ExtensionDecl *ext) = 0;

include/swift/AST/TypeLoc.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,24 @@ class TypeRepr;
3030
/// A TypeLoc is stored in AST nodes which use an explicitly written type.
3131
struct TypeLoc {
3232
private:
33-
/// \brief The resolved type and a bit indicating if it was validated, which
34-
/// means it went through possible generic substitutions.
35-
llvm::PointerIntPair<Type, 1, bool> TAndValidBit;
33+
Type Ty;
3634
TypeRepr *TyR = nullptr;
3735

38-
TypeLoc(Type T, TypeRepr *TyR) : TAndValidBit(T, false), TyR(TyR) {}
39-
4036
public:
4137
TypeLoc() {}
4238
TypeLoc(TypeRepr *TyR) : TyR(TyR) {}
4339
TypeLoc(TypeRepr *TyR, Type Ty) : TyR(TyR) {
4440
setType(Ty);
4541
}
4642

47-
bool wasValidated() const { return TAndValidBit.getInt(); }
43+
bool wasValidated() const { return !Ty.isNull(); }
4844
bool isError() const;
4945

5046
// FIXME: We generally shouldn't need to build TypeLocs without a location.
5147
static TypeLoc withoutLoc(Type T) {
52-
return TypeLoc(T, nullptr);
48+
TypeLoc result;
49+
result.Ty = T;
50+
return result;
5351
}
5452

5553
/// Get the representative location of this type, for diagnostic
@@ -60,12 +58,12 @@ struct TypeLoc {
6058

6159
bool hasLocation() const { return TyR != nullptr; }
6260
TypeRepr *getTypeRepr() const { return TyR; }
63-
Type getType() const { return TAndValidBit.getPointer(); }
61+
Type getType() const { return Ty; }
6462

6563
bool isNull() const { return getType().isNull() && TyR == nullptr; }
6664

6765
void setInvalidType(ASTContext &C);
68-
void setType(Type Ty, bool validated = false);
66+
void setType(Type Ty);
6967

7068
TypeLoc clone(ASTContext &ctx) const;
7169
};
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//===--- TypeCheckRequests.h - Type Checking Requests -----------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines type checking requests.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
#ifndef SWIFT_SEMA_REQUESTS_H
17+
#define SWIFT_SEMA_REQUESTS_H
18+
19+
#include "swift/AST/Type.h"
20+
#include "swift/AST/Evaluator.h"
21+
#include "swift/AST/SimpleRequest.h"
22+
#include "llvm/ADT/Hashing.h"
23+
24+
namespace swift {
25+
26+
struct TypeLoc;
27+
28+
/// Display a nominal type or extension thereof.
29+
void simple_display(
30+
llvm::raw_ostream &out,
31+
const llvm::PointerUnion<TypeDecl *, ExtensionDecl *> &value);
32+
33+
/// Request the type from the ith entry in the inheritance clause for the
34+
/// given declaration.
35+
class InheritedTypeRequest :
36+
public SimpleRequest<InheritedTypeRequest,
37+
CacheKind::SeparatelyCached,
38+
Type,
39+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *>,
40+
unsigned>
41+
{
42+
/// Retrieve the TypeLoc for this inherited type.
43+
TypeLoc &getTypeLoc(llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
44+
unsigned index) const;
45+
46+
public:
47+
using SimpleRequest::SimpleRequest;
48+
using SimpleRequest::operator();
49+
50+
private:
51+
friend class SimpleRequest;
52+
53+
// Evaluation.
54+
Type operator()(Evaluator &evaluator,
55+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
56+
unsigned index) const;
57+
58+
public:
59+
// Cycle handling
60+
Type breakCycle() const { return Type(); }
61+
void diagnoseCycle(DiagnosticEngine &diags) const;
62+
void noteCycleStep(DiagnosticEngine &diags) const;
63+
64+
// Caching
65+
bool isCached() const { return true; }
66+
Optional<Type> getCachedResult() const;
67+
void cacheResult(Type value) const;
68+
};
69+
70+
/// Request the superclass type for the given class.
71+
class SuperclassTypeRequest :
72+
public SimpleRequest<SuperclassTypeRequest,
73+
CacheKind::SeparatelyCached,
74+
Type,
75+
ClassDecl *> {
76+
public:
77+
using SimpleRequest::SimpleRequest;
78+
using SimpleRequest::operator();
79+
80+
private:
81+
friend class SimpleRequest;
82+
83+
// Evaluation.
84+
Type operator()(Evaluator &evaluator, ClassDecl *classDecl) const;
85+
86+
public:
87+
// Cycle handling
88+
Type breakCycle() const { return Type(); }
89+
void diagnoseCycle(DiagnosticEngine &diags) const;
90+
void noteCycleStep(DiagnosticEngine &diags) const;
91+
92+
// Separate caching.
93+
bool isCached() const { return true; }
94+
Optional<Type> getCachedResult() const;
95+
void cacheResult(Type value) const;
96+
};
97+
98+
/// Request the raw type of the given enum.
99+
class EnumRawTypeRequest :
100+
public SimpleRequest<EnumRawTypeRequest,
101+
CacheKind::SeparatelyCached,
102+
Type,
103+
EnumDecl *> {
104+
public:
105+
using SimpleRequest::SimpleRequest;
106+
using SimpleRequest::operator();
107+
108+
private:
109+
friend class SimpleRequest;
110+
111+
// Evaluation.
112+
Type operator()(Evaluator &evaluator, EnumDecl *enumDecl) const;
113+
114+
public:
115+
// Cycle handling
116+
Type breakCycle() const { return Type(); }
117+
void diagnoseCycle(DiagnosticEngine &diags) const;
118+
void noteCycleStep(DiagnosticEngine &diags) const;
119+
120+
// Separate caching.
121+
bool isCached() const { return true; }
122+
Optional<Type> getCachedResult() const;
123+
void cacheResult(Type value) const;
124+
};
125+
126+
#define SWIFT_TYPEID_ZONE 10
127+
#define SWIFT_TYPEID_HEADER "swift/Sema/TypeCheckerTypeIDZone.def"
128+
#include "swift/Basic/DefineTypeIDZone.h"
129+
130+
} // end namespace swift
131+
132+
#endif // SWIFT_SEMA_REQUESTS_H
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===--- ArithmeticEvaluatorTypeIDZone.def - --------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This definition file describes the types in the type checker's
14+
// TypeID zone, for use with the TypeID template.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
SWIFT_TYPEID(InheritedTypeRequest)
18+
SWIFT_TYPEID(SuperclassTypeRequest)
19+
SWIFT_TYPEID(EnumRawTypeRequest)

include/swift/Serialization/ModuleFile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class ModuleFile
5050
friend class SerializedASTFile;
5151
friend class SILDeserializer;
5252
using Status = serialization::Status;
53+
using TypeID = serialization::TypeID;
5354

5455
/// A reference back to the AST representation of the file.
5556
FileUnit *FileContext = nullptr;

lib/AST/ASTContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ ASTContext::ASTContext(LangOptions &langOpts, SearchPathOptions &SearchPathOpts,
463463
SearchPathOpts(SearchPathOpts),
464464
SourceMgr(SourceMgr),
465465
Diags(Diags),
466+
evaluator(Diags, /*shouldDiagnoseCycles=*/false),
466467
TheBuiltinModule(createBuiltinModule(*this)),
467468
StdlibModuleName(getIdentifier(STDLIB_NAME)),
468469
SwiftShimsModuleName(getIdentifier(SWIFT_SHIMS_NAME)),
@@ -4246,7 +4247,7 @@ CanType ArchetypeType::getAnyOpened(Type existential) {
42464247
}
42474248

42484249
void TypeLoc::setInvalidType(ASTContext &C) {
4249-
TAndValidBit.setPointerAndInt(ErrorType::get(C), true);
4250+
Ty = ErrorType::get(C);
42504251
}
42514252

42524253
namespace {

0 commit comments

Comments
 (0)