Thread overview
[Issue 12321] Contracts of implemented interface method aren't called
Jul 05, 2017
Vladimir Panteleev
Jan 11, 2020
Basile-z
Mar 21, 2020
Basile-z
Oct 08, 2020
FeepingCreature
July 05, 2017
https://issues.dlang.org/show_bug.cgi?id=12321

Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Hardware|x86_64                      |All
                 OS|Linux                       |All

--
January 11, 2020
https://issues.dlang.org/show_bug.cgi?id=12321

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
                 CC|                            |b2.temp@gmx.com

--- Comment #4 from Basile-z <b2.temp@gmx.com> ---
reduced without `shared`

---
interface IA
{
    void foo();
}

class A : IA
{
    void foo()
    in (false) { }
}

void main()
{
    new A().foo();
}
---

--
March 21, 2020
https://issues.dlang.org/show_bug.cgi?id=12321

Basile-z <b2.temp@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|b2.temp@gmx.com             |

--
October 08, 2020
https://issues.dlang.org/show_bug.cgi?id=12321

FeepingCreature <default_357-line@yahoo.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |default_357-line@yahoo.de

--- Comment #5 from FeepingCreature <default_357-line@yahoo.de> ---
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.

--