Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
pemo11 opened this issue Jan 16, 2025 · 8 comments
Assignees
Labels
Milestone

Comments

@pemo11
Copy link

pemo11 commented Jan 16, 2025

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

@cpyrgas
Copy link

cpyrgas commented Jan 16, 2025

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}"

@pemo11
Copy link
Author

pemo11 commented Jan 21, 2025

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).

@cpyrgas
Copy link

cpyrgas commented Jan 21, 2025

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!

@pemo11
Copy link
Author

pemo11 commented Jan 21, 2025

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

@cpyrgas
Copy link

cpyrgas commented Jan 21, 2025

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

@pemo11
Copy link
Author

pemo11 commented Jan 21, 2025

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

@cpyrgas
Copy link

cpyrgas commented Jan 21, 2025

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

@RobertvanderHulst
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants