-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace @SubCommands SumType!(TYPES...) with SubCommand!(TYPES...) #143
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #143 +/- ##
=======================================
Coverage 99.22% 99.23%
=======================================
Files 27 28 +1
Lines 1943 1966 +23
=======================================
+ Hits 1928 1951 +23
Misses 15 15 ☔ View full report in Codecov by Sentry. |
Co-authored-by: Nickolay Bukreyev <[email protected]>
* Fix compatibility with D <2.102 * Fix compatibility with D <2.101 * Avoid shortened-methods syntax This allows compiling without `-preview=shortenedMethods` on D <2.104. D <2.096 did not support them at all. * Fix compatibility with D <2.100 * Add an older DMD to the CI
source/argparse/api/subcommand.d
Outdated
package(argparse) enum bool isSubCommand(T) = is(T : SubCommand!Args, Args...); | ||
|
||
|
||
public template match(handlers...) | ||
{ | ||
auto ref match(Args...)(auto ref SubCommand!Args sc) | ||
{ | ||
alias RETURN_TYPE = typeof(SumType!(SubCommand!Args.Types).init.sumtype_match!handlers); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
package(argparse) enum bool isSubCommand(T) = is(T : SubCommand!Args, Args...); | |
public template match(handlers...) | |
{ | |
auto ref match(Args...)(auto ref SubCommand!Args sc) | |
{ | |
alias RETURN_TYPE = typeof(SumType!(SubCommand!Args.Types).init.sumtype_match!handlers); | |
package(argparse) enum bool isSubCommand(T) = is(T : const SubCommand!Args, Args...); | |
public template match(handlers...) | |
{ | |
auto ref match(Sub : const SubCommand!Args, Args...)(auto ref Sub sc) | |
{ | |
alias RETURN_TYPE = typeof(SumType!(Sub.Types).init.sumtype_match!handlers); |
immutable sub = SubCommand!(A, B)(A(1));
static assert(isSubCommand!(typeof(sub)));
assert(sub.match!(_ => _.i) == 1);
(Sorry for focusing on such tiny bits. Just can’t see anything more substantial.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed match
but compiler didn't complain about isSubCommand
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. A reduced example:
struct A(T)
{
T* p;
}
static if(is(immutable A!int : A!Args, Args...)) // Surprisingly, this is true.
{
// Let's see what it deduced:
static assert(Args.length == 1);
static assert(is(Args[0] == int));
// Let's check it again, just in case:
static assert(!is(immutable A!int : A!Args)); // Now it's false!
}
else
static assert(false);
Congratulations, I suppose we’ve discovered a bug in the compiler. I’ll need to mock this a bit more; will then report to D’s Bugzilla.
A unit test that passes now but IMO should fail with const
less isSubCommand
:
struct A
{
int[] a;
}
static assert(isSubCommand!(immutable SubCommand!A));
I think it is sensible to put const
in isSubCommand
to be safe against future fixes in the compiler in case it is really a bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before submitting issue to compiler, I'd suggest checking SumType
/isSumType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slightly modified examples from dlang reference:
Fails for short
onlineapp.d(2): Error: static assert: `is(const(short) == short)` is false
Works for SumType
:
assert(isSumType!(const SumType!int));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With indirections:
pragma(msg, is(const(int)* : int*)); // => false
pragma(msg, is(const SumType!(int*) : SumType!Args, Args...)); // => true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But:
struct A(T) {}
writeln(is(const(A!int) : A!T1,T1)); // => true
writeln(is(const(A!int) == A!T2,T2)); // => true
writeln(is(const(A!int) : A!int)); // => true
writeln(is(const(A!int) == A!int)); // => false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, your last snippet shows it clearly. Intuitively, const(A!int)
cannot be == A!T2
for any T2
, but DMD insists it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Asked on the forum about this, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh I don't expect any answers from forum
struct A
{
int[] arr;
}
immutable one = SubCommand!A(A([1]));
SubCommand!A mut;
mut = one;
mut.match!(_ => _.arr[0] = 2);
assert(one.match!(_ => _.arr[0]) == 2); // Successfully modified an immutable object! Still have to investigate if it’s a |
It seems also related to struct A
{
int arr;
}
immutable one = SubCommand!A(A(1));
SubCommand!A mut = one;
mut = one;
mut.match!(_ => _.arr = 2);
assert(one.match!(_ => _.arr) == 2); |
struct None {}
struct S(T)
{
SumType!(None,T) a;
}
struct A
{
int[] arr;
}
immutable one = S!A.init;
immutable two = SumType!(None,A)(A([1]));
immutable three = SumType!(A,None)(A([1]));
immutable four = SumType!(A)(A([1]));
|
Asked question on forum. |
# Conflicts: # source/argparse/internal/parser.d
May be adding
|
Pushed changes and confirmed that this does not compile: struct A
{
int[] i;
}
immutable sub = SubCommand!(A)(A([1])); Error:
|
@SirNickolas Is this now good from your point of view? |
Closes #80