-
Notifications
You must be signed in to change notification settings - Fork 832
Description
Repro steps
- Define a static class using the combination of
SealedAttributeandAbstractClassAttribute. - Add fields, instance members, even constructors:1
a. Fields (mutable or not), properties, methods, indexers.
b. Abstract, concrete, override...
Examples
E.g., this
// This compiles and produces nonsense IL.
[<Sealed; AbstractClass>]
type T =
abstract A : int
abstract B : int with get, set
abstract C : i:int -> int
abstract D : i:int -> int
default _.D i = i + 3
member _.E = 3
val F : int
val mutable G : int
member _.H (i, j) = i + j
member _.Item with get i = 3 and set i value = ()
override _.ToString () = "🙃"
new () = { F = 3; G = 3 }
new (x, y) = { F = x; G = y }generates this (SharpLab):
[Serializable]
[Sealed]
[AbstractClass]
[CompilationMapping(SourceConstructFlags.ObjectType)]
public static class T
{
internal int F@;
public int G;
[CompilationMapping(SourceConstructFlags.Field, 0)]
public int F
{
get
{
return F@;
}
}
public abstract override int A { get; }
public abstract override int B { get; set; }
public int E
{
get
{
return 3;
}
}
public int this[object i]
{
get
{
return 3;
}
set
{
}
}
public abstract override int C(int i);
public override int D(int i)
{
return i + 3;
}
public int H(int i, int j)
{
return i + j;
}
public override string ToString()
{
return "\ud83d\ude43";
}
public T()
{
F@ = 3;
G = 3;
}
public T(int x, int y)
{
F@ = x;
G = y;
}
}There is also no error when making a class with a primary constructor static (SharpLab):
// Just throw [<Sealed; AbstractClass>] on the default
// SharpLab class and it still compiles!
[<Sealed; AbstractClass>]
type C() =
member _.M() = ()There is no error for fieldless single-case unions, either (SharpLab):2345
[<Sealed; AbstractClass>]
type U = U
let u = UThere is likewise no warning or error when adding SealedAttribute to a struct fieldless single-case union (SharpLab):5
[<Sealed; Struct>]
type U = UExpected behavior
The code should not compile.
Actual behavior
The code compiles, and calling it results in a System.BadImageFormatException with the message "Bad IL format." at runtime.6
> Unchecked.defaultof<T>.A;;
System.BadImageFormatException: Bad IL format.
at <StartupCode$FSI_0007>.$FSI_0007.main@()
Stopped due to errorKnown workarounds
Don't try weird things.
Related information
- .NET SDK 6.0.300.
Footnotes
-
Not auto-properties: using
member valcorrectly givesFS3133, presumably because the check for a primary constructor is separate.member valis still let through if you do have a primary constructor (SharpLab). ↩ -
It looks like the compiler ignores the combination of
SealedandAbstractClasshere and just adds theAbstractClassattribute without actually making the class static. ↩ -
The compiler correctly gives
FS0942andFS0939when a field is added (SharpLab) or a second case is added (SharpLab). ↩ -
The compiler does disallow this for records with
FS0942andFS0939(SharpLab). ↩ -
If you add a field or a bar
|to either of these, the compiler does give youFS0942and/orFS0939. ↩ ↩2 -
The compiler does disallow calling a constructor added to a static class with
FS0759. ↩
Metadata
Metadata
Assignees
Labels
Type
Projects
Status