diff options
-rw-r--r-- | compiler/lineinfos.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 10 | ||||
-rw-r--r-- | doc/manual.md | 9 | ||||
-rw-r--r-- | tests/proc/t15949.nim | 16 |
4 files changed, 18 insertions, 19 deletions
diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 89aff57df..532478e4b 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -88,6 +88,7 @@ type warnUnnamedBreak = "UnnamedBreak", warnStmtListLambda = "StmtListLambda", warnBareExcept = "BareExcept", + warnImplicitDefaultValue = "ImplicitDefaultValue", warnUser = "User", # hints hintSuccess = "Success", hintSuccessX = "SuccessX", @@ -189,6 +190,7 @@ const warnUnnamedBreak: "Using an unnamed break in a block is deprecated; Use a named block with a named break instead", warnStmtListLambda: "statement list expression assumed to be anonymous proc; this is deprecated, use `do (): ...` or `proc () = ...` instead", warnBareExcept: "$1", + warnImplicitDefaultValue: "$1", warnUser: "$1", hintSuccess: "operation successful: $#", # keep in sync with `testament.isSuccess` diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index fbba4f36f..28ebe2398 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1311,6 +1311,16 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if hasDefault: def = a[^1] + if a.len > 3: + var msg = "" + for j in 0 ..< a.len - 2: + if msg.len != 0: msg.add(", ") + msg.add($a[j]) + msg.add(" all have default value '") + msg.add(def.renderTree) + msg.add("', this may be unintentional, " & + "either use ';' (semicolon) or explicitly write each default value") + message(c.config, a.info, warnImplicitDefaultValue, msg) block determineType: var defTyp = typ if genericParams != nil and genericParams.len > 0: diff --git a/doc/manual.md b/doc/manual.md index 850a04b0d..042773bcb 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -3816,15 +3816,6 @@ every time the function is called. proc foo(a: int, b: int = 47): int ``` -Just as the comma propagates the types from right to left until the -first parameter or until a semicolon is hit, it also propagates the -default value starting from the parameter declared with it. - - ```nim - # Both a and b are optional with 47 as their default values. - proc foo(a, b: int = 47): int - ``` - Parameters can be declared mutable and so allow the proc to modify those arguments, by using the type modifier `var`. diff --git a/tests/proc/t15949.nim b/tests/proc/t15949.nim index bc3fddc84..6467ed5d3 100644 --- a/tests/proc/t15949.nim +++ b/tests/proc/t15949.nim @@ -1,14 +1,9 @@ -# bug #15949 +# bug #15949 and RFC #480 -discard """ -errormsg: "parameter 'a' requires a type" -nimout: ''' -t15949.nim(20, 14) Error: parameter 'a' requires a type''' -""" +proc procWarn(a, b = 1): (int, int) = (a, b) #[tt.Warning + ^ a, b all have default value '1', this may be unintentional, either use ';' (semicolon) or explicitly write each default value [ImplicitDefaultValue]]# - -# line 10 -proc procGood(a, b = 1): (int, int) = (a, b) +proc procGood(a = 1, b = 1): (int, int) = (a, b) doAssert procGood() == (1, 1) doAssert procGood(b = 3) == (1, 3) @@ -17,4 +12,5 @@ doAssert procGood(a = 5, b = 6) == (5, 6) # The type (and default value propagation breaks in the below example # as semicolon is used instead of comma. -proc procBad(a; b = 1): (int, int) = (a, b) +proc procBad(a; b = 1): (int, int) = (a, b) #[tt.Error + ^ parameter 'a' requires a type]# |