@@ -4196,8 +4196,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4196
4196
4197
4197
// / Return type if the result type if \p VD should be represented as opaque
4198
4198
// / result type.
4199
- TypeLoc getOpaqueResultTypeLoc (const ValueDecl *VD, DeclVisibilityKind Reason,
4200
- DynamicLookupInfo dynamicLookupInfo) {
4199
+ Type getOpaqueResultType (const ValueDecl *VD, DeclVisibilityKind Reason,
4200
+ DynamicLookupInfo dynamicLookupInfo) {
4201
4201
if (Reason !=
4202
4202
DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal)
4203
4203
return nullptr ;
@@ -4207,50 +4207,76 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4207
4207
return nullptr ;
4208
4208
4209
4209
Type ResultT;
4210
- if (auto *FD = dyn_cast<FuncDecl>(VD))
4210
+ if (auto *FD = dyn_cast<FuncDecl>(VD)) {
4211
+ if (FD->getGenericParams ()) {
4212
+ // Generic function cannot have opaque result type.
4213
+ return nullptr ;
4214
+ }
4211
4215
ResultT = FD->getResultInterfaceType ();
4212
- else if (auto *SD = dyn_cast<SubscriptDecl>(VD))
4216
+ } else if (auto *SD = dyn_cast<SubscriptDecl>(VD)) {
4217
+ if (SD->getGenericParams ()) {
4218
+ // Generic subscript cannot have opaque result type.
4219
+ return nullptr ;
4220
+ }
4213
4221
ResultT = SD->getElementInterfaceType ();
4214
- else if (auto *VarD = dyn_cast<VarDecl>(VD))
4222
+ } else if (auto *VarD = dyn_cast<VarDecl>(VD)) {
4215
4223
ResultT = VarD->getInterfaceType ();
4216
- else
4217
- return nullptr ;
4218
-
4219
- if (!ResultT->is <DependentMemberType>())
4220
- // The result is not associatedtype.
4224
+ } else {
4221
4225
return nullptr ;
4226
+ }
4222
4227
4223
- // If associatedtype doesn't have conformance/superclass constraint, we
4224
- // can't use opaque type.
4225
- auto assocTyD = ResultT->castTo <DependentMemberType>()->getAssocType ();
4226
- if (!assocTyD->getInherited ().size ())
4228
+ if (!ResultT->is <DependentMemberType>() ||
4229
+ !ResultT->castTo <DependentMemberType>()->getAssocType ())
4230
+ // The result is not a valid associatedtype.
4227
4231
return nullptr ;
4228
4232
4229
4233
// Try substitution to see if the associated type is resolved to concrete
4230
4234
// type.
4231
4235
auto substMap = currTy->getMemberSubstitutionMap (
4232
4236
CurrDeclContext->getParentModule (), VD);
4233
- ResultT = ResultT.subst (substMap);
4234
- if (!ResultT || !ResultT->is <DependentMemberType>())
4237
+ if (!ResultT.subst (substMap)->is <DependentMemberType>())
4235
4238
// If resolved print it.
4236
4239
return nullptr ;
4237
4240
4238
- return assocTyD->getInherited ()[0 ];
4241
+ auto genericSig = VD->getDeclContext ()->getGenericSignatureOfContext ();
4242
+
4243
+ if (genericSig->isConcreteType (ResultT))
4244
+ // If it has same type requrement, we will emit the concrete type.
4245
+ return nullptr ;
4246
+
4247
+ // Collect requirements on the associatedtype.
4248
+ SmallVector<Type, 2 > opaqueTypes;
4249
+ bool hasExplicitAnyObject = false ;
4250
+ if (auto superTy = genericSig->getSuperclassBound (ResultT))
4251
+ opaqueTypes.push_back (superTy);
4252
+ for (auto proto : genericSig->getConformsTo (ResultT))
4253
+ opaqueTypes.push_back (proto->getDeclaredInterfaceType ());
4254
+ if (auto layout = genericSig->getLayoutConstraint (ResultT))
4255
+ hasExplicitAnyObject = layout->isClass ();
4256
+
4257
+ if (!hasExplicitAnyObject) {
4258
+ if (opaqueTypes.empty ())
4259
+ return nullptr ;
4260
+ if (opaqueTypes.size () == 1 )
4261
+ return opaqueTypes.front ();
4262
+ }
4263
+ return ProtocolCompositionType::get (
4264
+ VD->getASTContext (), opaqueTypes, hasExplicitAnyObject);
4239
4265
}
4240
4266
4241
4267
void addValueOverride (const ValueDecl *VD, DeclVisibilityKind Reason,
4242
4268
DynamicLookupInfo dynamicLookupInfo,
4243
4269
CodeCompletionResultBuilder &Builder,
4244
4270
bool hasDeclIntroducer) {
4245
4271
class DeclPrinter : public StreamPrinter {
4246
- TypeLoc OpaqueBaseTy;
4272
+ Type OpaqueBaseTy;
4247
4273
4248
4274
public:
4249
4275
using StreamPrinter::StreamPrinter;
4250
4276
4251
4277
Optional<unsigned > NameOffset;
4252
4278
4253
- DeclPrinter (raw_ostream &OS, TypeLoc OpaqueBaseTy)
4279
+ DeclPrinter (raw_ostream &OS, Type OpaqueBaseTy)
4254
4280
: StreamPrinter(OS), OpaqueBaseTy(OpaqueBaseTy) {}
4255
4281
4256
4282
void printDeclLoc (const Decl *D) override {
@@ -4262,7 +4288,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4262
4288
void printDeclResultTypePre (ValueDecl *VD, TypeLoc &TL) override {
4263
4289
if (!OpaqueBaseTy.isNull ()) {
4264
4290
OS << " some " ;
4265
- TL = OpaqueBaseTy;
4291
+ TL = TypeLoc::withoutLoc ( OpaqueBaseTy) ;
4266
4292
}
4267
4293
}
4268
4294
};
@@ -4272,7 +4298,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
4272
4298
{
4273
4299
llvm::raw_svector_ostream OS (DeclStr);
4274
4300
DeclPrinter Printer (
4275
- OS, getOpaqueResultTypeLoc (VD, Reason, dynamicLookupInfo));
4301
+ OS, getOpaqueResultType (VD, Reason, dynamicLookupInfo));
4276
4302
PrintOptions Options;
4277
4303
if (auto transformType = CurrDeclContext->getDeclaredTypeInContext ())
4278
4304
Options.setBaseType (transformType);
0 commit comments