Skip to content

Commit 5f3191c

Browse files
committed
[AST] Teach GenericParamList amd OpaqueReturnType Request to use plain protocols
Originally protocols prefixed with 'some' keyword are considered an opaue return type representation. In order to understand plain protocols, the GenericParamList Request must understand how to build a generic parameter list using alternative type representations: identifier and composition.
1 parent c3ef34b commit 5f3191c

File tree

7 files changed

+155
-87
lines changed

7 files changed

+155
-87
lines changed

include/swift/AST/Decl.h

+10-10
Original file line numberDiff line numberDiff line change
@@ -2822,7 +2822,7 @@ class GenericTypeDecl : public GenericContext, public TypeDecl {
28222822
/// (opaque archetype 1))`.
28232823
class OpaqueTypeDecl final :
28242824
public GenericTypeDecl,
2825-
private llvm::TrailingObjects<OpaqueTypeDecl, OpaqueReturnTypeRepr *> {
2825+
private llvm::TrailingObjects<OpaqueTypeDecl, TypeRepr *> {
28262826
friend TrailingObjects;
28272827

28282828
public:
@@ -2866,7 +2866,7 @@ class OpaqueTypeDecl final :
28662866
OpaqueTypeDecl(ValueDecl *NamingDecl, GenericParamList *GenericParams,
28672867
DeclContext *DC,
28682868
GenericSignature OpaqueInterfaceGenericSignature,
2869-
ArrayRef<OpaqueReturnTypeRepr *> OpaqueReturnTypeReprs);
2869+
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs);
28702870

28712871
unsigned getNumOpaqueReturnTypeReprs() const {
28722872
return NamingDeclAndHasOpaqueReturnTypeRepr.getInt()
@@ -2883,7 +2883,7 @@ class OpaqueTypeDecl final :
28832883
ValueDecl *NamingDecl, GenericParamList *GenericParams,
28842884
DeclContext *DC,
28852885
GenericSignature OpaqueInterfaceGenericSignature,
2886-
ArrayRef<OpaqueReturnTypeRepr *> OpaqueReturnTypeReprs);
2886+
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs);
28872887

28882888
ValueDecl *getNamingDecl() const {
28892889
return NamingDeclAndHasOpaqueReturnTypeRepr.getPointer();
@@ -2928,9 +2928,9 @@ class OpaqueTypeDecl final :
29282928

29292929
/// Retrieve the buffer containing the opaque return type
29302930
/// representations that correspond to the opaque generic parameters.
2931-
ArrayRef<OpaqueReturnTypeRepr *> getOpaqueReturnTypeReprs() const {
2931+
ArrayRef<TypeRepr *> getOpaqueReturnTypeReprs() const {
29322932
return {
2933-
getTrailingObjects<OpaqueReturnTypeRepr *>(),
2933+
getTrailingObjects<TypeRepr *>(),
29342934
getNumOpaqueReturnTypeReprs()
29352935
};
29362936
}
@@ -3163,7 +3163,7 @@ class AbstractTypeParamDecl : public TypeDecl {
31633163
/// \endcode
31643164
class GenericTypeParamDecl final :
31653165
public AbstractTypeParamDecl,
3166-
private llvm::TrailingObjects<GenericTypeParamDecl, OpaqueReturnTypeRepr *>{
3166+
private llvm::TrailingObjects<GenericTypeParamDecl, TypeRepr *>{
31673167
friend TrailingObjects;
31683168

31693169
size_t numTrailingObjects(OverloadToken<OpaqueReturnTypeRepr *>) const {
@@ -3180,7 +3180,7 @@ class GenericTypeParamDecl final :
31803180
/// \param nameLoc The location of the name.
31813181
GenericTypeParamDecl(DeclContext *dc, Identifier name, SourceLoc nameLoc,
31823182
bool isTypeSequence, unsigned depth, unsigned index,
3183-
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr);
3183+
bool isOpaqueType, TypeRepr *typeRepr);
31843184

31853185
public:
31863186
/// Construct a new generic type parameter.
@@ -3201,7 +3201,7 @@ class GenericTypeParamDecl final :
32013201
static GenericTypeParamDecl *
32023202
create(DeclContext *dc, Identifier name, SourceLoc nameLoc,
32033203
bool isTypeSequence, unsigned depth, unsigned index,
3204-
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr);
3204+
bool isOpaqueType, TypeRepr *typeRepr);
32053205

32063206
/// The depth of this generic type parameter, i.e., the number of outer
32073207
/// levels of generic parameter lists that enclose this type parameter.
@@ -3249,11 +3249,11 @@ class GenericTypeParamDecl final :
32493249
/// extension, meaning that it was specified explicitly
32503250
/// - the enclosing declaration was deserialized, in which case it lost
32513251
/// the source location information and has no type representation.
3252-
OpaqueReturnTypeRepr *getOpaqueTypeRepr() const {
3252+
TypeRepr *getOpaqueTypeRepr() const {
32533253
if (!isOpaqueType())
32543254
return nullptr;
32553255

3256-
return *getTrailingObjects<OpaqueReturnTypeRepr *>();
3256+
return *getTrailingObjects<TypeRepr *>();
32573257
}
32583258

32593259
/// The index of this generic type parameter within its generic parameter

include/swift/AST/TypeRepr.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ enum : unsigned { NumTypeReprKindBits =
4848
countBitsUsed(static_cast<unsigned>(TypeReprKind::Last_TypeRepr)) };
4949

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

5355
/// Representation of a type as written in source.
5456
class alignas(1 << TypeReprAlignInBits) TypeRepr
@@ -169,6 +171,10 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr
169171
/// `OpaqueReturnTypeRepr`s.
170172
CollectedOpaqueReprs collectOpaqueReturnTypeReprs();
171173

174+
/// Walk the type representation recursively, collecting any
175+
/// `CompositionTypeRepr`s and `IdentTypeRepr`s.
176+
CollectedOpaqueReprs collectTypeReprs();
177+
172178
/// Retrieve the type repr without any parentheses around it.
173179
///
174180
/// The use of this function must be restricted to contexts where
@@ -844,7 +850,7 @@ class TupleTypeRepr final : public TypeRepr,
844850
/// Foo & Bar
845851
/// \endcode
846852
class CompositionTypeRepr final : public TypeRepr,
847-
private llvm::TrailingObjects<CompositionTypeRepr, TypeRepr*> {
853+
private llvm::TrailingObjects<CompositionTypeRepr, TypeRepr*> {
848854
friend TrailingObjects;
849855
SourceLoc FirstTypeLoc;
850856
SourceRange CompositionRange;

lib/AST/Decl.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -4592,17 +4592,17 @@ AbstractTypeParamDecl::getConformingProtocols() const {
45924592
GenericTypeParamDecl::GenericTypeParamDecl(
45934593
DeclContext *dc, Identifier name, SourceLoc nameLoc,
45944594
bool isTypeSequence, unsigned depth, unsigned index,
4595-
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr
4595+
bool isOpaqueType, TypeRepr *typeRepr
45964596
) : AbstractTypeParamDecl(DeclKind::GenericTypeParam, dc, name, nameLoc) {
45974597
Bits.GenericTypeParamDecl.Depth = depth;
45984598
assert(Bits.GenericTypeParamDecl.Depth == depth && "Truncation");
45994599
Bits.GenericTypeParamDecl.Index = index;
46004600
assert(Bits.GenericTypeParamDecl.Index == index && "Truncation");
46014601
Bits.GenericTypeParamDecl.TypeSequence = isTypeSequence;
46024602
Bits.GenericTypeParamDecl.IsOpaqueType = isOpaqueType;
4603-
assert(isOpaqueType || !opaqueTypeRepr);
4603+
assert(isOpaqueType || !typeRepr);
46044604
if (isOpaqueType)
4605-
*getTrailingObjects<OpaqueReturnTypeRepr *>() = opaqueTypeRepr;
4605+
*getTrailingObjects<TypeRepr *>() = typeRepr;
46064606

46074607
auto &ctx = dc->getASTContext();
46084608
RecursiveTypeProperties props = RecursiveTypeProperties::HasTypeParameter;
@@ -4616,14 +4616,14 @@ GenericTypeParamDecl *
46164616
GenericTypeParamDecl::create(
46174617
DeclContext *dc, Identifier name, SourceLoc nameLoc,
46184618
bool isTypeSequence, unsigned depth, unsigned index,
4619-
bool isOpaqueType, OpaqueReturnTypeRepr *opaqueTypeRepr) {
4619+
bool isOpaqueType, TypeRepr *typeRepr) {
46204620
ASTContext &ctx = dc->getASTContext();
46214621
auto mem = ctx.Allocate(
4622-
totalSizeToAlloc<OpaqueReturnTypeRepr *>(isOpaqueType ? 1 : 0),
4622+
totalSizeToAlloc<TypeRepr *>(isOpaqueType ? 1 : 0),
46234623
alignof(GenericTypeParamDecl));
46244624
return new (mem) GenericTypeParamDecl(
46254625
dc, name, nameLoc, isTypeSequence, depth, index, isOpaqueType,
4626-
opaqueTypeRepr);
4626+
typeRepr);
46274627
}
46284628

46294629

@@ -8252,7 +8252,7 @@ void AbstractFunctionDecl::setParameters(ParameterList *BodyParams) {
82528252
OpaqueTypeDecl::OpaqueTypeDecl(ValueDecl *NamingDecl,
82538253
GenericParamList *GenericParams, DeclContext *DC,
82548254
GenericSignature OpaqueInterfaceGenericSignature,
8255-
ArrayRef<OpaqueReturnTypeRepr *>
8255+
ArrayRef<TypeRepr *>
82568256
OpaqueReturnTypeReprs)
82578257
: GenericTypeDecl(DeclKind::OpaqueType, DC, Identifier(), SourceLoc(), {},
82588258
GenericParams),
@@ -8269,16 +8269,16 @@ OpaqueTypeDecl::OpaqueTypeDecl(ValueDecl *NamingDecl,
82698269
OpaqueInterfaceGenericSignature.getInnermostGenericParams().size());
82708270
std::uninitialized_copy(
82718271
OpaqueReturnTypeReprs.begin(), OpaqueReturnTypeReprs.end(),
8272-
getTrailingObjects<OpaqueReturnTypeRepr *>());
8272+
getTrailingObjects<TypeRepr *>());
82738273
}
82748274

82758275
OpaqueTypeDecl *OpaqueTypeDecl::get(
82768276
ValueDecl *NamingDecl, GenericParamList *GenericParams,
82778277
DeclContext *DC,
82788278
GenericSignature OpaqueInterfaceGenericSignature,
8279-
ArrayRef<OpaqueReturnTypeRepr *> OpaqueReturnTypeReprs) {
8279+
ArrayRef<TypeRepr *> OpaqueReturnTypeReprs) {
82808280
ASTContext &ctx = DC->getASTContext();
8281-
auto size = totalSizeToAlloc<OpaqueReturnTypeRepr *>(
8281+
auto size = totalSizeToAlloc<TypeRepr *>(
82828282
OpaqueReturnTypeReprs.size());
82838283
auto mem = ctx.Allocate(size, alignof(OpaqueTypeDecl));
82848284
return new (mem) OpaqueTypeDecl(

lib/AST/NameLookup.cpp

+36-10
Original file line numberDiff line numberDiff line change
@@ -2764,6 +2764,19 @@ static bool declsAreAssociatedTypes(ArrayRef<TypeDecl *> decls) {
27642764
return true;
27652765
}
27662766

2767+
/// Whether there are only protocol decl types in the set of declarations.
2768+
static bool declsAreProtocols(ArrayRef<TypeDecl *> decls) {
2769+
if (decls.empty())
2770+
return false;
2771+
2772+
for (auto decl : decls) {
2773+
if (!isa<ProtocolDecl>(decl))
2774+
return false;
2775+
}
2776+
2777+
return true;
2778+
}
2779+
27672780
static GenericParamList *
27682781
createExtensionGenericParams(ASTContext &ctx,
27692782
ExtensionDecl *ext,
@@ -2789,6 +2802,7 @@ static SmallVector<GenericTypeParamDecl *, 2>
27892802
createOpaqueParameterGenericParams(
27902803
GenericContext *genericContext, GenericParamList *parsedGenericParams) {
27912804
ASTContext &ctx = genericContext->getASTContext();
2805+
27922806
auto value = dyn_cast_or_null<ValueDecl>(genericContext->getAsDecl());
27932807
if (!value)
27942808
return { };
@@ -2811,21 +2825,33 @@ createOpaqueParameterGenericParams(
28112825
if (!typeRepr)
28122826
continue;
28132827

2814-
auto opaqueTypeReprs = typeRepr->collectOpaqueReturnTypeReprs();
2815-
for (auto opaqueRepr : opaqueTypeReprs) {
2828+
// Plain protocols should imply 'some' with experimetal feature
2829+
CollectedOpaqueReprs typeReprs;
2830+
if (ctx.LangOpts.hasFeature(Feature::ImplicitSome)) {
2831+
typeReprs = typeRepr->collectTypeReprs();
2832+
} else { typeReprs = typeRepr->collectOpaqueReturnTypeReprs(); }
2833+
2834+
for (auto repr : typeReprs) {
2835+
if (isa<IdentTypeRepr>(repr)){
2836+
DirectlyReferencedTypeDecls d = directReferencesForTypeRepr(ctx.evaluator, ctx, repr, dc, true);
2837+
if(!declsAreProtocols(d))
2838+
continue;
2839+
}
28162840
// Allocate a new generic parameter to represent this opaque type.
2817-
auto gp = GenericTypeParamDecl::create(
2841+
auto gp = GenericTypeParamDecl::create(
28182842
dc, Identifier(), SourceLoc(), /*isTypeSequence=*/false,
28192843
GenericTypeParamDecl::InvalidDepth, index++, /*isOpaqueType=*/true,
2820-
opaqueRepr);
2821-
gp->setImplicit();
2844+
repr);
2845+
gp->setImplicit();
28222846

28232847
// Use the underlying constraint as the constraint on the generic parameter.
2824-
InheritedEntry inherited[1] = {
2825-
{ TypeLoc(opaqueRepr->getConstraint()) }
2826-
};
2827-
gp->setInherited(ctx.AllocateCopy(inherited));
2828-
2848+
// The underlying constraint is only present for OpaqueReturnTypeReprs
2849+
if( auto opaque = dyn_cast<OpaqueReturnTypeRepr>(repr)){
2850+
InheritedEntry inherited[1] = {
2851+
{ TypeLoc(opaque->getConstraint()) }
2852+
};
2853+
gp->setInherited(ctx.AllocateCopy(inherited));
2854+
}
28292855
implicitGenericParams.push_back(gp);
28302856
}
28312857
}

lib/AST/TypeRepr.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,30 @@ CollectedOpaqueReprs TypeRepr::collectOpaqueReturnTypeReprs() {
137137
return reprs;
138138
}
139139

140+
CollectedOpaqueReprs TypeRepr::collectTypeReprs() {
141+
class Walker : public ASTWalker {
142+
CollectedOpaqueReprs &Reprs;
143+
144+
public:
145+
explicit Walker(CollectedOpaqueReprs &reprs) : Reprs(reprs) {}
146+
147+
bool walkToTypeReprPre(TypeRepr *repr) override {
148+
if (auto opaqueRepr = dyn_cast<OpaqueReturnTypeRepr>(repr)){
149+
Reprs.push_back(opaqueRepr);
150+
} else if (auto compositionRepr = dyn_cast<CompositionTypeRepr>(repr)){
151+
Reprs.push_back(compositionRepr);
152+
} else if (auto identRepr = dyn_cast<IdentTypeRepr>(repr)){
153+
Reprs.push_back(identRepr);
154+
}
155+
return true;
156+
}
157+
};
158+
159+
CollectedOpaqueReprs reprs;
160+
walk(Walker(reprs));
161+
return reprs;
162+
}
163+
140164
SourceLoc TypeRepr::findUncheckedAttrLoc() const {
141165
auto typeRepr = this;
142166
while (auto attrTypeRepr = dyn_cast<AttributedTypeRepr>(typeRepr)) {

lib/Frontend/CompilerInvocation.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
686686
Opts.Features.insert(Feature::AdditiveArithmeticDerivedConformances);
687687
if (Args.hasArg(OPT_enable_experimental_opaque_type_erasure))
688688
Opts.Features.insert(Feature::OpaqueTypeErasure);
689-
if (Args.hasArg(OPT_enable_experimental_variadic_generics)){
689+
if (Args.hasArg(OPT_enable_experimental_implicit_some)){
690690
Opts.Features.insert(Feature::ImplicitSome);
691691
Opts.Features.insert(Feature::ExistentialAny);
692692
}

0 commit comments

Comments
 (0)