Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
}
+ public static void UnsafeInsideIteratorError (ResolveContext rc, Location loc)
+ {
+ UnsafeInsideIteratorError (rc.Report, loc);
+ }
+
+ public static void UnsafeInsideIteratorError (Report report, Location loc)
+ {
+ report.Error (1629, loc, "Unsafe code may not appear in iterators");
+ }
+
//
// Converts `source' to an int, uint, long or ulong.
//
return null;
}
- public bool IsPossibleTypeOrNamespace (IMemberContext mc)
+ bool IsPossibleTypeOrNamespace (IMemberContext mc)
{
- return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing, loc) != null;
+ //
+ // Has to ignore static usings because we are looking for any member not just type
+ // in this context
+ //
+ return mc.LookupNamespaceOrType (Name, Arity, LookupMode.Probing | LookupMode.IgnoreStaticUsing, loc) != null;
}
public bool IsPossibleType (IMemberContext mc)
return me;
}
+ //
+ // Stage 3: Lookup nested types, namespaces and type parameters in the context
+ //
+ if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
+ if (IsPossibleTypeOrNamespace (rc)) {
+ return ResolveAsTypeOrNamespace (rc, false);
+ }
+ }
+
var expr = NamespaceContainer.LookupStaticUsings (rc, Name, Arity, loc);
if (expr != null) {
if (Arity > 0) {
return expr;
}
- //
- // Stage 3: Lookup nested types, namespaces and type parameters in the context
- //
- if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
- if (IsPossibleTypeOrNamespace (rc)) {
- return ResolveAsTypeOrNamespace (rc, false);
- }
- }
-
if ((restrictions & MemberLookupRestrictions.NameOfExcluded) == 0 && Name == "nameof")
return new NameOf (this);
// introduce redundant storey but with `this' only but it's tricky to avoid
// at this stage as we don't know what expressions follow base
//
+ // TODO: It's needed only when the method with base call is moved to a storey
+ //
if (rc.CurrentAnonymousMethod != null) {
if (targs == null && method.IsGeneric) {
targs = method.TypeArguments;
CheckProtectedMemberAccess (rc, member);
}
- if (member.MemberType.IsPointer && !rc.IsUnsafe) {
- UnsafeError (rc, loc);
+ if (member.MemberType.IsPointer) {
+ if (rc.CurrentIterator != null) {
+ UnsafeInsideIteratorError (rc, loc);
+ } else if (!rc.IsUnsafe) {
+ UnsafeError (rc, loc);
+ }
}
var dep = member.GetMissingDependencies ();
static TypeSpec MoreSpecific (TypeSpec p, TypeSpec q)
{
- if (TypeManager.IsGenericParameter (p) && !TypeManager.IsGenericParameter (q))
- return q;
- if (!TypeManager.IsGenericParameter (p) && TypeManager.IsGenericParameter (q))
- return p;
+ if (p.IsGenericParameter != q.IsGenericParameter)
+ return p.IsGenericParameter ? q : p;
var ac_p = p as ArrayContainer;
if (ac_p != null) {
return p;
if (specific == ac_q.Element)
return q;
- } else if (p.IsGeneric && q.IsGeneric) {
- var pargs = TypeManager.GetTypeArguments (p);
- var qargs = TypeManager.GetTypeArguments (q);
+
+ return null;
+ }
+
+ if (p.IsGeneric && q.IsGeneric) {
+ var pargs = p.TypeArguments;
+ var qargs = q.TypeArguments;
bool p_specific_at_least_once = false;
bool q_specific_at_least_once = false;
for (int i = 0; i < pargs.Length; i++) {
- TypeSpec specific = MoreSpecific (pargs[i], qargs[i]);
- if (specific == pargs[i])
+ TypeSpec specific = MoreSpecific (pargs [i], qargs [i]);
+ if (specific == pargs [i])
p_specific_at_least_once = true;
- if (specific == qargs[i])
+ if (specific == qargs [i])
q_specific_at_least_once = true;
}
arg_count++;
}
- if (has_unsafe_arg && !ec.IsUnsafe) {
- Expression.UnsafeError (ec, loc);
+ if (has_unsafe_arg) {
+ if (ec.CurrentIterator != null) {
+ Expression.UnsafeInsideIteratorError (ec, loc);
+ } else if (!ec.IsUnsafe) {
+ Expression.UnsafeError (ec, loc);
+ }
}
//
public override void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
{
if (backing_field != null) {
- backing_field.EmitAssign (ec, source, false, false);
+ backing_field.EmitAssign (ec, source, leave_copy, false);
return;
}