Skip to content

Latest commit

 

History

History
148 lines (106 loc) · 9.07 KB

DIP1028.md

File metadata and controls

148 lines (106 loc) · 9.07 KB

Make @safe the Default

Field Value
DIP: 1028
Review Count: 2
Author: Walter Bright walter@digitalmars.com
Implementation: dlang/dmd#10709
Status: Rejected

Abstract

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

Contents

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

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, @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.

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

Reviews

Community Review Round 1

Reviewed Version

Discussion

In a very long discussion thread, there was a mix of support and opposition. Some critical feedback points were:

  • The DIP should specify a deprecation plan.
  • The DIP should specify an extended deprecation period.
  • Such a major change should be saved for a potential D3.
  • The DIP should not be approved until it is possible to make @safe ref-counted types and a tool exists to annotate existing default @system functions as @system. Another commenters suggested the tool should additionally annotate functions @safe if they compile. The DIP author replied that such a tool would be welcome.
  • Introduce @legacy that, when added to the top of a module, makes every function @trusted by default.
  • Weak rationale.
  • The rationale should be enhanced to say that the majority of existing, non-template D code is already @safe, but not annotated as such, preventing projects with dependencies from using the annotation. This change makes dependencies useful in @safe code.
  • Advising users to fix breakage by annotating unsafe functions with @trusted or @system should be revised to just advise @system, otherwise users may misunderstand and misuse @trusted. The DIP author agreed this is a good idea.
  • The DIP should also include the introduction of @trusted expressions. This was countered by the argument that changes to @trusted should be a separate DIP.
  • Make it a compiler option only.
  • The DIP does not address bugs in @safe which require a DIP to fix. The DIP author replied that this DIP is about making @safe the default, not changing its behavior.
  • The impact of the change should be assessed. The DIP author replied that compatibility can be achieved by labeling functions that don't compile as @system.
  • Too many DIPs resulting in new -preview switches. The DIP author replied that all programming languages improve or die.
  • The DIP does not explore alternatives, as recommended by the DIP guidelines. Examples would be a linting tool that annotates functions as @safe when they compile, or the ability to annotate module declarations with @safe or @system to specify the default behavior in that module.
  • What about function declarations with no body?
  • The DIP should also change @system to @unsafe. The DIP author replied that @unsafe was rejected when @system was introduced because it has negative connotations.
  • Perhaps the DIP should discuss DIP1000, since it may have an impact on the amount and nature of breakage this DIP causes. Is this DIP dependent on DIP1000 being the default? Does -preview=safedefault imply -preview=dip1000? The DIP should discuss the types breakage that will be avoided with DIP1000 enabled. The DIP author replied that DIP1000 and DIP1028 will remain independent.
  • The DIP should go into more detail about breaking changes, i.e., migration paths, third-party libraries that are no longer actively maintained, the problem with a catch-all @system: disabling template inference, the impact of the change on extern APIs, the impact of the change on @nogc code, and more.
  • The consideration of prior work should provide more detail.
  • How does the DIP affect interfaces and virtual functions? Implementations and subclasses with unmarked @system implementations will fail to compile when their interface/superclass member functions become @safe. The DIP author replied that functions in interfaces and base classes will initially need to be explicitly marked @system and can later be marked @safe in a transition.

Final Review

Reviewed Version

Discussion

Feedback

The following points were raised in the feedback thread:

  • The DIP specifically mentions extern (D) functions as being marked as @safe? The author replied that all extern functions will be @safe.
  • Saying that interfaces to C and C++ functions "should be explicitly marked" is too vague. How should they be marked?
  • Adding @system: to the top of a file will kill template inference of @safe. The DIP should deal with this somehow.
  • @safe should not be allowed on function declarations that are not extern (D) or, alternatively, the compiler should require all non-D mangled functions to be explictly marked with one of @safe, @trusted, or @system.

Formal Assessment

Reviewed Version

Discussion

This proposal was initially accepted by the language maintainers. After further discussion in the D forums, the DIP author in his role as language maintainer chose to reverse the decision. The proposal is now rejected.