Skip to content

Add Expression-Based Contract Syntax#8155

Merged
dlang-bot merged 8 commits intodlang:masterfrom
tgehr:contract-syntax
May 5, 2018
Merged

Add Expression-Based Contract Syntax#8155
dlang-bot merged 8 commits intodlang:masterfrom
tgehr:contract-syntax

Conversation

@tgehr
Copy link
Contributor

@tgehr tgehr commented Apr 9, 2018

Implementation of DIP 1009.

@dlang-bot
Copy link
Contributor

dlang-bot commented Apr 9, 2018

Thanks for your pull request and interest in making D better, @tgehr! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "master + dmd#8155"

@tgehr tgehr force-pushed the contract-syntax branch 2 times, most recently from c306ff4 to 357bfe8 Compare April 9, 2018 19:35
@wilzbach wilzbach added Review:Needs Changelog A changelog entry needs to be added to /changelog Review:Needs Spec PR A PR updating the language specification needs to be submitted to dlang.org labels Apr 9, 2018
@tgehr tgehr force-pushed the contract-syntax branch 2 times, most recently from c70941f to 34e6850 Compare April 9, 2018 20:23

typedef Array<class TemplateInstance *> TemplateInstances;

typedef Array<class Ensure> Ensures;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not be struct Ensure?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not make a difference in code semantics, but I guess using struct is better style.

Copy link
Member

@ibuclaw ibuclaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most notable thing missing here is documentation, both for new code blocks added and ddoc entries for functions and types introduced.

Other than that, just a couple notes on implementation detail that are trivial or could be explained away by adding documentation for why it's needed.

src/dmd/func.d Outdated
o.push(new TypeIdentifier(rloc,Id.result));
import dmd.cond: StaticIfCondition;
auto c = new StaticIfCondition(rloc, new TraitsExp(loc, Id.compiles, o));
auto result = new ConditionalStatement(rloc, c, new ExpStatement(rloc, a), null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need an artificial static if here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a hack to improve diagnostics. (__result should not appear in the output.)
The static if condition always passes in well-formed D programs, but will fail if out contracts of void functions specify a result identifier. I'd prefer to remove this. I can just not semantically analyze the out contracts if one of them specifies an output but the result is void, I guess.

/***********************************************************
*/

extern (C++) struct Ensure
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be better as class EnsureStatement : Statement? Then it can go in the statement module.

Copy link
Contributor Author

@tgehr tgehr Apr 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not really a statement, it's just a way to create a tuple of result identifier and out contract.
I can of course declare it as a statement if that is better. (But I don't think it is.)

src/dmd/func.d Outdated
const(char)* mangleString; /// mangled symbol created from mangleExact()

Identifier outId; /// identifier for out statement
@property Identifier outId(){ /// identifier for result
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be dead code now, so remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not dead code, but I can turn it into a more appropriately-named bool function.

}

case TOK.in_:
auto loc = token.loc;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a couple comments presenting the supported in syntaxes as per invariant above.


case TOK.out_:
// parse: out (identifier) { statement }
auto loc = token.loc;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise here, add comments for syntaxes that are now handled.

assert(0);
}

static Statements* arraySyntaxCopy(Statements* a){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document

@ibuclaw
Copy link
Member

ibuclaw commented Apr 11, 2018

I think this could be ironed out within a week ready for inclusion.

@tgehr tgehr force-pushed the contract-syntax branch 3 times, most recently from 57c8c90 to 0491d4c Compare April 11, 2018 18:27
@tgehr tgehr force-pushed the contract-syntax branch from 0491d4c to 9d8c577 Compare April 11, 2018 18:31
/*************************************
* Do syntax copy of an array of Statement's.
*/
static Statements* arraySyntaxCopy(Statements* a){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curly braces on next line, check for this style everywhere.

src/dmd/func.d Outdated
if (a)
{
b = a.copy();
foreach(i,e;*a)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add spaces in foreach (i, e; *a) - check for this style everywhere as I've seen it more than once.

src/dmd/func.d Outdated
* `true` if the function has a return type that
* is different from `void`.
*/
final bool canBuildResultVar(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that this is only used by the module its declared in. So make it private, and extern(D).

@tgehr tgehr force-pushed the contract-syntax branch 8 times, most recently from 852982c to db54028 Compare April 17, 2018 13:39
@tgehr
Copy link
Contributor Author

tgehr commented Apr 24, 2018

@JinShil Probably not, but I can delete code. (I think most of what is not covered in hdrgen it is currently dead code.)

@JinShil
Copy link
Contributor

JinShil commented Apr 24, 2018

I'm referring to coverage within this PR itself. The hdrgen code that isn't covered is new code in this PR. See https://codecov.io/gh/dlang/dmd/compare/b4d5005db0fd3581789d8a0942583f7c13efbc82...772309cbccb1c0d3e3cd9892f1ebc36024e5f7b7/diff

Ideally, we should have 100% coverage for all code in this PR.

@tgehr
Copy link
Contributor Author

tgehr commented Apr 24, 2018

So am I. I know.

@JinShil
Copy link
Contributor

JinShil commented Apr 24, 2018

If its dead code, why was it added?

@tgehr
Copy link
Contributor Author

tgehr commented Apr 24, 2018

There is an obvious way to handle the case other than an assertion failure. But if coverage is more important than robustness to changes to invariants in other parts of the code, I can remove that.

@JinShil
Copy link
Contributor

JinShil commented Apr 24, 2018

Sorry, I don't understand what you're implying. I think all that is required is a test to generate a .di file and verify that the result is correct. That should exercise the new code in hdrgen.d

@tgehr
Copy link
Contributor Author

tgehr commented Apr 24, 2018

Currently, a contract is always either a ScopeStatement or an AssertStatement. The header generation code also handles the case when it is a different statement. But yes, you are right, the AssertStatement case can still be covered. I'll add a test and delete the dead code.

@tgehr tgehr force-pushed the contract-syntax branch 2 times, most recently from 7c09f5b to 312d16f Compare May 2, 2018 10:48
@tgehr tgehr force-pushed the contract-syntax branch 3 times, most recently from 1c556ea to 34b6986 Compare May 2, 2018 13:31
@tgehr tgehr force-pushed the contract-syntax branch from 34b6986 to 1a9de07 Compare May 2, 2018 14:36
@tgehr
Copy link
Contributor Author

tgehr commented May 4, 2018

@JinShil @ibuclaw @klickverbot @RazvanN7 @WalterBright Gentle reminder. (The remaining few lines of uncovered code cannot be covered in an end-to-end test as far as I can tell, but they should be there for completeness.)

Copy link
Member

@andralex andralex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, thanks! Please follow with a spec PR.

@andralex
Copy link
Member

andralex commented May 5, 2018

cc @ibuclaw

@wilzbach
Copy link
Contributor

wilzbach commented May 5, 2018

@andralex FYI: there's already a PR to dlang.org: dlang/dlang.org#2339

@@ -0,0 +1,22 @@
Implement DIP 1009 - $(LINK2 https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1009.md, Add Expression-Based Contract Syntax)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The title is already a link. Thus it can't contain links.

Copy link
Member

@ibuclaw ibuclaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙈

@dlang-bot dlang-bot merged commit 09d3845 into dlang:master May 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants