return;
string from_type = type.GetSignatureForError ();
+ if (type.Kind == MemberKind.ByRef)
+ from_type = "ref " + from_type;
string to_type = target.GetSignatureForError ();
+ if (target.Kind == MemberKind.ByRef)
+ to_type = "ref " + to_type;
+
if (from_type == to_type) {
from_type = type.GetSignatureForErrorIncludingAssemblyName ();
to_type = target.GetSignatureForErrorIncludingAssemblyName ();
public Expression ResolveLValue (ResolveContext ec, Expression right_side)
{
int errors = ec.Report.Errors;
- bool out_access = right_side == EmptyExpression.OutAccess;
+ //bool out_access = right_side == EmptyExpression.OutAccess;
Expression e = DoResolveLValue (ec, right_side);
- if (e != null && out_access && !(e is IMemoryLocation)) {
+ //if (e != null && out_access && !(e is IMemoryLocation)) {
// FIXME: There's no problem with correctness, the 'Expr = null' handles that.
// Enabling this 'throw' will "only" result in deleting useless code elsewhere,
//throw new InternalErrorException ("ResolveLValue didn't return an IMemoryLocation: " +
// e.GetType () + " " + e.GetSignatureForError ());
- e = null;
- }
+ // e = null;
+ //}
if (e == null) {
if (errors == ec.Report.Errors) {
if (arg_type == InternalType.VarOutType)
return 0;
+ var ref_arg_type = arg_type as ReferenceContainer;
+ if (ref_arg_type != null) {
+ arg_type = ref_arg_type.Element;
+ }
+
//
// Do full equality check after quick path
//
int arg_count = args == null ? 0 : args.Count;
for (; a_idx < arg_count; a_idx++, ++a_pos) {
- a = args[a_idx];
+ a = args [a_idx];
if (a == null)
continue;
if (p_mod != Parameter.Modifier.PARAMS) {
p_mod = cpd.FixedParameters [a_idx].ModFlags;
- pt = ptypes[a_idx];
+ pt = ptypes [a_idx];
has_unsafe_arg |= pt.IsPointer;
if (p_mod == Parameter.Modifier.PARAMS) {
continue;
}
+ var ref_arg_type = arg_type as ReferenceContainer;
+ if (ref_arg_type != null) {
+ if (ref_arg_type.Element != pt)
+ break;
+
+ return true;
+ }
+
if (!TypeSpecComparer.IsEqual (arg_type, pt))
break;
}
GetSignatureForError ());
}
- return null;
+ return ErrorExpression.Instance;
}
if (right_side == EmptyExpression.LValueMemberAccess) {
// Already reported as CS1648/CS1650
- return null;
+ return ErrorExpression.Instance;
}
if (right_side == EmptyExpression.LValueMemberOutAccess) {
rc.Report.Error (1649, loc, "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)",
GetSignatureForError ());
}
- return null;
+ return ErrorExpression.Instance;
}
if (IsStatic) {
GetSignatureForError ());
}
- return null;
+ return ErrorExpression.Instance;
}
public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
Error_NullPropagatingLValue (rc);
if (right_side == EmptyExpression.OutAccess) {
+ if (best_candidate?.MemberType.Kind == MemberKind.ByRef) {
+ if (Arguments?.ContainsEmitWithAwait () == true) {
+ rc.Report.Error (8178, loc, "`await' cannot be used in an expression containing a call to `{0}' because it returns by reference",
+ GetSignatureForError ());
+ }
+
+ return this;
+ }
+
// TODO: best_candidate can be null at this point
INamedBlockVariable variable = null;
if (best_candidate != null && rc.CurrentBlock.ParametersBlock.TopBlock.GetLocalName (best_candidate.Name, rc.CurrentBlock, ref variable) && variable is Linq.RangeVariable) {