currently, code like the following is rejected:
abstract class C{
int foo(int x)
in{assert(x<0);}
out(result){assert(result>0);}
}
tt.d(10): Error: function tt.C.foo in and out contracts require function body.
Which does not make sense, because contracts logically belong to the method declaration.
Such code should be accepted and the contracts should be subject to contract inheritance. This will require a tiny grammar change.
Comment #1 by govellius — 2012-01-28T03:46:36Z
I would like a clarification about abstract class/methods with contracts.
Should the bottom two examples be valid D code?
----
// Works ( and documented TDPL/website )
interface I {
int func( int x )
in { assert(x == 0); }
}
class C : I {
int func( int x ) { return x; }
}
// Does not work ( undocumented )
abstract class A
{
int func( int x )
in { assert(x == 0); }
}
// ditto
class A2 {
abstract int func( int x )
in { assert(x == 0); }
}
Comment #2 by timon.gehr — 2012-01-28T07:46:14Z
Yes, that is the plan.
Comment #3 by alex — 2012-02-12T09:17:40Z
Is there any news on this? Design-by-contract in D is seriously crippled due to this bug.
Comment #4 by smjg — 2012-02-12T10:07:15Z
(In reply to comment #3)
> Is there any news on this? Design-by-contract in D is seriously crippled due to
> this bug.
It's an arbitrary restriction, not a bug.
http://www.dlang.org/declaration.html
Decl:
StorageClasses Decl
BasicType Declarators ;
BasicType Declarator FunctionBody
AutoDeclaration
http://www.dlang.org/function.html
FunctionBody:
BlockStatement
BodyStatement
InStatement BodyStatement
OutStatement BodyStatement
InStatement OutStatement BodyStatement
OutStatement InStatement BodyStatement
InStatement and OutStatement are part of FunctionBody, so if the function has no body then it can't have in and out contracts.
But I entirely agree that it should be allowed. Contracts are part of the API, not the implementation. As such, they are equally applicable to abstract/interface methods. It could also improve contract checking in closed-source libraries.
Comment #7 by destructionator — 2014-03-10T20:43:44Z
amen, this should DEFINITELY work. without it, we can't have contracts in .di generation nor in interfaces, making them really hard to use as intended.
This is a bigger problem to me than the lack of preconditions. Ugh.
Comment #8 by destructionator — 2014-03-10T20:46:56Z
well I guess we *can* have interfaces now, but not abstract classes... random limitation indeed.
Comment #9 by default_357-line — 2017-11-30T09:29:03Z
Seconding this issue.
Comment #10 by github-bugzilla — 2017-12-28T22:00:21Z
dlang/dmd pull request #12106 "[dmd-cxx] Implement new syntax for contracts and invariants" was merged into dmd-cxx:
- edaf335e4d3c7f9100aed809dca584aa8da2d713 by Iain Buclaw:
[dmd-cxx] fix issue 6549 - Implement contracts without implementation
https://github.com/dlang/dmd/pull/12106