Skip to content

Commit b12ecdb

Browse files
committed
[AST] Ignore existential types when building opaque parameter list
1 parent 22bbb01 commit b12ecdb

File tree

9 files changed

+233
-156
lines changed

9 files changed

+233
-156
lines changed

include/swift/AST/ASTWalker.h

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

2323
class ArgumentList;
24-
class ASTContext;
2524
class Decl;
2625
class Expr;
2726
class ClosureExpr;
2827
class ModuleDecl;
29-
class DeclContext;
3028
class Stmt;
3129
class Pattern;
3230
class TypeRepr;
3331
class ParameterList;
34-
class Evaluator;
3532
enum class AccessKind: unsigned char;
3633

3734
enum class SemaReferenceKind : uint8_t {
@@ -475,8 +472,6 @@ class ASTWalker {
475472
return Action::Continue();
476473
}
477474

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

include/swift/AST/NameLookup.h

+2-14
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,9 @@ class ASTSourceFileScope;
4545
class ASTScopeImpl;
4646
} // namespace ast_scope
4747

48-
using CollectedOpaqueReprs = SmallVector<TypeRepr *, 2>;
49-
50-
/// Walk the type representation recursively, collecting any
51-
/// `OpaqueReturnTypeRepr`s.
52-
CollectedOpaqueReprs collectOpaqueReturnTypeReprs(TypeRepr *);
53-
5448
/// 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-
49+
/// `OpaqueReturnTypeRepr`s, `CompositionTypeRepr`s or `IdentTypeRepr`s.
50+
CollectedOpaqueReprs collectOpaqueReturnTypeReprs(TypeRepr *, ASTContext &ctx, DeclContext *dc);
6151

6252
/// LookupResultEntry - One result of unqualified lookup.
6353
struct LookupResultEntry {
@@ -537,7 +527,6 @@ void filterForDiscriminator(SmallVectorImpl<Result> &results,
537527

538528
} // end namespace namelookup
539529

540-
541530
/// Describes an inherited nominal entry.
542531
struct InheritedNominalEntry : Located<NominalTypeDecl *> {
543532
/// The location of the "unchecked" attribute, if present.
@@ -656,7 +645,6 @@ class FindLocalVal : public StmtVisitor<FindLocalVal> {
656645

657646
};
658647

659-
660648
/// The bridge between the legacy UnqualifiedLookupFactory and the new ASTScope
661649
/// lookup system
662650
class AbstractASTScopeDeclConsumer {

include/swift/AST/TypeRepr.h

+12-4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/Support/TrailingObjects.h"
3434

3535
namespace swift {
36+
class ASTContext;
3637
class ASTWalker;
3738
class DeclContext;
3839
class IdentTypeRepr;
@@ -48,9 +49,7 @@ enum : unsigned { NumTypeReprKindBits =
4849
countBitsUsed(static_cast<unsigned>(TypeReprKind::Last_TypeRepr)) };
4950

5051
class OpaqueReturnTypeRepr;
51-
//using CollectedOpaqueReprs = SmallVector<OpaqueReturnTypeRepr *, 2>;
52-
using CollectedOpaqueReprs = SmallVector<TypeRepr *, 2>; //change to TypeRepr
53-
52+
using CollectedOpaqueReprs = SmallVector<TypeRepr *, 2>;
5453

5554
/// Representation of a type as written in source.
5655
class alignas(1 << TypeReprAlignInBits) TypeRepr
@@ -120,6 +119,9 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr
120119
return static_cast<TypeReprKind>(Bits.TypeRepr.Kind);
121120
}
122121

122+
/// Is this type representation a protocol?
123+
bool isProtocol(DeclContext *dc);
124+
123125
/// Is this type representation known to be invalid?
124126
bool isInvalid() const { return Bits.TypeRepr.Invalid; }
125127

@@ -842,7 +844,7 @@ class TupleTypeRepr final : public TypeRepr,
842844
/// Foo & Bar
843845
/// \endcode
844846
class CompositionTypeRepr final : public TypeRepr,
845-
private llvm::TrailingObjects<CompositionTypeRepr, TypeRepr*> {
847+
private llvm::TrailingObjects<CompositionTypeRepr, TypeRepr*> {
846848
friend TrailingObjects;
847849
SourceLoc FirstTypeLoc;
848850
SourceRange CompositionRange;
@@ -864,6 +866,12 @@ class CompositionTypeRepr final : public TypeRepr,
864866
SourceLoc getSourceLoc() const { return FirstTypeLoc; }
865867
SourceRange getCompositionRange() const { return CompositionRange; }
866868

869+
/// 'Any' is understood as CompositionTypeRepr by the compiler but its type array will be empty
870+
/// becasue it is a nonspecific type
871+
bool isTypeReprAny() {
872+
return getTypes().size() == 0 ? true : false;
873+
}
874+
867875
static CompositionTypeRepr *create(const ASTContext &C,
868876
ArrayRef<TypeRepr*> Protocols,
869877
SourceLoc FirstTypeLoc,

lib/AST/NameLookup.cpp

+37-52
Original file line numberDiff line numberDiff line change
@@ -2765,7 +2765,7 @@ static bool declsAreAssociatedTypes(ArrayRef<TypeDecl *> decls) {
27652765
return true;
27662766
}
27672767

2768-
/// Whether there are only protocol decl types in the set of declarations.
2768+
/// Verify there are only protocols in the set of declarations.
27692769
static bool declsAreProtocols(ArrayRef<TypeDecl *> decls) {
27702770
if (decls.empty())
27712771
return false;
@@ -2774,10 +2774,15 @@ static bool declsAreProtocols(ArrayRef<TypeDecl *> decls) {
27742774
if (!isa<ProtocolDecl>(decl))
27752775
return false;
27762776
}
2777-
27782777
return true;
27792778
}
27802779

2780+
bool TypeRepr::isProtocol(DeclContext *dc){
2781+
auto &ctx = dc->getASTContext();
2782+
DirectlyReferencedTypeDecls d = directReferencesForTypeRepr(ctx.evaluator, ctx, this, dc);
2783+
return declsAreProtocols(d);
2784+
}
2785+
27812786
static GenericParamList *
27822787
createExtensionGenericParams(ASTContext &ctx,
27832788
ExtensionDecl *ext,
@@ -2797,54 +2802,48 @@ createExtensionGenericParams(ASTContext &ctx,
27972802
return toParams;
27982803
}
27992804

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) {
2805+
CollectedOpaqueReprs swift::collectOpaqueReturnTypeReprs(TypeRepr *r, ASTContext &ctx, DeclContext *d) {
28202806
class Walker : public ASTWalker {
28212807
CollectedOpaqueReprs &Reprs;
2808+
ASTContext &Ctx;
2809+
DeclContext *dc;
28222810

28232811
public:
2824-
explicit Walker(CollectedOpaqueReprs &reprs) : Reprs(reprs) {}
2812+
explicit Walker(CollectedOpaqueReprs &reprs, ASTContext &ctx, DeclContext *d) : Reprs(reprs), Ctx(ctx), dc(d) {}
28252813

28262814
bool walkToTypeReprPre(TypeRepr *repr) override {
2815+
if (auto existential = dyn_cast<ExistentialTypeRepr>(repr)) {
2816+
return false;
2817+
}
2818+
28272819
if (auto opaqueRepr = dyn_cast<OpaqueReturnTypeRepr>(repr)){
2828-
Reprs.push_back(opaqueRepr);
2820+
Reprs.push_back(opaqueRepr);
2821+
if (Ctx.LangOpts.hasFeature(Feature::ImplicitSome))
28292822
return false;
2830-
} else if (auto compositionRepr = dyn_cast<CompositionTypeRepr>(repr)){
2831-
Reprs.push_back(compositionRepr);
2832-
} else if (auto identRepr = dyn_cast<IdentTypeRepr>(repr)){
2833-
Reprs.push_back(identRepr);
2823+
}
2824+
2825+
if (Ctx.LangOpts.hasFeature(Feature::ImplicitSome)){
2826+
if (auto compositionRepr = dyn_cast<CompositionTypeRepr>(repr)){
2827+
if (!compositionRepr->isTypeReprAny())
2828+
Reprs.push_back(compositionRepr);
2829+
} else if (auto identRepr = dyn_cast<IdentTypeRepr>(repr)) {
2830+
if (identRepr->isProtocol(dc))
2831+
Reprs.push_back(identRepr);
2832+
}
28342833
}
28352834
return true;
28362835
}
28372836
};
28382837

28392838
CollectedOpaqueReprs reprs;
2840-
r->walk(Walker(reprs));
2839+
r->walk(Walker(reprs, ctx, d));
28412840
return reprs;
28422841
}
28432842

28442843
/// If there are opaque parameters in the given declaration, create the
28452844
/// generic parameters associated with them.
28462845
static SmallVector<GenericTypeParamDecl *, 2>
2847-
createOpaqueParameterGenericParams(Evaluator &evaluator,GenericContext *genericContext, GenericParamList *parsedGenericParams) {
2846+
createOpaqueParameterGenericParams(GenericContext *genericContext, GenericParamList *parsedGenericParams) {
28482847
ASTContext &ctx = genericContext->getASTContext();
28492848

28502849
auto value = dyn_cast_or_null<ValueDecl>(genericContext->getAsDecl());
@@ -2871,51 +2870,37 @@ createOpaqueParameterGenericParams(Evaluator &evaluator,GenericContext *genericC
28712870

28722871
// Plain protocols should imply 'some' with experimetal feature
28732872
CollectedOpaqueReprs typeReprs;
2874-
if (ctx.LangOpts.hasFeature(Feature::ImplicitSome)) {
2875-
typeReprs = collectTypeReprs(typeRepr);
2876-
} else { typeReprs = collectOpaqueReturnTypeReprs(typeRepr); }
2873+
typeReprs = collectOpaqueReturnTypeReprs(typeRepr, ctx, dc);
28772874

2878-
for (auto repr : typeReprs) {
2875+
for (auto repr : typeReprs) {
28792876

2880-
if (isa<IdentTypeRepr>(repr)){
2881-
if(!isProtocol(evaluator,repr, ctx, dc))
2882-
continue;
2883-
}
28842877
// Allocate a new generic parameter to represent this opaque type.
2885-
auto gp = GenericTypeParamDecl::create(
2878+
auto gp = GenericTypeParamDecl::create(
28862879
dc, Identifier(), SourceLoc(), /*isTypeSequence=*/false,
28872880
GenericTypeParamDecl::InvalidDepth, index++, /*isOpaqueType=*/true,
28882881
repr);
2889-
gp->setImplicit();
2882+
gp->setImplicit();
28902883

28912884
// Use the underlying constraint as the constraint on the generic parameter.
28922885
// The underlying constraint is only present for OpaqueReturnTypeReprs
2893-
if( auto opaque = dyn_cast<OpaqueReturnTypeRepr>(repr)){
2886+
if (auto opaque = dyn_cast<OpaqueReturnTypeRepr>(repr)) {
28942887
InheritedEntry inherited[1] = {
28952888
{ TypeLoc(opaque->getConstraint()) }
28962889
};
28972890
gp->setInherited(ctx.AllocateCopy(inherited));
2898-
} else {
2891+
} else {
28992892
InheritedEntry inherited[1] = {
29002893
{ TypeLoc(repr) }
29012894
};
29022895
gp->setInherited(ctx.AllocateCopy(inherited));
2903-
}
2896+
}
29042897
implicitGenericParams.push_back(gp);
29052898
}
29062899
}
29072900

29082901
return implicitGenericParams;
29092902
}
29102903

2911-
2912-
bool swift::isProtocol( Evaluator &evaluator, TypeRepr *r, ASTContext &ctx, DeclContext *dc) {
2913-
DirectlyReferencedTypeDecls d = directReferencesForTypeRepr(evaluator, ctx, r, dc);
2914-
if(declsAreProtocols(d)){
2915-
return true;
2916-
} else { return false; }
2917-
}
2918-
29192904
GenericParamList *
29202905
GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) const {
29212906
if (auto *tupleDecl = dyn_cast<BuiltinTupleDecl>(value)) {
@@ -2986,7 +2971,7 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
29862971
// Create implicit generic parameters due to opaque parameters, if we need
29872972
// them.
29882973
auto implicitGenericParams =
2989-
createOpaqueParameterGenericParams(evaluator, value, parsedGenericParams);
2974+
createOpaqueParameterGenericParams(value, parsedGenericParams);
29902975
if (implicitGenericParams.empty())
29912976
return parsedGenericParams;
29922977

lib/AST/TypeRepr.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/Support/ErrorHandling.h"
3030
#include "llvm/Support/raw_ostream.h"
3131
using namespace swift;
32+
//using namespace swift::namelookup;
3233

3334
#define TYPEREPR(Id, _) \
3435
static_assert(IsTriviallyDestructible<Id##TypeRepr>::value, \

0 commit comments

Comments
 (0)