Skip to content

Commit 9458072

Browse files
committed
[AST] Verify identifier type representations are protocols
Now that GenericParamListRequest and OpaqueResultTypeRequest know to check for IdentTypeReprs when scanning for opaque parameters, the requests need to know it should only create Generic Paramters and Opaque Type Decls for IdentTypeReprs that are protocols. We should add a function to the swift namespace to check.
1 parent c3d4b3d commit 9458072

File tree

5 files changed

+92
-19
lines changed

5 files changed

+92
-19
lines changed

include/swift/AST/ASTWalker.h

+5
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,17 @@
2121
namespace swift {
2222

2323
class ArgumentList;
24+
class ASTContext;
2425
class Decl;
2526
class Expr;
2627
class ClosureExpr;
2728
class ModuleDecl;
29+
class DeclContext;
2830
class Stmt;
2931
class Pattern;
3032
class TypeRepr;
3133
class ParameterList;
34+
class Evaluator;
3235
enum class AccessKind: unsigned char;
3336

3437
enum class SemaReferenceKind : uint8_t {
@@ -472,6 +475,8 @@ class ASTWalker {
472475
return Action::Continue();
473476
}
474477

478+
virtual bool walkToTypeReprPre(Evaluator &evaluator, TypeRepr *T, ASTContext &ctx, DeclContext *dc) { return true; }
479+
475480
/// This method is called after visiting the children of a TypeRepr.
476481
///
477482
/// \param T The type that was walked.

include/swift/AST/NameLookup.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,38 @@
2727
#include "swift/Basic/SourceLoc.h"
2828
#include "swift/Basic/SourceManager.h"
2929
#include "llvm/ADT/SmallVector.h"
30+
#include "swift/AST/TypeRepr.h"
3031

3132
namespace swift {
3233
class ASTContext;
34+
class ASTWalker;
3335
class DeclName;
3436
class Type;
3537
class TypeDecl;
3638
class ValueDecl;
3739
struct SelfBounds;
3840
class NominalTypeDecl;
41+
class Evaluator;
3942

4043
namespace ast_scope {
4144
class ASTSourceFileScope;
4245
class ASTScopeImpl;
4346
} // namespace ast_scope
4447

48+
using CollectedOpaqueReprs = SmallVector<TypeRepr *, 2>;
49+
50+
/// Walk the type representation recursively, collecting any
51+
/// `OpaqueReturnTypeRepr`s.
52+
CollectedOpaqueReprs collectOpaqueReturnTypeReprs(TypeRepr *);
53+
54+
/// Walk the type representation recursively, collecting any
55+
/// `CompositionTypeRepr`s and `IdentTypeRepr`s.
56+
CollectedOpaqueReprs collectTypeReprs(TypeRepr *);
57+
58+
/// Given a Type Representation, decide if it is a protocol
59+
bool isProtocol(Evaluator &evaluator, TypeRepr *r, ASTContext &ctx, DeclContext *dc);
60+
61+
4562
/// LookupResultEntry - One result of unqualified lookup.
4663
struct LookupResultEntry {
4764
private:
@@ -520,6 +537,7 @@ void filterForDiscriminator(SmallVectorImpl<Result> &results,
520537

521538
} // end namespace namelookup
522539

540+
523541
/// Describes an inherited nominal entry.
524542
struct InheritedNominalEntry : Located<NominalTypeDecl *> {
525543
/// The location of the "unchecked" attribute, if present.
@@ -638,7 +656,7 @@ class FindLocalVal : public StmtVisitor<FindLocalVal> {
638656

639657
};
640658

641-
659+
642660
/// The bridge between the legacy UnqualifiedLookupFactory and the new ASTScope
643661
/// lookup system
644662
class AbstractASTScopeDeclConsumer {

include/swift/AST/TypeRepr.h

-8
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,6 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr
167167
/// opaque return type reprs.
168168
bool hasOpaque();
169169

170-
/// Walk the type representation recursively, collecting any
171-
/// `OpaqueReturnTypeRepr`s.
172-
CollectedOpaqueReprs collectOpaqueReturnTypeReprs();
173-
174-
/// Walk the type representation recursively, collecting any
175-
/// `CompositionTypeRepr`s and `IdentTypeRepr`s.
176-
CollectedOpaqueReprs collectTypeReprs();
177-
178170
/// Retrieve the type repr without any parentheses around it.
179171
///
180172
/// The use of this function must be restricted to contexts where

lib/AST/NameLookup.cpp

+59-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/NameLookup.h"
1818
#include "swift/AST/ASTContext.h"
1919
#include "swift/AST/ASTVisitor.h"
20+
#include "swift/AST/ASTWalker.h"
2021
#include "swift/AST/ClangModuleLoader.h"
2122
#include "swift/AST/DebuggerClient.h"
2223
#include "swift/AST/ExistentialLayout.h"
@@ -2796,11 +2797,53 @@ createExtensionGenericParams(ASTContext &ctx,
27962797
return toParams;
27972798
}
27982799

2800+
CollectedOpaqueReprs swift::collectOpaqueReturnTypeReprs(TypeRepr *r) {
2801+
class Walker : public ASTWalker {
2802+
CollectedOpaqueReprs &Reprs;
2803+
2804+
public:
2805+
explicit Walker(CollectedOpaqueReprs &reprs) : Reprs(reprs) {}
2806+
2807+
bool walkToTypeReprPre(TypeRepr *repr) override {
2808+
if (auto opaqueRepr = dyn_cast<OpaqueReturnTypeRepr>(repr))
2809+
Reprs.push_back(opaqueRepr);
2810+
return true;
2811+
}
2812+
};
2813+
2814+
CollectedOpaqueReprs reprs;
2815+
r->walk(Walker(reprs));
2816+
return reprs;
2817+
}
2818+
2819+
CollectedOpaqueReprs swift::collectTypeReprs(TypeRepr *r) {
2820+
class Walker : public ASTWalker {
2821+
CollectedOpaqueReprs &Reprs;
2822+
2823+
public:
2824+
explicit Walker(CollectedOpaqueReprs &reprs) : Reprs(reprs) {}
2825+
2826+
bool walkToTypeReprPre(TypeRepr *repr) override {
2827+
if (auto opaqueRepr = dyn_cast<OpaqueReturnTypeRepr>(repr)){
2828+
Reprs.push_back(opaqueRepr);
2829+
} else if (auto compositionRepr = dyn_cast<CompositionTypeRepr>(repr)){
2830+
Reprs.push_back(compositionRepr);
2831+
} else if (auto identRepr = dyn_cast<IdentTypeRepr>(repr)){
2832+
Reprs.push_back(identRepr);
2833+
}
2834+
return true;
2835+
}
2836+
};
2837+
2838+
CollectedOpaqueReprs reprs;
2839+
r->walk(Walker(reprs));
2840+
return reprs;
2841+
}
2842+
27992843
/// If there are opaque parameters in the given declaration, create the
28002844
/// generic parameters associated with them.
28012845
static SmallVector<GenericTypeParamDecl *, 2>
2802-
createOpaqueParameterGenericParams(
2803-
GenericContext *genericContext, GenericParamList *parsedGenericParams) {
2846+
createOpaqueParameterGenericParams(Evaluator &evaluator,GenericContext *genericContext, GenericParamList *parsedGenericParams) {
28042847
ASTContext &ctx = genericContext->getASTContext();
28052848

28062849
auto value = dyn_cast_or_null<ValueDecl>(genericContext->getAsDecl());
@@ -2828,14 +2871,14 @@ createOpaqueParameterGenericParams(
28282871
// Plain protocols should imply 'some' with experimetal feature
28292872
CollectedOpaqueReprs typeReprs;
28302873
if (ctx.LangOpts.hasFeature(Feature::ImplicitSome)) {
2831-
typeReprs = typeRepr->collectTypeReprs();
2832-
} else { typeReprs = typeRepr->collectOpaqueReturnTypeReprs(); }
2874+
typeReprs = collectTypeReprs(typeRepr);
2875+
} else { typeReprs = collectOpaqueReturnTypeReprs(typeRepr); }
28332876

28342877
for (auto repr : typeReprs) {
2878+
28352879
if (isa<IdentTypeRepr>(repr)){
2836-
DirectlyReferencedTypeDecls d = directReferencesForTypeRepr(ctx.evaluator, ctx, repr, dc, true);
2837-
if(!declsAreProtocols(d))
2838-
continue;
2880+
if(!isProtocol(evaluator,repr, ctx, dc))
2881+
continue;
28392882
}
28402883
// Allocate a new generic parameter to represent this opaque type.
28412884
auto gp = GenericTypeParamDecl::create(
@@ -2859,6 +2902,14 @@ createOpaqueParameterGenericParams(
28592902
return implicitGenericParams;
28602903
}
28612904

2905+
2906+
bool swift::isProtocol( Evaluator &evaluator, TypeRepr *r, ASTContext &ctx, DeclContext *dc) {
2907+
DirectlyReferencedTypeDecls d = directReferencesForTypeRepr(evaluator, ctx, r, dc);
2908+
if(declsAreProtocols(d)){
2909+
return true;
2910+
} else { return false; }
2911+
}
2912+
28622913
GenericParamList *
28632914
GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) const {
28642915
if (auto *tupleDecl = dyn_cast<BuiltinTupleDecl>(value)) {
@@ -2929,7 +2980,7 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
29292980
// Create implicit generic parameters due to opaque parameters, if we need
29302981
// them.
29312982
auto implicitGenericParams =
2932-
createOpaqueParameterGenericParams(value, parsedGenericParams);
2983+
createOpaqueParameterGenericParams(evaluator, value, parsedGenericParams);
29332984
if (implicitGenericParams.empty())
29342985
return parsedGenericParams;
29352986

lib/Sema/TypeCheckGeneric.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "TypeCheckProtocol.h"
1717
#include "TypeCheckType.h"
1818
#include "TypeChecker.h"
19+
#include "swift/AST/NameLookup.h"
1920
#include "swift/AST/ASTWalker.h"
2021
#include "swift/AST/DiagnosticsSema.h"
2122
#include "swift/AST/ExistentialLayout.h"
@@ -29,6 +30,7 @@
2930
#include "llvm/Support/ErrorHandling.h"
3031

3132
using namespace swift;
33+
using namespace swift::namelookup;
3234

3335
//
3436
// Generic functions
@@ -135,15 +137,20 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
135137
}
136138
} else {
137139
if (ctx.LangOpts.hasFeature(Feature::ImplicitSome)) {
138-
opaqueReprs = repr->collectTypeReprs();
140+
opaqueReprs = collectTypeReprs(repr);
139141
} else {
140-
opaqueReprs = repr->collectOpaqueReturnTypeReprs();
142+
opaqueReprs = collectOpaqueReturnTypeReprs(repr);
141143
}
142144
SmallVector<GenericTypeParamType *, 2> genericParamTypes;
143145
SmallVector<Requirement, 2> requirements;
144146
for (unsigned i = 0; i < opaqueReprs.size(); ++i) {
145147
auto *currentRepr = opaqueReprs[i];
146148

149+
if (isa<IdentTypeRepr>(currentRepr)){
150+
if(!isProtocol(evaluator, currentRepr, ctx, dc))
151+
continue;
152+
}
153+
147154
if( auto opaqueReturnRepr = dyn_cast<OpaqueReturnTypeRepr>(currentRepr) ) {
148155
// Usually, we resolve the opaque constraint and bail if it isn't a class
149156
// or existential type (see below). However, in this case we know we will

0 commit comments

Comments
 (0)