Skip to content

Commit 3d2b5bc

Browse files
committed
Implement SE-0066 - Standardize function type argument syntax to require parentheses
For now, we'll keep this as a warning to allow projects to adapt.
1 parent 8c1c0be commit 3d2b5bc

File tree

4 files changed

+39
-6
lines changed

4 files changed

+39
-6
lines changed

include/swift/AST/DiagnosticsSema.def

+2
Original file line numberDiff line numberDiff line change
@@ -2574,6 +2574,8 @@ ERROR(objc_invalid_with_generic_params,none,
25742574
ERROR(objc_convention_invalid,none,
25752575
"%0 is not representable in Objective-C, so it cannot be used"
25762576
" with '@convention(%1)'", (Type, StringRef))
2577+
WARNING(function_type_no_parens,none,
2578+
"single argument function types require parentheses", ())
25772579
NOTE(not_objc_empty_protocol_composition,none,
25782580
"'protocol<>' is not considered '@objc'; use 'AnyObject' instead", ())
25792581
NOTE(not_objc_protocol,none,

include/swift/AST/TypeRepr.h

+13-2
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,22 @@ class alignas(8) TypeRepr {
4646
void operator=(const TypeRepr&) = delete;
4747

4848
/// \brief The subclass of TypeRepr that this is.
49-
unsigned Kind : 7;
49+
unsigned Kind : 6;
5050

5151
/// Whether this type representation is known to contain an invalid
5252
/// type.
5353
unsigned Invalid : 1;
5454

55+
/// Whether this type representation had a warning emitted related to it.
56+
/// This is a hack related to how we resolve type exprs multiple times in
57+
/// generic contexts.
58+
unsigned Warned : 1;
59+
5560
SourceLoc getLocImpl() const { return getStartLoc(); }
5661

5762
protected:
58-
TypeRepr(TypeReprKind K) : Kind(static_cast<unsigned>(K)), Invalid(false) {}
63+
TypeRepr(TypeReprKind K)
64+
: Kind(static_cast<unsigned>(K)), Invalid(false), Warned(false) {}
5965

6066
public:
6167
TypeReprKind getKind() const { return static_cast<TypeReprKind>(Kind); }
@@ -66,6 +72,11 @@ class alignas(8) TypeRepr {
6672
/// Note that this type representation describes an invalid type.
6773
void setInvalid() { Invalid = true; }
6874

75+
/// If a warning is produced about this type repr, keep track of that so we
76+
/// don't emit another one upon further reanalysis.
77+
bool isWarnedAbout() const { return Warned; }
78+
void setWarned() { Warned = true; }
79+
6980
/// Get the representative location for pointing at this type.
7081
SourceLoc getLoc() const;
7182

lib/Sema/TypeCheckType.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -1341,10 +1341,11 @@ Type TypeChecker::resolveIdentifierType(
13411341
return result;
13421342
}
13431343

1344-
// Returns true if any illegal IUOs were found. If inference of IUO type is disabled, IUOs may only be specified in the following positions:
1345-
// * outermost type
1346-
// * function param
1347-
// * function return type
1344+
/// Returns true if any illegal IUOs were found. If inference of IUO type is
1345+
/// disabled, IUOs may only be specified in the following positions:
1346+
/// * outermost type
1347+
/// * function param
1348+
/// * function return type
13481349
static bool checkForIllegalIUOs(TypeChecker &TC, TypeRepr *Repr,
13491350
TypeResolutionOptions Options) {
13501351
class IllegalIUOWalker : public ASTWalker {
@@ -1889,6 +1890,20 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr,
18891890
extInfo = extInfo.withThrows(repr->throws());
18901891

18911892
ModuleDecl *M = DC->getParentModule();
1893+
1894+
1895+
// If this is a function type without parens around the parameter list,
1896+
// diagnose this and produce a fixit to add them.
1897+
if (!isa<TupleTypeRepr>(repr->getArgsTypeRepr()) &&
1898+
!repr->isWarnedAbout()) {
1899+
auto args = repr->getArgsTypeRepr();
1900+
TC.diagnose(args->getStartLoc(), diag::function_type_no_parens)
1901+
.highlight(args->getSourceRange())
1902+
.fixItInsert(args->getStartLoc(), "(")
1903+
.fixItInsertAfter(args->getEndLoc(), ")");
1904+
// Don't emit this warning three times when in generics.
1905+
repr->setWarned();
1906+
}
18921907

18931908
// SIL uses polymorphic function types to resolve overloaded member functions.
18941909
if (auto genericParams = repr->getGenericParams()) {

test/type/types.swift

+5
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,8 @@ class r21949448 {
155155
var myArray: inout [Int] = [] // expected-error {{'inout' is only valid in parameter lists}}
156156
}
157157

158+
// SE-0066 - Standardize function type argument syntax to require parentheses
159+
let _ : Int -> Float // expected-warning {{single argument function types require parentheses}} {{9-9=(}} {{12-12=)}}
160+
161+
162+

0 commit comments

Comments
 (0)