@@ -4159,8 +4159,8 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
41594159
41604160 // / Return type if the result type if \p VD should be represented as opaque
41614161 // / result type.
4162- TypeLoc getOpaqueResultTypeLoc (const ValueDecl *VD, DeclVisibilityKind Reason,
4163- DynamicLookupInfo dynamicLookupInfo) {
4162+ Type getOpaqueResultType (const ValueDecl *VD, DeclVisibilityKind Reason,
4163+ DynamicLookupInfo dynamicLookupInfo) {
41644164 if (Reason !=
41654165 DeclVisibilityKind::MemberOfProtocolImplementedByCurrentNominal)
41664166 return nullptr ;
@@ -4170,50 +4170,76 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
41704170 return nullptr ;
41714171
41724172 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+ }
41744178 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+ }
41764184 ResultT = SD->getElementInterfaceType ();
4177- else if (auto *VarD = dyn_cast<VarDecl>(VD))
4185+ } else if (auto *VarD = dyn_cast<VarDecl>(VD)) {
41784186 ResultT = VarD->getInterfaceType ();
4179- else
4180- return nullptr ;
4181-
4182- if (!ResultT->is <DependentMemberType>())
4183- // The result is not associatedtype.
4187+ } else {
41844188 return nullptr ;
4189+ }
41854190
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.
41904194 return nullptr ;
41914195
41924196 // Try substitution to see if the associated type is resolved to concrete
41934197 // type.
41944198 auto substMap = currTy->getMemberSubstitutionMap (
41954199 CurrDeclContext->getParentModule (), VD);
4196- ResultT = ResultT.subst (substMap);
4197- if (!ResultT || !ResultT->is <DependentMemberType>())
4200+ if (!ResultT.subst (substMap)->is <DependentMemberType>())
41984201 // If resolved print it.
41994202 return nullptr ;
42004203
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);
42024228 }
42034229
42044230 void addValueOverride (const ValueDecl *VD, DeclVisibilityKind Reason,
42054231 DynamicLookupInfo dynamicLookupInfo,
42064232 CodeCompletionResultBuilder &Builder,
42074233 bool hasDeclIntroducer) {
42084234 class DeclPrinter : public StreamPrinter {
4209- TypeLoc OpaqueBaseTy;
4235+ Type OpaqueBaseTy;
42104236
42114237 public:
42124238 using StreamPrinter::StreamPrinter;
42134239
42144240 Optional<unsigned > NameOffset;
42154241
4216- DeclPrinter (raw_ostream &OS, TypeLoc OpaqueBaseTy)
4242+ DeclPrinter (raw_ostream &OS, Type OpaqueBaseTy)
42174243 : StreamPrinter(OS), OpaqueBaseTy(OpaqueBaseTy) {}
42184244
42194245 void printDeclLoc (const Decl *D) override {
@@ -4225,7 +4251,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
42254251 void printDeclResultTypePre (ValueDecl *VD, TypeLoc &TL) override {
42264252 if (!OpaqueBaseTy.isNull ()) {
42274253 OS << " some " ;
4228- TL = OpaqueBaseTy;
4254+ TL = TypeLoc::withoutLoc ( OpaqueBaseTy) ;
42294255 }
42304256 }
42314257 };
@@ -4235,7 +4261,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
42354261 {
42364262 llvm::raw_svector_ostream OS (DeclStr);
42374263 DeclPrinter Printer (
4238- OS, getOpaqueResultTypeLoc (VD, Reason, dynamicLookupInfo));
4264+ OS, getOpaqueResultType (VD, Reason, dynamicLookupInfo));
42394265 PrintOptions Options;
42404266 if (auto transformType = CurrDeclContext->getDeclaredTypeInContext ())
42414267 Options.setBaseType (transformType);
0 commit comments