Skip to content

Commit 7ffb1a4

Browse files
authored
Merge pull request #13302 from rudkx/iuo-attr-on-param-decl
IUO: Add the IUO attr to function parameters declared with '!'
2 parents 72948ca + c23dd44 commit 7ffb1a4

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

include/swift/AST/Attr.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ SIMPLE_DECL_ATTR(_downgrade_exhaustivity_check, DowngradeExhaustivityCheck,
295295

296296
SIMPLE_DECL_ATTR(_implicitly_unwrapped_optional,
297297
ImplicitlyUnwrappedOptional,
298-
OnFunc | OnVar | OnSubscript | OnConstructor | RejectByParser, 72)
298+
OnFunc | OnVar | OnParam | OnSubscript | OnConstructor
299+
| RejectByParser, 72)
299300

300301
DECL_ATTR(_optimize, Optimize,
301302
OnFunc | OnConstructor | OnDestructor | OnSubscript | OnVar |

lib/Sema/TypeCheckPattern.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -719,20 +719,33 @@ static bool validateParameterType(ParamDecl *decl, DeclContext *DC,
719719

720720
bool hadError = false;
721721

722+
auto &TL = decl->getTypeLoc();
723+
722724
// We might have a null typeLoc if this is a closure parameter list,
723725
// where parameters are allowed to elide their types.
724-
if (!decl->getTypeLoc().isNull()) {
725-
hadError |= TC.validateType(decl->getTypeLoc(), DC,
726+
if (!TL.isNull()) {
727+
hadError |= TC.validateType(TL, DC,
726728
elementOptions, &resolver);
727729
}
728730

729-
Type Ty = decl->getTypeLoc().getType();
731+
// If this is declared with '!' indicating that it is an Optional
732+
// that we should implicitly unwrap if doing so is required to type
733+
// check, then add an attribute to the decl.
734+
if (elementOptions.contains(TypeResolutionFlags::AllowIUO)
735+
&& TL.getTypeRepr() && TL.getTypeRepr()->getKind() ==
736+
TypeReprKind::ImplicitlyUnwrappedOptional) {
737+
auto &C = DC->getASTContext();
738+
decl->getAttrs().add(
739+
new (C) ImplicitlyUnwrappedOptionalAttr(/* implicit= */ true));
740+
}
741+
742+
Type Ty = TL.getType();
730743
if (decl->isVariadic() && !Ty.isNull() && !hadError) {
731744
Ty = TC.getArraySliceType(decl->getStartLoc(), Ty);
732745
if (Ty.isNull()) {
733746
hadError = true;
734747
}
735-
decl->getTypeLoc().setType(Ty);
748+
TL.setType(Ty);
736749
}
737750

738751
// If the user did not explicitly write 'let', 'var', or 'inout', we'll let
@@ -751,7 +764,7 @@ static bool validateParameterType(ParamDecl *decl, DeclContext *DC,
751764
}
752765

753766
if (hadError)
754-
decl->getTypeLoc().setType(ErrorType::get(TC.Context), /*validated*/true);
767+
TL.setType(ErrorType::get(TC.Context), /*validated*/true);
755768

756769
return hadError;
757770
}

0 commit comments

Comments
 (0)