Roslyn: ref local gives bad error when inited with ternary initializer

Created on 11 Sep 2017  路  4Comments  路  Source: dotnet/roslyn

Version Used:
2.3.1.61919 (57c81319) - on OSX with mono 5.4.0.135

Steps to Reproduce:

Compile this:

using System;

class Driver {
    static int X;
    static void Main () {
        ref int x = X == 0 ? ref X : ref X;
    }
}

Expected Behavior:

It should either compile or give a clear error message that what I'm doing is wrong

Actual Behavior:

Microsoft (R) Visual C# Compiler version 2.3.1.61919 (57c81319)
Copyright (C) Microsoft Corporation. All rights reserved.

ref2.cs(6,24): error CS1525: Invalid expression term 'ref'
ref2.cs(6,24): error CS1003: Syntax error, ':' expected
ref2.cs(6,24): error CS1002: ; expected
ref2.cs(6,30): error CS1001: Identifier expected
ref2.cs(6,30): error CS1002: ; expected
ref2.cs(6,30): error CS1513: } expected
ref2.cs(6,37): error CS1001: Identifier expected

I tried all combinations of adding/removing ref and parens and nothing worked. The only one that gave me something good was ref int x = ref (X == 0 ? X : X); with: error CS1510: A ref or out value must be an assignable variable

Area-Compilers Concept-Diagnostic Clarity Language-C# New Language Feature - Readonly References Test help wanted

Most helpful comment

We do not yet support ref-ternary in master, so there is no syntax where this would work.

In the "features/readonly-ref" branch where we have support, the error is a bit more sane:

Error CS8172 Cannot initialize a by-reference variable with a value

The right syntax is:
ref int x = ref (X == 0 ? ref X : ref X);

The parens are optional - just to show how things are parsed.

X == 0 ? ref X : ref X is just an lvalue expression. Can assign by reference, pass by ref/out, even use on the LHS of assignments -

(X == 0 ? ref X : ref X) = 123;

All 4 comments

We do not yet support ref-ternary in master, so there is no syntax where this would work.

In the "features/readonly-ref" branch where we have support, the error is a bit more sane:

Error CS8172 Cannot initialize a by-reference variable with a value

The right syntax is:
ref int x = ref (X == 0 ? ref X : ref X);

The parens are optional - just to show how things are parsed.

X == 0 ? ref X : ref X is just an lvalue expression. Can assign by reference, pass by ref/out, even use on the LHS of assignments -

(X == 0 ? ref X : ref X) = 123;

I will keep this open, just to make sure we check broken cases in this scenario.
The way the parser breaks in master - with no decent recovery untill ; is clearly not good.

lets add a test if does not exist already

The right syntax is:
ref int x = ref (X == 0 ? ref X : ref X);

I found this issue because I got stuck with a CS8172 because I missed the ref outside the brackets.

Is it really necessary to require this? lvalue or not? I seriously wouldn't have come up with the idea to add another ref on my own. And especially without the brackets it looks like I ref a bool in an expression that returns something else. Its confusing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

orthoxerox picture orthoxerox  路  3Comments

MadsTorgersen picture MadsTorgersen  路  3Comments

vbcodec picture vbcodec  路  3Comments

AdamSpeight2008 picture AdamSpeight2008  路  3Comments

marler8997 picture marler8997  路  3Comments