Skip to content

Enum parameter with non-zero default member fails to compile (CS0266) #75

Description

@Mpdreamz

A command method parameter typed as an enum, with a default value pointing at a non-zero-valued enum member, fails to compile. The generator emits the member's underlying integer value as a bare int literal instead of a cast or the qualified member reference, and C# only allows implicit int-to-enum conversion for the literal 0.

Repro

Nullean.Argh 0.18.0, .NET SDK 10.0.300.

using Nullean.Argh;

var app = new ArghApp();
app.Map<Commands>();
return await app.RunAsync(args);

public enum ZeroBased { None = 0, A = 1 }
public enum OneBased { None = 1, A = 2 }

public sealed class Commands
{
	/// <param name="level">-l, --level, level.</param>
	[CommandName("zero")]
	public int Zero(ZeroBased level = ZeroBased.None) => (int)level;

	/// <param name="level">-l, --level, level.</param>
	[CommandName("one")]
	public int One(OneBased level = OneBased.None) => (int)level;
}

zero builds and runs fine. one — identical shape, the only difference is None = 1 instead of None = 0 — fails:

obj/.../ArghGenerated.g.cs(733,39): error CS0266: Cannot implicitly convert type 'int' to 'OneBased'. An explicit conversion exists (are you missing a cast?)
obj/.../ArghGenerated.g.cs(882,13): error CS0266: Cannot implicitly convert type 'int' to 'OneBased'. An explicit conversion exists (are you missing a cast?)

Looking at the generated source, the default-value local is initialized with the bare underlying value instead of a cast:

OneBased level = 1;   // should be: (OneBased)1, or OneBased.None

This will hit anyone with an existing enum whose first/default member isn't 0 — a fairly common pattern for "not-yet-parsed"/sentinel-avoidance reasons, or just historical numbering (I hit this trying to reuse enum SuggestedVersionChange { None = 1, Patch = 2, Minor = 3, Major = 4 } as a CLI option type).

Expected

Enum parameters work regardless of which member is 0 — the generator should emit a cast (or the qualified member name) for the default-value initializer instead of a bare integer literal.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions