Bug 20428 – Precondition bug for in/out

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-12-04T09:15:51Z
Last change time
2024-12-13T19:06:21Z
Keywords
contracts
Assigned to
No Owner
Creator
cbleser
See also
https://issues.dlang.org/show_bug.cgi?id=23535
Moved to GitHub: dmd#19645 →

Attachments

IDFilenameSummaryContent-TypeSize
1770precondition_bug.tgzThis file contains test example and a log fileapplication/x-compressed-tar1732

Comments

Comment #0 by cr — 2019-12-04T09:15:51Z
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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19645 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB