Bug 12321 – Contracts of implemented interface method aren't called

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-03-08T11:41:33Z
Last change time
2024-12-13T18:18:04Z
Keywords
contracts, wrong-code
Assigned to
No Owner
Creator
NCrashed
Moved to GitHub: dmd#17646 →

Comments

Comment #0 by NCrashed — 2014-03-08T11:41:33Z
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(); } ```
Comment #1 by NCrashed — 2014-03-08T11:43:27Z
Comment #2 by NCrashed — 2014-03-08T11:48:25Z
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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17646 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB