Skip to content

Commit 751f0e8

Browse files
committed
Fix var-parameter detection for inferred params
Previously, we would skip validating the type (and checking var/inout) on parameters that didn't have an explicit type. Instead, teach validateParameterType how to handle an elided type.
1 parent 36b8dc2 commit 751f0e8

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

lib/Sema/TypeCheckPattern.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -745,11 +745,17 @@ static bool validateParameterType(ParamDecl *decl, DeclContext *DC,
745745
auto elementOptions = (options |
746746
(decl->isVariadic() ? TR_VariadicFunctionInput
747747
: TR_FunctionInput));
748-
bool hadError = TC.validateType(decl->getTypeLoc(), DC,
749-
elementOptions, resolver);
750-
748+
bool hadError = false;
749+
750+
// We might have a null typeLoc if this is a closure parameter list,
751+
// where parameters are allowed to elide their types.
752+
if (!decl->getTypeLoc().isNull()) {
753+
hadError |= TC.validateType(decl->getTypeLoc(), DC,
754+
elementOptions, resolver);
755+
}
756+
751757
Type Ty = decl->getTypeLoc().getType();
752-
if (decl->isVariadic() && !hadError) {
758+
if (decl->isVariadic() && !Ty.isNull() && !hadError) {
753759
Ty = TC.getArraySliceType(decl->getStartLoc(), Ty);
754760
if (Ty.isNull()) {
755761
hadError = true;
@@ -759,7 +765,7 @@ static bool validateParameterType(ParamDecl *decl, DeclContext *DC,
759765
// If the param is not a 'let' and it is not an 'inout'.
760766
// It must be a 'var'. Provide helpful diagnostics like a shadow copy
761767
// in the function body to fix the 'var' attribute.
762-
if (!decl->isLet() && !Ty->is<InOutType>() && !hadError) {
768+
if (!decl->isLet() && (Ty.isNull() || !Ty->is<InOutType>()) && !hadError) {
763769
auto func = dyn_cast_or_null<AbstractFunctionDecl>(DC);
764770
diagnoseAndMigrateVarParameterToBody(decl, func, TC);
765771
decl->setInvalid();
@@ -768,7 +774,7 @@ static bool validateParameterType(ParamDecl *decl, DeclContext *DC,
768774

769775
if (hadError)
770776
decl->getTypeLoc().setType(ErrorType::get(TC.Context), /*validated*/true);
771-
777+
772778
return hadError;
773779
}
774780

@@ -779,8 +785,7 @@ bool TypeChecker::typeCheckParameterList(ParameterList *PL, DeclContext *DC,
779785
bool hadError = false;
780786

781787
for (auto param : *PL) {
782-
if (param->getTypeLoc().getTypeRepr())
783-
hadError |= validateParameterType(param, DC, options, resolver, *this);
788+
hadError |= validateParameterType(param, DC, options, resolver, *this);
784789

785790
auto type = param->getTypeLoc().getType();
786791
if (!type && param->hasType()) {

test/Sema/immutability.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,9 @@ func invalid_inout(inout var x : Int) { // expected-error {{parameter may not ha
351351
func invalid_var(var x: Int) { // expected-error {{parameters may not have the 'var' specifier}}{{18-21=}} {{1-1= var x = x\n}}
352352

353353
}
354-
354+
func takesClosure(_: (Int) -> Int) {
355+
takesClosure { (var d) in d } // expected-error {{parameters may not have the 'var' specifier}}
356+
}
355357

356358
func updateInt(_ x : inout Int) {}
357359

0 commit comments

Comments
 (0)