--- /dev/null
+// CS0128: A local variable named `x' is already defined in this scope
+// Line: 9
+
+class X
+{
+ public static void Main ()
+ {
+ Foo (out int x);
+ Foo (out int x);
+ }
+
+ static void Foo (out int arg)
+ {
+ arg = 2;
+ }
+}
\ No newline at end of file
+++ /dev/null
-// CS0815: An implicitly typed local variable declaration cannot be initialized with `void'
-// Line: 8
-// Compiler options: -langversion:experimental
-
-class X
-{
- public static void Main ()
- {
- Foo (out var x = Main ());
- }
-
- static void Foo (out int i)
- {
- i = 0;
- }
-}
\ No newline at end of file
+++ /dev/null
-// CS1501: Argument `#1' cannot convert `ref string' expression to type `ref int'
-// Line: 8
-// Compiler options: -langversion:experimental
-
-class C
-{
- public static void Main ()
- {
- Foo (ref var x = "");
- }
-
- static void Foo (ref int i)
- {
- }
-}
\ No newline at end of file
-// CS1644: Feature `declaration expression' cannot be used because it is not part of the C# 5.0 language specification
-// Line: 12
+// CS1644: Feature `out variable declaration' cannot be used because it is not part of the C# 5.0 language specification
+// Line: 9
// Compiler options: -langversion:5
class C
+++ /dev/null
-// CS8046: An expression tree cannot contain a declaration expression
-// Line: 11
-// Compiler options: -langversion:experimental
-
-using System;
-using System.Linq.Expressions;
-
-class C
-{
- static void Main()
- {
- Expression<Func<bool>> e = () => Out (out int x);
- }
-
- static bool Out (out int value)
- {
- value = 3;
- return true;
- }
-}
\ No newline at end of file
+++ /dev/null
-// CS8047: Declaration expression cannot be used in this context
-// Line: 8
-// Compiler options: -langversion:experimental
-
-public class C
-{
- public static void Main ()
- {
- dynamic target = 3;
- var x = new Test (target, out var y);
- }
-}
-
-class Test
-{
- public Test (int x, out int y)
- {
- y = 0;
- }
-}
\ No newline at end of file
--- /dev/null
+// CS8196: Reference to an implicitly typed out variable `x1' is not permitted in the same argument list
+// Line: 8
+
+public class C
+{
+ public static void Main ()
+ {
+ Test (out var x1, out x1);
+ }
+
+ static void Test (out int x, out int x2)
+ {
+ x = 1;
+ x2 = 2;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS8196: Reference to an implicitly typed out variable `x1' is not permitted in the same argument list
+// Line: 8
+
+public class C
+{
+ public static void Main ()
+ {
+ Test (out var x1, out x1);
+ }
+
+ static void Test (out int x, out int x2)
+ {
+ x = 1;
+ x2 = 2;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS8197: Cannot infer the type of implicitly-typed out variable `y'
+// Line: 9
+
+public class C
+{
+ public static void Main ()
+ {
+ dynamic target = 3;
+ var x = new Test (target, out var y);
+ }
+}
+
+class Test
+{
+ public Test (int x, out int y)
+ {
+ y = 0;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS8198: An expression tree cannot contain out variable declaration
+// Line: 11
+
+using System;
+using System.Linq.Expressions;
+
+class C
+{
+ static void Main()
+ {
+ Expression<Func<bool>> e = () => Out (out int x);
+ }
+
+ static bool Out (out int value)
+ {
+ value = 3;
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers
+// Line: 6
+
+public class C
+{
+ bool res = Foo (out int arg);
+
+ static bool Foo (out int arg)
+ {
+ arg = 2;
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers
+// Line: 11
+
+public class C
+{
+ bool Prop { get; } = Foo (out int arg);
+
+ static bool Foo (out int arg)
+ {
+ arg = 2;
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS8200: Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers
+// Line: 11
+
+public class C
+{
+ public C (bool value)
+ {
+ }
+
+ public C ()
+ : this (Foo (out int arg))
+ {
+ }
+
+ static bool Foo (out int arg)
+ {
+ arg = 2;
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+// CS8201: Out variable and pattern variable declarations are not allowed within a query clause
+// Line: 11
+
+using System.Linq;
+
+class Program
+{
+ public static void Main ()
+ {
+ var a = "abcdef";
+ var res = from x in a from y in M (a, out var z) select x;
+ }
+
+ public static T M<T>(T x, out T z) => z = x;
+}
\ No newline at end of file
//
// Returns dynamic when at least one argument is of dynamic type
//
- public void Resolve (ResolveContext ec, out bool dynamic)
+ public void Resolve (ResolveContext rc, out bool dynamic)
{
dynamic = false;
+
+ List<LocalVariable> var_locals = null;
foreach (Argument a in args) {
- a.Resolve (ec);
- if (a.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && !a.IsByRef)
+ a.Resolve (rc);
+
+ if (a.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && !a.IsByRef) {
dynamic = true;
+ continue;
+ }
+
+ if (a.Type == InternalType.VarOutType) {
+ var de = a.Expr as DeclarationExpression;
+ if (de != null) {
+ if (var_locals == null)
+ var_locals = new List<LocalVariable> ();
+
+ var_locals.Add (de.Variable);
+ continue;
+ }
+
+ var lvr = a.Expr as LocalVariableReference;
+ if (lvr != null && var_locals != null && var_locals.Contains (lvr.local_info)) {
+ rc.Report.Error (8196, lvr.Location, "Reference to an implicitly typed out variable `{0}' is not permitted in the same argument list", lvr.Name);
+ lvr.Type = InternalType.ErrorType;
+ }
+ }
}
}
if (rc.HasSet (ResolveContext.Options.BaseInitializer))
flags |= ResolveContext.Options.BaseInitializer;
+
+ if (rc.HasSet (ResolveContext.Options.QueryClauseScope))
+ flags |= ResolveContext.Options.QueryClauseScope;
}
public ExceptionStatement CurrentTryBlock { get; set; }
NameOfScope = 1 << 17,
+ QueryClauseScope = 1 << 18,
+
///
/// Indicates the current context is in probing mode, no errors are reported.
///
$$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4, arg_mod);
lbag.AddLocation ($$, GetLocation($2));
}
+ | identifier_inside_body COLON OUT named_argument_expr_or_out_variable_declaration
+ {
+ if (lang_version <= LanguageVersion.V_3)
+ FeatureIsNotAvailable (GetLocation ($1), "named argument");
+
+ var lt = (LocatedToken) $1;
+ $$ = new NamedArgument (lt.Value, lt.Location, (Expression) $4, Argument.AType.Out);
+ lbag.AddLocation ($$, GetLocation($2));
+ }
+
;
named_argument_expr
: expression_or_error
-// | declaration_expression
+ ;
+
+named_argument_expr_or_out_variable_declaration
+ : expression_or_error
+ | out_variable_declaration
;
opt_named_modifier
{
$$ = Argument.AType.Ref;
}
- | OUT
- {
- $$ = Argument.AType.Out;
- }
;
opt_class_member_declarations
$$ = new Argument ((Expression) $2, Argument.AType.Ref);
lbag.AddLocation ($$, GetLocation ($1));
}
- | REF declaration_expression
- {
- $$ = new Argument ((Expression) $2, Argument.AType.Ref);
- }
| OUT variable_reference
{
$$ = new Argument ((Expression) $2, Argument.AType.Out);
lbag.AddLocation ($$, GetLocation ($1));
}
- | OUT declaration_expression
+ | OUT out_variable_declaration
{
$$ = new Argument ((Expression) $2, Argument.AType.Out);
}
}
;
-declaration_expression
- : OPEN_PARENS declaration_expression CLOSE_PARENS
- {
- $$ = new ParenthesizedExpression ((Expression) $2, GetLocation ($1));
- lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
- }
-/*
- | CHECKED open_parens_any declaration_expression CLOSE_PARENS
- {
- $$ = new CheckedExpr ((Expression) $3, GetLocation ($1));
- lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
- }
- | UNCHECKED open_parens_any declaration_expression CLOSE_PARENS
- {
- $$ = new UnCheckedExpr ((Expression) $3, GetLocation ($1));
- lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
- }
-*/
- | variable_type identifier_inside_body
+out_variable_declaration
+ : variable_type identifier_inside_body
{
- if (lang_version != LanguageVersion.Experimental)
- FeatureIsNotAvailable (GetLocation ($1), "declaration expression");
+ if (lang_version < LanguageVersion.V_7)
+ FeatureIsNotAvailable (GetLocation ($1), "out variable declaration");
var lt = (LocatedToken) $2;
var lv = new LocalVariable (current_block, lt.Value, lt.Location);
current_block.AddLocalName (lv);
$$ = new DeclarationExpression ((FullNamedExpression) $1, lv);
}
- | variable_type identifier_inside_body ASSIGN expression
- {
- if (lang_version != LanguageVersion.Experimental)
- FeatureIsNotAvailable (GetLocation ($1), "declaration expression");
-
- var lt = (LocatedToken) $2;
- var lv = new LocalVariable (current_block, lt.Value, lt.Location);
- current_block.AddLocalName (lv);
- $$ = new DeclarationExpression ((FullNamedExpression) $1, lv) {
- Initializer = (Expression) $4
- };
- }
;
variable_reference
foreach (var arg in arguments) {
if (arg.Type == InternalType.VarOutType) {
// Should be special error message about dynamic dispatch
- rc.Report.Error (8047, arg.Expr.Location, "Declaration expression cannot be used in this context");
+ rc.Report.Error (8197, arg.Expr.Location, "Cannot infer the type of implicitly-typed out variable `{0}'", ((DeclarationExpression) arg.Expr).Variable.Name);
}
}
public override Expression CreateExpressionTree (ResolveContext rc)
{
- rc.Report.Error (8046, loc, "An expression tree cannot contain a declaration expression");
+ rc.Report.Error (8198, loc, "An expression tree cannot contain out variable declaration");
return null;
}
bool DoResolveCommon (ResolveContext rc)
{
+ if (rc.HasAny (ResolveContext.Options.BaseInitializer | ResolveContext.Options.FieldInitializerScope)) {
+ rc.Report.Error (8200, loc, "Out variable and pattern variable declarations are not allowed within constructor initializers, field initializers, or property initializers");
+ } else if (rc.HasSet (ResolveContext.Options.QueryClauseScope)) {
+ rc.Report.Error (8201, loc, "Out variable and pattern variable declarations are not allowed within a query clause");
+ }
+
var var_expr = VariableType as VarExpr;
if (var_expr != null) {
type = InternalType.VarOutType;
{
}
- protected override MethodGroupExpr DoResolveOverload (ResolveContext ec)
+ protected override MethodGroupExpr DoResolveOverload (ResolveContext rc)
{
- MethodGroupExpr rmg = mg.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.None);
- return rmg;
+ using (rc.Set (ResolveContext.Options.QueryClauseScope)) {
+ return mg.OverloadResolve (rc, ref arguments, this, OverloadResolver.Restrictions.None);
+ }
}
protected override Expression DoResolveDynamic (ResolveContext ec, Expression memberExpr)
-// Compiler options: -langversion:experimental
using System;
class DeclarationExpression
return 2;
}
- Out (out int o2 = 2);
- if (o2 != 3)
- return 3;
-
Out (out var o3);
if (o3 != 3)
return 4;
- Ref (ref int r = 2);
- if (r != 7)
- return 5;
-
- Ref (ref ((var r2 = 3)));
- if (r2 != 8)
- return 6;
-
-// Out2 (str: "b", v: out var o5);
-// if (o5 != 9)
-// return 7;
-
- Out3 (out var o6 = 9m);
- if (o6.GetType () != typeof (decimal))
- return 8;
+ Out2 (str: "b", v: out var o5);
+ if (o5 != 9)
+ return 7;
Console.WriteLine ("ok");
return 0;
v = 9;
return true;
}
-
- static void Out3<T> (out T t)
- {
- t = default (T);
- }
-
- static void Ref (ref int arg)
- {
- arg += 5;
- }
}
\ No newline at end of file
-// Compiler options: -langversion:experimental
+using System;
-using static System.Console;
-
-public class DeclarationExpressions
+public class C
{
- public static void Main()
- {
- // TODO:
- //Test (int value = 5);
- //WriteLine (value);
- }
-
- void M2 ()
+ public static void Main ()
{
-// for (int i = 0; int v = 2; ++i) {
-
-// }
-
}
- static int Test (int x)
- {
- WriteLine (x);
- return x;
- }
+ bool Test1 => int.TryParse ("1", out int x);
+ int Test2 => int.TryParse ("2", out int x) ? x : 0;
}
\ No newline at end of file
--- /dev/null
+using System;
+using System.Linq;
+
+public class C
+{
+ public static void Main ()
+ {
+ var a = "abcdef";
+
+ var t1 = from x in Foo (a, out var q1) select x;
+ var t2 = from x in a join y in Foo (a, out var q2) on x equals y select x;
+ }
+
+ public static T Foo<T> (T x, out T z) => z = x;
+}
\ No newline at end of file
--- /dev/null
+public class C
+{
+ public static void Main ()
+ {
+ Test2 (Test (out var x1), x1);
+ }
+
+ static int Test (out int x)
+ {
+ x = 1;
+ return 2;
+ }
+
+ static int Test2 (int x, int y)
+ {
+ return 2;
+ }
+}
\ No newline at end of file
<test name="test-decl-expr-01.cs">
<type name="DeclarationExpression">
<method name="Int32 Main()" attrs="150">
- <size>223</size>
+ <size>121</size>
</method>
<method name="Boolean Out(Int32 ByRef)" attrs="145">
<size>13</size>
<method name="Boolean Out2(Int32 ByRef, System.String)" attrs="145">
<size>14</size>
</method>
- <method name="Void Out3[T](T ByRef)" attrs="145">
- <size>17</size>
- </method>
- <method name="Void Ref(Int32 ByRef)" attrs="145">
- <size>8</size>
- </method>
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
</test>
<test name="test-decl-expr-02.cs">
- <type name="DeclarationExpressions">
+ <type name="C">
<method name="Void Main()" attrs="150">
<size>2</size>
</method>
- <method name="Void M2()" attrs="129">
- <size>2</size>
+ <method name="Boolean get_Test1()" attrs="2177">
+ <size>20</size>
</method>
- <method name="Int32 Test(Int32)" attrs="145">
+ <method name="Int32 get_Test2()" attrs="2177">
+ <size>32</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
+ <test name="test-decl-expr-03.cs">
+ <type name="C">
+ <method name="Void Main()" attrs="150">
+ <size>153</size>
+ </method>
+ <method name="T Foo[T](T, T ByRef)" attrs="150">
+ <size>18</size>
+ </method>
+ <method name="Char <Main>m__0(Char)" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="Char <Main>m__1(Char)" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="Char <Main>m__2(Char)" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="Char <Main>m__3(Char, Char)" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
+ <test name="test-decl-expr-04.cs">
+ <type name="C">
+ <method name="Void Main()" attrs="150">
<size>16</size>
</method>
+ <method name="Int32 Test(Int32 ByRef)" attrs="145">
+ <size>13</size>
+ </method>
+ <method name="Int32 Test2(Int32, Int32)" attrs="145">
+ <size>10</size>
+ </method>
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>