Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safe by default v2 #228

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions DIPs/DIP1044.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Make @safe the Default v2

| Field | Value |
|-----------------|-----------------------------------------------------------------|
| DIP: | |
| Review Count: | |
| Author: | Walter Bright [email protected] / [Mark]([email protected]) |
| Implementation: | https://github.com/dlang/dmd/pull/10709 |
| Status: | |

## Abstract

Currently, D functions default to being `@system`. This DIP proposes changing the default to `@safe`.


## Contents
* [Rationale](#rationale)
* [Prior Work](#prior-work)
* [Description](#description)
* [Breaking Changes and Deprecations](#breaking-changes-and-deprecations)
* [Reference](#reference)
* [Copyright & License](#copyright--license)

## Rationale

When D was first developed, there was little interest in the extra safety checks
introduced by `@safe`. But as the costs of unsafe code have become ever more apparent
and expensive, and `@safe` has grown more capable, the balance has shifted. Users expect
safety to be opt-out, not opt-in.

Most code should be naturally safe, and system code should be relatively rare. It makes
sense that the common case - safe code - should be the default and not require an
annotation.


## Prior Work

* Other languages such as Rust and C# have safety as opt-out, rather than opt-in.
* A previous draft proposal: [@safe-by-default First Draft](https://github.com/dlang/DIPs/pull/153)
* [DIP1028](https://github.com/dlang/DIPs/blob/master/DIPs/rejected/DIP1028.md)

## Description

Functions such as template functions, nested functions, and lambdas that are not annotated
currently have their `@safe` / `@system` attribute inferred. This behavior will not change.
Other unannotated functions will now be assumed to be `@safe` rather than `@system`.

Because this is expected to break a lot of existing code, it will be enabled with the
compiler switch:

```
-preview=safedefault
```

There are no grammar changes.

### Non-Virtual Templated Functions

Non-virtual function templates get their attributes inferred if they are not explicitly marked.
Hence, this proposal should not affect them.

## Breaking Changes and Deprecations

This will likely break most code that has not already been annotated with `@safe`,

Choose a reason for hiding this comment

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

This will likely break some code.

`@trusted`, or `@system`. Annotate functions that aren't safe with `@system`.
Once the project compiles again successfully, start with the leaves marked `@system` and
modify as required to make them `@safe`.

In general, `@system` should not be applied to blocks of functions. It should be added
specifically to each function that requires it.

### Extern C and C++ Functions

An unmarked `extern (D)` function will now be considered `@safe`. If its implementation is not recompiled,
it will no longer link because the mangling will be different. But for `extern (C)` and `(C++)` functions,
safety is not part of the mangling and it will compile and link without error. This has always
relied on the user getting it correct.

Interfaces to extern C and C++ functions should always be explicitly marked.

Any unmarked `extern` C and C++ functions will remain `@system`.

Choose a reason for hiding this comment

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

Does this includes both body and bodiless extern functions?

Choose a reason for hiding this comment

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

The problem with this is that a lot of those functions are actually D code.


### 3rd Party Libraries

It's best practice for 3rd party libraries to use explicit safety annotations and not rely on defaults.
It is also best practice to compile those libraries with the same compiler that is being used
to compile the project.

### Virtual Functions (Covariance)

An `@safe` function can override an `@system` function, but not vice-versa. Hence, with `@safe` being
the default, the user may see compile errors when overriding a now-default `@safe` function with
a `@system` one. The user will have to decide which the inheritance hierarchy should be and annotate
as required.

## Reference

## Copyright & License
Copyright (c) 2019 by the D Language Foundation

Licensed under [Creative Commons Zero 1.0](https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt)