Skip to content

Commit 9e95a93

Browse files
committed
[Evaluator] Sink type checker requests into the AST library.
Sink the type checker request classes into the AST library, so that various functions in the AST library can form type-checking requests. The actual evaluator functions for these requests continue to live in the Sema library, called via indirection through the function pointer tables registered with the request-evaluator.
1 parent 84273b2 commit 9e95a93

10 files changed

+176
-19
lines changed

include/swift/AST/DiagnosticsCommon.def

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,24 @@ ERROR(attr_only_on_parameters, none,
9393
ERROR(function_type_no_parens,none,
9494
"single argument function types require parentheses", ())
9595

96+
//------------------------------------------------------------------------------
97+
// MARK: Circular reference diagnostics
98+
//------------------------------------------------------------------------------
99+
ERROR(circular_reference, none,
100+
"circular reference", ())
101+
102+
ERROR(redundant_type_alias_define, none,
103+
"redundant type alias declaration", ())
104+
105+
NOTE(circular_reference_through, none,
106+
"through reference here", ())
107+
108+
ERROR(circular_class_inheritance,none,
109+
"%0 inherits from itself", (Identifier))
110+
111+
ERROR(circular_enum_inheritance,none,
112+
"%0 has a raw type that depends on itself", (Identifier))
113+
96114
#ifndef DIAG_NO_UNDEF
97115
# if defined(DIAG)
98116
# undef DIAG

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,8 +2155,6 @@ ERROR(superclass_not_open,none,
21552155
NOTE(superclass_here,none,"superclass is declared here", ())
21562156
ERROR(superclass_of_open_not_open,none,
21572157
"superclass %0 of open class must be open", (Type))
2158-
ERROR(circular_class_inheritance,none,
2159-
"%0 inherits from itself", (Identifier))
21602158
ERROR(inheritance_from_final_class,none,
21612159
"inheritance from a final class %0", (Identifier))
21622160
ERROR(inheritance_from_unspecialized_objc_generic_class,none,
@@ -2199,8 +2197,6 @@ ERROR(enum_stored_property,none,
21992197
// Enum raw types
22002198
ERROR(multiple_enum_raw_types,none,
22012199
"multiple enum raw types %0 and %1", (Type, Type))
2202-
ERROR(circular_enum_inheritance,none,
2203-
"%0 has a raw type that depends on itself", (Identifier))
22042200
ERROR(raw_type_not_first,none,
22052201
"raw type %0 must appear first in the enum inheritance clause", (Type))
22062202
ERROR(raw_type_not_literal_convertible,none,
@@ -4061,18 +4057,6 @@ WARNING(variable_never_read, none,
40614057
"%select{variable|parameter}1 %0 was written to, but never read",
40624058
(Identifier, unsigned))
40634059

4064-
//------------------------------------------------------------------------------
4065-
// MARK: Circular reference diagnostics
4066-
//------------------------------------------------------------------------------
4067-
ERROR(circular_reference, none,
4068-
"circular reference", ())
4069-
4070-
ERROR(redundant_type_alias_define, none,
4071-
"redundant type alias declaration", ())
4072-
4073-
NOTE(circular_reference_through, none,
4074-
"through reference here", ())
4075-
40764060
//------------------------------------------------------------------------------
40774061
// MARK: Debug diagnostics
40784062
//------------------------------------------------------------------------------

include/swift/Basic/Statistics.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ FRONTEND_STATISTIC(Sema, NumUnloadedLazyIterableDeclContexts)
197197

198198
/// All type check requests go into the Sema area.
199199
#define SWIFT_TYPEID(NAME) FRONTEND_STATISTIC(Sema, NAME)
200-
#include "swift/Sema/TypeCheckerTypeIDZone.def"
200+
#include "swift/AST/TypeCheckerTypeIDZone.def"
201201
#undef SWIFT_TYPEID
202202

203203
/// The next 10 statistics count 5 kinds of SIL entities present

lib/AST/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ add_swift_library(swiftAST STATIC
5252
SubstitutionMap.cpp
5353
SwiftNameTranslation.cpp
5454
Type.cpp
55+
TypeCheckRequests.cpp
5556
TypeJoinMeet.cpp
5657
TypeRefinementContext.cpp
5758
TypeRepr.cpp
File renamed without changes.

lib/Sema/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ add_swift_library(swiftSema STATIC
4848
TypeCheckProtocol.cpp
4949
TypeCheckProtocolInference.cpp
5050
TypeCheckREPL.cpp
51-
TypeCheckRequests.cpp
51+
TypeCheckRequestFunctions.cpp
5252
TypeCheckStmt.cpp
5353
TypeCheckSwitchStmt.cpp
5454
TypeCheckType.cpp

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
#include "swift/Parse/Parser.h"
4141
#include "swift/Serialization/SerializedModuleLoader.h"
4242
#include "swift/Strings.h"
43-
#include "swift/Sema/TypeCheckRequests.h"
43+
#include "swift/AST/TypeCheckRequests.h"
4444
#include "swift/Basic/Defer.h"
4545
#include "llvm/ADT/APFloat.h"
4646
#include "llvm/ADT/APInt.h"
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
//===--- TypeCheckRequests.cpp - Type Checking Requests ------------------===//
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+
#include "GenericTypeResolver.h"
13+
#include "TypeChecker.h"
14+
#include "swift/AST/TypeCheckRequests.h"
15+
#include "swift/AST/Decl.h"
16+
#include "swift/AST/ExistentialLayout.h"
17+
#include "swift/AST/TypeLoc.h"
18+
#include "swift/AST/Types.h"
19+
#include "swift/Subsystems.h"
20+
21+
using namespace swift;
22+
23+
Type InheritedTypeRequest::evaluate(
24+
Evaluator &evaluator,
25+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
26+
unsigned index) const {
27+
// Figure out how to resolve types.
28+
TypeResolutionOptions options;
29+
DeclContext *dc;
30+
if (auto typeDecl = decl.dyn_cast<TypeDecl *>()) {
31+
if (auto nominal = dyn_cast<NominalTypeDecl>(typeDecl)) {
32+
dc = nominal;
33+
options |= TypeResolutionFlags::GenericSignature;
34+
options |= TypeResolutionFlags::InheritanceClause;
35+
options |= TypeResolutionFlags::AllowUnavailableProtocol;
36+
} else {
37+
dc = typeDecl->getDeclContext();
38+
39+
if (isa<GenericTypeParamDecl>(typeDecl)) {
40+
// For generic parameters, we want name lookup to look at just the
41+
// signature of the enclosing entity.
42+
if (auto nominal = dyn_cast<NominalTypeDecl>(dc)) {
43+
dc = nominal;
44+
options |= TypeResolutionFlags::GenericSignature;
45+
} else if (auto ext = dyn_cast<ExtensionDecl>(dc)) {
46+
dc = ext;
47+
options |= TypeResolutionFlags::GenericSignature;
48+
} else if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {
49+
dc = func;
50+
options |= TypeResolutionFlags::GenericSignature;
51+
} else if (!dc->isModuleScopeContext()) {
52+
// Skip the generic parameter's context entirely.
53+
dc = dc->getParent();
54+
}
55+
}
56+
}
57+
} else {
58+
auto ext = decl.get<ExtensionDecl *>();
59+
dc = ext;
60+
options |= TypeResolutionFlags::GenericSignature;
61+
options |= TypeResolutionFlags::InheritanceClause;
62+
options |= TypeResolutionFlags::AllowUnavailableProtocol;
63+
}
64+
65+
ProtocolRequirementTypeResolver protoResolver;
66+
GenericTypeToArchetypeResolver archetypeResolver(dc);
67+
GenericTypeResolver *resolver;
68+
if (isa<ProtocolDecl>(dc)) {
69+
resolver = &protoResolver;
70+
} else {
71+
resolver = &archetypeResolver;
72+
}
73+
74+
// FIXME: Hack for calls through here when we have no type checker.
75+
auto lazyResolver = dc->getASTContext().getLazyResolver();
76+
if (!lazyResolver) return ErrorType::get(dc->getASTContext());
77+
78+
TypeChecker &tc = *static_cast<TypeChecker *>(lazyResolver);
79+
TypeLoc &typeLoc = getTypeLoc(decl, index);
80+
81+
Type inheritedType =
82+
tc.resolveType(typeLoc.getTypeRepr(), dc, options, resolver);
83+
if (inheritedType && !isa<ProtocolDecl>(dc))
84+
inheritedType = inheritedType->mapTypeOutOfContext();
85+
return inheritedType ? inheritedType : ErrorType::get(tc.Context);
86+
}
87+
88+
Type SuperclassTypeRequest::evaluate(Evaluator &evaluator,
89+
NominalTypeDecl *nominalDecl) const {
90+
assert(isa<ClassDecl>(nominalDecl) || isa<ProtocolDecl>(nominalDecl));
91+
92+
for (unsigned int idx : indices(nominalDecl->getInherited())) {
93+
Type inheritedType = evaluator(InheritedTypeRequest{nominalDecl, idx});
94+
if (!inheritedType) continue;
95+
96+
// If we found a class, return it.
97+
if (inheritedType->getClassOrBoundGenericClass()) {
98+
if (inheritedType->hasArchetype())
99+
return inheritedType->mapTypeOutOfContext();
100+
101+
return inheritedType;
102+
}
103+
104+
// If we found an existential with a superclass bound, return it.
105+
if (inheritedType->isExistentialType()) {
106+
if (auto superclassType =
107+
inheritedType->getExistentialLayout().superclass) {
108+
if (superclassType->getClassOrBoundGenericClass()) {
109+
if (superclassType->hasArchetype())
110+
return superclassType->mapTypeOutOfContext();
111+
112+
return superclassType;
113+
}
114+
}
115+
}
116+
}
117+
118+
// No superclass.
119+
return Type();
120+
}
121+
122+
Type EnumRawTypeRequest::evaluate(Evaluator &evaluator,
123+
EnumDecl *enumDecl) const {
124+
for (unsigned int idx : indices(enumDecl->getInherited())) {
125+
Type inheritedType = evaluator(InheritedTypeRequest{enumDecl, idx});
126+
if (!inheritedType) continue;
127+
128+
// Skip existential types.
129+
if (inheritedType->isExistentialType()) continue;
130+
131+
// We found a raw type; return it.
132+
if (inheritedType->hasArchetype())
133+
return inheritedType->mapTypeOutOfContext();
134+
135+
return inheritedType;
136+
}
137+
138+
// No raw type.
139+
return Type();
140+
}
141+
142+
// Define request evaluation functions for each of the type checker requests.
143+
static AbstractRequestFunction *typeCheckerRequestFunctions[] = {
144+
#define SWIFT_TYPEID(Name) \
145+
reinterpret_cast<AbstractRequestFunction *>(&Name::evaluateRequest),
146+
#include "swift/AST/TypeCheckerTypeIDZone.def"
147+
#undef SWIFT_TYPEID
148+
};
149+
150+
void swift::registerTypeCheckerRequestFunctions(Evaluator &evaluator) {
151+
evaluator.registerRequestFunctions(SWIFT_TYPE_CHECKER_REQUESTS_TYPEID_ZONE,
152+
typeCheckerRequestFunctions);
153+
}
154+

0 commit comments

Comments
 (0)