DMD64 D Compiler v2.065
Contract isn't called:
```
interface IA
{
shared void foo();
}
synchronized class A : IA
{
void foo()
in
{
assert(false);
}
body
{
}
}
void main()
{
shared IA a1 = new shared A();
a1.foo();
}
```
Workaround: add empty in{} after interface method specification.
```
void foo() in {}
```
Comment #3 by NCrashed — 2014-03-08T11:54:57Z
(In reply to comment #2)
> Workaround: add empty in{} after interface method specification.
> ```
> void foo() in {}
> ```
Unfortunately i harried up. This enables only unreachable code detection, but contract still isn't called.
Comment #4 by b2.temp — 2020-01-11T22:06:49Z
reduced without `shared`
---
interface IA
{
void foo();
}
class A : IA
{
void foo()
in (false) { }
}
void main()
{
new A().foo();
}
---
Comment #5 by default_357-line — 2020-10-08T10:53:48Z
Not a bug - or rather, the issue is a different bug.
As per Liskov, a class may only widen, not narrow, its in-contracts. As such, there is no point to calling foo's in-condition, since the interface method already promised that no in-contract would be necessary for the function call.
The actual bug is that this specific combination of in-contracts is never valid, and as such the compiler should inform us that if we want to have an incondition on the class, we need to at least define one on the interface as well. (Otherwise the class method contract is provably pointless, as per above.) Such a warning already appears for class inheritance, but is not yet implemented for class-interface inheritance.
I've filed that as https://issues.dlang.org/show_bug.cgi?id=21298 .
Note that if you put an `in(true);` on foo(), the child foo() will still be ignored, because D interprets incontracts as "if any hierarchy contract passes, the child contract is assumed to pass." You can change this behavior with my flag `-preview=inclusiveincontracts`, whereupon you will get a "Logic error" exception indicating that A's foo() contract was tighter than IA's contract.
Comment #6 by robert.schadek — 2024-12-13T18:18:04Z