Questions about not-interpolated string literals (like in #sourceLocation)

So, I'm trying to understand how not-interpolated string literals behave compared to other string literals.

I'm referring to Strings that are parsed by Parser::getStringLiteralIfNotInterpolated, like in #sourceLocation(file: "this string", line: 12)

So, obviously a string literal with an extra quote "foo"" gives an error:

test.swift:1:28: error: unterminated string literal
#sourceLocation(file: "foo"", line: 42)
                           ^

Inserting a backslash like such: #sourceLocation(file: "foo\"", line: 42) successfully parses. However, I was trying to check the actual value of the string. Using -emit-sil, I get some output like this:

// Mappings from '#fileID' to '#filePath':
//   'test/foo\"' => 'foo\"'
//   'test/test.swift' => 'test.swift'

I may be misinterpreting this, but it appears like the backslash not only serves as an escape sequence for the parser, but also ends up including an actual backslash.

Furthermore, I don't see any test cases that cover the backslash character within a #sourceLocation string, so I'm not sure what the intended behavior is here. If a backslash escape sequence actually worked, I would expect the -emit-sil to produce something like:

// Mappings from '#fileID' to '#filePath':
//   'test/foo"' => 'foo"'
//   'test/test.swift' => 'test.swift'

It looks like: 1) The parser recognizes the escape sequence while creating the token, but the string buffer is never altered. Parser::getStringLiteralIfNotInterpolated returns the StringRef directly from the source text.

I then stumbled on SR-12346 by @brentdax which pretty much says that Lexer::getEncodedStringSegment() is skipped, but to implement it:

This will require us to change how Parser::getStringLiteralIfNotInterpolated() and perhaps its callers manage memory, because they currently assume that the StringRef is backed directly by a source buffer and will never be freed.

I confirmed this. Simply returning something like getEncodedStringSegment(Segments.front(), Buf) will spit out gibberish (only when an escape sequence is present), so the way memory is managed does need to be changed.

I just started contributing to Swift this past week, and don't quite have a grasp on what this "memory management" change entails. I looked at all the callees of Parser::getStringLiteralIfNotInterpolated() and am still not sure what needs to change as far as memory management.

...

Okay, this may have been a bit of a ramble, but I'm new to contributing, and I wanted to jot down all my thoughts. Any feedback on my thought process as well as feedback on implementation is greatly appreciated.

Thanks!

Terms of Service

Privacy Policy

Cookie Policy