XSharpPublic icon indicating copy to clipboard operation
XSharpPublic copied to clipboard

Internal compiler error caused by syntax error when using something like i"{ex:Message})"

Open pemo11 opened this issue 1 year ago • 9 comments

Using the syntax

i"Some text ({ex:Message)}"

causes an internal compiler error altough it is a syntax error.

Image

I am using X# 2.18.0.4 (release)

Peter

pemo11 avatar Jan 16 '25 15:01 pemo11

Hi Peter! Problem confirmed, still exists in 2.22, the syntax is actually valid, even if there's no reason for using the parentheses, but the compiler does not handle them and crashes indeed.

Btw, the correct way to use object members inside interpolated strings, is to use the "." operator (when the allowdot compiler option is enabled in the project options, as it is in your case), instead of the ":" operator. That's for the interpolated string syntax only that ":" is not allowed in this case. So this will work correctly:

infoMessage := i"Error happened: {(ex.Message)}"

and of course you can also remove the parentheses as in

infoMessage := i"Error happened: {ex.Message}"

cpyrgas avatar Jan 16 '25 15:01 cpyrgas

Hi Chris, (sorry for my late response).

I know about the syntax of course, but when I use

infoMessage := i"Error happened: {(ex.Message)}"

in the VO dialect, I'll get a "'ex' is variable but is used like a type" error which I don't like;)

(and the parantheses are just for separating the exception message from the rest).

pemo11 avatar Jan 21 '25 10:01 pemo11

Hi Peter!

You can allow using the dot also in the VO dialect, by enabling the compiler option "Allow dot" in the project properties.

Did you mean to put the parentheses outside of the {}? The way it is now, I don't see them separating the exception message from anything else, the expression (ex.Message) is the same as ex.Message without the parentheses. Same as it's the same if you type n := (1+2) or n := 1+2. Or did I misunderstand you?

No worries about taking time to reply!

cpyrgas avatar Jan 21 '25 11:01 cpyrgas

Hi Chris,

Yes, I meant "({ex:Message})" of course (I did not had my glasses on while I was typing this;))

We did not use the option because we don't want to enable it globally. But thats another topic.

Regards,

Peter

pemo11 avatar Jan 21 '25 11:01 pemo11

OK, understood, in this case you need to use the colon operator, as in {ex:Message}.

You can also use a #pragma to enable the option only locally, but I realize this is a bit akward:

#pragma options (allowdot,on) // enable the option only locally
infoMessage := i"Error happened: {ex.Message}"
#pragma options (allowdot,default) // restore state of option as specified in the project settings

cpyrgas avatar Jan 21 '25 11:01 cpyrgas

I wish Copilot would use the colon everywhere I like to use it (based on my usage pattern) and the dot for the rest (joke;))

Peter

pemo11 avatar Jan 21 '25 11:01 pemo11

Well, if you train it enough, I suppose it eventually will! Even though I will still dislike it :)

cpyrgas avatar Jan 21 '25 11:01 cpyrgas

Guys, I have fixed this now.

The expression i"Some text {(ex:Message)}" normally gets translated by the compiler to String.Format("Some text {0}",ex:Message)

When AllowDot is enabled, then the Colon inside this message is seen as the divider between the expression and the format specifier (like in C#) so the compiler tries to translate this to:

String.Format("Some text {0:Message)}",(ex )

This caused the exception in the current build and will generate a new error message in the next build: unexpected End of Expression, are you missing a ')' ? The extra closing parenthesis after Message will be ignored and will be printed as literal.

If you WANT a format specifier, then you can use :: with AllowDot on and AllowDot off. This will work always.

RobertvanderHulst avatar Jan 21 '25 15:01 RobertvanderHulst

ICE is fixed, but the compiler does not warn in some of those cases for the syntax errors inside the interpolated strings. In C#, this

string c;
c= $"Some text ({c.Length)}";

results to

Error (active) CS1003 Syntax error, '}' expected Error (active) CS1073 Unexpected token ')'

but X# compiles the same thing with no errors/warnings.

c := i"Some text ({c.Length)}" // no errors

Also something else I noticed, it's not possible to specify a literal closing or opening bracket in X# in an interpolated string. This should result to a single opening and a single closing bracket (works in c#), but throws errors::

c := i"{{" // error XS8076: Missing close delimiter '}' for interpolated expression started with '{'.
c := i"}}" // error XS1056: Unexpected character '}'

cpyrgas avatar Feb 14 '25 11:02 cpyrgas