Improve error messages for byref-like type loading errors (#20789)
authorJan Kotas <jkotas@microsoft.com>
Sat, 3 Nov 2018 23:14:10 +0000 (16:14 -0700)
committerGitHub <noreply@github.com>
Sat, 3 Nov 2018 23:14:10 +0000 (16:14 -0700)
Related to dotnet/corefx#33233

src/System.Private.CoreLib/Resources/Strings.resx
src/dlls/mscorrc/mscorrc.rc
src/dlls/mscorrc/resource.h
src/vm/classcompat.cpp
src/vm/classcompat.h
src/vm/clsload.cpp
src/vm/methodtablebuilder.cpp

index fe7ea71..0349819 100644 (file)
     <value>Cannot create arrays of ByRef-like values.</value>
   </data>
   <data name="NotSupported_ByRefToByRefLikeReturn" xml:space="preserve">
-    <value>ByRef to ByRefLike return values not supported in reflection invocation.</value>
+    <value>ByRef to ByRef-like return values are not supported in reflection invocation.</value>
   </data>
   <data name="NotSupported_ByRefToVoidReturn" xml:space="preserve">
-    <value>ByRef to void return values not supported in reflection invocation.</value>
+    <value>ByRef to void return values are not supported in reflection invocation.</value>
   </data>
   <data name="NotSupported_CallToVarArg" xml:space="preserve">
     <value>Vararg calling convention not supported.</value>
index 5c5c534..0e35c29 100644 (file)
@@ -712,7 +712,6 @@ BEGIN
     IDS_CLASSLOAD_VARIANCE_IN_CONSTRAINT    "Could not load type '%1' from assembly '%2' because a covariant or contravariant type parameter was used illegally in a type parameter constraint in method '%3'."
     IDS_CLASSLOAD_VARIANCE_CLASS            "Could not load type '%1' from assembly '%2' because it declares a covariant or contravariant type parameter and is not an interface or delegate."
     IDS_CLASSLOAD_BADVARIANCE               "Could not load type '%1' from assembly '%2' because it uses an illegal variance annotation on a type parameter."
-    IDS_CLASSLOAD_CONTEXT_BOUND_GENERIC_METHOD "Context-bound objects with generic methods are not supported."
     IDS_CLASSLOAD_ENUM_EXTRA_GENERIC_TYPE_PARAM "Enumerated types cannot have any generic type parameters, beyond any inherited from their enclosing type (for nested enums)."
        IDS_CLASSLOAD_GENERICTYPE_RECURSIVE     "Could not load type '%1' from assembly '%2' because it has recursive generic definition."
     IDS_CLASSLOAD_TOOMANYGENERICARGS        "Could not load type '%1' from assembly '%2'. Internal limitation: Too many generic arguments."
@@ -721,7 +720,8 @@ BEGIN
     IDS_CLASSLOAD_TYPESPEC                  "Could not load TypeSpec from assembly '%2'."
     IDS_CLASSLOAD_SEALEDPARENT              "Could not load type '%1' from assembly '%2' because the parent type is sealed."
     IDS_CLASSLOAD_BADFORMAT                 "Could not load type '%1' from assembly '%2' because the format is invalid."
-    IDS_CLASSLOAD_CANTCREATEARRAYCLASS      "Could not create array type '%1' from assembly '%2'."
+    IDS_CLASSLOAD_BYREFARRAY                "Could not create array type '%1' from assembly '%2' because the element type is ByRef."
+    IDS_CLASSLOAD_BYREFLIKEARRAY            "Could not create array type '%1' from assembly '%2' because the element type is ByRef-like."
     IDS_CLASSLOAD_MISSINGMETHOD             "Could not load type '%1' from assembly '%2' because the method '%3' could not be loaded."
     IDS_CLASSLOAD_FIELDTOOLARGE             "Size of field of type '%1' from assembly '%2' is too large."
     IDS_CLASSLOAD_CANTEXTEND                "Type '%1' from assembly '%2' cannot extend from any other type."
@@ -740,8 +740,8 @@ BEGIN
     IDS_CLASSLOAD_NOTINTERFACE              "Could not load type '%1' from assembly '%2' because it attempts to implement a class as an interface."
     IDS_CLASSLOAD_VALUEINSTANCEFIELD        "Could not load the value type '%1' from assembly '%2' because it has an instance field of itself."
 
-    IDS_CLASSLOAD_BYREFLIKE_STATICFIELD     "A value type containing a by-ref instance field, such as Span<T>, cannot be used as the type for a static field."
-    IDS_CLASSLOAD_BYREFLIKE_NOTVALUECLASSFIELD "A value type containing a by-ref instance field, such as Span<T>, cannot be used as the type for a class instance field."
+    IDS_CLASSLOAD_BYREFLIKE_STATICFIELD     "A ByRef-like type cannot be used as the type for a static field."
+    IDS_CLASSLOAD_BYREFLIKE_INSTANCEFIELD   "A ByRef-like type cannot be used as the type for an instance field in a non-ByRef-like type."
 
     IDS_CLASSLOAD_RANK_TOOLARGE             "'%1' from assembly '%2' has too many dimensions."
     IDS_CLASSLOAD_BAD_UNMANAGED_RVA         "Native method '%3' on type '%1' from assembly '%2' is not supported."
index 555ee4c..512b22e 100644 (file)
 
 #define IDS_CLASSLOAD_GENERAL                   0x80131522
 #define IDS_CLASSLOAD_BADFORMAT                 0x1774
-#define IDS_CLASSLOAD_CANTCREATEARRAYCLASS      0x1775
+#define IDS_CLASSLOAD_BYREFARRAY                0x1775
+#define IDS_CLASSLOAD_BYREFLIKEARRAY            0x1776
 #define IDS_CLASSLOAD_MISSINGMETHOD             0x1777
 #define IDS_CLASSLOAD_STATICVIRTUAL             0x1778
 #define IDS_CLASSLOAD_REDUCEACCESS              0x1779
 #define IDS_EE_TOOMANYFIELDS                    0x2072
 
 #define IDS_EE_NDIRECT_GETPROCADDRESS_NONAME    0x2073
-#define IDS_CLASSLOAD_CONTEXT_BOUND_GENERIC_METHOD 0x2075
 #define IDS_EE_CLASS_CONSTRAINTS_VIOLATION      0x2076
 #define IDS_EE_METHOD_CONSTRAINTS_VIOLATION     0x2077
 #define IDS_CLASSLOAD_TOO_MANY_METHODS          0x2078
 #define IDS_NATIVE_IMAGE_CANNOT_BE_LOADED_MULTIPLE_TIMES                               0x263a
 
 #define IDS_CLASSLOAD_BYREFLIKE_STATICFIELD        0x263b
-#define IDS_CLASSLOAD_BYREFLIKE_NOTVALUECLASSFIELD 0x263c
-#define IDS_CLASSLOAD_NOTBYREFLIKE                                0x263d
+#define IDS_CLASSLOAD_BYREFLIKE_INSTANCEFIELD      0x263c
 #define IDS_EE_NDIRECT_LOADLIB_LINUX               0x263e
 #define IDS_EE_NDIRECT_LOADLIB_MAC                 0x263f
 #define IDS_EE_NDIRECT_GETPROCADDRESS_UNIX         0x2640
index cc67550..4c38303 100644 (file)
@@ -288,7 +288,6 @@ InteropMethodTableData *MethodTableBuilder::BuildInteropVTable(AllocMemTracker *
     if (pThisMT->IsEnum()) SetEnum();
     if (pThisMT->HasLayout()) SetHasLayout();
     if (pThisMT->IsDelegate()) SetIsDelegate();
-    if (pThisMT->IsContextful()) SetContextful();
 #ifdef FEATURE_COMINTEROP
     if(pThisMT->GetClass()->IsComClassInterface()) SetIsComClassInterface();
 #endif
@@ -2414,12 +2413,6 @@ VOID    MethodTableBuilder::EnumerateClassMethods()
 
         WORD numGenericMethodArgs = (WORD) hEnumTyPars.EnumGetCount();
 
-        // We do not want to support context-bound objects with generic methods.
-        if (IsContextful() && numGenericMethodArgs > 0)
-        {
-            BuildMethodTableThrowException(IDS_CLASSLOAD_CONTEXT_BOUND_GENERIC_METHOD);
-        }
-
         if (numGenericMethodArgs != 0)
         {
             for (unsigned methIdx = 0; methIdx < numGenericMethodArgs; methIdx++)
index 9b3c8fd..02c86e0 100644 (file)
@@ -266,7 +266,6 @@ private:
     BOOL IsAbstract() { LIMITED_METHOD_CONTRACT; return IsTdAbstract(bmtType->dwAttr); } 
     BOOL HasLayout() { LIMITED_METHOD_CONTRACT; return bmtProp->fHasLayout; } 
     BOOL IsDelegate() { LIMITED_METHOD_CONTRACT; return bmtProp->fIsDelegate; } 
-    BOOL IsContextful() { LIMITED_METHOD_CONTRACT; return bmtProp->fIsContextful; } 
     Module *GetModule() { LIMITED_METHOD_CONTRACT; return bmtType->pModule; } 
     Assembly *GetAssembly() { WRAPPER_NO_CONTRACT; return GetModule()->GetAssembly(); } 
     BaseDomain *GetDomain() { LIMITED_METHOD_CONTRACT; return bmtDomain; } 
@@ -289,7 +288,6 @@ private:
     void SetEnum() { LIMITED_METHOD_CONTRACT; bmtProp->fIsEnum = TRUE; }
     void SetHasLayout() { LIMITED_METHOD_CONTRACT; bmtProp->fHasLayout = TRUE; }
     void SetIsDelegate() { LIMITED_METHOD_CONTRACT; bmtProp->fIsDelegate = TRUE; }
-    void SetContextful() { LIMITED_METHOD_CONTRACT; bmtProp->fIsContextful = TRUE; }
 #ifdef _DEBUG
     void SetDebugClassName(LPUTF8 x) { LIMITED_METHOD_CONTRACT; bmtProp->szDebugClassName = x; }
 #endif
@@ -325,7 +323,6 @@ private:
  
         BOOL fIsValueClass;
         BOOL fIsEnum;
-        BOOL fIsContextful;
         BOOL fIsComClassInterface;
         BOOL fHasLayout;
         BOOL fIsDelegate;
index 24887a4..9c4afd5 100644 (file)
@@ -3656,7 +3656,7 @@ TypeHandle ClassLoader::CreateTypeHandleForTypeKey(TypeKey* pKey, AllocMemTracke
             // Arrays of BYREFS not allowed
             if (paramType.GetInternalCorElementType() == ELEMENT_TYPE_BYREF)
             {
-                ThrowTypeLoadException(pKey, IDS_CLASSLOAD_CANTCREATEARRAYCLASS);
+                ThrowTypeLoadException(pKey, IDS_CLASSLOAD_BYREFARRAY);
             }
 
             // Arrays of ByRefLike types not allowed
@@ -3665,7 +3665,7 @@ TypeHandle ClassLoader::CreateTypeHandleForTypeKey(TypeKey* pKey, AllocMemTracke
             {
                 if (pMT->IsByRefLike())
                 {
-                    ThrowTypeLoadException(pKey, IDS_CLASSLOAD_CANTCREATEARRAYCLASS);
+                    ThrowTypeLoadException(pKey, IDS_CLASSLOAD_BYREFLIKEARRAY);
                 }
             }
 
index cfc4f4c..3f54c2f 100644 (file)
@@ -4053,17 +4053,13 @@ VOID    MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
                 {
                     if (fIsStatic)
                     {
-                        // By-ref-like types cannot be used for static fields
+                        // Byref-like types cannot be used for static fields
                         BuildMethodTableThrowException(IDS_CLASSLOAD_BYREFLIKE_STATICFIELD);
                     }
-                    if (!IsValueClass())
-                    {
-                        // Non-value-classes cannot contain by-ref-like instance fields
-                        BuildMethodTableThrowException(IDS_CLASSLOAD_BYREFLIKE_NOTVALUECLASSFIELD);
-                    }
                     if (!bmtFP->fIsByRefLikeType)
                     {
-                        BuildMethodTableThrowException(IDS_CLASSLOAD_NOTBYREFLIKE);
+                        // Non-byref-like types cannot contain byref-like instance fields
+                        BuildMethodTableThrowException(IDS_CLASSLOAD_BYREFLIKE_INSTANCEFIELD);
                     }
                 }
 
@@ -9589,7 +9585,7 @@ void MethodTableBuilder::CheckForSystemTypes()
             {
                 // x86 by default treats the type of ByReference<T> as the actual type of its IntPtr field, see calls to
                 // ComputeInternalCorElementTypeForValueType in this file. This is a special case where the struct needs to be
-                // treated as a value type so that its field can be considered as a by-ref pointer.
+                // treated as a value type so that its field can be considered as a byref pointer.
                 _ASSERTE(pMT->GetFlag(MethodTable::enum_flag_Category_Mask) == MethodTable::enum_flag_Category_PrimitiveValueType);
                 pMT->ClearFlag(MethodTable::enum_flag_Category_Mask);
                 pMT->SetInternalCorElementType(ELEMENT_TYPE_VALUETYPE);
@@ -9670,7 +9666,7 @@ void MethodTableBuilder::CheckForSystemTypes()
         {
             // x86 by default treats the type of ByReference<T> as the actual type of its IntPtr field, see calls to
             // ComputeInternalCorElementTypeForValueType in this file. This is a special case where the struct needs to be
-            // treated as a value type so that its field can be considered as a by-ref pointer.
+            // treated as a value type so that its field can be considered as a byref pointer.
             _ASSERTE(pMT->GetFlag(MethodTable::enum_flag_Category_Mask) == MethodTable::enum_flag_Category_PrimitiveValueType);
             pMT->ClearFlag(MethodTable::enum_flag_Category_Mask);
             pMT->SetInternalCorElementType(ELEMENT_TYPE_VALUETYPE);