diff --git a/vlib/builtin/string_test.v b/vlib/builtin/string_test.v index 9aca92e4af..820a23ca44 100644 --- a/vlib/builtin/string_test.v +++ b/vlib/builtin/string_test.v @@ -907,3 +907,29 @@ fn test_split_by_whitespace() { assert '\n xyz \t abc def'.split_by_whitespace() == ['xyz', 'abc', 'def'] assert ''.split_by_whitespace() == [] } + +fn test_interpolation_after_quoted_variable_still_works() { + rr := 'abc' + tt := 'xyz' + + // Basic interpolation, no internal quotes + yy := 'Replacing $rr with $tt' + assert yy == 'Replacing abc with xyz' + + // Interpolation after quoted variable ending with 'r'quote + // that may be mistaken with the start of a raw string, + // ensure that it is not. + ss := 'Replacing "$rr" with "$tt"' + assert ss == 'Replacing "abc" with "xyz"' + zz := "Replacing '$rr' with '$tt'" + assert zz == "Replacing 'abc' with 'xyz'" + + // Interpolation after quoted variable ending with 'c'quote + // may be mistaken with the start of a c string, so + // check it is not. + cc := 'abc' + ccc := "Replacing '$cc' with '$tt'" + assert ccc == "Replacing 'abc' with 'xyz'" + cccq := 'Replacing "$cc" with "$tt"' + assert cccq == 'Replacing "abc" with "xyz"' +} diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 950ff0327f..6664feb18e 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1025,8 +1025,8 @@ fn (s &Scanner) count_symbol_before(p int, sym byte) int { fn (mut s Scanner) ident_string() string { q := s.text[s.pos] is_quote := q == scanner.single_quote || q == scanner.double_quote - is_raw := is_quote && s.pos > 0 && s.text[s.pos - 1] == `r` - is_cstr := is_quote && s.pos > 0 && s.text[s.pos - 1] == `c` + is_raw := is_quote && s.pos > 0 && s.text[s.pos - 1] == `r` && !s.is_inside_string + is_cstr := is_quote && s.pos > 0 && s.text[s.pos - 1] == `c` && !s.is_inside_string if is_quote { if s.is_inside_string || s.is_enclosed_inter || s.is_inter_start { s.inter_quote = q