Comment #0 by default_357-line — 2020-03-03T09:23:47Z
Right now, D does "check in-contract in superclass, if it fails then check in-contract in subclass." However, in-contracts are defined to only be allowed to tighten the condition. As such, this behavior makes no sense either within debug mode or without.
Within debug mode, D should enforce that in contracts widen the conditions. As such, it should always execute both superclass and subclass contract and Error if superclass-in passes but subclass-in does not. This will also fix weirdnesses such as
interface I { void foo(); }
class C : I { void foo() in(this.is.never.compiled) { } }
or
interface I { void foo() in(true); }
class C : I { void foo() in(false) { } }
which would then be a compiletime error or runtime error, respectively.
Without debug mode, it still doesn't make sense to check the superclass in-contracts. A method is either written correctly or it isn't. If it is written correctly, its in-contract will include the superclass in-contract by definition, so there's no need to check it. If it is not written correctly, and doesn't accept things that it should accept according to the superclass, then we preferably want to fail with a nice assert-provided error message, not randomly enter the class body anyways.
What we don't want to see is `void foo(int i) in (i > 5) { assert(i > 5, "this cannot happen"); } }` fail with "this cannot happen".
Comment #1 by default_357-line — 2020-07-13T13:34:44Z
Sorry, that should be "widen the condition", not "tighten the condition", in the first paragraph. The argument is unaffected.
Comment #2 by robert.schadek — 2024-12-13T19:07:21Z