@@ -4159,8 +4159,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4159
4159
4160
4160
// / Return type if the result type if \p VD should be represented as opaque
4161
4161
// / result type.
4162
- TypeLoc getOpaqueResultTypeLoc (const ValueDecl *VD, DeclVisibilityKind Reason,
4163
- DynamicLookupInfo dynamicLookupInfo) {
4162
+ Type getOpaqueResultType (const ValueDecl *VD, DeclVisibilityKind Reason,
4163
+ DynamicLookupInfo dynamicLookupInfo) {
4164
4164
if (Reason !=
4165
4165
DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal)
4166
4166
return nullptr ;
@@ -4170,50 +4170,76 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4170
4170
return nullptr ;
4171
4171
4172
4172
Type ResultT;
4173
- if (auto *FD = dyn_cast<FuncDecl>(VD))
4173
+ if (auto *FD = dyn_cast<FuncDecl>(VD)) {
4174
+ if (FD->getGenericParams ()) {
4175
+ // Generic function cannot have opaque result type.
4176
+ return nullptr ;
4177
+ }
4174
4178
ResultT = FD->getResultInterfaceType ();
4175
- else if (auto *SD = dyn_cast<SubscriptDecl>(VD))
4179
+ } else if (auto *SD = dyn_cast<SubscriptDecl>(VD)) {
4180
+ if (SD->getGenericParams ()) {
4181
+ // Generic subscript cannot have opaque result type.
4182
+ return nullptr ;
4183
+ }
4176
4184
ResultT = SD->getElementInterfaceType ();
4177
- else if (auto *VarD = dyn_cast<VarDecl>(VD))
4185
+ } else if (auto *VarD = dyn_cast<VarDecl>(VD)) {
4178
4186
ResultT = VarD->getInterfaceType ();
4179
- else
4180
- return nullptr ;
4181
-
4182
- if (!ResultT->is <DependentMemberType>())
4183
- // The result is not associatedtype.
4187
+ } else {
4184
4188
return nullptr ;
4189
+ }
4185
4190
4186
- // If associatedtype doesn't have conformance/superclass constraint, we
4187
- // can't use opaque type.
4188
- auto assocTyD = ResultT->castTo <DependentMemberType>()->getAssocType ();
4189
- if (!assocTyD->getInherited ().size ())
4191
+ if (!ResultT->is <DependentMemberType>() ||
4192
+ !ResultT->castTo <DependentMemberType>()->getAssocType ())
4193
+ // The result is not a valid associatedtype.
4190
4194
return nullptr ;
4191
4195
4192
4196
// Try substitution to see if the associated type is resolved to concrete
4193
4197
// type.
4194
4198
auto substMap = currTy->getMemberSubstitutionMap (
4195
4199
CurrDeclContext->getParentModule (), VD);
4196
- ResultT = ResultT.subst (substMap);
4197
- if (!ResultT || !ResultT->is <DependentMemberType>())
4200
+ if (!ResultT.subst (substMap)->is <DependentMemberType>())
4198
4201
// If resolved print it.
4199
4202
return nullptr ;
4200
4203
4201
- return assocTyD->getInherited ()[0 ];
4204
+ auto genericSig = VD->getDeclContext ()->getGenericSignatureOfContext ();
4205
+
4206
+ if (genericSig->isConcreteType (ResultT))
4207
+ // If it has same type requrement, we will emit the concrete type.
4208
+ return nullptr ;
4209
+
4210
+ // Collect requirements on the associatedtype.
4211
+ SmallVector<Type, 2 > opaqueTypes;
4212
+ bool hasExplicitAnyObject = false ;
4213
+ if (auto superTy = genericSig->getSuperclassBound (ResultT))
4214
+ opaqueTypes.push_back (superTy);
4215
+ for (auto proto : genericSig->getConformsTo (ResultT))
4216
+ opaqueTypes.push_back (proto->getDeclaredInterfaceType ());
4217
+ if (auto layout = genericSig->getLayoutConstraint (ResultT))
4218
+ hasExplicitAnyObject = layout->isClass ();
4219
+
4220
+ if (!hasExplicitAnyObject) {
4221
+ if (opaqueTypes.empty ())
4222
+ return nullptr ;
4223
+ if (opaqueTypes.size () == 1 )
4224
+ return opaqueTypes.front ();
4225
+ }
4226
+ return ProtocolCompositionType::get (
4227
+ VD->getASTContext (), opaqueTypes, hasExplicitAnyObject);
4202
4228
}
4203
4229
4204
4230
void addValueOverride (const ValueDecl *VD, DeclVisibilityKind Reason,
4205
4231
DynamicLookupInfo dynamicLookupInfo,
4206
4232
CodeCompletionResultBuilder &Builder,
4207
4233
bool hasDeclIntroducer) {
4208
4234
class DeclPrinter : public StreamPrinter {
4209
- TypeLoc OpaqueBaseTy;
4235
+ Type OpaqueBaseTy;
4210
4236
4211
4237
public:
4212
4238
using StreamPrinter::StreamPrinter;
4213
4239
4214
4240
Optional<unsigned > NameOffset;
4215
4241
4216
- DeclPrinter (raw_ostream &OS, TypeLoc OpaqueBaseTy)
4242
+ DeclPrinter (raw_ostream &OS, Type OpaqueBaseTy)
4217
4243
: StreamPrinter(OS), OpaqueBaseTy(OpaqueBaseTy) {}
4218
4244
4219
4245
void printDeclLoc (const Decl *D) override {
@@ -4225,7 +4251,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4225
4251
void printDeclResultTypePre (ValueDecl *VD, TypeLoc &TL) override {
4226
4252
if (!OpaqueBaseTy.isNull ()) {
4227
4253
OS << " some " ;
4228
- TL = OpaqueBaseTy;
4254
+ TL = TypeLoc::withoutLoc ( OpaqueBaseTy) ;
4229
4255
}
4230
4256
}
4231
4257
};
@@ -4235,7 +4261,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4235
4261
{
4236
4262
llvm::raw_svector_ostream OS (DeclStr);
4237
4263
DeclPrinter Printer (
4238
- OS, getOpaqueResultTypeLoc (VD, Reason, dynamicLookupInfo));
4264
+ OS, getOpaqueResultType (VD, Reason, dynamicLookupInfo));
4239
4265
PrintOptions Options;
4240
4266
if (auto transformType = CurrDeclContext->getDeclaredTypeInContext ())
4241
4267
Options.setBaseType (transformType);
0 commit comments