@@ -313,31 +313,15 @@ void TypeChecker::checkProtocolSelfRequirements(ValueDecl *decl) {
313313 }
314314}
315315
316- // / All generic parameters of a generic function must be referenced in the
317- // / declaration's type, otherwise we have no way to infer them.
318- void TypeChecker::checkReferencedGenericParams (GenericContext *dc) {
319- // Don't do this check for accessors: they're not used directly, so we
320- // never need to infer their generic arguments. This is mostly a
321- // compile-time optimization, but it also avoids problems with accessors
322- // like 'read' and 'modify' that would arise due to yields not being
323- // part of the formal type.
324- if (isa<AccessorDecl>(dc))
325- return ;
326-
327- auto *genericParams = dc->getGenericParams ();
328- auto genericSig = dc->getGenericSignatureOfContext ();
329- if (!genericParams)
330- return ;
331-
332- auto *decl = cast<ValueDecl>(dc->getInnermostDeclarationDeclContext ());
316+ void TypeChecker::collectReferencedGenericParams (Type ty, SmallPtrSet<CanType, 4 > &referenced) {
333317
334318 // A helper class to collect referenced generic type parameters
335319 // and dependent member types.
336320 class ReferencedGenericTypeWalker : public TypeWalker {
337- SmallPtrSet<CanType, 4 > ReferencedGenericParams;
321+ SmallPtrSet<CanType, 4 > & ReferencedGenericParams;
338322
339323 public:
340- ReferencedGenericTypeWalker () {}
324+ ReferencedGenericTypeWalker (SmallPtrSet<CanType, 4 > &referenced) : ReferencedGenericParams(referenced ) {}
341325 Action walkToTypePre (Type ty) override {
342326 // Find generic parameters or dependent member types.
343327 // Once such a type is found, don't recurse into its children.
@@ -368,24 +352,39 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
368352
369353 return Action::Continue;
370354 }
371-
372- SmallPtrSetImpl<CanType> &getReferencedGenericParams () {
373- return ReferencedGenericParams;
374- }
375355 };
376356
357+ ty.walk (ReferencedGenericTypeWalker (referenced));
358+ }
359+
360+ // / All generic parameters of a generic function must be referenced in the
361+ // / declaration's type, otherwise we have no way to infer them.
362+ void TypeChecker::checkReferencedGenericParams (GenericContext *dc) {
363+ // Don't do this check for accessors: they're not used directly, so we
364+ // never need to infer their generic arguments. This is mostly a
365+ // compile-time optimization, but it also avoids problems with accessors
366+ // like 'read' and 'modify' that would arise due to yields not being
367+ // part of the formal type.
368+ if (isa<AccessorDecl>(dc))
369+ return ;
370+
371+ auto *genericParams = dc->getGenericParams ();
372+ auto genericSig = dc->getGenericSignatureOfContext ();
373+ if (!genericParams)
374+ return ;
375+
376+ auto *decl = cast<ValueDecl>(dc->getInnermostDeclarationDeclContext ());
377+
378+ // Set of generic params referenced in parameter types,
379+ // return type or requirements.
380+ SmallPtrSet<CanType, 4 > referencedGenericParams;
381+
377382 // Collect all generic params referenced in parameter types and
378383 // return type.
379- ReferencedGenericTypeWalker paramsAndResultWalker;
380384 auto *funcTy = decl->getInterfaceType ()->castTo <GenericFunctionType>();
381385 for (const auto ¶m : funcTy->getParams ())
382- param.getPlainType ().walk (paramsAndResultWalker);
383- funcTy->getResult ().walk (paramsAndResultWalker);
384-
385- // Set of generic params referenced in parameter types,
386- // return type or requirements.
387- auto &referencedGenericParams =
388- paramsAndResultWalker.getReferencedGenericParams ();
386+ collectReferencedGenericParams (param.getPlainType (), referencedGenericParams);
387+ collectReferencedGenericParams (funcTy->getResult (), referencedGenericParams);
389388
390389 // Check if at least one of the generic params in the requirement refers
391390 // to an already referenced generic parameter. If this is the case,
@@ -409,13 +408,11 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
409408 }
410409
411410 // Collect generic parameter types referenced by types used in a requirement.
412- ReferencedGenericTypeWalker walker ;
411+ SmallPtrSet<CanType, 4 > genericParamsUsedByRequirementTypes ;
413412 if (first && first->hasTypeParameter ())
414- first. walk (walker );
413+ collectReferencedGenericParams (first, genericParamsUsedByRequirementTypes );
415414 if (second && second->hasTypeParameter ())
416- second.walk (walker);
417- auto &genericParamsUsedByRequirementTypes =
418- walker.getReferencedGenericParams ();
415+ collectReferencedGenericParams (second, genericParamsUsedByRequirementTypes);
419416
420417 // If at least one of the collected generic types or a root generic
421418 // parameter of dependent member types is known to be referenced by
0 commit comments