return !TypeManager.IsGenericParameter (expr_type) &&
!TypeManager.IsValueType (expr_type);
}
-
- if (!TypeManager.IsGenericType (target_type) && !TypeManager.IsGenericType (expr_type)) {
- foreach (Type iface in TypeManager.GetInterfaces (target_type)) {
- if (TypeManager.ImplementsInterface (expr_type, iface))
- return true;
- }
- }
}
// from any interface type S to interface-type T.
out bool use_class_cast)
{
Type expr_type = expr.Type;
-
use_class_cast = false;
-
+
//
- // notice that it is possible to write "ValueType v = 1", the ValueType here
- // is an abstract class, and not really a value type, so we apply the same rules.
+ // From any value-type to the type object.
//
if (target_type == TypeManager.object_type) {
//
return false;
return TypeManager.IsValueType (expr_type);
- } else if (target_type == TypeManager.value_type) {
+ }
+
+ //
+ // From any value-type to the type System.ValueType.
+ //
+ if (target_type == TypeManager.value_type)
return TypeManager.IsValueType (expr_type);
- } else if (TypeManager.IsSubclassOf (expr_type, target_type)) {
+
+ if (target_type == TypeManager.enum_type) {
//
- // Special case: enumeration to System.Enum.
- // System.Enum is not a value type, it is a class, so we need
- // a boxing conversion
+ // From any enum-type to the type System.Enum.
//
- if (expr_type.IsEnum || TypeManager.IsGenericParameter (expr_type))
+ if (expr_type.IsEnum)
+ return true;
+ //
+ // From any nullable-type with an underlying enum-type to the type System.Enum
+ //
+ if (TypeManager.IsNullableType (expr_type))
+ return TypeManager.GetTypeArguments (expr_type) [0].IsEnum;
+ }
+
+ if (TypeManager.IsSubclassOf (expr_type, target_type)) {
+ if (TypeManager.IsGenericParameter (expr_type))
return true;
return false;
return new UnboxCast (expr, target_type);
if (TypeManager.IsEnumType (expr_type)) {
- if (expr is EnumConstant)
- return ExplicitConversionCore (ec, ((EnumConstant) expr).Child, target_type, loc);
+ Expression underlying = EmptyCast.Create (expr, TypeManager.EnumToUnderlying (expr_type));
+ expr = ExplicitConversionCore (ec, underlying, target_type, loc);
+ if (expr != null)
+ return expr;
- return ExplicitConversionCore (ec, EmptyCast.Create (expr, TypeManager.EnumToUnderlying (expr_type)), target_type, loc);
+ return ExplicitUserConversion (ec, underlying, target_type, loc);
}
if (TypeManager.IsEnumType (target_type)){
Expression ce = ExplicitConversionCore (ec, expr, TypeManager.EnumToUnderlying (target_type), loc);
if (ce != null)
return EmptyCast.Create (ce, target_type);
+
+ //
+ // LAMESPEC: IntPtr and UIntPtr conversion to any Enum is allowed
+ //
+ if (expr_type == TypeManager.intptr_type || expr_type == TypeManager.uintptr_type) {
+ ne = ExplicitUserConversion (ec, expr, TypeManager.EnumToUnderlying (target_type), loc);
+ if (ne != null)
+ return ExplicitConversionCore (ec, ne, target_type, loc);
+ }
+
+ return null;
}
ne = ExplicitNumericConversion (expr, target_type);
if (ne != null)
return ne;
}
-
- ne = ExplicitUserConversion (ec, expr, target_type, loc);
- if (ne != null)
- return ne;
-
+
return null;
}
} else if (TypeManager.IsNullableType (expr_type)) {
Expression source = Nullable.Unwrap.Create (expr, ec);
if (source != null) {
- e = ExplicitConversionCore (ec, source, target_type, loc);
- if (e != null)
- return e;
+ return ExplicitConversion (ec, source, target_type, loc);
}
}
#endif
e = ExplicitConversionCore (ec, expr, target_type, loc);
if (e != null)
return e;
+
+ e = ExplicitUserConversion (ec, expr, target_type, loc);
+ if (e != null)
+ return e;
expr.Error_ValueCannotBeConverted (ec, loc, target_type, true);
return null;