From 7dc2fd9995852c55c4c3092296728347030bff5c Mon Sep 17 00:00:00 2001 From: Mathias Lang Date: Mon, 26 Sep 2016 14:32:14 +0200 Subject: [PATCH 1/2] Turn implicit string concatenation in d_do_test into explicit one --- test/d_do_test.d | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/d_do_test.d b/test/d_do_test.d index 588a5f95ef4d..974569e2b95b 100755 --- a/test/d_do_test.d +++ b/test/d_do_test.d @@ -17,25 +17,25 @@ import core.sys.posix.sys.wait; void usage() { write("d_do_test \n" - "\n" - " input_dir: one of: compilable, fail_compilation, runnable\n" - " test_name: basename of test case to run\n" - " test_extension: one of: d, html, or sh\n" - "\n" - " example: d_do_test runnable pi d\n" - "\n" - " relevant environment variables:\n" - " ARGS: set to execute all combinations of\n" - " REQUIRED_ARGS: arguments always passed to the compiler\n" - " DMD: compiler to use, ex: ../src/dmd\n" - " CC: C++ compiler to use, ex: dmc, g++\n" - " OS: win32, win64, linux, freebsd, osx\n" - " RESULTS_DIR: base directory for test results\n" - " windows vs non-windows portability env vars:\n" - " DSEP: \\\\ or /\n" - " SEP: \\ or /\n" - " OBJ: .obj or .o\n" - " EXE: .exe or \n"); + ~ "\n" + ~ " input_dir: one of: compilable, fail_compilation, runnable\n" + ~ " test_name: basename of test case to run\n" + ~ " test_extension: one of: d, html, or sh\n" + ~ "\n" + ~ " example: d_do_test runnable pi d\n" + ~ "\n" + ~ " relevant environment variables:\n" + ~ " ARGS: set to execute all combinations of\n" + ~ " REQUIRED_ARGS: arguments always passed to the compiler\n" + ~ " DMD: compiler to use, ex: ../src/dmd\n" + ~ " CC: C++ compiler to use, ex: dmc, g++\n" + ~ " OS: win32, win64, linux, freebsd, osx\n" + ~ " RESULTS_DIR: base directory for test results\n" + ~ " windows vs non-windows portability env vars:\n" + ~ " DSEP: \\\\ or /\n" + ~ " SEP: \\ or /\n" + ~ " OBJ: .obj or .o\n" + ~ " EXE: .exe or \n"); } enum TestMode From 31f070f607398bcef72110f40c125a7f2ea7761b Mon Sep 17 00:00:00 2001 From: Mathias Lang Date: Mon, 26 Sep 2016 14:25:41 +0200 Subject: [PATCH 2/2] Fix issue 3827 - Deprecate implicit string concatenation Implicit string concatenation is an old feature that can now be replaced by explicit concatenation. It was also a source of bug, even for experienced D programmer, and the deprecation has been agreed on in 2010: http://forum.dlang.org/post/ibi742$gi2$1@digitalmars.com --- changelog.dd | 18 ++++++++++++++++++ src/parse.d | 4 ++++ test/fail_compilation/diag10805.d | 7 ++++--- test/fail_compilation/issue3827.d | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 test/fail_compilation/issue3827.d diff --git a/changelog.dd b/changelog.dd index e334f91bc7e7..b036ec91124b 100644 --- a/changelog.dd +++ b/changelog.dd @@ -18,6 +18,8 @@ $(BUGSTITLE Language Changes, ) $(LI $(RELATIVE_LINK2 align_by_ctfe, Align attribute can be used with CTFEable expression.)) + + $(LI $(RELATIVE_LINK2 deprecated_implicit_cat, Implicit string concatenation is deprecated.)) ) $(BUGSTITLE Compiler Changes, @@ -202,6 +204,22 @@ $(BUGSTITLE Compiler Changes, --- $(P The number after `spec:` is the nesting of the speculative compiles.) ) + + $(LI $(LNAME2 deprecated_implicit_cat, Implicit string concatenation is deprecated.) + + $(P Implicit concatenation of string literal is a very early feature that is now supplanted + by the concatenation operator ('~'), the later being more explicit.) + + $(P It could result in hard to spot bug, where one missed a coma in an array expression:) + + --- + void foo () + { + string[] arr = [ "Hello", "buggy" "World" ]; + assert(arr.length = 3); // Fail, the length of the array is 2 and the content is [ "Hello", "buggyWorld" ] + } + --- + ) ) Macros: diff --git a/src/parse.d b/src/parse.d index 252ff24995e3..cc251fbd268d 100644 --- a/src/parse.d +++ b/src/parse.d @@ -7192,6 +7192,7 @@ final class Parser : Lexer auto postfix = token.postfix; while (1) { + const prev = token; nextToken(); if (token.value == TOKstring || token.value == TOKxstring) { @@ -7202,6 +7203,9 @@ final class Parser : Lexer postfix = token.postfix; } + deprecation("Implicit string concatenation is deprecated, use %s ~ %s instead", + prev.toChars(), token.toChars()); + const len1 = len; const len2 = token.len; len = len1 + len2; diff --git a/test/fail_compilation/diag10805.d b/test/fail_compilation/diag10805.d index fa52d9aca472..a32b376f9f0e 100644 --- a/test/fail_compilation/diag10805.d +++ b/test/fail_compilation/diag10805.d @@ -1,9 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/diag10805.d(10): Error: delimited string must end in FOO" -fail_compilation/diag10805.d(12): Error: unterminated string constant starting at fail_compilation/diag10805.d(12) -fail_compilation/diag10805.d(13): Error: semicolon expected following auto declaration, not 'EOF' +fail_compilation/diag10805.d(11): Error: delimited string must end in FOO" +fail_compilation/diag10805.d(13): Error: unterminated string constant starting at fail_compilation/diag10805.d(13) +fail_compilation/diag10805.d(13): Deprecation: Implicit string concatenation is deprecated, use "" ~ "" instead +fail_compilation/diag10805.d(14): Error: semicolon expected following auto declaration, not 'EOF' --- */ diff --git a/test/fail_compilation/issue3827.d b/test/fail_compilation/issue3827.d new file mode 100644 index 000000000000..76d90ed7141a --- /dev/null +++ b/test/fail_compilation/issue3827.d @@ -0,0 +1,14 @@ +// REQUIRED_ARGS: -de +/* +TEST_OUTPUT: +--- +fail_compilation/issue3827.d(12): Deprecation: Implicit string concatenation is deprecated, use "Hello" ~ "World" instead +fail_compilation/issue3827.d(13): Deprecation: Implicit string concatenation is deprecated, use "A" ~ "B" instead +--- +*/ + +void main () +{ + string[] arr = [ "Hello" "World" ]; + auto foo = "A" "B"; +}