https://wiki.dlang.org/api.php?action=feedcontributions&user=Schveiguy&feedformat=atomD Wiki - User contributions [en]2024-03-28T21:41:49ZUser contributionsMediaWiki 1.31.2https://wiki.dlang.org/?title=Beerconf&diff=10119Beerconf2022-10-28T19:15:03Z<p>Schveiguy: Add Rikki as a host</p>
<hr />
<div>BeerConf is the unofficial name given to the daily evening gatherings during [https://dconf.org/ the annual DConf]. It was coined by Ethan Watson, who noted that many of the participants drink beer during their discussions of D and other topics. Often, these gatherings have taken place in the lobby or bar of a designated hotel where most conference attendees stay. When no suitable facilities are available, such as in our 2019 and 2022 editions in London, sponsors have stepped up to rent space in a local pub.<br />
<br />
== Online Beerconf ==<br />
After DConf 2020, scheduled for June of that year, was cancelled due to the COVID-19 pandemic, a few people decided to create a virtual BeerConf to recreate the camaraderie, discussion, and general enjoyment real-world BeerConf participants experience. Using a freely available [https://meet.jit.si/ Jitsi Meet instance], BeerConf June 2020 was the first online gathering of its kind in The D community.<br />
<br />
Steven Schveighoffer and Iain Buclaw, two core D developers, were the hosts of the first BeerConf. It was a success, so they decided to make it a monthly event. So every month, typically on the last weekend (unless special circumstances require moving it to another weekend), Steven and Iain, along with Rikki Cattermole, continue to host BeerConf for the D community to chat, enjoy our shared fascination with the language, and work through sometimes difficult problems that don't lend themselves well to text-based discussion.<br />
<br />
The online group is generally started on a Saturday, and is left open for 48 hours to account for the disparate time zones in which D community members reside. Topics are unrestricted and unplanned. Past topics include Beer (of course), core D development, D game development, using D for controlling car transmissions, future directions of the D language, WIP projects, and more, and many people get work done in D while in the chat. Language maintainers Walter Bright and Atila Neves, as well as Andrei Alexandrescu, frequently join for a time as well.<br />
<br />
Contrary to the name, there is no requirement to actually drink Beer or any alcoholic beverage during BeerConf. There is no requirement to participate either via audio or video; many people join in only to listen, or choose not to enable their cameras. In fact, the requirements are very very loose; all you need is a device that provides access to Jitsi Meet via a web browser or the mobile app.<br />
<br />
BeerConf served as a testbed for DConf Online, during which Q & A sessions take place over Jitsi Meet.<br />
<br />
[[Category:Conferences]]</div>Schveiguyhttps://wiki.dlang.org/?title=The_D_Programming_Language&diff=10118The D Programming Language2022-10-28T19:13:13Z<p>Schveiguy: Add beerconf link</p>
<hr />
<div>__NOTOC__<br />
<table cellspacing="10" style="width:100%; margin-top:-3em;"><br />
<tr><br />
<td><br />
[http://dlang.org/index.html The D Programming Language] has been said to be "what C++ wanted to be," which is a better C. D is developed with system level programming in mind, but brings to the table modern language design with a simple C-like syntax. For these reasons D makes for a good language choice for both performance code and application development.<br />
<br />
D is rapidly reaching a stable [http://dlang.org/spec.html specification] and [http://dlang.org/download.html implementation].<br />
<br />
[http://www.amazon.com/exec/obidos/ASIN/0321635361/classicempire "The D Programming Language"] by Andrei Alexandrescu is available on Amazon and other locations. <br />
<br />
</td><br />
<td><br />
<table cellspacing="10" style="width:100%;"><br />
<tr><br />
<td style="vertical-align:top;"><br />
== Hello World ==<br />
<br />
<syntaxhighlight lang="D">import std.stdio;<br />
<br />
void main()<br />
{<br />
writeln("Hello, world!");<br />
}</syntaxhighlight><br />
[https://run.dlang.io &#9654; Run code]<br />
<br />
</td><br />
</tr><br />
</table><br />
</td><br />
</tr><br />
<br />
</table><br />
<br />
<table style="width:100%;"><br />
<tr><br />
<td style="vertical-align:top; width:50%;"><br />
<table cellspacing="10" style="width:100%;"><br />
<br />
<tr><br />
<td style="margin:0; margin-top:10px; margin-right:10px; border:1px solid #e9e7d4; border-bottom: 2px solid #c9c7b4; border-top: 1px solid #fff; padding:0 1em 1em 1em; background-color: #f9f7e4; align:right;vertical-align:top;"><br />
== [[File:Icon intro 32.png|link=Why program in D]] Introduction ==<br />
* [[Why program in D|Why program in D?]]<br />
* [https://tour.dlang.org Take the tour]<br />
* [[Getting Started | Getting started]]<br />
* [[First Language | Learning D as a first language]] &mdash; [[Coming From | As a second language]]<br />
* [https://dlang.org/orgs-using-d.html Current uses of D] by organizations and notable projects <br />
</td><br />
</tr><br />
<br />
<tr><br />
<td style="margin:0; margin-top:10px; margin-right:10px; border:1px solid #c0d9e2; border-bottom: 2px solid #a0b9c2; border-top: 1px solid #fff; padding:0 1em 1em 1em; background-color: #e4f4f9; align:right;vertical-align:top;"><br />
<br />
== [[File:Icon community 32.png|link=http://forum.dlang.org]] Community ==<br />
* [http://forum.dlang.org Forums] / [news://news.digitalmars.com Newsgroup] / [http://lists.puremagic.com/mailman/listinfo Mailing lists] (Same content)<br />
* [[Guidelines for Professional Conduct]]<br />
* [http://dlang.org/orgs-using-d.html Organizations using D]<br />
* [irc://irc.libera.chat/d <tt>#d</tt> on Libera.Chat] or [irc://irc.oftc.net/d OFTC] IRC<br />
* [https://discord.gg/bMZk9Q4 D Code Club] on Discord<br />
* [https://discord.gg/MrJV27E DLang (Unofficial)] on Discord<br />
* [https://dlang.org/blog Official blog]<br />
* [http://planet.dsource.org/ Planet D]<br />
* [http://dpldocs.info/this-week-in-d/Blog.html This Week in D]<br />
* [http://www.linkedin.com/groups/D-Developer-Network-3923820 LinkedIn: D Developer Network (DDN)]<br />
<!-- [https://plus.google.com/communities/100033468228217743303 Google+: D Programming Enthusiasts] --><br />
* [https://www.facebook.com/dlang.org Facebook: D Programming Language]<br />
<!-- [https://www.xing.com/net/dlang XING - D Programming Language] --><br />
* [http://letsfindcourse.com/d-programming-courses D Programming Tutorials Recommended by Programming Community]<br />
<!-- [https://www.meetup.com/topics/dpl/|D User Groups (DUGs)] — [[Events]] --><br />
* [http://stackoverflow.com/questions/tagged/d D on StackOverflow]<br />
* [http://rosettacode.org/wiki/Category:D D on RosettaCode] - See solutions of common programming tasks in the D programming language.<br />
* [http://www.reddit.com/r/d_language/ reddit: /r/d_language]<br />
* [[GSOC_2019_Ideas | Google Summer of Code 2019 (GSoC)]]<br />
* [[Research_scholarship | Research Scholarship]]<br />
* [https://exercism.io/tracks/d D Track on Exercism.io] - Solve exercises and get feedback<br />
* [[Beerconf]]<br />
</td><br />
</tr><br />
<br />
<tr><br />
<td style="margin:0; margin-top:10px; margin-right:10px; border:1px solid #dddddd; border-bottom: 2px solid #bbb; border-top: 1px solid #fff; padding:0 1em 1em 1em; background-color:#f2f2f2; align:right;vertical-align:top;"><br />
<br />
== [[File:Icon dev 32.png|link=Get involved]] Contributing ==<br />
* [[Get involved]]<br />
* [https://trello.com/dlang Trello Board]<br />
* [[DIPs|D Improvement Proposals]] (DIPs)<br />
* [https://github.com/dlang/projects/issues Task List]<br />
* [https://www.flipcause.com/secure/cause_pdetails/NjI2Njg= Task Bounties]<br />
* [[Review Queue]]<br />
* [[Runtime internals]]<br />
* [[Beta Testing]]<br />
* [[Language_issues | Language Issues]]<br />
* [[Language_design_discussions | Language Design Discussions]]<br />
* [[Wish_list | Wish list and action list]]<br />
* [[Documentation_improvement_initiative | Documentation Improvement Initiative]]<br />
</tr><br />
<br />
</table><br />
</td><br />
<td style="vertical-align:top; width:50%;"><br />
<table cellspacing="10" style="width:100%;"><br />
<br />
<tr><br />
<td style="margin:0; margin-top:10px; margin-right:10px; border:1px solid #d0e2c0; border-bottom: 2px solid #b0c2a0; border-top: 1px solid #fff; padding:0 1em 1em 1em; background-color: #eaf7df; align:right;vertical-align:top;"><br />
<br />
== [[File:Icon docs 32.png|link=http://dlang.org/spec.html]] Documentation ==<br />
* [http://dlang.org/spec.html D Language Specification]<br />
* [http://dlang.org/phobos/index.html Standard Library Reference (Phobos)]<br />
<!--* [http://ddocs.org Third-party library documentation]--><br />
* [[Commonly-Used Acronyms]]<br />
* [[Books|Books (Online and printed)]]<br />
* [[Articles]] — [[Tutorials]] — [[Cookbook]]<br />
* [[ResearchPapers| Research papers]]<br />
* [[Language Designs Explained]]<br />
* [[Language History and Future]]<br />
</td><br />
</tr><br />
<br />
<tr><br />
<td style="margin:0; margin-top:10px; margin-right:10px; border:1px solid #e9e7d4; border-bottom: 2px solid #c9c7b4; border-top: 1px solid #fff; padding:0 1em 1em 1em; background-color: #f1f7df; align:right;vertical-align:top;"><br />
<br />
== [[File:Icon tools 32.png|link=Compilers]] Compilers &amp; Tools ==<br />
* [[Compilers | D Compilers]] ([[DMD]], [[GDC]], [[LDC]])<br />
* [[Experimental compilers]] ([[SDC]], [[DIL]])<br />
* [[IDEs]] &mdash; [[Editors | Text Editors ]]<br />
* [[Development tools]]<br />
* [[Lexers Parsers | Lexers, Parsers]]<br />
* [[Build Tools|Build tools]]<br />
* [[Debuggers]] <br />
* [[Continuous Integration | Continuous Integration services]]<br />
* [[Online compilers|Online compilers and disassemblers]]<br />
</td><br />
</tr><br />
<br />
<tr><br />
<td style="margin:0; margin-top:10px; margin-right:10px; border:1px solid #dde0e9; border-bottom: 2px solid #bdc0c9; border-top: 1px solid #fff; padding:0 1em 1em 1em; background-color: #edf0f9; align:right;vertical-align:top;"><br />
<br />
== [[File:Icon resources 32.png|link=Libraries and Frameworks]] Resources & Directory ==<br />
* [https://code.dlang.org/ Official package repository]<br />
* [[Libraries and Frameworks]]<br />
* [[Open Source Projects]]<br />
* [[Bindings]]<br />
* [[Videos]]<br />
* [[Websites]] ([[Websites/Blogs|Blogs]])<br />
* [[People]] ([[People/Github|On Github]])<br />
* [[BenchMarks]]<br />
* [[Art]] (Logos, etc...)<br />
</td><br />
</tr><br />
<br />
<tr><br />
<td style="margin:0; margin-top:10px; margin-right:10px; border:1px solid #eee; border-top: 2px solid #ccc; border-bottom: 1px solid #f6f6f6; padding:0 1em 1em 1em; background-color:#fff; align:right;vertical-align:top;"><br />
<br />
== [[File:Icon meta 32.png|link=Meta]] <span style="color:#999;">Meta</span> ==<br />
* [[DWiki:General discussion|Discuss this wiki]] <span style="color:#999;">(Criticise, suggest improvements etc.)</span><br />
* [[DWiki:Community portal|DWiki Community Portal]]<br />
</td><br />
</tr><br />
<br />
</table><br />
</td><br />
</tr><br />
</table><br />
<br />
{{:DMD Widget}}</div>Schveiguyhttps://wiki.dlang.org/?title=Beerconf&diff=10066Beerconf2022-05-14T19:25:33Z<p>Schveiguy: fix sentence grammar</p>
<hr />
<div>BeerConf is the unofficial name given to the daily evening gatherings during [https://dconf.org/ the annual DConf]. It was coined by Ethan Watson, who noted that many of the participants drink beer during their discussions of D and other topics. Often, these gatherings have taken place in the lobby or bar of a designated hotel where most conference attendees stay. When no suitable facilities are available, such as in our 2019 and 2022 editions in London, sponsors have stepped up to rent space in a local pub.<br />
<br />
== Online Beerconf ==<br />
After DConf 2020, scheduled for June of that year, was cancelled due to the COVID-19 pandemic, a few people decided to create a virtual BeerConf to recreate the camaraderie, discussion, and general enjoyment real-world BeerConf participants experience. Using a freely available [https://meet.jit.si/ Jitsi Meet instance], BeerConf June 2020 was the first online gathering of its kind in The D community.<br />
<br />
Steven Schveighoffer and Iain Buclaw, two core D developers, were the hosts of the first BeerConf. It was a success, so they decided to make it a monthly event. So every month, typically on the last weekend (unless special circumstances require moving it to another weekend), Steven and Iain continue to host BeerConf for the D community to chat, enjoy our shared fascination with the language, and work through sometimes difficult problems that don't lend themselves well to text-based discussion.<br />
<br />
The online group is generally started on a Saturday, and is left open for 48 hours to account for the disparate time zones in which D community members reside. Topics are unrestricted and unplanned. Past topics include Beer (of course), core D development, D game development, using D for controlling car transmissions, future directions of the D language, WIP projects, and more, and many people get work done in D while in the chat. Language maintainers Walter Bright and Atila Neves, as well as Andrei Alexandrescu, frequently join for a time as well.<br />
<br />
Contrary to the name, there is no requirement to actually drink Beer or any alcoholic beverage during BeerConf. There is no requirement to participate either via audio or video; many people join in only to listen, or choose not to enable their cameras. In fact, the requirements are very very loose; all you need is a device that provides access to Jitsi Meet via a web browser or the mobile app.<br />
<br />
BeerConf served as a testbed for DConf Online, during which Q & A sessions take place over Jitsi Meet.<br />
<br />
[[Category:Conferences]]</div>Schveiguyhttps://wiki.dlang.org/?title=DWiki:Current_events&diff=9942DWiki:Current events2021-02-13T17:22:16Z<p>Schveiguy: Update dconf info, add beerconf link</p>
<hr />
<div>For now, the best places to follow news on upcoming D events is the Announce forum, and Adam Ruppe's This Week in D blog:<br />
<br />
*[http://forum.dlang.org/group/announce dlang.org forum, Announce section]<br />
*[http://forum.dlang.org/search?q=talk&scope=group%3AdigitalmarsDannounce search for talks in the Announce forum]<br />
*[http://arsdnet.net/this-week-in-d/ This Week in D]<br />
<br />
=== DConf ===<br />
<br />
[[DConf]] - 2020, was scheduled to be in June of 2020, but was cancelled due to the COVID-19 pandemic<br />
<br />
*[https://dconf.org/2020/ dconf 2020]<br />
<br />
==== DConf Online ====<br />
<br />
[[DConf Online]] - 2020, happened on 21 November - 22 November.<br />
<br />
*[http://dconf.org/2020/online/index.html dconf online 2020]<br />
<br />
==== Beerconf ====<br />
<br />
[[Beerconf]] is a nightly gathering of D conferencegoers during the DConf conferences. It also has become a monthly online gathering since the cancellation of DConf 2020. <br />
<br />
=== Meetups ===<br />
<br />
There are regular meetup groups in London, Silicon Valley, and other locations - please check the forums.<br />
<br />
*[https://www.meetup.com/D-Lang-Silicon-Valley/ D Lang / Silicon Valley]</div>Schveiguyhttps://wiki.dlang.org/?title=Beerconf&diff=9940Beerconf2021-02-13T17:17:38Z<p>Schveiguy: Beerconf - the other conference that happens during dconf</p>
<hr />
<div>Beerconf is an unofficial name given to the frequent gatherings in the evenings at all Dconf conferences. It was given the name by Ethan Watson, noting how many of the participants drink beer while gathering to discuss D topics. These gatherings frequently happened in the "hang-out" place which was usually the hotel lobby where most participants were staying.<br />
<br />
== Online Beerconf ==<br />
In June of 2020, when Dconf 2020 was supposed to happen, but was cancelled due to the COVID-19 pandemic, a few people decided to create a virtual Beerconf to recreate the camaraderie, discussion, and general enjoyment the live Beerconf participants had every night after live Dconf. Using a freely available Jitsi online conference service, Beerconf June 2020 was the first online gathering of its kind in The D community.<br />
<br />
Steven Schveighoffer and Iain Buclaw, two language core developers, are the hosts of Beerconf. After the first Beerconf, they decided that it would be a beneficial thing to hold every month. So every month, typically at the end of the month (but can be moved usually due to holidays), Beerconf is held for people to chat, enjoy our shared fascination with the language, and work through sometimes difficult problems that don't lend themselves well to text-based discussion.<br />
<br />
The online group is generally started on a Saturday, and is left open for 48 hours to account for the disparate time zones of all the D community. Topics can be anything, and are not planned. Past topics include Beer (of course), core D development, D game development, using D for controlling car transmissions, future directions of the D language, projects people are working on, and many people do some work in D while on the conference. Language maintainers Walter Bright and Atila Neves, as well as Andrei Alexandrescu will generally join for a time as well.<br />
<br />
Contrary to the name, there is no requirement to actually drink Beer or any alcoholic beverage during the conference. There is no requirement to participate either via audio or video, many people join in to listen and sometimes chat. In fact, the requirements are very very loose -- you need a computer and access to Jitsi.<br />
<br />
Beerconf served as the base testbed for Dconf Online 2020, which was also run mostly over Jitsi.</div>Schveiguyhttps://wiki.dlang.org/?title=GDC&diff=9329GDC2018-08-07T12:54:20Z<p>Schveiguy: Removing more dead links.</p>
<hr />
<div>{{:Compilers_Widget}}<br />
<br />
Welcome to GDC. This project aims to continue the development of GDC, a GCC frontend for the D programming language.<br />
<br />
=== Useful Links ===<br />
* [https://github.com/D-Programming-GDC/GDC Source code (GitHub)]<br />
* [http://www.gdcproject.org/ Project website]<br />
* [http://bugzilla.gdcproject.org/describecomponents.cgi Bug tracker]<br />
* [https://www.bountysource.com/trackers/455080-gdc Bountysource project]<br />
<br />
== Introduction ==<br />
=== What is GDC? ===<br />
GDC is a frontend for the [//dlang.org D programming language]. By using GCC as a backend, it gives us the ability to target the same platforms that GCC targets.<br />
<br />
This project was originally started by David Friedman. His first announcement can be found [http://forum.dlang.org/post/c3mnst$2htg$1@digitaldaemon.com here] and his original project page can be found [http://dgcc.sourceforge.net here]. Unfortunately, he disappeared from the D scene, and was no longer able to maintain GDC. This project was the result of an effort to help continue David Friedman's work on GDC.<br />
<br />
The paperwork is complete and efforts are currently underway to merge GDC into the official GCC codebase, which represents a great step forward for D. However, more than ever, GDC is in need of contributors to keep it up to date with both the D frontend and the trunk development of the GCC backend.<br />
<br />
=== Why GDC? ===<br />
There are many advantages to adding a D frontend to GCC, and most of them stem from the fact that the GCC codebase has been the focus of extensive development over several decades, and that the GCC middle and back ends are designed such that multiple languages can easily take advantage of them. This means that a D frontend that can make use of the GCC middle and backend code will gain many advantages that would require years of development to match in the DMD codebase.<br />
<br />
Firstly, GCC targets many more platforms than DMD.<br />
<br />
Secondly, GCC has a very well-developed optimization framework that can generally generate more performant code than DMD, particularly when taking advantage of more recent CPU features such as SIMD instructions (both directly and through automatic vectorization).<br />
<br />
Thirdly, GDB is primarily developed to debug code generated by GCC, so debugging code generated by GCC will generally result in a better user experience.<br />
<br />
=== Status ===<br />
D2 Frontend Version: [//www.digitalmars.com/d/2.0/changelog.html#new2_066.1 2.066.1]<br />
<br />
=== Supported GCC versions ===<br />
* [//gcc.gnu.org/gcc-4.7 GCC 4.7.x (2.062)]<br />
* [//gcc.gnu.org/gcc-4.8 GCC 4.8.x (2.066.1)]<br />
* [//gcc.gnu.org/gcc-4.9 GCC 4.9.x (2.066.1)]<br />
* [//gcc.gnu.org/gcc-5 GCC 5.x (2.066.1)]<br />
* [//gcc.gnu.org/gcc-6 GCC 6.x (2.068.2)]<br />
* [//gcc.gnu.org/gcc-7 GCC 7.x (2.068.2)]<br />
* [//gcc.gnu.org/snapshots.html GCC 8.x Development (2.068.2)]<br />
<br />
== Installing GDC ==<br />
=== Linux distribution packages ===<br />
Official packages are available for these distributions<br />
* [https://packages.debian.org/search?keywords=gdc&searchon=names&exact=1&suite=all&section=all Debian]<br />
* [http://packages.ubuntu.com/search?keywords=gdc&searchon=names&exact=1&suite=all&section=all Ubuntu]<br />
<br />
For Arch linux, an AUR package is available:<br />
<br />
* [https://aur.archlinux.org/packages/gdc/ AUR package]<br />
<br />
For Gentoo Linux, GDC enabled ebuilds of GCC are available from the [https://github.com/gentoo/dlang dlang] overlay:<br />
* [https://wiki.gentoo.org/wiki/Dlang Gentoo Wiki: Dlang]<br />
Enable the ''d'' USE-flag for sys-devel/gcc and emerge it again. If you are currently on stable GCC you can install the GDC enabled testing version in parallel. gcc-config should be used to switch the active version temporarily if you would like to be able to run ''gdc'' without typing the full path.<br />
<br />
=== Official prebuilt binaries ===<br />
Various precompiled toolchains are available on the [http://gdcproject.org/downloads/ official download page].<br />
<br />
=== Detailed installation guide ===<br />
[[GDC/Installation|GDC/Installation]] contains detailed information on building and installing GDC alongside your system's host compilers.<br />
<br />
== Documentation ==<br />
=== User Documentation ===<br />
[[GDC/Using_GDC]] aims to explain some aspects of GDC such as its usage, differences from DMD, and known issues. If you need help using GDC, take a look here.<br />
<br />
=== Target Documentation ===<br />
==== MinGW ====<br />
[[GDC/MinGW|This documentation page]] aims to explain aspects of the MinGW port of GDC. Such as MinGW specific features, Windows specific topics and known issues. A source code repository containing various patches and a build script can be found [https://github.com/venix1/MinGW-GDC here], but it may be out of date.<br />
<br />
==== ARM Cortex-M ====<br />
A minimal "Hello World!" example that requires no D runtime, no standard library (Phobos), and no C can be found [[Minimal semihosted ARM Cortex-M %22Hello_World%22 | here]]. It serves as an excellent starting point for anyone wishing to pursue their own port of D to the ARM Cortex-M family of microcontrollers.<br />
<br />
Additionally, there is [https://bitbucket.org/timosi/minlibd minlibd]. A collection of libraries and tools to compile D language programs for embedded systems with the GDC compiler.<br />
<br />
See also [[Bare Metal ARM Cortex-M GDC Cross Compiler]] for instructions specific to building a bare metal ARM Cortex-M GDC cross compiler.<br />
<br />
=== Developer Documentation ===<br />
[[GDC/Development/DevelopmentEnvironment]] provides instructions on how to set up a development environment for hacking the GDC compiler.<br />
<br />
[[GDC/Hacking]] describes the structure of the GCC and GDC source code repositories.<br />
<br />
[[GDC/Development]] contains information about the internals of GDC, and will be a valuable resource for those that wish to help with GDC's development.<br />
<br />
== Support ==<br />
Support can be found in a couple of different places:<br />
<br />
* On irc.freenode.net, there is a GDC irc channel. It is channel #d.gdc.<br />
* The D.gnu newsgroup, located [//forum.dlang.org/group/D.gnu here].<br />
* Sending an inbox message to one of the maintainers.<br />
<br />
The D.gnu newsgroup should also be used for general discussion about GDC. A bug, proposal, or enhancement can go to the [http://bugzilla.gdcproject.org/describecomponents.cgi issue tracker]. If you choose to use the issue tracker, please label the issue appropriately. (bug, proposal, enhancement)<br />
<br />
=== Bugs ===<br />
A list of open bugs can be found [http://bugzilla.gdcproject.org/describecomponents.cgi here.] New bugs should be submitted to the GDC Bugzilla site. A simple comment saying "This also happens/doesn't happen on Mac\Windows\Linux under GCC x.x.x(GCC version)" can be useful in helping solve the bug.<br />
<br />
If you have found a possible bug in GDC, please submit it! Here are some guidelines that you should follow when submitting a bug:<br />
<br />
# Make sure the bug has not already been submitted to GDC.<br />
# Include the GCC version. (e.g. 4.7.0, etc)<br />
# Include the git changeset you are using for GDC. (e.g. changset 6f03952ff48f)<br />
# Include your operating system.(Mac/Windows/flavour of Linux)<br />
# Include a simple test case demonstrating the issue.<br />
# if possible, include a patch to fix the issue.<br />
<br />
== Getting Involved ==<br />
<br />
Please see [[GDC/GCCSubmission|Submission of D Front End]] for a list of open (and closed) tasks for the current GCC submission process.<br />
<br />
Please see [[GDC/ProjectIdeas|Project Ideas]] for inspiration and long term goals.<br />
<br />
GDC is currently developed by a very small group (as the commit history on GitHub shows). While the addition of a D frontend to GCC represents a great step forward for D, it also represents an informal promise by the D community to keep the D frontend up to date with the latest GCC development.<br />
<br />
If you use GDC, we encourage you to try to contribute, whether by submitting pull requests or bug reports. In the past, GDC has nearly died due to poor communication and lack of development. Avoiding those issues is easier than ever before, but GDC will always need a community that's willing to give back.<br />
<br />
Thanks to GitHub, contributing to GDC is as easy as forking the repository and submitting a pull request (although this workflow will likely change when the merge is officially complete), and filing a bug report is a simple web form.<br />
<br />
There are a lot of things that you can do to get involved and help out with GDC. They vary from making simple documentation for some of the files, finding and submitting bugs, testing out bugs on different platforms, or submitting patches for GDC. Any help is appreciated.<br />
<br />
[[Category:GDC Compiler]]</div>Schveiguyhttps://wiki.dlang.org/?title=Using_GDC&diff=9328Using GDC2018-08-07T12:52:09Z<p>Schveiguy: Removing dead link (no GDC bugs are stored in D bugzilla)</p>
<hr />
<div><br />
== Simple Compilation ==<br />
<br />
Creating an executable is quite easy.<br />
<br />
<syntaxhighlight lang="bash"><br />
gdc main.d -o main<br />
</syntaxhighlight><br />
<br />
This will attempt to compile and link the file 'main.d' and place the output into the file 'main'.<br />
If you do not use the -o switch, then your executable will be called 'a.out'.<br />
<br />
On a typical Unix system, you can execute the resulting program with "./main" or "./a.out". On Windows, you can run the program with "main" or "a.out".(?)<br />
<br />
To help make a transition from [[DMD]] to [[GDC]] easier, there is the standalone program 'gdmd', distributed with GDC releases, which maps DMD's command line options to GDC.<br />
To see the available options for gdmd, type 'gdmd' or 'gdmd -help' on the command line.<br />
<br />
----<br />
<br />
== Command line switches ==<br />
<br />
You can always display a list of D-specific command line switches with:<br />
<br />
<syntaxhighlight lang="bash"><br />
gdc --help=d<br />
</syntaxhighlight><br />
<br />
Many of the options in GCC may also be applicable to GDC, such as optimization flags, -O1, -O2, -Os, -O3, or flags such as -c, which compiles a file, but does not link it, and will send the object file to "main.o", if you file is main.d<br />
<br />
==== Compiler Options ====<br />
<br />
{|class="wikitable"<br />
! Switch<br />
! Description<br />
|-<br />
| '''-debuglib='''<lib>||Link against a debug <lib> instead of Phobos.<br />
|-<br />
| '''-defaultlib='''<lib>||Link against <lib> instead of Phobos.<br />
|-<br />
| '''-fdeps'''||Print information about module dependencies.<br />
|-<br />
| '''-fdeps='''<file>||Write module dependencies to <file>.<br />
|-<br />
| '''-fdoc'''||Generate Ddoc documentation.<br />
|-<br />
| '''-fdoc-dir='''<dir>||Write Ddoc documentation files to <dir>.<br />
|-<br />
| '''-fdoc-file='''<file>||Write Ddoc documentation to <file>.<br />
|-<br />
| '''-fdoc-inc='''<file>||Include a Ddoc macro <file>.<br />
|-<br />
| '''-fintfc'''||Generate D interface files,<br />
|-<br />
| '''-fintfc-dir='''<dir>||Write D interface files to directory <dir>.<br />
|-<br />
| '''-fintfc-file='''<file>||Write D interface file to <file>.<br />
|-<br />
| '''-fmake-deps'''||Print information about module Makefile dependencies.<br />
|-<br />
| '''-fmake-deps='''<file>||Write Makefile dependency output to <file>.<br />
|-<br />
| '''-fmake-mdeps'''||Like -fmake-deps but ignore system modules.<br />
|-<br />
| '''-fmake-mdeps='''<file>||Like -fmake-deps=<file> but ignore system modules.<br />
|-<br />
| '''-fonly='''<file>||Process all modules specified on the command line, but only generate code for the module <file>.<br />
|-<br />
| '''-fXf='''<file>|| Write JSON documenation to <file>.<br />
|-<br />
| '''-imultilib''' <dir>||Set <dir> to be the multilib include subdirectory.<br />
|-<br />
| '''-iprefix''' <path>||Specify <path> as a prefix for next two options.<br />
|-<br />
| '''-isysroot''' <dir>||Set <dir> to be the system root directory.<br />
|-<br />
| '''-isystem''' <dir>||Add <dir> to the start of the system include path.<br />
|-<br />
| '''-I''' <dir>||Add <dir> to the list of the module import paths.<br />
|-<br />
| '''-J''' <dir>||Add <dir> to the list of string import paths.<br />
|-<br />
| '''-nophoboslib'''||Do not link the standard D library in the compilation. The D standard library, Phobos, and the D runtime are compiled into a single library, libgphobos2. Therefore, this option prevents linking both Phobos and the D runtime.<br />
|-<br />
| '''-nostdinc'''||Do not search standard system include directories.<br />
|-<br />
| '''-nostdlib'''||Do not link the standard gcc libraries in the compilation.<br />
|}<br />
<br />
==== Language Options ====<br />
<br />
Most of these have both positive and negative forms; the negative form of '''-ffoo''' is '''-fno-foo'''.<br />
This page lists only one of these two forms, whichever one is not the default.<br />
<br />
{|class="wikitable"<br />
! Switch<br />
! Description<br />
|-<br />
| '''-fno-assert'''||Don't generate runtime code for the <code>assert</code> keyword.<br />
|-<br />
| '''-fno-bounds-check'''||Don't generate runtime code for checking array bounds before indexing.<br />
|-<br />
| '''-fno-builtin'''||Don't recognize built-in functions. It only goes as far as not recognizing user declared functions as being built-in. The compiler may still generate builtin calls internally.<br />
|-<br />
| '''-fno-debug'''||Don't compile <code>debug</code> code.<br />
|-<br />
| '''-fdebug='''<level>||Compile in debug code less than or equal to that in <level>.<br />
|-<br />
| '''-fdebug='''<ident>||Compile in debug code identified by <ident>.<br />
|-<br />
| '''-fd-verbose'''||Print information about D language processing to stdout.<br />
|-<br />
| '''-fd-vtls'''||Print information about all variables going into thread local storage to stdout.<br />
|-<br />
| '''-femit-templates'''||Generate code for all template instantiations, not just used instantiations.<br />
|-<br />
| '''-fno-in'''||Don't compile <code>in</code> contracts.<br />
|-<br />
| '''-fno-invariants'''||Don't compile <code>invariant</code> contracts.<br />
|-<br />
| '''-fno-emit-moduleinfo'''||Don't generate any <code>ModuleInfo</code>.<br />
|-<br />
| '''-fno-out'''||Don't compile <code>out</code> contracts.<br />
|-<br />
| '''-fproperty'''||Enforce @property syntax of D code.<br />
|-<br />
| '''-frelease'''||Compile release version. Equivalent to -fno-invariants -fno-in -fno-out -fno-assert -fno-bounds-check.<br />
|-<br />
| '''-funittest'''||Compile <code>unittest</code> code.<br />
|-<br />
| '''-fversion='''<level>||Compile in version code greater than or equal to that in <level>.<br />
|-<br />
| '''-fversion='''<ident>||Compile in version code identified by <ident>.<br />
|-<br />
| '''-Wall'''||Enable most warning messages.<br />
|-<br />
| '''-Werror'''||Error out the compiler on warnings.<br />
|-<br />
| '''-Wdeprecated'''||Enable warning of deprecated language features.<br />
|-<br />
| '''-Wunknown-pragmas'''||Enable warning of unsupported pragmas.<br />
|}<br />
<br />
<br />
----<br />
<br />
== Extensions ==<br />
=== Extended Assembler ===<br />
GDC implements a GCC extension that allows inline assembler with D expression operands. It is available on nearly all targets, not just i386. The syntax differs from the C language extension in the following ways: <br />
* Statements start with 'asm { ...', just like the regular DMD inline assembler.<br />
* It is not necesary to put parentheses around operands.<br />
* Instruction templates can be compile-time string constants, not just string literals. If the template is not a string literal, use parenthesis to indicate that it is not an opcode.<br />
<br />
Unlike i386 inline assembler statements, extended assembler statements do not prevent a function from being inlined.<br />
<br />
See the GCC manual for more information about this extension.<br />
<br />
Example:<br />
<syntaxhighlight lang="D"><br />
uint invert(uint v)<br />
{<br />
uint result;<br />
version(X86)<br />
asm{ "notl %[iov]" : [iov] "=r" result : "0" v; }<br />
else version(PPC)<br />
asm{ "nor %[oresult],%[iv],%[iv]" : [oresult] "=r" result : [iv] "r" v; }<br />
return result;<br />
}<br />
</syntaxhighlight><br />
<br />
=== Attributes ===<br />
GDC supports a small subset of the [http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html GCC attributes]. The syntax differs from the C language __attribute__ extension in the following ways: <br />
<br />
* All attributes are recognised only through the 'gcc.attribute' module.<br />
* The attribute, and all its arguments are comma-delimited CTFE strings packed in a tuple.<br />
* Nesting (brackets) for attribute arguments are optional.<br />
<br />
<br />
{|class="wikitable"<br />
! Attribute<br />
! Description<br />
|-<br />
| forceinline* || Inlines the function even if no optimization level is specified.<br />
|-<br />
| flatten* || Inlines every call inside this function, if possible.<br />
|-<br />
| noinline* || Prevents the function from being considered for inlining.<br />
|-<br />
| target* || Specify that the function is to be compiled with different target options than specified on the command line.<br />
|-<br />
| noclone* || See [http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html GCC documentation].<br />
|-<br />
| section* || Place symbol in specific section. See [http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html GCC documentation].<br />
|-<br />
| weak* || Mark symbol as weak. See [http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html GCC documentation].<br />
|-<br />
| alias* || Mark symbol as an alias (on object file level). See [http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html GCC documentation].<br />
|-<br />
| architecture specific attributes || All target specific attributes are available. See [http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html GCC documentation].<br />
|}<br />
<br />
<nowiki>*</nowiki> Being backend attributes, you can't enforce that these attributes actually take effect in user code (no static asserts!) - but you have some guarantee in that the backend will complain if it can't apply the attribute<br />
<br />
<br />
Example:<br />
<syntaxhighlight lang="D"><br />
import gcc.attribute;<br />
<br />
@attribute("noinline") void foobar() { }<br />
<br />
@attribute("target", ("sse3")) void sse3_func() { }<br />
<br />
//Can be overwritten in other source files<br />
@attribute("weak") extern(C) void c_func() {};<br />
@attribute("alias", "c_func") void aliased_func();<br />
<br />
//Place into "test" section<br />
@attribute("section", "test") int value;<br />
<br />
</syntaxhighlight><br />
<br />
== Known Issues ==<br />
<br />
See [http://bugzilla.gdcproject.org bugzilla] to see<br />
bugs that have been reported to GDC.<br />
<br />
Some more known issues, taken from [//dgcc.sourceforge.net/gdc/manual.html here]:<br />
<br />
* See [http://dstress.kuehne.cn/www/dstress.html DStress] for known failing cases. (Again, may be irrelevant)<br />
* Debugging information may have a few problems. For D symbol name demangling you need at least gdb 7.2.<br />
* Some targets do not support once-only linking. A workaround is to manually control template emission. See the -femit-templates option below. For Darwin, Apple's GCC 3.x compiler supports one-only linking, but GDC does not build with those sources. There are no problems with the stock GCC 4.x on Darwin.<br />
* Complex floating point operations may not work the same as DMD.<br />
* Some math functions behave differently due to different implementations of the extended floating-point type.<br />
* Volatile statements may not always do the right thing.<br />
* Because of [//groups-beta.google.com/groups?hl=en&q=%22large+executables+on+AIX%22&qt_s=Search a problem on AIX], the linker will pull in more modules than needed.<br />
* Some C libraries (Cygwin, MinGW, AIX) don't handle floating-point formatting and parsing in a standard way.<br />
<br />
== See also ==<br />
* [[GDC]]<br />
<br />
== External links ==<br />
*[https://github.com/D-Programming-GDC/GDMD GDMD Perl source]<br />
*[https://github.com/D-Programming-GDC/GDMD/tree/dport GDMD D version]<br />
<br />
[[Category:GDC Compiler]]</div>Schveiguyhttps://wiki.dlang.org/?title=Bindings&diff=9327Bindings2018-08-07T12:48:41Z<p>Schveiguy: Fix ancient bugzilla link</p>
<hr />
<div>Binding is a procedure that converts header files, function prototypes, and variable declarations to from another language to D.<br />
<br />
== Projects ==<br />
Projects and repositories for collecting / maintaining D bindings:<br />
<br />
* [https://github.com/D-Programming-Deimos Deimos]<br />
* [http://dsource.org/projects/bindings DSource bindings project]<br />
<br />
== Binding generators ==<br />
Projects which automate generating D bindings:<br />
<br />
=== C/C++ to D ===<br />
<br />
{{Projects<br />
| Projects =<br />
<br />
{{Project<br />
| name = '''dstep'''<br />
| about = A tool for converting C and Objective-C headers to D modules<br />
| platform = Posix, Windows<br />
| license = Boost Software License 1.0<br />
| url = https://github.com/jacob-carlborg/dstep<br />
}}<br />
<br />
{{Project<br />
| name = '''dpp'''<br />
| about = #include C headers in D code<br />
| platform =<br />
| license = Boost License 1.0. <br />
| url = https://github.com/atilaneves/dpp<br />
}}<br />
<br />
{{Project<br />
| name = '''SWIG'''<br />
| about = Simplified Wrapper and Interface Generator<br />
| platform =<br />
| license = <br />
| url = http://www.swig.org/Doc2.0/D.html<br />
}}<br />
<br />
{{Project<br />
| name = '''cwrap'''<br />
| about = High-level wrapper generator<br />
| platform =<br />
| license = Boost License 1.0. <br />
| url = https://bitbucket.org/denis-sh/cwrap<br />
}}<br />
<br />
{{Project<br />
| name = '''htod'''<br />
| about = Migration tool to aid in converting C header files<br />
| platform = Windows<br />
| license = <br />
| url = http://dlang.org/htod.html<br />
}}<br />
<br />
}}<br />
<br />
=== Objective-C to D ===<br />
<br />
* [https://github.com/jacob-carlborg/dstep dstep]<br />
<br />
=== D to C/C++ ===<br />
<br />
* [https://issues.dlang.org/show_bug.cgi?id=9285 dtoh]<br />
<br />
== Bindings ==<br />
=== Compression & Encryption ===<br />
{{Projects<br />
| Projects =<br />
<br />
{{Project<br />
| name = '''OpenSSL'''<br />
| about = D version of the C headers for openssl<br />
| platform = Windows/POSIX<br />
| license = MIT <br />
| url = https://github.com/D-Programming-Deimos/openssl<br />
}}<br />
{{Project<br />
| name = '''liblzma'''<br />
| about = Interface to LZMA compression library<br />
| platform = Windows/POSIX<br />
| license = <br />
| url = https://github.com/D-Programming-Deimos/liblzma<br />
}}<br />
{{Project<br />
| name = '''GNUTLS'''<br />
| about = Interface to GNUTLS library<br />
| platform = <br />
| license = LGPL<br />
| url = https://github.com/opticron/libdtls<br />
}}<br />
}}<br />
<br />
=== Multimedia & Games ===<br />
{{Projects<br />
| Projects =<br />
{{Project<br />
| name = '''MediaInfo'''<br />
| about = MediaInfo supplies technical and tag information about your video or audio files.<br />
| platform = Windows<br />
| license = GPL/LGPL<br />
| url = https://github.com/D-Programming-Deimos/libmediainfo<br />
}}<br />
{{Project<br />
| name = '''libsndfile'''<br />
| about = Libsndfile is a C library for reading and writing files containing sampled sound (such as MS Windows WAV and the Apple/SGI AIFF format) through one standard library interface. It is released in source code format under the Gnu Lesser General Public License.<br />
| platform = Windows/POSIX<br />
| license = LGPL<br />
| url = https://github.com/D-Programming-Deimos/libsndfile<br />
}}<br />
{{Project<br />
| name = '''Allegro'''<br />
| about = Allegro 4 and Allegro 5 are cross-platform, open source, game programming libraries, primarily for C and C++ developers.<br />
| platform = <br />
| license = <br />
| url = http://www.dsource.org/projects/dallegro<br />
}}<br />
{{Project<br />
| name = '''DerelictOrg'''<br />
| about = DerelictOrg is a collection of D bindings to C shared (dynamic) libraries which are useful for multimedia applications, with a heavy bias toward game development-related libraries.<br />
Bindings:<br />
* ALURE<br />
* ASSIMP<br />
* DevIL<br />
* FreeImage<br />
* FreeType<br />
* GLFW<br />
* Lua<br />
* ODE<br />
* OpenAL<br />
* OpenGL<br />
* PhysicsFS<br />
* SDL2<br />
* SFML2<br />
* Vorbis<br />
* libogg<br />
* libpq<br />
Older versions:<br />
* [http://www.dsource.org/projects/derelict Original DSource project]<br />
* [http://www.dsource.org/projects/derelict/browser/branches/Derelict2 Derelict 2 branch]<br />
* [https://github.com/aldacron/Derelict3 Derelict 3]<br />
| platform = <br />
| license = <br />
| url = https://github.com/DerelictOrg<br />
}}<br />
{{Project<br />
| name = '''Mediastreamer2'''<br />
| about = Mediastreamer2 is a powerful and lightweighted streaming engine specialized for voice/video telephony applications.<br />
| platform = <br />
| license = <br />
| url = https://github.com/axeoth/mediastreamer2_layer<br />
}}<br />
{{Project<br />
| name = '''AntTweakBarD'''<br />
| about = AntTweakBarD is a binding to AntTweakBar which is a multi-render-engine (D3D/OpenGL) GUI tweaking library.<br />
| platform = <br />
| license = zlib/libpng<br />
| url = https://github.com/d-gamedev-team/AntTweakBarD<br />
}}<br />
}}<br />
<br />
== Source code translators ==<br />
<br />
* [http://rainers.github.io/visuald/visuald/CppConversion.html cpp2d] - C++ to D converter (included with Visual D)<br />
* [https://github.com/dlang/visuald/blob/master/c2d/idl2d.d idl2d] - IDL / C++ header file to D converter<br />
<br />
== See also ==<br />
<br />
* [[D binding for C]]<br />
* [[Binding generators]]<br />
<br />
==External links==<br />
* [http://www.gamedev.net/page/resources/_/technical/game-programming/binding-d-to-c-r3122 Article] <br />
* [http://www.gamedev.net/blog/1140/entry-2254003-binding-d-to-c/ Series on creating bindings to C libraries for the D programming language].<br />
* [http://dlang.org/interfaceToC.html Interfacing to C (DLang page)]<br />
* [http://dlang.org/htod.html DLang htod tool]<br />
* [http://digitalmars.com/d/1.0/htomodule.html D1 article]<br />
<br />
<br />
[[Category:Binding]]</div>Schveiguyhttps://wiki.dlang.org/?title=Pull_Requests&diff=6655Pull Requests2015-09-11T12:58:01Z<p>Schveiguy: /* Stable Branch */</p>
<hr />
<div>The source code of the D compiler (dmd), runtime library (druntime), and standard library (Phobos), are all available at [https://github.com/D-Programming-Language GitHub].<br />
<br />
==Fork the project==<br />
<br />
To contribute to the D compiler, runtime library, or standard library, you need to create an account on GitHub, and then navigate to the [https://github.com/D-Programming-Language D programming language] page, select the project you wish to contribute to, and create a fork of that project.<br />
<br />
For example, if you wish to submit a patch to the D compiler, you should navigate to [https://github.com/D-Programming-Language/dmd D-Programming-Language/dmd], then click on the "Fork" button at the top right corner of the page. This will clone the D compiler sources into your list of projects.<br />
<br />
==Check out the sources==<br />
<br />
{{seealso|Using Git on Windows}}<br />
<br />
Once you have forked the project you wish to contribute to, use git to checkout a local copy of the project.<br />
<br />
Generally, you should checkout a copy of at least dmd, druntime, and phobos in order to have a working compiler toolchain that you can use to test your changes.<br />
<br />
Note: if you are intending to fix a regression for the current version for a point release, you must use the [[#Stable Branch|stable branch]] of the code. See the section on the stable branch for more information.<br />
<br />
After checking out the sources, you will probably want to [[Building DMD|build DMD]].<br />
<br />
==Make your changes in a branch==<br />
<br />
{{seealso_url|http://dlang.org/dstyle.html|D coding style}}<br />
<br />
Generally, it is preferred that any changes you wish to contribute should be made in its own dedicated topic branch. For example, if you have a fix for issue 1234 in the D compiler, you might want to do something like this:<br />
<br />
<syntaxhighlight lang="bash"><br />
cd /usr/src/d/dmd/src<br />
git checkout -b issue_1234<br />
vim expression.c # make your changes here<br />
make -f posix.mak<br />
... # test your changes here<br />
git commit -a # commit to the branch named 'issue_1234'<br />
git push -u origin # push changes to your fork of DMD<br />
</syntaxhighlight><br />
<br />
If you are fixing a specific bugzilla issue, then putting "Fix Issue NNNN" in the commit message will automatically add a message to the bug report when the commit is merged.<br />
<br />
==Test your changes==<br />
<br />
Before you submit your changes, it's a good idea to test it thoroughly first. It's also a good idea to run the unittests for druntime and phobos:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/druntime<br />
make -f posix.mak unittest<br />
cd ../phobos<br />
make -f posix.mak unittest<br />
</syntaxhighlight><br />
<br />
Pull requests that fail unittests will not be accepted by the maintainers, except under special circumstances.<br />
<br />
'''TBD:''' add instructions on running dmd's unittests.<br />
<br />
==Create a pull request==<br />
<br />
Once you have tested all your changes and pushed them to your fork on GitHub, you are ready to submit a pull request.<br />
<br />
# Navigate to your fork of the project on GitHub.<br />
# '''Important''': Select the branch that you made your changes in, say issue_1234.<br />
# Click on the "Pull Request" button.<br />
<br />
This will submit your changes for review by the D maintainers. If your changes are approved, they will be merged into the master branch. Otherwise, if the maintainers have some comments or feedback, you can refine your changes by editing and testing in your local workspace, and pushing the new changes to the same git branch. The new changes will be automatically included in your pull request.<br />
<br />
Choose a title for your pull request that clearly states what it does. When fixing a bug, the usual thing to do is to use the summary from the bugzilla report. Eg a title like "Fix 3797" or "Issue 3797" contains much less information than "Fix Issue 3797 - Regression(2.038): Implicit conversion between incompatible function pointers" and requires a lot more effort for the reviewers to determine if it is something they are interested in.<br />
<br />
Pull request descriptions should contain a hyperlink to the [[Bugzilla]] issue that is being fixed. This is usually added at the end of the description.<br />
<br />
After the pull request is created, the corresponding bugzilla issue should have the 'pull' keyword added and a link to the pull request posted in a comment.<br />
<br />
===Autotester===<br />
<br />
Pull requests are automatically picked up by the [[Git Commit Tester|autotester]], which compiles the code in the pull request and runs it through the dmd, druntime, and phobos unittests on all supported platforms. Generally, pull requests must pass all tests before they will be merged. The status of the tests can be monitored through the pull request page.<br />
<br />
Every user must be manually approved before the autotester will start testing their pull requests. Users can be approved by anyone with commit access.<br />
<br />
===Rebasing===<br />
<br />
Sometimes, if a particular change you are working on is taking a long time, or if you encounter a problem that is fixed by a new commit upstream, you may need to sync your local branch with master in order to keep the code up-to-date. In this case, it is recommended that you use git rebase to apply your changes ''on top of'' the latest git master, so that when you submit a pull request, the change history will be easier for the reviewers to follow. Using git merge is ''not'' recommended, as it may produce a lot of merge commits that may not be relevant to your changes.<br />
<br />
For example, you may be working on your changes:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/phobos<br />
git checkout mybranch<br />
vim std/algorithm.d # apply lots of cool changes here<br />
</syntaxhighlight><br />
<br />
First, before you resync with master, make sure all your changes are checked in (or stashed):<br />
<br />
<syntaxhighlight lang=bash><br />
git commit -a<br />
</syntaxhighlight><br />
<br />
If you forked from the official D programming language repositories you may need to add an upstream remote to pull in the latest official changes. If this is the case you can add an upstream remote like this:<br />
<br />
<syntaxhighlight lang=bash><br />
git remote add upstream git@github.com:D-Programming-Language/phobos<br />
</syntaxhighlight><br />
<br />
This adds another remote to your repository called upstream and only needs to be done once. Once the upstream remote is added, you can update your repository's master branch by running the following:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout master<br />
git pull --ff-only upstream master<br />
</syntaxhighlight><br />
<br />
The --ff-only option is to ensure that your master branch is identical to the official D sources' master branch, since otherwise you will end up with a very messy history that will be hard to clean up (and the reviewers will probably reject your pull request due to having unrelated merge commits).<br />
<br />
Now go back to your branch and rebase it:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout mybranch<br />
git rebase master<br />
</syntaxhighlight><br />
<br />
Now your sources should be up-to-date. Recompile and test everything to make sure it all works.<br />
<br />
Note that after rebasing, you will need to force an update to your fork on GitHub with the -f flag, otherwise it will fail because the histories don't match anymore:<br />
<br />
<syntaxhighlight lang=bash><br />
git push -f origin mybranch<br />
</syntaxhighlight><br />
<br />
You may wish to read up on [http://git-scm.com/book/en/Git-Branching-Rebasing how git rebase works] if you're not familiar with the concept.<br />
<br />
If, during the 'git rebase' command, you encounter conflicts, you may want to learn [http://stackoverflow.com/questions/8780257/git-rebase-a-branch-onto-master-failed-how-to-resolve how to resolve a conflict during git rebase].<br />
<br />
==Stable Branch==<br />
<br />
If you are working on a fix for a regression, chances are it should go into the next point release, and not the next major version (e.g. 2.067.1 instead of 2.068). In this case, you should check out the stable branch of each subproject BEFORE you create your topic branch:<br />
<br />
<syntaxhighlight lang=bash><br />
cd dmd<br />
git checkout stable<br />
cd ../druntime<br />
git checkout stable<br />
cd ../phobos<br />
git checkout stable<br />
</syntaxhighlight><br />
<br />
Then follow the instructions for [[#Make your changes in a branch|making a branch]].<br />
<br />
If you forget to do this, or didn't realize it, It's not possible to simply re-target your branch for pulling into the stable branch. Github will let you do this, but your branch will include many of the changes from the unstable branch!<br />
<br />
In order to fix such a problem, you can [[#Rebasing|rebase]] your changes from master on top of the stable branch. First you need to pull in the stable branch from your fork on github:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout stable<br />
</syntaxhighlight><br />
<br />
Then, you go back to your branch, and replay the changes from master using rebase:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout mybranch<br />
git rebase master --onto stable<br />
</syntaxhighlight><br />
<br />
You may have to follow the instructions in the [[#Rebasing|Rebasing section]] on adding the upstream branch, substituting stable for master, if you need to update to the latest stable changes.<br />
<br />
This sometimes may not work, as the changes between the stable and master are too drastic. In this case, you may have to re create your changes after a clean checkout of the stable branch.<br />
<br />
When creating a pull request, you need to tell github to target the stable branch instead of master on the upstream repository. This is done via a drop-down at the top of the page, make sure to do this before submitting your pull request as this cannot be changed after the PR is created (you will have to close the PR and create a new one).<br />
<br />
If you notice in your PR a whole slew of changes that seem to have nothing to do with your changes, it's likely because you forgot one of these steps.<br />
<br />
==Reviews==<br />
<br />
Any pull requests that make language changes must be approved by Walter and Andrei. This includes druntime changes that implement the specification.<br />
<br />
Any pull requests that make significant changes to code should be reviewed by more than one person. This means that at least two people need to approve the pull request before it is merged. One person must be a person with commit rights, but the other need not be, as long as that person is trusted within the developer community.<br />
<br />
Pull requests that are trivial (typos, obvious minor bug fixes, etc.) may be pulled without a second review.<br />
<br />
Please note that any updates pushed to the candidate branch do not automatically notify a subscribed person. If you update your branch to correct an issue, please also put in a comment indicating it.<br />
<br />
==Copyright assignment==<br />
<br />
Please note that all contributions to DMD source code require that the copyright to that code be assigned to Digital Mars.<br />
<br />
<br />
[[Category: Contribution Guidelines]]</div>Schveiguyhttps://wiki.dlang.org/?title=Pull_Requests&diff=6654Pull Requests2015-09-11T12:57:08Z<p>Schveiguy: Fix some commands for rebasing.</p>
<hr />
<div>The source code of the D compiler (dmd), runtime library (druntime), and standard library (Phobos), are all available at [https://github.com/D-Programming-Language GitHub].<br />
<br />
==Fork the project==<br />
<br />
To contribute to the D compiler, runtime library, or standard library, you need to create an account on GitHub, and then navigate to the [https://github.com/D-Programming-Language D programming language] page, select the project you wish to contribute to, and create a fork of that project.<br />
<br />
For example, if you wish to submit a patch to the D compiler, you should navigate to [https://github.com/D-Programming-Language/dmd D-Programming-Language/dmd], then click on the "Fork" button at the top right corner of the page. This will clone the D compiler sources into your list of projects.<br />
<br />
==Check out the sources==<br />
<br />
{{seealso|Using Git on Windows}}<br />
<br />
Once you have forked the project you wish to contribute to, use git to checkout a local copy of the project.<br />
<br />
Generally, you should checkout a copy of at least dmd, druntime, and phobos in order to have a working compiler toolchain that you can use to test your changes.<br />
<br />
Note: if you are intending to fix a regression for the current version for a point release, you must use the [[#Stable Branch|stable branch]] of the code. See the section on the stable branch for more information.<br />
<br />
After checking out the sources, you will probably want to [[Building DMD|build DMD]].<br />
<br />
==Make your changes in a branch==<br />
<br />
{{seealso_url|http://dlang.org/dstyle.html|D coding style}}<br />
<br />
Generally, it is preferred that any changes you wish to contribute should be made in its own dedicated topic branch. For example, if you have a fix for issue 1234 in the D compiler, you might want to do something like this:<br />
<br />
<syntaxhighlight lang="bash"><br />
cd /usr/src/d/dmd/src<br />
git checkout -b issue_1234<br />
vim expression.c # make your changes here<br />
make -f posix.mak<br />
... # test your changes here<br />
git commit -a # commit to the branch named 'issue_1234'<br />
git push -u origin # push changes to your fork of DMD<br />
</syntaxhighlight><br />
<br />
If you are fixing a specific bugzilla issue, then putting "Fix Issue NNNN" in the commit message will automatically add a message to the bug report when the commit is merged.<br />
<br />
==Test your changes==<br />
<br />
Before you submit your changes, it's a good idea to test it thoroughly first. It's also a good idea to run the unittests for druntime and phobos:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/druntime<br />
make -f posix.mak unittest<br />
cd ../phobos<br />
make -f posix.mak unittest<br />
</syntaxhighlight><br />
<br />
Pull requests that fail unittests will not be accepted by the maintainers, except under special circumstances.<br />
<br />
'''TBD:''' add instructions on running dmd's unittests.<br />
<br />
==Create a pull request==<br />
<br />
Once you have tested all your changes and pushed them to your fork on GitHub, you are ready to submit a pull request.<br />
<br />
# Navigate to your fork of the project on GitHub.<br />
# '''Important''': Select the branch that you made your changes in, say issue_1234.<br />
# Click on the "Pull Request" button.<br />
<br />
This will submit your changes for review by the D maintainers. If your changes are approved, they will be merged into the master branch. Otherwise, if the maintainers have some comments or feedback, you can refine your changes by editing and testing in your local workspace, and pushing the new changes to the same git branch. The new changes will be automatically included in your pull request.<br />
<br />
Choose a title for your pull request that clearly states what it does. When fixing a bug, the usual thing to do is to use the summary from the bugzilla report. Eg a title like "Fix 3797" or "Issue 3797" contains much less information than "Fix Issue 3797 - Regression(2.038): Implicit conversion between incompatible function pointers" and requires a lot more effort for the reviewers to determine if it is something they are interested in.<br />
<br />
Pull request descriptions should contain a hyperlink to the [[Bugzilla]] issue that is being fixed. This is usually added at the end of the description.<br />
<br />
After the pull request is created, the corresponding bugzilla issue should have the 'pull' keyword added and a link to the pull request posted in a comment.<br />
<br />
===Autotester===<br />
<br />
Pull requests are automatically picked up by the [[Git Commit Tester|autotester]], which compiles the code in the pull request and runs it through the dmd, druntime, and phobos unittests on all supported platforms. Generally, pull requests must pass all tests before they will be merged. The status of the tests can be monitored through the pull request page.<br />
<br />
Every user must be manually approved before the autotester will start testing their pull requests. Users can be approved by anyone with commit access.<br />
<br />
===Rebasing===<br />
<br />
Sometimes, if a particular change you are working on is taking a long time, or if you encounter a problem that is fixed by a new commit upstream, you may need to sync your local branch with master in order to keep the code up-to-date. In this case, it is recommended that you use git rebase to apply your changes ''on top of'' the latest git master, so that when you submit a pull request, the change history will be easier for the reviewers to follow. Using git merge is ''not'' recommended, as it may produce a lot of merge commits that may not be relevant to your changes.<br />
<br />
For example, you may be working on your changes:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/phobos<br />
git checkout mybranch<br />
vim std/algorithm.d # apply lots of cool changes here<br />
</syntaxhighlight><br />
<br />
First, before you resync with master, make sure all your changes are checked in (or stashed):<br />
<br />
<syntaxhighlight lang=bash><br />
git commit -a<br />
</syntaxhighlight><br />
<br />
If you forked from the official D programming language repositories you may need to add an upstream remote to pull in the latest official changes. If this is the case you can add an upstream remote like this:<br />
<br />
<syntaxhighlight lang=bash><br />
git remote add upstream git@github.com:D-Programming-Language/phobos<br />
</syntaxhighlight><br />
<br />
This adds another remote to your repository called upstream and only needs to be done once. Once the upstream remote is added, you can update your repository's master branch by running the following:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout master<br />
git pull --ff-only upstream master<br />
</syntaxhighlight><br />
<br />
The --ff-only option is to ensure that your master branch is identical to the official D sources' master branch, since otherwise you will end up with a very messy history that will be hard to clean up (and the reviewers will probably reject your pull request due to having unrelated merge commits).<br />
<br />
Now go back to your branch and rebase it:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout mybranch<br />
git rebase master<br />
</syntaxhighlight><br />
<br />
Now your sources should be up-to-date. Recompile and test everything to make sure it all works.<br />
<br />
Note that after rebasing, you will need to force an update to your fork on GitHub with the -f flag, otherwise it will fail because the histories don't match anymore:<br />
<br />
<syntaxhighlight lang=bash><br />
git push -f origin mybranch<br />
</syntaxhighlight><br />
<br />
You may wish to read up on [http://git-scm.com/book/en/Git-Branching-Rebasing how git rebase works] if you're not familiar with the concept.<br />
<br />
If, during the 'git rebase' command, you encounter conflicts, you may want to learn [http://stackoverflow.com/questions/8780257/git-rebase-a-branch-onto-master-failed-how-to-resolve how to resolve a conflict during git rebase].<br />
<br />
==Stable Branch==<br />
<br />
If you are working on a fix for a regression, chances are it should go into the next point release, and not the next major version (e.g. 2.067.1 instead of 2.068). In this case, you should check out the stable branch of each subproject BEFORE you create your topic branch:<br />
<br />
<syntaxhighlight lang=bash><br />
cd dmd<br />
git checkout stable<br />
cd ../druntime<br />
git checkout stable<br />
cd ../phobos<br />
git checkout stable<br />
</syntaxhighlight><br />
<br />
Then follow the instructions for [[#Make your changes in a branch|making a branch]].<br />
<br />
If you forget to do this, or didn't realize it, It's not possible to simply re-target your branch for pulling into the stable branch. Github will let you do this, but your branch will include many of the changes from the unstable branch!<br />
<br />
In order to fix such a problem, you can [[#Rebasing|rebase]] your changes from master on top of the stable branch. First you need to pull in the stable branch from your fork on github:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout stable<br />
</syntaxhighlight><br />
<br />
Then, you go back to your branch, and replay the changes from master using rebase:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout mytopic<br />
git rebase master --onto stable<br />
</syntaxhighlight><br />
<br />
You may have to follow the instructions in the [[#Rebasing|Rebasing section]] on adding the upstream branch, substituting stable for master, if you need to update to the latest stable changes.<br />
<br />
This sometimes may not work, as the changes between the stable and master are too drastic. In this case, you may have to re create your changes after a clean checkout of the stable branch.<br />
<br />
When creating a pull request, you need to tell github to target the stable branch instead of master on the upstream repository. This is done via a drop-down at the top of the page, make sure to do this before submitting your pull request as this cannot be changed after the PR is created (you will have to close the PR and create a new one).<br />
<br />
If you notice in your PR a whole slew of changes that seem to have nothing to do with your changes, it's likely because you forgot one of these steps.<br />
<br />
==Reviews==<br />
<br />
Any pull requests that make language changes must be approved by Walter and Andrei. This includes druntime changes that implement the specification.<br />
<br />
Any pull requests that make significant changes to code should be reviewed by more than one person. This means that at least two people need to approve the pull request before it is merged. One person must be a person with commit rights, but the other need not be, as long as that person is trusted within the developer community.<br />
<br />
Pull requests that are trivial (typos, obvious minor bug fixes, etc.) may be pulled without a second review.<br />
<br />
Please note that any updates pushed to the candidate branch do not automatically notify a subscribed person. If you update your branch to correct an issue, please also put in a comment indicating it.<br />
<br />
==Copyright assignment==<br />
<br />
Please note that all contributions to DMD source code require that the copyright to that code be assigned to Digital Mars.<br />
<br />
<br />
[[Category: Contribution Guidelines]]</div>Schveiguyhttps://wiki.dlang.org/?title=Pull_Requests&diff=6642Pull Requests2015-09-10T19:21:41Z<p>Schveiguy: Updated to deal with stable branch</p>
<hr />
<div>The source code of the D compiler (dmd), runtime library (druntime), and standard library (Phobos), are all available at [https://github.com/D-Programming-Language GitHub].<br />
<br />
==Fork the project==<br />
<br />
To contribute to the D compiler, runtime library, or standard library, you need to create an account on GitHub, and then navigate to the [https://github.com/D-Programming-Language D programming language] page, select the project you wish to contribute to, and create a fork of that project.<br />
<br />
For example, if you wish to submit a patch to the D compiler, you should navigate to [https://github.com/D-Programming-Language/dmd D-Programming-Language/dmd], then click on the "Fork" button at the top right corner of the page. This will clone the D compiler sources into your list of projects.<br />
<br />
==Check out the sources==<br />
<br />
{{seealso|Using Git on Windows}}<br />
<br />
Once you have forked the project you wish to contribute to, use git to checkout a local copy of the project.<br />
<br />
Generally, you should checkout a copy of at least dmd, druntime, and phobos in order to have a working compiler toolchain that you can use to test your changes.<br />
<br />
Note: if you are intending to fix a regression for the current version for a point release, you must use the [[#Stable Branch|stable branch]] of the code. See the section on the stable branch for more information.<br />
<br />
After checking out the sources, you will probably want to [[Building DMD|build DMD]].<br />
<br />
==Make your changes in a branch==<br />
<br />
{{seealso_url|http://dlang.org/dstyle.html|D coding style}}<br />
<br />
Generally, it is preferred that any changes you wish to contribute should be made in its own dedicated topic branch. For example, if you have a fix for issue 1234 in the D compiler, you might want to do something like this:<br />
<br />
<syntaxhighlight lang="bash"><br />
cd /usr/src/d/dmd/src<br />
git checkout -b issue_1234<br />
vim expression.c # make your changes here<br />
make -f posix.mak<br />
... # test your changes here<br />
git commit -a # commit to the branch named 'issue_1234'<br />
git push -u origin # push changes to your fork of DMD<br />
</syntaxhighlight><br />
<br />
If you are fixing a specific bugzilla issue, then putting "Fix Issue NNNN" in the commit message will automatically add a message to the bug report when the commit is merged.<br />
<br />
==Test your changes==<br />
<br />
Before you submit your changes, it's a good idea to test it thoroughly first. It's also a good idea to run the unittests for druntime and phobos:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/druntime<br />
make -f posix.mak unittest<br />
cd ../phobos<br />
make -f posix.mak unittest<br />
</syntaxhighlight><br />
<br />
Pull requests that fail unittests will not be accepted by the maintainers, except under special circumstances.<br />
<br />
'''TBD:''' add instructions on running dmd's unittests.<br />
<br />
==Create a pull request==<br />
<br />
Once you have tested all your changes and pushed them to your fork on GitHub, you are ready to submit a pull request.<br />
<br />
# Navigate to your fork of the project on GitHub.<br />
# '''Important''': Select the branch that you made your changes in, say issue_1234.<br />
# Click on the "Pull Request" button.<br />
<br />
This will submit your changes for review by the D maintainers. If your changes are approved, they will be merged into the master branch. Otherwise, if the maintainers have some comments or feedback, you can refine your changes by editing and testing in your local workspace, and pushing the new changes to the same git branch. The new changes will be automatically included in your pull request.<br />
<br />
Choose a title for your pull request that clearly states what it does. When fixing a bug, the usual thing to do is to use the summary from the bugzilla report. Eg a title like "Fix 3797" or "Issue 3797" contains much less information than "Fix Issue 3797 - Regression(2.038): Implicit conversion between incompatible function pointers" and requires a lot more effort for the reviewers to determine if it is something they are interested in.<br />
<br />
Pull request descriptions should contain a hyperlink to the [[Bugzilla]] issue that is being fixed. This is usually added at the end of the description.<br />
<br />
After the pull request is created, the corresponding bugzilla issue should have the 'pull' keyword added and a link to the pull request posted in a comment.<br />
<br />
===Autotester===<br />
<br />
Pull requests are automatically picked up by the [[Git Commit Tester|autotester]], which compiles the code in the pull request and runs it through the dmd, druntime, and phobos unittests on all supported platforms. Generally, pull requests must pass all tests before they will be merged. The status of the tests can be monitored through the pull request page.<br />
<br />
Every user must be manually approved before the autotester will start testing their pull requests. Users can be approved by anyone with commit access.<br />
<br />
===Rebasing===<br />
<br />
Sometimes, if a particular change you are working on is taking a long time, or if you encounter a problem that is fixed by a new commit upstream, you may need to sync your local branch with master in order to keep the code up-to-date. In this case, it is recommended that you use git rebase to apply your changes ''on top of'' the latest git master, so that when you submit a pull request, the change history will be easier for the reviewers to follow. Using git merge is ''not'' recommended, as it may produce a lot of merge commits that may not be relevant to your changes.<br />
<br />
For example, you may be working on your changes:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/phobos<br />
git checkout mybranch<br />
vim std/algorithm.d # apply lots of cool changes here<br />
</syntaxhighlight><br />
<br />
First, before you resync with master, make sure all your changes are checked in (or stashed):<br />
<br />
<syntaxhighlight lang=bash><br />
git commit -a<br />
</syntaxhighlight><br />
<br />
If you forked from the official D programming language repositories you may need to add an upstream remote to pull in the latest official changes. If this is the case you can add an upstream remote like this:<br />
<br />
<syntaxhighlight lang=bash><br />
git remote add upstream git@github.com:D-Programming-Language/phobos<br />
</syntaxhighlight><br />
<br />
This adds another remote to your repository called upstream and only needs to be done once. Once the upstream remote is added, you can update your repository's master branch by running the following:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout master<br />
git pull --ff-only upstream master<br />
</syntaxhighlight><br />
<br />
The --ff-only option is to ensure that your master branch is identical to the official D sources' master branch, since otherwise you will end up with a very messy history that will be hard to clean up (and the reviewers will probably reject your pull request due to having unrelated merge commits).<br />
<br />
Now go back to your branch and rebase it:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout mybranch<br />
git rebase master<br />
</syntaxhighlight><br />
<br />
Now your sources should be up-to-date. Recompile and test everything to make sure it all works.<br />
<br />
Note that after rebasing, you will need to force an update to your fork on GitHub with the -f flag, otherwise it will fail because the histories don't match anymore:<br />
<br />
<syntaxhighlight lang=bash><br />
git push -f origin mybranch<br />
</syntaxhighlight><br />
<br />
You may wish to read up on [http://git-scm.com/book/en/Git-Branching-Rebasing how git rebase works] if you're not familiar with the concept.<br />
<br />
If, during the 'git rebase' command, you encounter conflicts, you may want to learn [http://stackoverflow.com/questions/8780257/git-rebase-a-branch-onto-master-failed-how-to-resolve how to resolve a conflict during git rebase].<br />
<br />
==Stable Branch==<br />
<br />
If you are working on a fix for a regression, chances are it should go into the next point release, and not the next major version (e.g. 2.067.1 instead of 2.068). In this case, you should check out the stable branch of each subproject BEFORE you create your topic branch:<br />
<br />
<syntaxhighlight lang=bash><br />
cd dmd<br />
git checkout stable<br />
cd ../druntime<br />
git checkout stable<br />
cd ../phobos<br />
git checkout stable<br />
</syntaxhighlight><br />
<br />
Then follow the instructions for [[#Make your changes in a branch|making a branch]].<br />
<br />
If you forget to do this, or didn't realize it, It's not possible to simply re-target your branch for pulling into the stable branch. Github will let you do this, but your branch will include many of the changes from the unstable branch!<br />
<br />
In order to fix such a problem, you can [[#Rebasing|rebase]] on top of the stable branch:<br />
<br />
<syntaxhighlight lang=bash><br />
git rebase stable<br />
</syntaxhighlight><br />
<br />
You may have to follow the instructions in the [[#Rebasing|Rebasing section]] on adding the upstream branch, substituting stable for master.<br />
<br />
This sometimes may not work, as the changes between the stable and master are too drastic. In this case, you may have to re create your changes after a clean checkout of the stable branch.<br />
<br />
When creating a pull request, you need to tell github to target the stable branch instead of master on the upstream repository. This is done via a drop-down at the top of the page, make sure to do this before submitting your pull request as this cannot be changed after the PR is created (you will have to close the PR and create a new one).<br />
<br />
If you notice in your PR a whole slew of changes that seem to have nothing to do with your changes, it's likely because you forgot one of these steps.<br />
<br />
==Reviews==<br />
<br />
Any pull requests that make language changes must be approved by Walter and Andrei. This includes druntime changes that implement the specification.<br />
<br />
Any pull requests that make significant changes to code should be reviewed by more than one person. This means that at least two people need to approve the pull request before it is merged. One person must be a person with commit rights, but the other need not be, as long as that person is trusted within the developer community.<br />
<br />
Pull requests that are trivial (typos, obvious minor bug fixes, etc.) may be pulled without a second review.<br />
<br />
Please note that any updates pushed to the candidate branch do not automatically notify a subscribed person. If you update your branch to correct an issue, please also put in a comment indicating it.<br />
<br />
==Copyright assignment==<br />
<br />
Please note that all contributions to DMD source code require that the copyright to that code be assigned to Digital Mars.<br />
<br />
<br />
[[Category: Contribution Guidelines]]</div>Schveiguyhttps://wiki.dlang.org/?title=Pull_Requests&diff=6290Pull Requests2015-06-08T12:04:06Z<p>Schveiguy: /* Reviews */</p>
<hr />
<div>The source code of the D compiler (dmd), runtime library (druntime), and standard library (Phobos), are all available at [https://github.com/D-Programming-Language GitHub].<br />
<br />
==Fork the project==<br />
<br />
To contribute to the D compiler, runtime library, or standard library, you need to create an account on GitHub, and then navigate to the [https://github.com/D-Programming-Language D programming language] page, select the project you wish to contribute to, and create a fork of that project.<br />
<br />
For example, if you wish to submit a patch to the D compiler, you should navigate to [https://github.com/D-Programming-Language/dmd D-Programming-Language/dmd], then click on the "Fork" button at the top right corner of the page. This will clone the D compiler sources into your list of projects.<br />
<br />
==Check out the sources==<br />
<br />
{{seealso|Using Git on Windows}}<br />
<br />
Once you have forked the project you wish to contribute to, use git to checkout a local copy of the project.<br />
<br />
Generally, you should checkout a copy of at least dmd, druntime, and phobos in order to have a working compiler toolchain that you can use to test your changes.<br />
<br />
After checking out the sources, you will probably want to [[Building DMD|build DMD]].<br />
<br />
==Make your changes in a branch==<br />
<br />
{{seealso_url|http://dlang.org/dstyle.html|D coding style}}<br />
<br />
Generally, it is preferred that any changes you wish to contribute should be made in its own dedicated topic branch. For example, if you have a fix for issue 1234 in the D compiler, you might want to do something like this:<br />
<br />
<syntaxhighlight lang="bash"><br />
cd /usr/src/d/dmd/src<br />
git checkout -b issue_1234<br />
vim expression.c # make your changes here<br />
make -f posix.mak<br />
... # test your changes here<br />
git commit -a # commit to the branch named 'issue_1234'<br />
git push -u origin # push changes to your fork of DMD<br />
</syntaxhighlight><br />
<br />
If you are fixing a specific bugzilla issue, then putting "Fix Issue NNNN" in the commit message will automatically add a message to the bug report when the commit is merged.<br />
<br />
==Test your changes==<br />
<br />
Before you submit your changes, it's a good idea to test it thoroughly first. It's also a good idea to run the unittests for druntime and phobos:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/druntime<br />
make -f posix.mak unittest<br />
cd ../phobos<br />
make -f posix.mak unittest<br />
</syntaxhighlight><br />
<br />
Pull requests that fail unittests will not be accepted by the maintainers, except under special circumstances.<br />
<br />
'''TBD:''' add instructions on running dmd's unittests.<br />
<br />
==Create a pull request==<br />
<br />
Once you have tested all your changes and pushed them to your fork on GitHub, you are ready to submit a pull request.<br />
<br />
# Navigate to your fork of the project on GitHub.<br />
# '''Important''': Select the branch that you made your changes in, say issue_1234.<br />
# Click on the "Pull Request" button.<br />
<br />
This will submit your changes for review by the D maintainers. If your changes are approved, they will be merged into the master branch. Otherwise, if the maintainers have some comments or feedback, you can refine your changes by editing and testing in your local workspace, and pushing the new changes to the same git branch. The new changes will be automatically included in your pull request.<br />
<br />
Choose a title for your pull request that clearly states what it does. When fixing a bug, the usual thing to do is to use the summary from the bugzilla report. Eg a title like "Fix 3797" or "Issue 3797" contains much less information than "Fix Issue 3797 - Regression(2.038): Implicit conversion between incompatible function pointers" and requires a lot more effort for the reviewers to determine if it is something they are interested in.<br />
<br />
Pull request descriptions should contain a hyperlink to the [[Bugzilla]] issue that is being fixed. This is usually added at the end of the description.<br />
<br />
After the pull request is created, the corresponding bugzilla issue should have the 'pull' keyword added and a link to the pull request posted in a comment.<br />
<br />
===Autotester===<br />
<br />
Pull requests are automatically picked up by the [[Git Commit Tester|autotester]], which compiles the code in the pull request and runs it through the dmd, druntime, and phobos unittests on all supported platforms. Generally, pull requests must pass all tests before they will be merged. The status of the tests can be monitored through the pull request page.<br />
<br />
Every user must be manually approved before the autotester will start testing their pull requests. Users can be approved by anyone with commit access.<br />
<br />
===Rebasing===<br />
<br />
Sometimes, if a particular change you are working on is taking a long time, or if you encounter a problem that is fixed by a new commit upstream, you may need to sync your local branch with master in order to keep the code up-to-date. In this case, it is recommended that you use git rebase to apply your changes ''on top of'' the latest git master, so that when you submit a pull request, the change history will be easier for the reviewers to follow. Using git merge is ''not'' recommended, as it may produce a lot of merge commits that may not be relevant to your changes.<br />
<br />
For example, you may be working on your changes:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/phobos<br />
git checkout mybranch<br />
vim std/algorithm.d # apply lots of cool changes here<br />
</syntaxhighlight><br />
<br />
First, before you resync with master, make sure all your changes are checked in (or stashed):<br />
<br />
<syntaxhighlight lang=bash><br />
git commit -a<br />
</syntaxhighlight><br />
<br />
If you forked from the official D programming language repositories you may need to add an upstream remote to pull in the latest official changes. If this is the case you can add an upstream remote like this:<br />
<br />
<syntaxhighlight lang=bash><br />
git remote add upstream git@github.com:D-Programming-Language/phobos<br />
</syntaxhighlight><br />
<br />
This adds another remote to your repository called upstream and only needs to be done once. Once the upstream remote is added, you can update your repository's master branch by running the following:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout master<br />
git pull --ff-only upstream master<br />
</syntaxhighlight><br />
<br />
The --ff-only option is to ensure that your master branch is identical to the official D sources' master branch, since otherwise you will end up with a very messy history that will be hard to clean up (and the reviewers will probably reject your pull request due to having unrelated merge commits).<br />
<br />
Now go back to your branch and rebase it:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout mybranch<br />
git rebase master<br />
</syntaxhighlight><br />
<br />
Now your sources should be up-to-date. Recompile and test everything to make sure it all works.<br />
<br />
Note that after rebasing, you will need to force an update to your fork on GitHub with the -f flag, otherwise it will fail because the histories don't match anymore:<br />
<br />
<syntaxhighlight lang=bash><br />
git push -f origin mybranch<br />
</syntaxhighlight><br />
<br />
You may wish to read up on [http://git-scm.com/book/en/Git-Branching-Rebasing how git rebase works] if you're not familiar with the concept.<br />
<br />
If, during the 'git rebase' command, you encounter conflicts, you may want to learn [http://stackoverflow.com/questions/8780257/git-rebase-a-branch-onto-master-failed-how-to-resolve how to resolve a conflict during git rebase].<br />
<br />
===Reviews===<br />
<br />
Any pull requests that make language changes must be approved by Walter and Andrei. This includes druntime changes that implement the specification.<br />
<br />
Any pull requests that make significant changes to code should be reviewed by more than one person. This means that at least two people need to approve the pull request before it is merged. One person must be a person with commit rights, but the other need not be, as long as that person is trusted within the developer community.<br />
<br />
Pull requests that are trivial (typos, obvious minor bug fixes, etc.) may be pulled without a second review.<br />
<br />
Please note that any updates pushed to the candidate branch do not automatically notify a subscribed person. If you update your branch to correct an issue, please also put in a comment indicating it.<br />
<br />
===Copyright assignment===<br />
<br />
Please note that all contributions to DMD source code require that the copyright to that code be assigned to Digital Mars.</div>Schveiguyhttps://wiki.dlang.org/?title=Pull_Requests&diff=6231Pull Requests2015-06-01T23:00:39Z<p>Schveiguy: /* Create a pull request */</p>
<hr />
<div>The source code of the D compiler (dmd), runtime library (druntime), and standard library (Phobos), are all available at [https://github.com/D-Programming-Language GitHub].<br />
<br />
==Fork the project==<br />
<br />
To contribute to the D compiler, runtime library, or standard library, you need to create an account on GitHub, and then navigate to the [https://github.com/D-Programming-Language D programming language] page, select the project you wish to contribute to, and create a fork of that project.<br />
<br />
For example, if you wish to submit a patch to the D compiler, you should navigate to [https://github.com/D-Programming-Language/dmd D-Programming-Language/dmd], then click on the "Fork" button at the top right corner of the page. This will clone the D compiler sources into your list of projects.<br />
<br />
==Check out the sources==<br />
<br />
{{seealso|Using Git on Windows}}<br />
<br />
Once you have forked the project you wish to contribute to, use git to checkout a local copy of the project.<br />
<br />
Generally, you should checkout a copy of at least dmd, druntime, and phobos in order to have a working compiler toolchain that you can use to test your changes.<br />
<br />
After checking out the sources, you will probably want to [[Building DMD|build DMD]].<br />
<br />
==Make your changes in a branch==<br />
<br />
{{seealso_url|http://dlang.org/dstyle.html|D coding style}}<br />
<br />
Generally, it is preferred that any changes you wish to contribute should be made in its own dedicated topic branch. For example, if you have a fix for issue 1234 in the D compiler, you might want to do something like this:<br />
<br />
<syntaxhighlight lang="bash"><br />
cd /usr/src/d/dmd/src<br />
git checkout -b issue_1234<br />
vim expression.c # make your changes here<br />
make -f posix.mak<br />
... # test your changes here<br />
git commit -a # commit to the branch named 'issue_1234'<br />
git push -u origin # push changes to your fork of DMD<br />
</syntaxhighlight><br />
<br />
If you are fixing a specific bugzilla issue, then putting "Fix Issue NNNN" in the commit message will automatically add a message to the bug report when the commit is merged.<br />
<br />
==Test your changes==<br />
<br />
Before you submit your changes, it's a good idea to test it thoroughly first. It's also a good idea to run the unittests for druntime and phobos:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/druntime<br />
make -f posix.mak unittest<br />
cd ../phobos<br />
make -f posix.mak unittest<br />
</syntaxhighlight><br />
<br />
Pull requests that fail unittests will not be accepted by the maintainers, except under special circumstances.<br />
<br />
'''TBD:''' add instructions on running dmd's unittests.<br />
<br />
==Create a pull request==<br />
<br />
Once you have tested all your changes and pushed them to your fork on GitHub, you are ready to submit a pull request.<br />
<br />
# Navigate to your fork of the project on GitHub.<br />
# '''Important''': Select the branch that you made your changes in, say issue_1234.<br />
# Click on the "Pull Request" button.<br />
<br />
This will submit your changes for review by the D maintainers. If your changes are approved, they will be merged into the master branch. Otherwise, if the maintainers have some comments or feedback, you can refine your changes by editing and testing in your local workspace, and pushing the new changes to the same git branch. The new changes will be automatically included in your pull request.<br />
<br />
Choose a title for your pull request that clearly states what it does. When fixing a bug, the usual thing to do is to use the summary from the bugzilla report. Eg a title like "Fix 3797" or "Issue 3797" contains much less information than "Fix Issue 3797 - Regression(2.038): Implicit conversion between incompatible function pointers" and requires a lot more effort for the reviewers to determine if it is something they are interested in.<br />
<br />
Pull request descriptions should contain a hyperlink to the [[Bugzilla]] issue that is being fixed. This is usually added at the end of the description.<br />
<br />
After the pull request is created, the corresponding bugzilla issue should have the 'pull' keyword added and a link to the pull request posted in a comment.<br />
<br />
===Autotester===<br />
<br />
Pull requests are automatically picked up by the [[Git Commit Tester|autotester]], which compiles the code in the pull request and runs it through the dmd, druntime, and phobos unittests on all supported platforms. Generally, pull requests must pass all tests before they will be merged. The status of the tests can be monitored through the pull request page.<br />
<br />
Every user must be manually approved before the autotester will start testing their pull requests. Users can be approved by anyone with commit access.<br />
<br />
===Rebasing===<br />
<br />
Sometimes, if a particular change you are working on is taking a long time, or if you encounter a problem that is fixed by a new commit upstream, you may need to sync your local branch with master in order to keep the code up-to-date. In this case, it is recommended that you use git rebase to apply your changes ''on top of'' the latest git master, so that when you submit a pull request, the change history will be easier for the reviewers to follow. Using git merge is ''not'' recommended, as it may produce a lot of merge commits that may not be relevant to your changes.<br />
<br />
For example, you may be working on your changes:<br />
<br />
<syntaxhighlight lang=bash><br />
cd /usr/src/d/phobos<br />
git checkout mybranch<br />
vim std/algorithm.d # apply lots of cool changes here<br />
</syntaxhighlight><br />
<br />
First, before you resync with master, make sure all your changes are checked in (or stashed):<br />
<br />
<syntaxhighlight lang=bash><br />
git commit -a<br />
</syntaxhighlight><br />
<br />
If you forked from the official D programming language repositories you may need to add an upstream remote to pull in the latest official changes. If this is the case you can add an upstream remote like this:<br />
<br />
<syntaxhighlight lang=bash><br />
git remote add upstream git@github.com:D-Programming-Language/phobos<br />
</syntaxhighlight><br />
<br />
This adds another remote to your repository called upstream and only needs to be done once. Once the upstream remote is added, you can update your repository's master branch by running the following:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout master<br />
git pull --ff-only upstream master<br />
</syntaxhighlight><br />
<br />
The --ff-only option is to ensure that your master branch is identical to the official D sources' master branch, since otherwise you will end up with a very messy history that will be hard to clean up (and the reviewers will probably reject your pull request due to having unrelated merge commits).<br />
<br />
Now go back to your branch and rebase it:<br />
<br />
<syntaxhighlight lang=bash><br />
git checkout mybranch<br />
git rebase master<br />
</syntaxhighlight><br />
<br />
Now your sources should be up-to-date. Recompile and test everything to make sure it all works.<br />
<br />
Note that after rebasing, you will need to force an update to your fork on GitHub with the -f flag, otherwise it will fail because the histories don't match anymore:<br />
<br />
<syntaxhighlight lang=bash><br />
git push -f origin mybranch<br />
</syntaxhighlight><br />
<br />
You may wish to read up on [http://git-scm.com/book/en/Git-Branching-Rebasing how git rebase works] if you're not familiar with the concept.<br />
<br />
If, during the 'git rebase' command, you encounter conflicts, you may want to learn [http://stackoverflow.com/questions/8780257/git-rebase-a-branch-onto-master-failed-how-to-resolve how to resolve a conflict during git rebase].<br />
<br />
===Reviews===<br />
<br />
Any pull requests that make breaking language changes must be approved by Walter and Andrei. This includes druntime changes that implement the specification.<br />
<br />
Any pull requests that make significant changes to code should be reviewed by more than one person. This means that at least two people need to approve the pull request before it is merged. One person must be a person with commit rights, but the other need not be, as long as that person is trusted within the developer community.<br />
<br />
Pull requests that are trivial (typos, obvious minor bug fixes, etc.) may be pulled without a second review.<br />
<br />
Please note that any updates pushed to the candidate branch do not automatically notify a subscribed person. If you update your branch to correct an issue, please also put in a comment indicating it.<br />
<br />
===Copyright assignment===<br />
<br />
Please note that all contributions to DMD source code require that the copyright to that code be assigned to Digital Mars.</div>Schveiguyhttps://wiki.dlang.org/?title=DIP1&diff=5353DIP12015-01-17T01:53:10Z<p>Schveiguy: Change last modified date to auto-updating.</p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''DIP Template'''<br />
|-<br />
|DIP:<br />
|1<br />
|-<br />
|Version:<br />
|3<br />
|-<br />
|Status:<br />
|Draft<br />
|-<br />
|Created:<br />
|2009-07-07<br />
|-<br />
|Last Modified:<br />
|{{REVISIONYEAR}}-{{REVISIONMONTH}}-{{REVISIONDAY}}<br />
|-<br />
|Author:<br />
|Leandro Lucarella<br />
|-<br />
|Links:<br />
|[[DIP1/Archive]] — [http://www.digitalmars.com/d/archives/digitalmars/D/announce/dmd_1.046_and_2.031_releases_16320.html#N16448 NG discussion that triggered the DIP]<br />
— [http://www.digitalmars.com/d/archives/digitalmars/D/new_DIP1_DIP_Template_92908.html NG announcement and discussion]<br />
|}<br />
<br />
== Abstract ==<br />
This is a sample template to easily start a new DIP. DIPs can be fairly informal for now, but at least the leading metadata should be included, and a short abstract.<br />
<br />
== Rationale ==<br />
Keeping track of improvement proposals is very hard and not well documented organized. Having a template (and a process) for such proposals can improve the situation significantly.<br />
<br />
== Description ==<br />
A DIP is a D Improvement Proposal, a way propose changes to the language in a sightly more formal way than just throwing out the idea in the news group. A DIP should have an structure similar to this one, but nothing is set in stone, you can add or remove sections and/or metadata as long as the DIP is both clean and complete, but try to stick to this template as a bare minimum unless is really necessary to remove something.<br />
<br />
A DIP should represent a problem the community wants to resolve and not just a specific resolution to a problem. This allows the DIP to be a central hub for any given problem. If a resolution is radically different from the current state of the DIP, an alternative DIP could be created as a sub page, e.g. under /DIP1/Alternatives/Alt1. The DIP should be created in its entirety such that it could replace the current DIP through simple copy and past.<br />
<br />
== Usage ==<br />
To start a new DIP you can go to Edit link and copy the source of this DIP, then go to [[DIPs|DIP index]] and add a new item in the list. The DIP number should be one more than the last DIP in the index (for example, if the DIP1 is the last DIP, your DIP should be DIP2). The link in the index should have the form: <nowiki>[[DIPx]]</nowiki>, Title, Status, resume. Where x is the DIP number, title is the DIP title and resume is a short description about the DIP.<br />
<br />
Save the [[DIPs|DIP index]] page and click on the new red link. Now you are editing the new DIP you just created, now paste the copied source text from this template and replace all the you need.<br />
<br />
Remember to update the metadata at the start of the DIP, and keep it as a Draft at the beginning. When your DIP is done, you should announce it in the News Group for discussion, with a subject like this: new DIPx: title (where one more time x is the DIP number and title is the DIP title).<br />
<br />
You should always put you DIPs in the Public Domain (or a similarly permissive license but use Public Domain unless you're very sure of what you're doing).<br />
<br />
== Recommendations ==<br />
When writing a DIP, try not to express your opinion. DIPs should provide facts and be as objective as possible. Even when that's pretty hard, you can make the DIP look more objective by not using, for example, "I prefer XXX because YYY". If YYY is an objective advantage, write that in a more objective way, like "XXX can be a better option because YYY". Try to leave non-technical personal preferences aside; "XXX can be a better option because the syntax is nicer" is not good enough even when you don't say "I prefer".<br />
<br />
Try not to include half-baked ideas. If you are not sure about something, leave it outside the DIP and write it on the NG announcement instead for further discussion. The idea can be added to the DIP in the future when it is in a better shape.<br />
<br />
== Abstract ==<br />
Make the abstract as descriptive as possible (while keeping it brief). From an abstract you should be able to tell what the DIP is about, you should introduce for every non-trivial concept a person should know for understanding the DIP (or provide links if you can't briefly describe those concepts in the abstract). Don't copy the title of the DIP to use it as an abstract. Ideally an abstract should be a paragraph 5 to 10 lines long.<br />
<br />
== Rationale ==<br />
Rationale should be complete. When the DIP tries to solve a problem, try to describe that problem as detailed as possible. If you have links to the NG describing the problem more deeply, used them. All the background information is welcome.<br />
<br />
== NG Announcement ==<br />
When posting the DIP announcement to the NG, please copy the abstract, so people can easily know what is it about and follow the link if they are interested.<br />
<br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.<br />
<br />
[[Category: DIP]]</div>Schveiguyhttps://wiki.dlang.org/?title=DIP25&diff=5352DIP252015-01-17T01:45:41Z<p>Schveiguy: Yay, can use special variables to automatically update last modified date.</p>
<hr />
<div>== DIP25: Sealed references ==<br />
<br />
{| class="wikitable"<br />
!Title: <br />
!''Sealed references''<br />
|-<br />
|DIP: <br />
|25<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Preliminary Approved<br />
|-<br />
|Created:<br />
|2013-02-05<br />
|-<br />
|Last Modified:<br />
|{{REVISIONYEAR}}-{{REVISIONMONTH}}-{{REVISIONDAY}}<br />
|-<br />
|Author:<br />
|Walter Bright and Andrei Alexandrescu<br />
|-<br />
|Links:<br />
|<br />
|}<br />
<br />
== Abstract ==<br />
<br />
D offers a number of features aimed at systems-level coding, such as unrestricted pointers, casting between integers and pointers, and the [http://dlang.org/function.html#system-functions <code>@system</code>] attribute. These means, combined with the other features of D, make it a complete and expressive language for systems-level tasks. On the other hand, economy of means should be exercised in defining such powerful but dangerous features. Most other features should offer good safety guarantees with little or no loss in efficiency or expressiveness. This proposal makes <code>ref</code> provide such a guarantee: with the proposed rules, it is impossible in safe code to have <code>ref</code> refer to a destroyed object. The restrictions introduced are not entirely backward compatible, but disallow code that is stylistically questionable and that can be easily replaced either with equivalent and clearer code.<br />
<br />
== In a nutshell ==<br />
<br />
This DIP proposes that any <code>ref</code> parameter that a function received and also wants to return must be also annotated with <code>return</code>. Annotation are deduced for templates and lambdas, but must be explicit for all other declarations. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe:<br />
ref int fun(ref int a} { return a; } // ERROR<br />
ref int gun(return ref int a} { return a; } // FINE<br />
ref T hun(T)(ref T a} { return a; } // FINE, templates use deduction<br />
</syntaxhighlight><br />
<br />
== Description ==<br />
<br />
Currently, D has some provisions for avoiding dangling references:<br />
<br />
<syntaxhighlight lang=D><br />
ref int fun(int x) {<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
struct S {<br />
int x;<br />
}<br />
<br />
ref int hun() {<br />
S s;<br />
return s.x; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
<br />
ref int iun() {<br />
int a[42];<br />
return a[5]; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
</syntaxhighlight><br />
<br />
However, this enforcement is shallow (even after fixing [https://issues.dlang.org/show_bug.cgi?id=13902 issue 13902]). The following code compiles and allows reads and writes through defunct stack locations, bypassing scoping and lifetime rules:<br />
<br />
<syntaxhighlight lang=D><br />
ref int identity(ref int x) {<br />
return x; // pass-through function that does nothing <br />
}<br />
<br />
ref int fun(int x) {<br />
return identity(x); // escape the address of a parameter <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return identity(x); // escape the address of a local<br />
}<br />
<br />
struct S {<br />
int x;<br />
ref int get() { return x; }<br />
}<br />
<br />
ref int hun(S x) {<br />
return x.get; // escape the address of a part of a parameter <br />
}<br />
<br />
ref int iun() {<br />
S s;<br />
return s.get; // escape the address of part of a local<br />
}<br />
<br />
ref int jun() {<br />
return S().get; // worst contender: escape the address of a part of an rvalue<br />
}<br />
</syntaxhighlight><br />
<br />
The escape patterns are obvious in these simple examples that make all code available and use no recursion, and may be found automatically. The problem is that generally the compiler cannot see the body of <code>identity</code> or <code>S.get()</code>. We need to devise a method that derives enough information for safety analysis only given the function signatures, not their bodies.<br />
<br />
This DIP devises rules that allow passing objects by reference ''down'' into functions, and return references ''up'' from functions, whilst disallowing cases such as the above when a reference passed up ends up referring to a deallocated temporary.<br />
<br />
=== Adding <tt>return</tt> as a parameter attribute ===<br />
<br />
The main issue is typechecking functions that return a <tt>ref T</tt> and accept some of their parameters by <tt>ref</tt>. Those that attempt to return locals or parts thereof are already addressed directly, contingent to [https://issues.dlang.org/show_bug.cgi?id=13902 Issue 13902]. The one case remaining is allowing a function returning <code>ref T</code> to return a (part of a) parameter passed by <code>ref</code>.<br />
<br />
The key is to distinguish legal from illegal cases. One simple but overly conservative option would be to simply disallow returning a <code>ref</code> parameter or part thereof. That makes <code>identity</code> impossible to implement, and as a consequence accessing elements of a container by reference becomes difficult or impossible to typecheck properly. Also, heap-allocated structures with deterministic destruction (e.g. reference counted) must insert member copies for all accesses. <br />
<br />
This proposal promotes adding <code>return</code> as an attribute that propagates the lifetime of a parameter to the return value of a function. With the proposed semantics, a function is disallowed to return a <code>ref</code> parameter of a part thereof UNLESS the parameter is also annotated with <code>return</code>. Under the proposed semantics <code>identity</code> will be spelled as follows:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int wrongIdentity(ref int x) { <br />
return x; // ERROR! Cannot return a ref, please use "return ref"<br />
}<br />
@safe ref int identity(return ref int x) { <br />
return x; // fine<br />
}<br />
</syntaxhighlight><br />
<br />
Just by seeing the signature <code>ref int identity(return ref int x)</code> the compiler assumes that the result of identity must have a shorter or equal lifetime than <code>x</code> and typechecks callers accordingly. Example (given the previous definition of <code>identity</code>):<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref int x) { <br />
int a;<br />
return a; // ERROR per current language rules<br />
static int b;<br />
return b; // fine per current language rules<br />
return identity(a); // ERROR, this may escape the address of a local<br />
return x; // fine, propagate x's lifetime to output<br />
return identity(x); // fine, propagate x's lifetime through identity to the output<br />
return identity(identity(x)); // fine, propagate x's lifetime twice through identity to the output<br />
}<br />
<br />
@safe ref int gun(ref int input) {<br />
static int[42] data;<br />
return data[input]; // works, can always return static-lived data<br />
}<br />
<br />
@safe struct S {<br />
private int x;<br />
ref int get() return { return x; } // should work, see next section <br />
}<br />
</syntaxhighlight><br />
<br />
===Interaction with <tt>auto ref</tt>===<br />
<br />
Syntactically it is illegal to use <tt>auto ref</tt> and <tt>return ref</tt> on the same parameter. Deduction of the <tt>return</tt> attribute still applies as discussed below.<br />
<br />
===Deduction===<br />
<br />
Deduction of the <tt>return</tt> attribute will be effected under the same conditions as for <tt>pure</tt> (currently for generic and lambda functions). That means the generic <tt>identity</tt> function does not require the <tt>return</tt> attribute:<br />
<br />
<syntaxhighlight lang=D><br />
auto ref T identity(auto ref T) {<br />
return x; // correct, no need for return<br />
}<br />
</syntaxhighlight><br />
<br />
===Types of Result vs. Parameters===<br />
<br />
Consider:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref float x);<br />
</syntaxhighlight><br />
<br />
This function arguably cannot return a value scoped within the lifetime of its argument for the simple reason it's impossible to find an <code>int</code> somewhere in a <code>float</code> (apart from unsafe address manipulation). However, this DIP ignores types; if a parameter is <code>return ref</code>, it is always considered potentially escaped as a result. It is in fact possible that the author of <code>fun</code> wants to constrain its output's lifetime for unrelated reasons.<br />
<br />
Future versions of this DIP may relax this rule.<br />
<br />
===Multiple Parameters===<br />
<br />
If multiple <code>return ref</code> parameters are present, the result's lifetime is conservatively assumed to be enclosed in the lifetime of the shortest-lived of those arguments.<br />
<br />
===Member Functions===<br />
Member functions of <code>struct</code>s must qualify <code>this</code> with <code>return</code> if they want to return a result by <code>ref</code> that won't outlive <code>this</code>. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe struct S {<br />
static int a;<br />
int b;<br />
ref int fun() { return a; } // fine, callers assume infinite lifetime<br />
ref int gun() { return b; } // ERROR! Cannot return a direct member<br />
ref int hun() return { return b; } // fine, result is scoped within this<br />
}<br />
</syntaxhighlight><br />
<br />
===@safe===<br />
For the initial release, the requirement of returns for <code>ref</code> parameter data to be marked with <code>return</code> will only apply to <code>@safe</code> functions. The reasons for this are to avoid breaking existing code, and because it's not yet clear whether this feature will interfere with valid constructs in a system language.<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(ref int x) { return x;} // Error<br />
@safe ref int gun(return ref int x) { return x;} // OK<br />
@system ref int hun(ref int x) { return x;} // OK for now, @system code.<br />
@system ref int jun(return ref int x) { return x;} // preferred, gives more hints to compiler for lifetime of return value<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.</div>Schveiguyhttps://wiki.dlang.org/?title=DIP25&diff=5351DIP252015-01-17T00:27:03Z<p>Schveiguy: Gahh! more grammar editing.</p>
<hr />
<div>== DIP25: Sealed references ==<br />
{| class="wikitable"<br />
!Title: <br />
!''Sealed references''<br />
|-<br />
|DIP: <br />
|25<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Preliminary Approved<br />
|-<br />
|Created:<br />
|2013-02-05<br />
|-<br />
|Last Modified:<br />
|2015-01-16<br />
|-<br />
|Author:<br />
|Walter Bright and Andrei Alexandrescu<br />
|-<br />
|Links:<br />
|<br />
|}<br />
<br />
== Abstract ==<br />
<br />
D offers a number of features aimed at systems-level coding, such as unrestricted pointers, casting between integers and pointers, and the [http://dlang.org/function.html#system-functions <code>@system</code>] attribute. These means, combined with the other features of D, make it a complete and expressive language for systems-level tasks. On the other hand, economy of means should be exercised in defining such powerful but dangerous features. Most other features should offer good safety guarantees with little or no loss in efficiency or expressiveness. This proposal makes <code>ref</code> provide such a guarantee: with the proposed rules, it is impossible in safe code to have <code>ref</code> refer to a destroyed object. The restrictions introduced are not entirely backward compatible, but disallow code that is stylistically questionable and that can be easily replaced either with equivalent and clearer code.<br />
<br />
== In a nutshell ==<br />
<br />
This DIP proposes that any <code>ref</code> parameter that a function received and also wants to return must be also annotated with <code>return</code>. Annotation are deduced for templates and lambdas, but must be explicit for all other declarations. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe:<br />
ref int fun(ref int a} { return a; } // ERROR<br />
ref int gun(return ref int a} { return a; } // FINE<br />
ref T hun(T)(ref T a} { return a; } // FINE, templates use deduction<br />
</syntaxhighlight><br />
<br />
== Description ==<br />
<br />
Currently, D has some provisions for avoiding dangling references:<br />
<br />
<syntaxhighlight lang=D><br />
ref int fun(int x) {<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
struct S {<br />
int x;<br />
}<br />
<br />
ref int hun() {<br />
S s;<br />
return s.x; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
<br />
ref int iun() {<br />
int a[42];<br />
return a[5]; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
</syntaxhighlight><br />
<br />
However, this enforcement is shallow (even after fixing [https://issues.dlang.org/show_bug.cgi?id=13902 issue 13902]). The following code compiles and allows reads and writes through defunct stack locations, bypassing scoping and lifetime rules:<br />
<br />
<syntaxhighlight lang=D><br />
ref int identity(ref int x) {<br />
return x; // pass-through function that does nothing <br />
}<br />
<br />
ref int fun(int x) {<br />
return identity(x); // escape the address of a parameter <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return identity(x); // escape the address of a local<br />
}<br />
<br />
struct S {<br />
int x;<br />
ref int get() { return x; }<br />
}<br />
<br />
ref int hun(S x) {<br />
return x.get; // escape the address of a part of a parameter <br />
}<br />
<br />
ref int iun() {<br />
S s;<br />
return s.get; // escape the address of part of a local<br />
}<br />
<br />
ref int jun() {<br />
return S().get; // worst contender: escape the address of a part of an rvalue<br />
}<br />
</syntaxhighlight><br />
<br />
The escape patterns are obvious in these simple examples that make all code available and use no recursion, and may be found automatically. The problem is that generally the compiler cannot see the body of <code>identity</code> or <code>S.get()</code>. We need to devise a method that derives enough information for safety analysis only given the function signatures, not their bodies.<br />
<br />
This DIP devises rules that allow passing objects by reference ''down'' into functions, and return references ''up'' from functions, whilst disallowing cases such as the above when a reference passed up ends up referring to a deallocated temporary.<br />
<br />
=== Adding <tt>return</tt> as a parameter attribute ===<br />
<br />
The main issue is typechecking functions that return a <tt>ref T</tt> and accept some of their parameters by <tt>ref</tt>. Those that attempt to return locals or parts thereof are already addressed directly, contingent to [https://issues.dlang.org/show_bug.cgi?id=13902 Issue 13902]. The one case remaining is allowing a function returning <code>ref T</code> to return a (part of a) parameter passed by <code>ref</code>.<br />
<br />
The key is to distinguish legal from illegal cases. One simple but overly conservative option would be to simply disallow returning a <code>ref</code> parameter or part thereof. That makes <code>identity</code> impossible to implement, and as a consequence accessing elements of a container by reference becomes difficult or impossible to typecheck properly. Also, heap-allocated structures with deterministic destruction (e.g. reference counted) must insert member copies for all accesses. <br />
<br />
This proposal promotes adding <code>return</code> as an attribute that propagates the lifetime of a parameter to the return value of a function. With the proposed semantics, a function is disallowed to return a <code>ref</code> parameter of a part thereof UNLESS the parameter is also annotated with <code>return</code>. Under the proposed semantics <code>identity</code> will be spelled as follows:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int wrongIdentity(ref int x) { <br />
return x; // ERROR! Cannot return a ref, please use "return ref"<br />
}<br />
@safe ref int identity(return ref int x) { <br />
return x; // fine<br />
}<br />
</syntaxhighlight><br />
<br />
Just by seeing the signature <code>ref int identity(return ref int x)</code> the compiler assumes that the result of identity must have a shorter or equal lifetime than <code>x</code> and typechecks callers accordingly. Example (given the previous definition of <code>identity</code>):<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref int x) { <br />
int a;<br />
return a; // ERROR per current language rules<br />
static int b;<br />
return b; // fine per current language rules<br />
return identity(a); // ERROR, this may escape the address of a local<br />
return x; // fine, propagate x's lifetime to output<br />
return identity(x); // fine, propagate x's lifetime through identity to the output<br />
return identity(identity(x)); // fine, propagate x's lifetime twice through identity to the output<br />
}<br />
<br />
@safe ref int gun(ref int input) {<br />
static int[42] data;<br />
return data[input]; // works, can always return static-lived data<br />
}<br />
<br />
@safe struct S {<br />
private int x;<br />
ref int get() return { return x; } // should work, see next section <br />
}<br />
</syntaxhighlight><br />
<br />
===Interaction with <tt>auto ref</tt>===<br />
<br />
Syntactically it is illegal to use <tt>auto ref</tt> and <tt>return ref</tt> on the same parameter. Deduction of the <tt>return</tt> attribute still applies as discussed below.<br />
<br />
===Deduction===<br />
<br />
Deduction of the <tt>return</tt> attribute will be effected under the same conditions as for <tt>pure</tt> (currently for generic and lambda functions). That means the generic <tt>identity</tt> function does not require the <tt>return</tt> attribute:<br />
<br />
<syntaxhighlight lang=D><br />
auto ref T identity(auto ref T) {<br />
return x; // correct, no need for return<br />
}<br />
</syntaxhighlight><br />
<br />
===Types of Result vs. Parameters===<br />
<br />
Consider:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref float x);<br />
</syntaxhighlight><br />
<br />
This function arguably cannot return a value scoped within the lifetime of its argument for the simple reason it's impossible to find an <code>int</code> somewhere in a <code>float</code> (apart from unsafe address manipulation). However, this DIP ignores types; if a parameter is <code>return ref</code>, it is always considered potentially escaped as a result. It is in fact possible that the author of <code>fun</code> wants to constrain its output's lifetime for unrelated reasons.<br />
<br />
Future versions of this DIP may relax this rule.<br />
<br />
===Multiple Parameters===<br />
<br />
If multiple <code>return ref</code> parameters are present, the result's lifetime is conservatively assumed to be enclosed in the lifetime of the shortest-lived of those arguments.<br />
<br />
===Member Functions===<br />
Member functions of <code>struct</code>s must qualify <code>this</code> with <code>return</code> if they want to return a result by <code>ref</code> that won't outlive <code>this</code>. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe struct S {<br />
static int a;<br />
int b;<br />
ref int fun() { return a; } // fine, callers assume infinite lifetime<br />
ref int gun() { return b; } // ERROR! Cannot return a direct member<br />
ref int hun() return { return b; } // fine, result is scoped within this<br />
}<br />
</syntaxhighlight><br />
<br />
===@safe===<br />
For the initial release, the requirement of returns for <code>ref</code> parameter data to be marked with <code>return</code> will only apply to <code>@safe</code> functions. The reasons for this are to avoid breaking existing code, and because it's not yet clear whether this feature will interfere with valid constructs in a system language.<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(ref int x) { return x;} // Error<br />
@safe ref int gun(return ref int x) { return x;} // OK<br />
@system ref int hun(ref int x) { return x;} // OK for now, @system code.<br />
@system ref int jun(return ref int x) { return x;} // preferred, gives more hints to compiler for lifetime of return value<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.</div>Schveiguyhttps://wiki.dlang.org/?title=DIP25&diff=5350DIP252015-01-17T00:26:18Z<p>Schveiguy: grammar edit.</p>
<hr />
<div>== DIP25: Sealed references ==<br />
{| class="wikitable"<br />
!Title: <br />
!''Sealed references''<br />
|-<br />
|DIP: <br />
|25<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Preliminary Approved<br />
|-<br />
|Created:<br />
|2013-02-05<br />
|-<br />
|Last Modified:<br />
|2015-01-16<br />
|-<br />
|Author:<br />
|Walter Bright and Andrei Alexandrescu<br />
|-<br />
|Links:<br />
|<br />
|}<br />
<br />
== Abstract ==<br />
<br />
D offers a number of features aimed at systems-level coding, such as unrestricted pointers, casting between integers and pointers, and the [http://dlang.org/function.html#system-functions <code>@system</code>] attribute. These means, combined with the other features of D, make it a complete and expressive language for systems-level tasks. On the other hand, economy of means should be exercised in defining such powerful but dangerous features. Most other features should offer good safety guarantees with little or no loss in efficiency or expressiveness. This proposal makes <code>ref</code> provide such a guarantee: with the proposed rules, it is impossible in safe code to have <code>ref</code> refer to a destroyed object. The restrictions introduced are not entirely backward compatible, but disallow code that is stylistically questionable and that can be easily replaced either with equivalent and clearer code.<br />
<br />
== In a nutshell ==<br />
<br />
This DIP proposes that any <code>ref</code> parameter that a function received and also wants to return must be also annotated with <code>return</code>. Annotation are deduced for templates and lambdas, but must be explicit for all other declarations. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe:<br />
ref int fun(ref int a} { return a; } // ERROR<br />
ref int gun(return ref int a} { return a; } // FINE<br />
ref T hun(T)(ref T a} { return a; } // FINE, templates use deduction<br />
</syntaxhighlight><br />
<br />
== Description ==<br />
<br />
Currently, D has some provisions for avoiding dangling references:<br />
<br />
<syntaxhighlight lang=D><br />
ref int fun(int x) {<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
struct S {<br />
int x;<br />
}<br />
<br />
ref int hun() {<br />
S s;<br />
return s.x; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
<br />
ref int iun() {<br />
int a[42];<br />
return a[5]; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
</syntaxhighlight><br />
<br />
However, this enforcement is shallow (even after fixing [https://issues.dlang.org/show_bug.cgi?id=13902 issue 13902]). The following code compiles and allows reads and writes through defunct stack locations, bypassing scoping and lifetime rules:<br />
<br />
<syntaxhighlight lang=D><br />
ref int identity(ref int x) {<br />
return x; // pass-through function that does nothing <br />
}<br />
<br />
ref int fun(int x) {<br />
return identity(x); // escape the address of a parameter <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return identity(x); // escape the address of a local<br />
}<br />
<br />
struct S {<br />
int x;<br />
ref int get() { return x; }<br />
}<br />
<br />
ref int hun(S x) {<br />
return x.get; // escape the address of a part of a parameter <br />
}<br />
<br />
ref int iun() {<br />
S s;<br />
return s.get; // escape the address of part of a local<br />
}<br />
<br />
ref int jun() {<br />
return S().get; // worst contender: escape the address of a part of an rvalue<br />
}<br />
</syntaxhighlight><br />
<br />
The escape patterns are obvious in these simple examples that make all code available and use no recursion, and may be found automatically. The problem is that generally the compiler cannot see the body of <code>identity</code> or <code>S.get()</code>. We need to devise a method that derives enough information for safety analysis only given the function signatures, not their bodies.<br />
<br />
This DIP devises rules that allow passing objects by reference ''down'' into functions, and return references ''up'' from functions, whilst disallowing cases such as the above when a reference passed up ends up referring to a deallocated temporary.<br />
<br />
=== Adding <tt>return</tt> as a parameter attribute ===<br />
<br />
The main issue is typechecking functions that return a <tt>ref T</tt> and accept some of their parameters by <tt>ref</tt>. Those that attempt to return locals or parts thereof are already addressed directly, contingent to [https://issues.dlang.org/show_bug.cgi?id=13902 Issue 13902]. The one case remaining is allowing a function returning <code>ref T</code> to return a (part of a) parameter passed by <code>ref</code>.<br />
<br />
The key is to distinguish legal from illegal cases. One simple but overly conservative option would be to simply disallow returning a <code>ref</code> parameter or part thereof. That makes <code>identity</code> impossible to implement, and as a consequence accessing elements of a container by reference becomes difficult or impossible to typecheck properly. Also, heap-allocated structures with deterministic destruction (e.g. reference counted) must insert member copies for all accesses. <br />
<br />
This proposal promotes adding <code>return</code> as an attribute that propagates the lifetime of a parameter to the return value of a function. With the proposed semantics, a function is disallowed to return a <code>ref</code> parameter of a part thereof UNLESS the parameter is also annotated with <code>return</code>. Under the proposed semantics <code>identity</code> will be spelled as follows:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int wrongIdentity(ref int x) { <br />
return x; // ERROR! Cannot return a ref, please use "return ref"<br />
}<br />
@safe ref int identity(return ref int x) { <br />
return x; // fine<br />
}<br />
</syntaxhighlight><br />
<br />
Just by seeing the signature <code>ref int identity(return ref int x)</code> the compiler assumes that the result of identity must have a shorter or equal lifetime than <code>x</code> and typechecks callers accordingly. Example (given the previous definition of <code>identity</code>):<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref int x) { <br />
int a;<br />
return a; // ERROR per current language rules<br />
static int b;<br />
return b; // fine per current language rules<br />
return identity(a); // ERROR, this may escape the address of a local<br />
return x; // fine, propagate x's lifetime to output<br />
return identity(x); // fine, propagate x's lifetime through identity to the output<br />
return identity(identity(x)); // fine, propagate x's lifetime twice through identity to the output<br />
}<br />
<br />
@safe ref int gun(ref int input) {<br />
static int[42] data;<br />
return data[input]; // works, can always return static-lived data<br />
}<br />
<br />
@safe struct S {<br />
private int x;<br />
ref int get() return { return x; } // should work, see next section <br />
}<br />
</syntaxhighlight><br />
<br />
===Interaction with <tt>auto ref</tt>===<br />
<br />
Syntactically it is illegal to use <tt>auto ref</tt> and <tt>return ref</tt> on the same parameter. Deduction of the <tt>return</tt> attribute still applies as discussed below.<br />
<br />
===Deduction===<br />
<br />
Deduction of the <tt>return</tt> attribute will be effected under the same conditions as for <tt>pure</tt> (currently for generic and lambda functions). That means the generic <tt>identity</tt> function does not require the <tt>return</tt> attribute:<br />
<br />
<syntaxhighlight lang=D><br />
auto ref T identity(auto ref T) {<br />
return x; // correct, no need for return<br />
}<br />
</syntaxhighlight><br />
<br />
===Types of Result vs. Parameters===<br />
<br />
Consider:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref float x);<br />
</syntaxhighlight><br />
<br />
This function arguably cannot return a value scoped within the lifetime of its argument for the simple reason it's impossible to find an <code>int</code> somewhere in a <code>float</code> (apart from unsafe address manipulation). However, this DIP ignores types; if a parameter is <code>return ref</code>, it is always considered potentially escaped as a result. It is in fact possible that the author of <code>fun</code> wants to constrain its output's lifetime for unrelated reasons.<br />
<br />
Future versions of this DIP may relax this rule.<br />
<br />
===Multiple Parameters===<br />
<br />
If multiple <code>return ref</code> parameters are present, the result's lifetime is conservatively assumed to be enclosed in the lifetime of the shortest-lived of those arguments.<br />
<br />
===Member Functions===<br />
Member functions of <code>struct</code>s must qualify <code>this</code> with <code>return</code> if they want to return a result by <code>ref</code> that won't outlive <code>this</code>. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe struct S {<br />
static int a;<br />
int b;<br />
ref int fun() { return a; } // fine, callers assume infinite lifetime<br />
ref int gun() { return b; } // ERROR! Cannot return a direct member<br />
ref int hun() return { return b; } // fine, result is scoped within this<br />
}<br />
</syntaxhighlight><br />
<br />
===@safe===<br />
For the initial release, the requirement of returns for <code>ref</code> parameter data to be marked with <code>return</code> will only apply to <code>@safe</code> functions. The reason for this are to avoid breaking existing code, and because it's not yet clear whether this feature will interfere with valid constructs in a system language.<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(ref int x) { return x;} // Error<br />
@safe ref int gun(return ref int x) { return x;} // OK<br />
@system ref int hun(ref int x) { return x;} // OK for now, @system code.<br />
@system ref int jun(return ref int x) { return x;} // preferred, gives more hints to compiler for lifetime of return value<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.</div>Schveiguyhttps://wiki.dlang.org/?title=DIP25&diff=5349DIP252015-01-17T00:23:58Z<p>Schveiguy: Added section clarifying requirement of @safe</p>
<hr />
<div>== DIP25: Sealed references ==<br />
{| class="wikitable"<br />
!Title: <br />
!''Sealed references''<br />
|-<br />
|DIP: <br />
|25<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Preliminary Approved<br />
|-<br />
|Created:<br />
|2013-02-05<br />
|-<br />
|Last Modified:<br />
|2015-01-16<br />
|-<br />
|Author:<br />
|Walter Bright and Andrei Alexandrescu<br />
|-<br />
|Links:<br />
|<br />
|}<br />
<br />
== Abstract ==<br />
<br />
D offers a number of features aimed at systems-level coding, such as unrestricted pointers, casting between integers and pointers, and the [http://dlang.org/function.html#system-functions <code>@system</code>] attribute. These means, combined with the other features of D, make it a complete and expressive language for systems-level tasks. On the other hand, economy of means should be exercised in defining such powerful but dangerous features. Most other features should offer good safety guarantees with little or no loss in efficiency or expressiveness. This proposal makes <code>ref</code> provide such a guarantee: with the proposed rules, it is impossible in safe code to have <code>ref</code> refer to a destroyed object. The restrictions introduced are not entirely backward compatible, but disallow code that is stylistically questionable and that can be easily replaced either with equivalent and clearer code.<br />
<br />
== In a nutshell ==<br />
<br />
This DIP proposes that any <code>ref</code> parameter that a function received and also wants to return must be also annotated with <code>return</code>. Annotation are deduced for templates and lambdas, but must be explicit for all other declarations. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe:<br />
ref int fun(ref int a} { return a; } // ERROR<br />
ref int gun(return ref int a} { return a; } // FINE<br />
ref T hun(T)(ref T a} { return a; } // FINE, templates use deduction<br />
</syntaxhighlight><br />
<br />
== Description ==<br />
<br />
Currently, D has some provisions for avoiding dangling references:<br />
<br />
<syntaxhighlight lang=D><br />
ref int fun(int x) {<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
struct S {<br />
int x;<br />
}<br />
<br />
ref int hun() {<br />
S s;<br />
return s.x; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
<br />
ref int iun() {<br />
int a[42];<br />
return a[5]; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
</syntaxhighlight><br />
<br />
However, this enforcement is shallow (even after fixing [https://issues.dlang.org/show_bug.cgi?id=13902 issue 13902]). The following code compiles and allows reads and writes through defunct stack locations, bypassing scoping and lifetime rules:<br />
<br />
<syntaxhighlight lang=D><br />
ref int identity(ref int x) {<br />
return x; // pass-through function that does nothing <br />
}<br />
<br />
ref int fun(int x) {<br />
return identity(x); // escape the address of a parameter <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return identity(x); // escape the address of a local<br />
}<br />
<br />
struct S {<br />
int x;<br />
ref int get() { return x; }<br />
}<br />
<br />
ref int hun(S x) {<br />
return x.get; // escape the address of a part of a parameter <br />
}<br />
<br />
ref int iun() {<br />
S s;<br />
return s.get; // escape the address of part of a local<br />
}<br />
<br />
ref int jun() {<br />
return S().get; // worst contender: escape the address of a part of an rvalue<br />
}<br />
</syntaxhighlight><br />
<br />
The escape patterns are obvious in these simple examples that make all code available and use no recursion, and may be found automatically. The problem is that generally the compiler cannot see the body of <code>identity</code> or <code>S.get()</code>. We need to devise a method that derives enough information for safety analysis only given the function signatures, not their bodies.<br />
<br />
This DIP devises rules that allow passing objects by reference ''down'' into functions, and return references ''up'' from functions, whilst disallowing cases such as the above when a reference passed up ends up referring to a deallocated temporary.<br />
<br />
=== Adding <tt>return</tt> as a parameter attribute ===<br />
<br />
The main issue is typechecking functions that return a <tt>ref T</tt> and accept some of their parameters by <tt>ref</tt>. Those that attempt to return locals or parts thereof are already addressed directly, contingent to [https://issues.dlang.org/show_bug.cgi?id=13902 Issue 13902]. The one case remaining is allowing a function returning <code>ref T</code> to return a (part of a) parameter passed by <code>ref</code>.<br />
<br />
The key is to distinguish legal from illegal cases. One simple but overly conservative option would be to simply disallow returning a <code>ref</code> parameter or part thereof. That makes <code>identity</code> impossible to implement, and as a consequence accessing elements of a container by reference becomes difficult or impossible to typecheck properly. Also, heap-allocated structures with deterministic destruction (e.g. reference counted) must insert member copies for all accesses. <br />
<br />
This proposal promotes adding <code>return</code> as an attribute that propagates the lifetime of a parameter to the return value of a function. With the proposed semantics, a function is disallowed to return a <code>ref</code> parameter of a part thereof UNLESS the parameter is also annotated with <code>return</code>. Under the proposed semantics <code>identity</code> will be spelled as follows:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int wrongIdentity(ref int x) { <br />
return x; // ERROR! Cannot return a ref, please use "return ref"<br />
}<br />
@safe ref int identity(return ref int x) { <br />
return x; // fine<br />
}<br />
</syntaxhighlight><br />
<br />
Just by seeing the signature <code>ref int identity(return ref int x)</code> the compiler assumes that the result of identity must have a shorter or equal lifetime than <code>x</code> and typechecks callers accordingly. Example (given the previous definition of <code>identity</code>):<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref int x) { <br />
int a;<br />
return a; // ERROR per current language rules<br />
static int b;<br />
return b; // fine per current language rules<br />
return identity(a); // ERROR, this may escape the address of a local<br />
return x; // fine, propagate x's lifetime to output<br />
return identity(x); // fine, propagate x's lifetime through identity to the output<br />
return identity(identity(x)); // fine, propagate x's lifetime twice through identity to the output<br />
}<br />
<br />
@safe ref int gun(ref int input) {<br />
static int[42] data;<br />
return data[input]; // works, can always return static-lived data<br />
}<br />
<br />
@safe struct S {<br />
private int x;<br />
ref int get() return { return x; } // should work, see next section <br />
}<br />
</syntaxhighlight><br />
<br />
===Interaction with <tt>auto ref</tt>===<br />
<br />
Syntactically it is illegal to use <tt>auto ref</tt> and <tt>return ref</tt> on the same parameter. Deduction of the <tt>return</tt> attribute still applies as discussed below.<br />
<br />
===Deduction===<br />
<br />
Deduction of the <tt>return</tt> attribute will be effected under the same conditions as for <tt>pure</tt> (currently for generic and lambda functions). That means the generic <tt>identity</tt> function does not require the <tt>return</tt> attribute:<br />
<br />
<syntaxhighlight lang=D><br />
auto ref T identity(auto ref T) {<br />
return x; // correct, no need for return<br />
}<br />
</syntaxhighlight><br />
<br />
===Types of Result vs. Parameters===<br />
<br />
Consider:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref float x);<br />
</syntaxhighlight><br />
<br />
This function arguably cannot return a value scoped within the lifetime of its argument for the simple reason it's impossible to find an <code>int</code> somewhere in a <code>float</code> (apart from unsafe address manipulation). However, this DIP ignores types; if a parameter is <code>return ref</code>, it is always considered potentially escaped as a result. It is in fact possible that the author of <code>fun</code> wants to constrain its output's lifetime for unrelated reasons.<br />
<br />
Future versions of this DIP may relax this rule.<br />
<br />
===Multiple Parameters===<br />
<br />
If multiple <code>return ref</code> parameters are present, the result's lifetime is conservatively assumed to be enclosed in the lifetime of the shortest-lived of those arguments.<br />
<br />
===Member Functions===<br />
Member functions of <code>struct</code>s must qualify <code>this</code> with <code>return</code> if they want to return a result by <code>ref</code> that won't outlive <code>this</code>. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe struct S {<br />
static int a;<br />
int b;<br />
ref int fun() { return a; } // fine, callers assume infinite lifetime<br />
ref int gun() { return b; } // ERROR! Cannot return a direct member<br />
ref int hun() return { return b; } // fine, result is scoped within this<br />
}<br />
</syntaxhighlight><br />
<br />
===@safe===<br />
For the initial release, the requirement of returns for <code>ref</code> parameter data to be marked with <code>return</code> will only apply to <code>@safe</code> functions. The sole reason for this is to avoid breaking existing code, and because it's not yet clear whether this feature will interfere with valid constructs in a system language.<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(ref int x) { return x;} // Error<br />
@safe ref int gun(return ref int x) { return x;} // OK<br />
@system ref int hun(ref int x) { return x;} // OK for now, @system code.<br />
@system ref int jun(return ref int x) { return x;} // preferred, gives more hints to compiler for lifetime of return value<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.</div>Schveiguyhttps://wiki.dlang.org/?title=DIP25&diff=5348DIP252015-01-16T23:00:06Z<p>Schveiguy: /* DIP25: Sealed references */</p>
<hr />
<div>== DIP25: Sealed references ==<br />
{| class="wikitable"<br />
!Title: <br />
!''Sealed references''<br />
|-<br />
|DIP: <br />
|25<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Preliminary Approved<br />
|-<br />
|Created:<br />
|2013-02-05<br />
|-<br />
|Last Modified:<br />
|2015-01-16<br />
|-<br />
|Author:<br />
|Walter Bright and Andrei Alexandrescu<br />
|-<br />
|Links:<br />
|<br />
|}<br />
<br />
== Abstract ==<br />
<br />
D offers a number of features aimed at systems-level coding, such as unrestricted pointers, casting between integers and pointers, and the [http://dlang.org/function.html#system-functions <code>@system</code>] attribute. These means, combined with the other features of D, make it a complete and expressive language for systems-level tasks. On the other hand, economy of means should be exercised in defining such powerful but dangerous features. Most other features should offer good safety guarantees with little or no loss in efficiency or expressiveness. This proposal makes <code>ref</code> provide such a guarantee: with the proposed rules, it is impossible in safe code to have <code>ref</code> refer to a destroyed object. The restrictions introduced are not entirely backward compatible, but disallow code that is stylistically questionable and that can be easily replaced either with equivalent and clearer code.<br />
<br />
== In a nutshell ==<br />
<br />
This DIP proposes that any <code>ref</code> parameter that a function received and also wants to return must be also annotated with <code>return</code>. Annotation are deduced for templates and lambdas, but must be explicit for all other declarations. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe:<br />
ref int fun(ref int a} { return a; } // ERROR<br />
ref int gun(return ref int a} { return a; } // FINE<br />
ref T hun(T)(ref T a} { return a; } // FINE, templates use deduction<br />
</syntaxhighlight><br />
<br />
== Description ==<br />
<br />
Currently, D has some provisions for avoiding dangling references:<br />
<br />
<syntaxhighlight lang=D><br />
ref int fun(int x) {<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return x; // Error: escaping reference to local variable x <br />
}<br />
<br />
struct S {<br />
int x;<br />
}<br />
<br />
ref int hun() {<br />
S s;<br />
return s.x; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
<br />
ref int iun() {<br />
int a[42];<br />
return a[5]; // see https://issues.dlang.org/show_bug.cgi?id=13902<br />
}<br />
</syntaxhighlight><br />
<br />
However, this enforcement is shallow (even after fixing [https://issues.dlang.org/show_bug.cgi?id=13902 issue 13902]). The following code compiles and allows reads and writes through defunct stack locations, bypassing scoping and lifetime rules:<br />
<br />
<syntaxhighlight lang=D><br />
ref int identity(ref int x) {<br />
return x; // pass-through function that does nothing <br />
}<br />
<br />
ref int fun(int x) {<br />
return identity(x); // escape the address of a parameter <br />
}<br />
<br />
ref int gun() {<br />
int x;<br />
return identity(x); // escape the address of a local<br />
}<br />
<br />
struct S {<br />
int x;<br />
ref int get() { return x; }<br />
}<br />
<br />
ref int hun(S x) {<br />
return x.get; // escape the address of a part of a parameter <br />
}<br />
<br />
ref int iun() {<br />
S s;<br />
return s.get; // escape the address of part of a local<br />
}<br />
<br />
ref int jun() {<br />
return S().get; // worst contender: escape the address of a part of an rvalue<br />
}<br />
</syntaxhighlight><br />
<br />
The escape patterns are obvious in these simple examples that make all code available and use no recursion, and may be found automatically. The problem is that generally the compiler cannot see the body of <code>identity</code> or <code>S.get()</code>. We need to devise a method that derives enough information for safety analysis only given the function signatures, not their bodies.<br />
<br />
This DIP devises rules that allow passing objects by reference ''down'' into functions, and return references ''up'' from functions, whilst disallowing cases such as the above when a reference passed up ends up referring to a deallocated temporary.<br />
<br />
=== Adding <tt>return</tt> as a parameter attribute ===<br />
<br />
The main issue is typechecking functions that return a <tt>ref T</tt> and accept some of their parameters by <tt>ref</tt>. Those that attempt to return locals or parts thereof are already addressed directly, contingent to [https://issues.dlang.org/show_bug.cgi?id=13902 Issue 13902]. The one case remaining is allowing a function returning <code>ref T</code> to return a (part of a) parameter passed by <code>ref</code>.<br />
<br />
The key is to distinguish legal from illegal cases. One simple but overly conservative option would be to simply disallow returning a <code>ref</code> parameter or part thereof. That makes <code>identity</code> impossible to implement, and as a consequence accessing elements of a container by reference becomes difficult or impossible to typecheck properly. Also, heap-allocated structures with deterministic destruction (e.g. reference counted) must insert member copies for all accesses. <br />
<br />
This proposal promotes adding <code>return</code> as an attribute that propagates the lifetime of a parameter to the return value of a function. With the proposed semantics, a function is disallowed to return a <code>ref</code> parameter of a part thereof UNLESS the parameter is also annotated with <code>return</code>. Under the proposed semantics <code>identity</code> will be spelled as follows:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int wrongIdentity(ref int x) { <br />
return x; // ERROR! Cannot return a ref, please use "return ref"<br />
}<br />
@safe ref int identity(return ref int x) { <br />
return x; // fine<br />
}<br />
</syntaxhighlight><br />
<br />
Just by seeing the signature <code>ref int identity(return ref int x)</code> the compiler assumes that the result of identity must have a shorter or equal lifetime than <code>x</code> and typechecks callers accordingly. Example (given the previous definition of <code>identity</code>):<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref int x) { <br />
int a;<br />
return a; // ERROR per current language rules<br />
static int b;<br />
return b; // fine per current language rules<br />
return identity(a); // ERROR, this may escape the address of a local<br />
return x; // fine, propagate x's lifetime to output<br />
return identity(x); // fine, propagate x's lifetime through identity to the output<br />
return identity(identity(x)); // fine, propagate x's lifetime twice through identity to the output<br />
}<br />
<br />
@safe ref int gun(ref int input) {<br />
static int[42] data;<br />
return data[input]; // works, can always return static-lived data<br />
}<br />
<br />
@safe struct S {<br />
private int x;<br />
ref int get() return { return x; } // should work, see next section <br />
}<br />
</syntaxhighlight><br />
<br />
===Interaction with <tt>auto ref</tt>===<br />
<br />
Syntactically it is illegal to use <tt>auto ref</tt> and <tt>return ref</tt> on the same parameter. Deduction of the <tt>return</tt> attribute still applies as discussed below.<br />
<br />
===Deduction===<br />
<br />
Deduction of the <tt>return</tt> attribute will be effected under the same conditions as for <tt>pure</tt> (currently for generic and lambda functions). That means the generic <tt>identity</tt> function does not require the <tt>return</tt> attribute:<br />
<br />
<syntaxhighlight lang=D><br />
auto ref T identity(auto ref T) {<br />
return x; // correct, no need for return<br />
}<br />
</syntaxhighlight><br />
<br />
===Types of Result vs. Parameters===<br />
<br />
Consider:<br />
<br />
<syntaxhighlight lang=D><br />
@safe ref int fun(return ref float x);<br />
</syntaxhighlight><br />
<br />
This function arguably cannot return a value scoped within the lifetime of its argument for the simple reason it's impossible to find an <code>int</code> somewhere in a <code>float</code> (apart from unsafe address manipulation). However, this DIP ignores types; if a parameter is <code>return ref</code>, it is always considered potentially escaped as a result. It is in fact possible that the author of <code>fun</code> wants to constrain its output's lifetime for unrelated reasons.<br />
<br />
Future versions of this DIP may relax this rule.<br />
<br />
===Multiple Parameters===<br />
<br />
If multiple <code>return ref</code> parameters are present, the result's lifetime is conservatively assumed to be enclosed in the lifetime of the shortest-lived of those arguments.<br />
<br />
===Member Functions===<br />
Member functions of <code>struct</code>s must qualify <code>this</code> with <code>return</code> if they want to return a result by <code>ref</code> that won't outlive <code>this</code>. Example:<br />
<br />
<syntaxhighlight lang=D><br />
@safe struct S {<br />
static int a;<br />
int b;<br />
ref int fun() { return a; } // fine, callers assume infinite lifetime<br />
ref int gun() { return b; } // ERROR! Cannot return a direct member<br />
ref int hun() return { return b; } // fine, result is scoped within this<br />
}<br />
</syntaxhighlight><br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.</div>Schveiguyhttps://wiki.dlang.org/?title=DIP69&diff=5146DIP692014-12-04T14:54:52Z<p>Schveiguy: Fix subscript tags</p>
<hr />
<div>{| class="wikitable"<br />
!Title:<br />
!'''Implement scope for escape proof references'''<br />
|-<br />
|DIP:<br />
|69<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Draft<br />
|-<br />
|Created:<br />
|2014-12-04<br />
|-<br />
|Last Modified:<br />
|2014-12-04<br />
|-<br />
|Authors:<br />
|Marc Sch&uuml;tz, deadalnix, Andrei Alexandrescu and Walter Bright<br />
|-<br />
|Links:<br />
|'''Proposals'''<br />
* [http://wiki.dlang.org/User:Schuetzm/scope Scope Proposal by Marc Sch&uuml;tz. The above document is derived from this one.]<br />
* [http://wiki.dlang.org/DIP36 DIP36: Scope References by Dicebot]<br />
* [http://wiki.dlang.org/DIP35 DIP35: Addition to DIP25: Sealed References by Zach Tollen]<br />
* [http://wiki.dlang.org/DIP25 DIP25: Sealed References by Andrei Alexandrescu and Walter Bright]<br />
|'''Discussions'''<br />
* [http://forum.dlang.org/post/m5p99m$luk$1@digitalmars.com Discussion about this proposal]<br />
* [http://www.digitalmars.com/d/archives/digitalmars/D/Why_is_scope_planned_for_deprecation_247445.html Why is scope planned for deprecation?]<br />
* [http://www.digitalmars.com/d/archives/digitalmars/D/RFC_scope_and_borrowing_240834.html RFC: scope and borrowing]<br />
* [http://www.digitalmars.com/d/archives/digitalmars/D/borrowed_pointers_vs_ref_232090.html borrowed pointers vs ref]<br />
* [http://www.digitalmars.com/d/archives/digitalmars/D/Proposal_for_design_of_scope_Was_Re_Opportunities_for_D_236686.html Proposal for design of scope]<br />
* [http://www.digitalmars.com/d/archives/digitalmars/D/Re_Proposal_for_design_of_scope_Was_Re_Opportunities_for_D_236705.html Proposal for the design of scope pt 2]<br />
* [http://www.digitalmars.com/d/archives/digitalmars/D/scope_escaping_222858.html scope escaping]<br />
|}<br />
<br />
<br />
=== Abstract ===<br />
<br />
A garbage collected language is inherently memory safe. References to data can be passed<br />
around without concern for ownership, lifetimes, etc. But this runs into difficulty when<br />
combined with other sorts of memory management, like stack allocation, malloc/free allocation,<br />
reference counting, etc.<br />
<br />
Knowing when the lifetime of a reference is over is critical for safely implementing memory<br />
management schemes other than GC. It is also critical for the performance of reference<br />
counting systems, as it will expose opportunities for elision of the inc/dec operations.<br />
<br />
<tt>scope</tt> provides a mechanism to guarantee that a reference cannot<br />
escape lexical scope.<br />
<br />
=== Benefits ===<br />
<br />
* References to stack variables can no longer escape.<br />
* Delegates currently defensively allocate closures with the GC. Few actually escape, and with scope only those that actually escape need to have the closures allocated.<br />
* <tt>@system</tt> code like <tt>std.internal.scopebuffer</tt> can be made <tt>@safe</tt>.<br />
* Reference counting systems need not adjust the count when passing references that do not escape.<br />
* Better self-documentation of encapsulation.<br />
<br />
=== Definitions ===<br />
<br />
==== Lifetime ====<br />
<br />
Any object exists for a specific period of time, with a well defined beginning and end point: from the<br />
point it is created (constructed), to the point it is released (destroyed). This is called its ''lifetime''.<br />
A reference that points to an object whose lifetime has ended is a dangling reference.<br />
Use of such references can cause all kinds of errors, and must therefore be prevented. <br />
<br />
The lifetime of variables is based purely on their lexical scope and order of declaration.<br />
The following rules define a hierarchy of lifetimes:<br />
<br />
* A variable's lifetime starts at the point of its declaration, and ends with the lexical scope it is defined in.<br />
* An (rvalue) expression's lifetime is temporary; it lives till the end of the statement that it appears in.<br />
* The lifetime of A is higher than that of B, if A appears in a higher scope than B, or if both appear in the same scope, but A comes lexically before B. This matches the order of destruction of local variables. <br />
* The lifetime of a function parameter is higher than that of that function's local variables, but lower than any variables in higher scopes.<br />
<br />
<br />
<br />
==== Ownership ====<br />
<br />
A variable ''owns'' the data it contains if, when the lifetime of the variable is ended, the data can be destroyed. There can be at most one owner for any piece of data.<br />
<br />
Ownership may be ''transitive'', meaning anything reachable through the owned data is also owned, or ''head'' where only<br />
the top level reference is owned.<br />
<br />
==== View ====<br />
<br />
Other references to ''owned'' data are called ''views''. Views must not survive the end of the lifetime of the owner<br />
of the data. A view v<sub>2</sub> may be taken of another view v<sub>1</sub>, and the lifetime of v<sub>2</sub> must be subset of the<br />
lifetime of v<sub>1</sub>.<br />
Views may also be transitive or head.<br />
<br />
=== Scope Fundamentals ===<br />
<br />
The purpose of <tt>scope</tt> is to provide a means for ensuring the lifetime of a viewer is a subset of the lifetime of the viewee.<br />
<br />
<tt>scope</tt> is a storage class, and affects declarations. It is not a type constructor.<br />
There is no change to existing [http://dlang.org/attribute <tt>scope</tt> grammar]. It fits in the grammar as a storage class.<br />
<br />
Scope affects:<br />
<br />
* local variables allocated on the stack<br />
* function parameters<br />
* non-static member functions (applying to the <tt>this</tt>)<br />
* delegates (applying to the <tt>this</tt>)<br />
* return value of functions<br />
<br />
It is ignored for other declarations. It is ignored for declarations which are not views.<br />
<br />
<syntaxhighlight lang="D"><br />
scope enum e = 3; // scope is ignored for enums<br />
scope int i; // scope is ignored because integers are not references and so are not views<br />
</syntaxhighlight><br />
<br />
Scope affects variables according to these rules:<br />
<br />
# Scope variables can only be assigned values that have lifetimes that are a superset of the variable's lifetime.<br />
# Scope variables can only be assigned to scope variables with a lifetime that is a subset.<br />
# A variable is inferred to be scope if it is initialized with a view that has a non-&infin; lifetime.<br />
# A scope variable cannot be initialized with the address of a scoped variable.<br />
# A scope ref variable can be initialized with another scope ref variable - scope ref is idempotent.<br />
<br />
<br />
Basic operation:<br />
<br />
<syntaxhighlight lang="D"><br />
int global_var;<br />
int* global_ptr;<br />
<br />
void bar(scope int* input);<br />
<br />
void foo() {<br />
scope int* a;<br />
a = &global_var; // Ok, `global_var` has a greater lifetime than `a`<br />
scope b = &global_var; // Ok, type deduction<br />
int c;<br />
<br />
if(...) {<br />
scope x = a; // Ok, copy of reference,`x` has shorter lifetime than `a`<br />
scope y = &c; // Ok, lifetime(y) < lifetime(& c)<br />
int z;<br />
b = &z; // Error, `b` will outlive `z`<br />
int* d = a; // Ok: d is inferred to be `scope`<br />
}<br />
<br />
bar(a); // Ok, scoped pointer is passed to scoped parameter<br />
bar(&c); // Ok, lifetime(parameter input) < lifetime(c)<br />
int* e;<br />
e = &c; // Error, lifetime(e's view) is &infin; and is greater than lifetime(c)<br />
a = e; // Ok, lifetime(a) < lifetime(e)<br />
scope int** f = &a; // Error, rule 5<br />
scope int** h = &e; // Ok<br />
int* j = *h; // Ok, scope is not transitive<br />
}<br />
<br />
void abc() {<br />
scope int* a;<br />
int* b;<br />
scope ref int* c = a; // Error, rule 5<br />
scope ref int* d = b; // Ok<br />
int* i = a; // Ok, scope is inferred for i<br />
global_ptr = d; // Error, lifetime(d) < lifetime(global_ptr)<br />
global_ptr = i; // Error, lifetime(i) < lifetime(global_ptr)<br />
int* j; // Ok, scope is inferred for i<br />
global_ptr = j; // Ok, j is not scope<br />
}<br />
</syntaxhighlight><br />
<br />
=== Return Statement ===<br />
<br />
A view annotated with <tt>scope</tt> cannot be returned from a function.<br />
<br />
<syntaxhighlight lang="D"><br />
class C { ... }<br />
scope C c;<br />
return c; // Error<br />
<br />
scope int i;<br />
return i; // Ok, i is not a view<br />
<br />
scope int* p;<br />
return p; // Error<br />
return p+1; // Error, nice try!<br />
return &*p; // Error, won't work either<br />
<br />
ref int func(scope ref int r, scope out int s)<br />
{<br />
return r; // Error<br />
return s; // Error, 'out' is treated like 'ref'<br />
}<br />
</syntaxhighlight><br />
<br />
=== Functions ===<br />
<br />
==== Inference ====<br />
<br />
Scope is inferred for function parameters if not specified, under the same circumstances as <tt>pure</tt>, <tt>nothrow</tt>, <tt>@nogc</tt><br />
and safety are inferred.<br />
<br />
==== Overloading ====<br />
<br />
Scope does not affect overloading. If it did, then whether a variable was scope or not would affect the code path, making<br />
scope inference impractical. It also makes turning scope checking on/off impractical.<br />
<br />
<syntaxhighlight lang="D"><br />
T func(scope ref T);<br />
T func(ref T);<br />
<br />
T t; func(t); // Error, ambiguous<br />
scope T u; func(u); // Error, ambiguous<br />
</syntaxhighlight><br />
<br />
<br />
==== Implicit Conversion of Function Pointers and Delegates ====<br />
<br />
<tt>scope</tt> can be added to parameters, but not removed.<br />
<br />
<syntaxhighlight lang="D"><br />
alias int function(ref T) fp_t;<br />
alias int function(scope ref T) fps_t;<br />
<br />
int foo(ref T);<br />
int bar(scope ref T);<br />
<br />
fp_t fp = &bar; // Ok, scope behavior is subset of non-scope<br />
fps_t fp = &foo; // Error, fps_t demands scope behavior<br />
</syntaxhighlight><br />
<br />
==== Inheritance ====<br />
<br />
Overriding functions inherit any <tt>scope</tt> annotations from their antecedents.<br />
Scope is covariant, meaning it can be added to overriding functions.<br />
<br />
<syntaxhighlight lang="D"><br />
class C<br />
{<br />
int foo(ref T);<br />
int bar(scope ref T);<br />
}<br />
<br />
class D<br />
{<br />
override int foo(scope ref T); // Ok, can add scope<br />
override int bar(ref T); // Error, cannot remove scope<br />
}<br />
</syntaxhighlight><br />
<br />
==== Mangling ====<br />
<br />
Scope will require additional mangling, as it affects the interface of the function.<br />
In cases where scope is ignored, it does not contribute to the mangling.<br />
Scope parameters will be mangled with ???.<br />
<br />
==== Nested Functions ====<br />
<br />
Nested functions have more objects available than just their arguments:<br />
<br />
<syntaxhighlight lang="D"><br />
ref T foo() {<br />
T t;<br />
ref T func() { return t; }<br />
return func(); // disallowed<br />
}<br />
</syntaxhighlight><br />
<br />
Nested functions are analyzed as if each variable accessed outside of its scope was passed as a ref parameter.<br />
All parameters have scope inferred from how they are used in the function body.<br />
<br />
<br />
=== Ref ===<br />
<br />
==== Escaping via Return ====<br />
<br />
The simple cases of this are disallowed:<br />
<br />
<syntaxhighlight lang="D"><br />
T* func(T t) {<br />
T u;<br />
return &t; // Error: escaping reference to local t<br />
return &u; // Error: escaping reference to local u<br />
}<br />
</syntaxhighlight><br />
<br />
But are easily circumvented:<br />
<br />
<syntaxhighlight lang="D"><br />
T* func(T t) {<br />
T* p = &t;<br />
return p; // no error detected<br />
}<br />
</syntaxhighlight><br />
<br />
@safe currently deals with this by preventing taking the address of a local:<br />
<br />
<syntaxhighlight lang="D"><br />
T* func(T t) @safe {<br />
T* p = &t; // Error: cannot take address of parameter t in @safe function func<br />
return p;<br />
}<br />
</syntaxhighlight><br />
<br />
This is restrictive. The <tt>ref</tt> storage class was introduced which<br />
defines a special purpose pointer. <tt>ref</tt> can only appear in certain contexts,<br />
in particular function parameters and returns, only applies to declarations,<br />
cannot be stored, and cannot be incremented.<br />
<br />
<syntaxhighlight lang="D"><br />
ref T func(T t) @safe {<br />
return t; // Error: escaping reference to local variable t<br />
}<br />
</syntaxhighlight><br />
<br />
Ref can be passed down to functions:<br />
<br />
<syntaxhighlight lang="D"><br />
void func(ref T t) @safe;<br />
void bar(ref T t) @safe {<br />
func(t); // ok<br />
}<br />
</syntaxhighlight><br />
<br />
But the following idiom is far too useful to be disallowed:<br />
<br />
<syntaxhighlight lang="D"><br />
ref T func(ref T t) {<br />
return t; // ok<br />
}<br />
</syntaxhighlight><br />
<br />
And if it is misused it can result in stack corruption:<br />
<br />
<syntaxhighlight lang="D"><br />
ref T foo() {<br />
T t;<br />
return func(t); // currently, no error detected, despite returning pointer to t<br />
}<br />
</syntaxhighlight><br />
<br />
The:<br />
<br />
<syntaxhighlight lang="D"><br />
return func(t);<br />
</syntaxhighlight><br />
<br />
case is detected by all of the following conditions being true:<br />
<br />
<br />
* foo() returns by reference<br />
* func() returns by reference<br />
* func() has one or more parameters that are by reference<br />
* 1 or more of the arguments to those parameters are stack objects local to foo()<br />
* Those arguments can be @safe-ly converted from the parameter to the return type.<br />
For example, if the return type is larger than the parameter type, the return type<br />
cannot be a reference to the argument. If the return type is a pointer, and the<br />
parameter type is a size_t, it cannot be a reference to the argument. The larger<br />
a list of these cases can be made, the more code will pass @safe checks without requiring<br />
further annotation.<br />
<br />
==== Scope Ref ====<br />
<br />
The above solution is correct, but a bit restrictive. After all, func(t, u) could be returning<br />
a reference to non-local u, not local t, and so should work. To fix this, introduce the concept<br />
of <tt>scope ref</tt>:<br />
<br />
<syntaxhighlight lang="D"><br />
ref T func(scope ref T t, ref T u) {<br />
return t; // Error: escaping scope ref t<br />
return u; // ok<br />
}<br />
</syntaxhighlight><br />
<br />
Scope means that the ref is guaranteed not to escape.<br />
<br />
<syntaxhighlight lang="D"><br />
T u;<br />
ref T foo() @safe {<br />
T t;<br />
return func(t, u); // Ok, u is not local<br />
return func(u, t); // Error: escaping scope ref t<br />
}<br />
</syntaxhighlight><br />
<br />
This minimizes the number of <tt>scope</tt> annotations required.<br />
<br />
==== Scope Function Returns ====<br />
<br />
<tt>scope</tt> can be applied to function return values (even though it is not a type constructor).<br />
It must be applied to the left of the declaration, in the same way <tt>ref</tt> is:<br />
<br />
<br />
<syntaxhighlight lang="D"><br />
int* foo() scope; // applies to 'this' reference<br />
scope: int* foo(); // applies to 'this' reference<br />
scope { int* foo(); } // applies to 'this' reference<br />
scope int* foo(); // applies to return value<br />
</syntaxhighlight><br />
<br />
The lifetime of a scope return value is the lifetime of an rvalue. It may not be copied in a way that extends its life.<br />
<br />
<syntaxhighlight lang="D"><br />
int* bar(scope int*);<br />
scope int* foo();<br />
...<br />
return foo(); // Error, lifetime(return) > lifetime(foo())<br />
int* p = foo(); // Error, lifetime(p) is &infin;<br />
bar(foo()); // Ok, lifetime(foo()) > lifetime(bar())<br />
scope int* q = foo(); // error, lifetime(q) > lifetime(rvalue)<br />
</syntaxhighlight><br />
<br />
This enables scope return values to be safely chained from function to function; in particular<br />
it also allows a ref counted struct to safely expose a reference to its wrapped type.<br />
<br />
==== Out Parameters ====<br />
<br />
<tt>out</tt> parameters are treated like <tt>ref</tt> parameters when <tt>scope</tt> is applied.<br />
<br />
=== Expressions ===<br />
<br />
The ''lifetime'' of an expression is either &infin; or the lifetime of a single variable. Which it is can be statically<br />
deduced by looking at the type and AST of the expression.<br />
<br />
The root cases are:<br />
<br />
<table border=1 cellpadding=4 cellspacing=0><br />
<tr><th class="donthyphenate">'''root case'''</th><th class="donthyphenate">'''lifetime'''</th></tr><br />
<tr><td>address of variable v</td><td>lifetime(v)</td></tr><br />
<tr><td>v containing value with references</td><td>lifetime(v)</td></tr><br />
<tr><td>otherwise</td><td>&infin;</td></tr><br />
</table><br />
<br />
<br />
More complex expressions can be reduced to be one of the root cases:<br />
<br />
<table border=1 cellpadding=4 cellspacing=0><br />
<tr><th class="donthyphenate">'''expression'''</th><th class="donthyphenate">'''lifetime'''</th></tr><br />
<tr><td><tt>&amp;(*e)</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>*(&e + integer)</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>*((e1? &amp; e2 : &e3) + integer)</tt></td><td>min(lifetime(e2), lifetime(e3))</td></tr><br />
<tr><td><tt>*e</tt></td><td>&infin;</td></tr><br />
<tr><td><tt>e1,e2</tt></td><td>lifetime(e2)</td></tr><br />
<tr><td><tt>e1 = e2</tt></td><td>lifetime(e1)</td></tr><br />
<tr><td><tt>e1 op= e2</tt></td><td>lifetime(e1)</td></tr><br />
<tr><td><tt>e1 ? e2 : e3</tt></td><td>min(lifetime(e2), lifetime(e3))</td></tr><br />
<tr><td><tt>ptr + integer</tt></td><td>lifetime(ptr)</td></tr><br />
<tr><td><tt>e1 op e2</tt></td><td>min(lifetime(e1), lifetime(e2))</td></tr><br />
<tr><td><tt>op e</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>e++</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>e--</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>cast(type) e</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>new</tt></td><td>&infin;</td></tr><br />
<tr><td><tt>e.field</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>(*e).field</tt></td><td>lifetime(*e)</td></tr><br />
<tr><td><tt>e.func(args)</tt></td><td>min(lifetime(e, args), &infin;)</td></tr><br />
<tr><td><tt>func(args)</tt></td><td>min(lifetime(non-scope-ref args), &infin;)</td></tr><br />
<tr><td><tt>e[]</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>e[i..j]</tt></td><td>lifetime(e)</td></tr><br />
<tr><td><tt>e[i]</tt></td><td>lifetime(*e)</td></tr><br />
<tr><td>''ArrayLiteral''</td><td>min(lifetime(args))</td></tr><br />
<tr><td>''ArrayLiteral[constant]''</td><td>lifetime(ArrayLiteral[constant])</td></tr><br />
</table><br />
<br />
=== Classes ===<br />
<br />
Scope class semantics are equivalent to a pointer to a struct.<br />
<br />
=== Static Arrays ===<br />
<br />
Scope static array semantics are to equivalent to a scope struct:<br />
<br />
<syntaxhighlight lang="D"><br />
T[3] a;<br />
struct A { T t0, t1, t2; } A a;<br />
</syntaxhighlight><br />
<br />
=== @safe ===<br />
<br />
Errors for scope violations are only reported in @safe code.<br />
<br />
=== Breaking Existing Code ===<br />
<br />
Some code will no longer work. Although inference will take care of a lot of cases,<br />
there are still some that will fail.<br />
<br />
<syntaxhighlight lang="D"><br />
int i,j;<br />
int* p = &i; // Ok, scope is inferred for p<br />
int* q;<br />
q = &i; // Error: too late to infer scope for q<br />
</syntaxhighlight><br />
<br />
Currently, <tt>scope</tt> is ignored except that a new class use to initialize a scope variable allocates the class<br />
instance on the stack. Fortunately, this can work with this new proposal, with an optimization that recognizes<br />
that if a new class is unique, and assigned to a scope variable, that that instance can be placed on the stack.<br />
<br />
=== Implementation Plan ===<br />
<br />
Turning this on may cause significant breakage, and may also be found to be an unworkable design. Therefore, implementation stages will be:<br />
<br />
* enable new behavior with a compiler switch <tt>-scope</tt><br />
* remove <tt>-scope</tt>, issue warning when errors are detected<br />
* replace warnings with deprecation messages<br />
* replace deprecations with errors</div>Schveiguyhttps://wiki.dlang.org/?title=DIP23&diff=1842DIP232013-02-03T16:49:59Z<p>Schveiguy: /* No module-level properties */</p>
<hr />
<div>== DIP23: Fixing properties redux ==<br />
{| class="wikitable"<br />
!Title: <br />
!'''Fixing properties'''<br />
|-<br />
|DIP: <br />
|23<br />
|-<br />
|Version:<br />
|1<br />
|-<br />
|Status:<br />
|Draft<br />
|-<br />
|Created:<br />
|2013-02-02<br />
|-<br />
|Last Modified:<br />
|2013-02-02<br />
|-<br />
|Author:<br />
|Andrei Alexandrescu and Walter Bright<br />
|-<br />
|Links:<br />
|<br />
|}<br />
<br />
== Abstract ==<br />
<br />
There has been significant debate about finalizing property implementation. This document attempts to provide a proposal of reasonable complexity along with checkable examples.<br />
<br />
Forces:<br />
<br />
* Break as little code as possible<br />
* Avoid departing from the existing and intended syntax and semantics of properties<br />
* Make economy of means (little or no new syntax to learn)<br />
* Avoid embarrassing situations such as expressions with unexpressible types or no-op address-of operator (as is the case with C functions).<br />
<br />
== Description ==<br />
<br />
=== The <code>-property</code> switch gets deprecated ===<br />
<br />
This DIP obviates any behavioral change via <code>-property</code>.<br />
<br />
=== Optional parens stay in ===<br />
<br />
One can't discuss properties without also discussing optional parens. These obviate to some extent the need for properties (at least of the read-only kind) and make for potential ambiguities.<br />
<br />
This proposal sustains that optional parentheses should stay in. That means, if a function or method may be called without arguments, the trailing parens may be omitted.<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
int a;<br />
void fun1() { ++a; }<br />
// will call fun<br />
fun1;<br />
assert(a == 1);<br />
<br />
// Works with default arguments, too<br />
void fun2(string s = "abc") { ++a; }<br />
fun2;<br />
assert(a == 2);<br />
}<br />
</syntaxhighlight><br />
<br />
The same goes about methods:<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
int a;<br />
struct S1 { void fun1() { ++a; } }<br />
S1 s1;<br />
// will call fun<br />
s1.fun1;<br />
assert(a == 1);<br />
<br />
// Works with default arguments, too<br />
struct S2 { void fun2(string s = "abc") { ++a; } }<br />
S2 s2;<br />
s2.fun2;<br />
assert(a == 2);<br />
}<br />
</syntaxhighlight><br />
<br />
However, that's not the case with function objects, delegate objects, or objects that implement the function call operator.<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
static int a;<br />
static void fun1() { ++a; }<br />
auto p1 = &fun1;<br />
// Error: var has no effect in expression (p1)<br />
p1;<br />
assert(a == 0);<br />
}<br />
unittest<br />
{<br />
int a;<br />
void fun1() { ++a; }<br />
auto p1 = &fun1;<br />
// Error: var has no effect in expression (p1)<br />
p1;<br />
}<br />
unittest<br />
{<br />
static int a;<br />
struct S1 { void opCall() { ++a; } }<br />
S1 s1;<br />
// Error: var has no effect in expression (s1) s1;<br />
s1;<br />
}<br />
</syntaxhighlight><br />
<br />
Taking the type of a symbol that may be used in a paren-less call results in the type of the returned object. THIS IS A CHANGE OF SEMANTICS.<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
int fun1() { return 42; }<br />
static assert(is(typeof(fun1) == int));<br />
}<br />
</syntaxhighlight><br />
<br />
To get the function type, one must apply the address-of operator.<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
int fun1() { return 42; }<br />
static assert(is(typeof(&fun1) == int delegate()));<br />
static int fun2() { return 42; }<br />
static assert(is(typeof(&fun2) == int function()));<br />
}<br />
</syntaxhighlight><br />
<br />
The same goes about member functions. THIS IS A CHANGE OF BEHAVIOR.<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
struct S1 { int fun() { return 42; } }<br />
S1 s1;<br />
assert(s1.fun == 42);<br />
static assert(is(typeof(s1.fun) == int)); // currently fails<br />
}<br />
</syntaxhighlight><br />
<br />
The basic motivation here is that "s1.fun" should not change type when under "typeof".<br />
<br />
If a function returns a reference, then assignment through the paren-less call should work:<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
static int x;<br />
ref int fun1() { return x; }<br />
fun1 = 42;<br />
assert(x == 42);<br />
}<br />
</syntaxhighlight><br />
<br />
A function that returns an object that in turn supports a call with "()" will never automatically apply implicit parens to the returned object. Using either `fun` or `fun()` will return the callable entity. To invoke the callable entity immediately one must use `fun()()`.<br />
<br />
<syntaxhighlight lang="d"><br />
unittest<br />
{<br />
static int x;<br />
int function() fun1() { return () => 42; }<br />
assert(is(typeof(fun1) == int function()));<br />
assert(is(typeof(fun1()) == int function()));<br />
assert(is(typeof(fun1()()) == int));<br />
assert(fun1()() == 42);<br />
}<br />
</syntaxhighlight><br />
<br />
=== "Read" properties with the @property annotation ===<br />
<br />
Functions annotated with @property are subject to additional restrictions compared to regular functions.<br />
<br />
In brief, the "()" operator may NEVER be applied EXPLICITLY to a function annotated with @property. THIS IS A CHANGE OF SEMANTICS.<br />
<br />
<syntaxhighlight lang=D><br />
unittest<br />
{<br />
@property int prop1() { return 42; }<br />
assert(prop1 == 42);<br />
static assert(is(typeof(prop1) == int));<br />
static assert(!__traits(compiles, prop1()));<br />
}<br />
</syntaxhighlight><br />
<br />
Applying the "()" to a property will simply apply it to the result of the property. THIS IS A CHANGE OF BEHAVIOR.<br />
<br />
<syntaxhighlight lang=D><br />
unittest<br />
{<br />
@property int function() prop1() { return () => 42; }<br />
assert(prop1() == 42);<br />
}<br />
</syntaxhighlight><br />
<br />
(Note: The @property annotation is not part of the function type, so it is impossible for a property to return a property.)<br />
<br />
==="Write" properties via the @property annotation===<br />
<br />
In order to use the assignment operator "=" property-style, the @property annotation MUST be used.<br />
<br />
The rule for allowing assignment with properties is simple. <br />
<br />
1. If "foo" is a function that has the @property annotation AND takes exactly one parameter, then "foo = x" calls foo with argument x. Calling "foo(x)" is disallowed. The type of the expression "foo = x" is the type of foo's result.<br />
<br />
<syntaxhighlight lang=D><br />
unittest<br />
{<br />
@property void fun(int x) { assert(x == 42); }<br />
fun = 42;<br />
assert(is(typeof(fun = 42) == void));<br />
}<br />
</syntaxhighlight><br />
<br />
2. If "foo" is a function that has the @property annotation AND takes exactly two parameters, then "x.foo = y" calls foo with arguments x and y. Calling "foo(x, y)" or "x.foo(y)" is disallowed.<br />
<br />
<syntaxhighlight lang=D><br />
unittest<br />
{<br />
@property double fun(int x, double y) { assert(x == 42 && y == 43); return y; }<br />
42.fun = 43;<br />
assert(is(typeof(42.fun = 43) == double));<br />
}<br />
</syntaxhighlight><br />
<br />
3. If "foo" is a member function of a class or struct that has the @property annotation AND takes exactly one parameter (aside from the implicit parameter this), then "x.foo = y" calls x.foo with argument y.<br />
<br />
<syntaxhighlight lang=D><br />
unittest<br />
{<br />
struct S1<br />
{<br />
@property double fun(int x) { assert(x == 42); return 43; }<br />
}<br />
S1 s1;<br />
s1.fun = 42;<br />
assert((s1.fun = 42) == 43);<br />
assert(is(typeof(s1.fun = 42) == double));<br />
}<br />
</syntaxhighlight><br />
<br />
=== No module-level properties ===<br />
<br />
There is no module-level property emulating a global variable. That means a <code>@property</code> defined at module level must take either one parameter (meaning it's a getter) or two parameters (meaning it's a setter).<br />
<br />
<syntaxhighlight lang=D><br />
// at module level<br />
@property int truncated(double x) { return cast(int) x; }<br />
@property void all(double[] x, int y) { x[] = cast(double) y; }<br />
unittest<br />
{<br />
// truncated = 4.2; // compile-time error<br />
int a = 4.2.truncated;<br />
assert(a == 4);<br />
auto d = [ 1.2, 3.4 ];<br />
d.all = 42;<br />
assert(d == [ 42.0, 42.0 ]);<br />
}<br />
</syntaxhighlight><br />
<br />
===Taking the address of a property===<br />
<br />
If <code>prop</code> is a property, '''&prop''' or '''a.prop''' obey the normal rules of function/delegate access. They do not take the addres of the returned value implicitly. To do so, one must use '''&(prop)''' or '''&(a.prop)'''.<br />
<br />
===Applying operators===<br />
<br />
This may be getting a bit too cute, but there's quite some demand for it.<br />
<br />
If <code>a.prop</code> is a member variable, the expression <code>a.prop op= x</code> has the usual meaning. Otherwise, <code>a.prop op= x</code> gets rewritten twice. First rewrite is <code>(a.prop) op= x</code>, i.e. apply <code>op=</code> to the result of the property. Second rewrite is <code>a.prop = a.prop op x</code>. If only one of the two rewrite compiles, use it. If both compile, fail with ambiguity error.<br />
<br />
For properties, the increment operators are rewritten as follows<br />
<br />
Rewrite 1:<br />
<br />
<code>++a.p</code> ----> <code>++(a.p)</code><br />
<br />
<code>a.p++</code> ----> <code>(++a.p)</code><br />
<br />
Rewrite 2:<br />
<code>++a.p</code> ----> <code>{ auto v = a.p; ++v; a.p = v; return v; }()</code><br />
<br />
<code>a.p++</code> ----> <code>{ auto v = a.p; ++a.p; return v; }()</code><br />
<br />
If only one of the two rewrite compiles, use it. If both compile, fail with ambiguity error.<br />
<br />
== Talk ==<br />
<br />
goes here<br />
<br />
== Copyright ==<br />
This document has been placed in the Public Domain.</div>Schveiguy