@@ -384,6 +384,21 @@ static Type getAdjustedParamType(const AnyFunctionType::Param ¶m) {
384
384
return param.getType ();
385
385
}
386
386
387
+ // Is a particular parameter of a function or subscript declaration
388
+ // declared to be an IUO?
389
+ static bool paramIsIUO (Decl *decl, int paramNum) {
390
+ if (auto *fn = dyn_cast<AbstractFunctionDecl>(decl)) {
391
+ auto *paramList =
392
+ fn->getParameterList (fn->getDeclContext ()->isTypeContext ());
393
+ auto *param = paramList->get (paramNum);
394
+ return param->getAttrs ().hasAttribute <ImplicitlyUnwrappedOptionalAttr>();
395
+ }
396
+
397
+ auto *subscript = cast<SubscriptDecl>(decl);
398
+ auto *index = subscript->getIndices ()->get (paramNum);
399
+ return index->getAttrs ().hasAttribute <ImplicitlyUnwrappedOptionalAttr>();
400
+ }
401
+
387
402
// / \brief Determine whether the first declaration is as "specialized" as
388
403
// / the second declaration.
389
404
// /
@@ -676,6 +691,17 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc,
676
691
continue ;
677
692
}
678
693
694
+ // Emulate behavior from when IUO was a type, where IUOs
695
+ // were considered subtypes of plain optionals, but not
696
+ // vice-versa. This wouldn't normally happen, but there are
697
+ // cases where we can rename imported APIs so that we have a
698
+ // name collision, and where the parameter type(s) are the
699
+ // same except for details of the kind of optional declared.
700
+ auto param1IsIUO = paramIsIUO (decl1, param1);
701
+ auto param2IsIUO = paramIsIUO (decl2, param2);
702
+ if (param2IsIUO && !param1IsIUO)
703
+ return false ;
704
+
679
705
if (!maybeAddSubtypeConstraint (params1[param1], params2[param2]))
680
706
return false ;
681
707
0 commit comments