Created attachment 1770
This file contains test example and a log file
Hej Alle.
This the pre-condtion bug has been around for a while now, and it is stated that it should be fixed.
But it doesn't seem to be.
I have test that this bug is in alle version dmd/ldc2/gdc.
I my view the pre- and post-conditions stated in an interface or and abstract member function should also be apply to the class which implements this function or overide the this member function
Ex.
interface I {
int func(int x)
in {
assert(x < 10);
}
}
class C : I {
int func(int x) {
return x*x;
}
}
So I would expect the C.func function to fail if I call it with value 11, but it does not.
In the attachment you can find a log-file and the and test example.
The logfile also include information about the OS and the compiler versions use to test this bug.
Keep up the good work!
Comment #1 by default_357-line — 2019-12-04T09:20:48Z
Sorta a bug but not really. More a really confusing aspect of how in-conditions work.
By substitutability, a subclass can always say that it chooses to accept more data as parameters than its parent class or interface demands. Contracts are an extension of this mechanism, so an in-condition on an interface is mostly useless - the subclass only *has to* accept all the values that the interface in-condition lets through; but it can always choose to accept more values. (This is fundamental to what inheritance formally means.)
In D, a lack of in-condition is taken to mean "the function takes any value allowed by the type." As such, you can always override a method with an in-condition with one that doesn't have an in-condition, which is taken to dissolve the in-condition.
Now, from a language design perspective it would probably be better if "no in-condition" meant "copy the in-condition of the parent interface" and you'd signal the desire to accept any value with something like "in (true)". However, that'd be a feature proposal, not a bug.
Comment #2 by default_357-line — 2019-12-04T09:55:14Z
Just to make it clearer:
interface I {
void foo(int i) in (i < 10);
}
This means that for any implementation of I, foo() *has to* take all i < 10.
But it can always *choose* to additionally take i >= 10.
And by default, if you specify no in-condition in C : I {}, it does.
Comment #3 by dkorpel — 2021-07-12T10:39:51Z
Not a bug, derived classes must tighten the outputs but can loosen the inputs:
https://dlang.org/spec/function.html#in_out_inheritance
Running checks on derived classes would break valid code.
Changing this to an enhancement "copy parent's contracts by default" like FeepingCreature suggested, though that might need a DIP since it's a breaking change as well.
Comment #4 by robert.schadek — 2024-12-13T19:06:21Z