Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2018-01-16 15:10:20 +0300
committerMarek Safar <marek.safar@gmail.com>2018-01-17 16:43:18 +0300
commitc282af6df5ffbc7fc4ec2ab857299c8d455f9d72 (patch)
tree9a93083743e40585b303b1f9f5a90ad584874e13 /mcs
parent3f372d06eeb4b924a26871c91a2100205fb10550 (diff)
[mcs] Implements C# 7.0 discards
Diffstat (limited to 'mcs')
-rw-r--r--mcs/errors/cs0029-42.cs10
-rw-r--r--mcs/errors/cs0103-18.cs10
-rw-r--r--mcs/errors/cs1644-60.cs11
-rw-r--r--mcs/errors/cs8183.cs11
-rw-r--r--mcs/errors/cs8207.cs19
-rw-r--r--mcs/errors/cs8209.cs10
-rw-r--r--mcs/errors/cs8323.cs15
-rw-r--r--mcs/errors/cs8324.cs12
-rw-r--r--mcs/mcs/ecore.cs14
-rw-r--r--mcs/mcs/expression.cs69
-rw-r--r--mcs/mcs/tuples.cs12
-rw-r--r--mcs/mcs/typespec.cs26
-rw-r--r--mcs/tests/test-discards-01.cs36
-rw-r--r--mcs/tests/ver-il-net_4_x.xml24
14 files changed, 276 insertions, 3 deletions
diff --git a/mcs/errors/cs0029-42.cs b/mcs/errors/cs0029-42.cs
new file mode 100644
index 00000000000..c7671000c76
--- /dev/null
+++ b/mcs/errors/cs0029-42.cs
@@ -0,0 +1,10 @@
+// CS0029: Cannot implicitly convert type `string' to `int'
+// Line: 8
+
+class C
+{
+ void Exists (int _)
+ {
+ _ = "2";
+ }
+} \ No newline at end of file
diff --git a/mcs/errors/cs0103-18.cs b/mcs/errors/cs0103-18.cs
new file mode 100644
index 00000000000..8cec755d23d
--- /dev/null
+++ b/mcs/errors/cs0103-18.cs
@@ -0,0 +1,10 @@
+// CS0103: The name `_' does not exist in the current context
+// Line: 8
+
+class C
+{
+ void Test ()
+ {
+ _.ToString ();
+ }
+} \ No newline at end of file
diff --git a/mcs/errors/cs1644-60.cs b/mcs/errors/cs1644-60.cs
new file mode 100644
index 00000000000..ca9547bc561
--- /dev/null
+++ b/mcs/errors/cs1644-60.cs
@@ -0,0 +1,11 @@
+// CS1644: Feature `discards' cannot be used because it is not part of the C# 6.0 language specification
+// Line: 9
+// Compiler options: -langversion:6
+
+class X
+{
+ int Test ()
+ {
+ _ = 2;
+ }
+}
diff --git a/mcs/errors/cs8183.cs b/mcs/errors/cs8183.cs
new file mode 100644
index 00000000000..f9e9004b737
--- /dev/null
+++ b/mcs/errors/cs8183.cs
@@ -0,0 +1,11 @@
+// CS8183: Cannot infer the type of implicitly-typed discard
+// Line: 9
+// Compiler options: -langversion:7.2
+
+class X
+{
+ public static void Main ()
+ {
+ _ = default;
+ }
+} \ No newline at end of file
diff --git a/mcs/errors/cs8207.cs b/mcs/errors/cs8207.cs
new file mode 100644
index 00000000000..31090948b45
--- /dev/null
+++ b/mcs/errors/cs8207.cs
@@ -0,0 +1,19 @@
+// CS8207: An expression tree cannot contain a discard
+// Line: 11
+
+using System;
+using System.Linq.Expressions;
+
+class X
+{
+ void Test ()
+ {
+ Expression<Func<bool>> e = () => TryGetValue (out _);
+ }
+
+ bool TryGetValue (out int arg)
+ {
+ arg = 3;
+ return true;
+ }
+}
diff --git a/mcs/errors/cs8209.cs b/mcs/errors/cs8209.cs
new file mode 100644
index 00000000000..3a46a206c8e
--- /dev/null
+++ b/mcs/errors/cs8209.cs
@@ -0,0 +1,10 @@
+// CS8209: Cannot assign void to a discard
+// Line: 8
+
+class C
+{
+ public static void Main ()
+ {
+ _ = Main ();
+ }
+} \ No newline at end of file
diff --git a/mcs/errors/cs8323.cs b/mcs/errors/cs8323.cs
new file mode 100644
index 00000000000..c6c9309ec0d
--- /dev/null
+++ b/mcs/errors/cs8323.cs
@@ -0,0 +1,15 @@
+// CS8323: Named argument `str' is used out of position but is followed by positional argument
+// Line: 9
+// Compiler options: -langversion:7.2
+
+class X
+{
+ public static void Main ()
+ {
+ Test (str: "", "");
+ }
+
+ static void Test (int arg, string str)
+ {
+ }
+} \ No newline at end of file
diff --git a/mcs/errors/cs8324.cs b/mcs/errors/cs8324.cs
new file mode 100644
index 00000000000..8a0be1aefb9
--- /dev/null
+++ b/mcs/errors/cs8324.cs
@@ -0,0 +1,12 @@
+// CS8324: Named argument specifications must appear after all fixed arguments have been specified in a dynamic invocation
+// Line: 10
+// Compiler options: -langversion:7.2
+
+class C
+{
+ void M ()
+ {
+ dynamic d = new object ();
+ d.M (arg: 1, "");
+ }
+} \ No newline at end of file
diff --git a/mcs/mcs/ecore.cs b/mcs/mcs/ecore.cs
index 9b40d8a2399..20ee9e73b19 100644
--- a/mcs/mcs/ecore.cs
+++ b/mcs/mcs/ecore.cs
@@ -2957,6 +2957,13 @@ namespace Mono.CSharp {
if ((restrictions & MemberLookupRestrictions.NameOfExcluded) == 0 && Name == "nameof")
return new NameOf (this);
+ if ((restrictions & MemberLookupRestrictions.ReadAccess) == 0 && Name == "_") {
+ if (rc.Module.Compiler.Settings.Version < LanguageVersion.V_7)
+ rc.Report.FeatureIsNotAvailable (rc.Module.Compiler, loc, "discards");
+
+ return new Discard (loc).Resolve (rc);
+ }
+
if (errorMode) {
if (variable_found) {
rc.Report.Error (841, loc, "A local variable `{0}' cannot be used before it is declared", Name);
@@ -5442,7 +5449,7 @@ namespace Mono.CSharp {
}
if (arg_type != parameter) {
- if (arg_type == InternalType.VarOutType)
+ if (arg_type == InternalType.VarOutType || arg_type == InternalType.Discard)
return 0;
var ref_arg_type = arg_type as ReferenceContainer;
@@ -6051,6 +6058,11 @@ namespace Mono.CSharp {
continue;
}
+ if (arg_type == InternalType.Discard) {
+ a.Expr.Type = pt;
+ continue;
+ }
+
var ref_arg_type = arg_type as ReferenceContainer;
if (ref_arg_type != null) {
if (ref_arg_type.Element != pt)
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
index fce59faf238..0368532c6d3 100644
--- a/mcs/mcs/expression.cs
+++ b/mcs/mcs/expression.cs
@@ -13252,4 +13252,73 @@ namespace Mono.CSharp
throw new NotSupportedException ();
}
}
+
+ class Discard : Expression, IAssignMethod, IMemoryLocation
+ {
+ public Discard (Location loc)
+ {
+ this.loc = loc;
+ }
+
+ public override Expression CreateExpressionTree (ResolveContext rc)
+ {
+ rc.Report.Error (8207, loc, "An expression tree cannot contain a discard");
+ return null;
+ }
+
+ protected override Expression DoResolve (ResolveContext rc)
+ {
+ type = InternalType.Discard;
+ eclass = ExprClass.Variable;
+ return this;
+ }
+
+ public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
+ {
+ if (right_side.Type == InternalType.DefaultType) {
+ rc.Report.Error (8183, loc, "Cannot infer the type of implicitly-typed discard");
+ type = InternalType.ErrorType;
+ return this;
+ }
+
+ if (right_side.Type.Kind == MemberKind.Void) {
+ rc.Report.Error (8209, loc, "Cannot assign void to a discard");
+ type = InternalType.ErrorType;
+ return this;
+ }
+
+ if (right_side != EmptyExpression.OutAccess) {
+ type = right_side.Type;
+ }
+
+ return this;
+ }
+
+ public override void Emit (EmitContext ec)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public void Emit (EmitContext ec, bool leave_copy)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
+ {
+ if (leave_copy)
+ source.Emit (ec);
+ else
+ source.EmitSideEffect (ec);
+ }
+
+ public void AddressOf (EmitContext ec, AddressOp mode)
+ {
+ var temp = ec.GetTemporaryLocal (type);
+ ec.Emit (OpCodes.Ldloca, temp);
+
+ // TODO: Should free it on next statement but don't have mechanism for that yet
+ // ec.FreeTemporaryLocal (temp, type);
+ }
+ }
}
diff --git a/mcs/mcs/tuples.cs b/mcs/mcs/tuples.cs
index 71175acf540..6497a894876 100644
--- a/mcs/mcs/tuples.cs
+++ b/mcs/mcs/tuples.cs
@@ -503,6 +503,9 @@ namespace Mono.CSharp
}
eclass = ExprClass.Value;
+
+ // TODO: The type is same only if there is no target element conversion
+ // var res = (/*byte*/ b, /*short*/ s) = (2, 4);
type = src.Type;
return this;
}
@@ -527,7 +530,14 @@ namespace Mono.CSharp
public override void Emit (EmitContext ec)
{
- throw new NotImplementedException ();
+ if (instance != null)
+ ((ExpressionStatement)source).EmitStatement (ec);
+
+ foreach (ExpressionStatement expr in targetExprs)
+ expr.Emit (ec);
+
+ var ctor = MemberCache.FindMember (type, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly | BindingRestriction.InstanceOnly) as MethodSpec;
+ ec.Emit (OpCodes.Newobj, ctor);
}
public override void EmitStatement (EmitContext ec)
diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs
index 14fabb26340..a58a0fe5178 100644
--- a/mcs/mcs/typespec.cs
+++ b/mcs/mcs/typespec.cs
@@ -1464,6 +1464,29 @@ namespace Mono.CSharp
class InternalType : TypeSpec, ITypeDefinition
{
+ sealed class InternalTypeAssembly : IAssemblyDefinition
+ {
+ public static readonly InternalTypeAssembly Instance = new InternalTypeAssembly ();
+
+ public string FullName => throw new NotImplementedException ();
+
+ public bool IsCLSCompliant => false;
+
+ public bool IsMissing => false;
+
+ public string Name => throw new NotImplementedException ();
+
+ public byte [] GetPublicKeyToken ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public bool IsFriendAssemblyTo (IAssemblyDefinition assembly)
+ {
+ return false;
+ }
+ }
+
public static readonly InternalType AnonymousMethod = new InternalType ("anonymous method");
public static readonly InternalType Arglist = new InternalType ("__arglist");
public static readonly InternalType MethodGroup = new InternalType ("method group");
@@ -1474,6 +1497,7 @@ namespace Mono.CSharp
public static readonly InternalType VarOutType = new InternalType ("var out");
public static readonly InternalType ThrowExpr = new InternalType ("throw expression");
public static readonly InternalType DefaultType = new InternalType ("default");
+ public static readonly InternalType Discard = new InternalType ("discard");
readonly string name;
@@ -1498,7 +1522,7 @@ namespace Mono.CSharp
IAssemblyDefinition ITypeDefinition.DeclaringAssembly {
get {
- throw new NotImplementedException ();
+ return InternalTypeAssembly.Instance;
}
}
diff --git a/mcs/tests/test-discards-01.cs b/mcs/tests/test-discards-01.cs
new file mode 100644
index 00000000000..54cf29779c6
--- /dev/null
+++ b/mcs/tests/test-discards-01.cs
@@ -0,0 +1,36 @@
+using System;
+
+class X
+{
+ public static void Main ()
+ {
+ string s = null;
+
+ _ = 1;
+ {
+ char _ = '4';
+ }
+
+ _ = TestValue ();
+
+ _ = _ = s;
+
+ byte k1;
+ var s1 = (k1, _) = (1, s);
+
+ Func<object> l1 = () => _ = (_, _) = (1, s);
+
+ TryGetValue (out _);
+ }
+
+ static bool TryGetValue (out int arg)
+ {
+ arg = 3;
+ return true;
+ }
+
+ static int TestValue ()
+ {
+ return 4;
+ }
+} \ No newline at end of file
diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml
index 78e6782767e..faa5d1f780b 100644
--- a/mcs/tests/ver-il-net_4_x.xml
+++ b/mcs/tests/ver-il-net_4_x.xml
@@ -68790,6 +68790,30 @@
</method>
</type>
</test>
+ <test name="test-discards-01.cs">
+ <type name="X">
+ <method name="Void Main()" attrs="150">
+ <size>63</size>
+ </method>
+ <method name="Boolean TryGetValue(Int32 ByRef)" attrs="145">
+ <size>13</size>
+ </method>
+ <method name="Int32 TestValue()" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="X+&lt;Main&gt;c__AnonStorey0">
+ <method name="System.Object &lt;&gt;m__0()" attrs="131">
+ <size>25</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="test-ex-filter-01.cs">
<type name="X">
<method name="Int32 Main()" attrs="150">