Difference between revisions of "DIP29"

From D Wiki
Jump to: navigation, search
(major revamp)
(Wikification)
 
Line 38: Line 38:
 
== Definition ==
 
== Definition ==
  
Unique Value
+
;Unique Value
 +
:Rvalues are always unique.
  
Rvalues are always unique.
+
;Unique Reference
 +
:A reference is unique if there are no other references to the same object (including references to the object's interior).
  
Unique Reference
+
;Transitively Unique Reference
  
A reference is unique if there are no other references to the same object
+
:A Unique Reference and there are no external references to any values transitively accessible through it.
(including references to the object's interior).
 
  
Transitively Unique Reference
+
;Implicitly Convertible To Immutable
 +
:One of:
 +
:# The type is implicitly convertible to Immutable.
 +
:# Transitively Unique Reference
 +
:# Transitive graph is reachable only via immutable references
  
A Unique Reference and there are no external references to any
+
; Implicitly Convertible To Shared
values transitively accessible through it.
+
:One of:
 
+
:# Type is implicitly convertible to Shared
Implicitly Convertible To Immutable
+
:# Transitively Unique Reference; head is not immutable
 
+
:# Transitive graph is reachable only via shared or immutable references; head is not immutable
One of:
 
 
 
1. The type is implicitly convertible to Immutable.
 
 
 
2. Transitively Unique Reference
 
 
 
3. Transitive graph is reachable only via immutable references
 
 
 
Implicitly Convertible To Shared
 
 
 
One of:
 
 
 
1. Type is implicitly convertible to Shared
 
 
 
2. Transitively Unique Reference; head is not immutable
 
 
 
3. Transitive graph is reachable only via shared or immutable references;
 
head is not immutable
 
  
 
== Library Types ==
 
== Library Types ==
Line 80: Line 67:
 
i.e. they are magic types.
 
i.e. they are magic types.
  
Each has a static assume(T e) method which unsafely assumes the properties of the argument
+
Each has a static <tt>assume(T e)</tt> method which unsafely assumes the properties of the argument
 
Expression e and returns an instance of the type.
 
Expression e and returns an instance of the type.
  
Unique(T)(T e)
+
;<tt>Unique(T)(T e)</tt>
 
+
:T: class, pointer, dynamic array, delegate
T: class, pointer, dynamic array, delegate
+
:Forms a transitively unique reference
 
 
Forms a transitively unique reference
 
 
 
UniqueImmutable(T)(T e)
 
 
 
T: class, pointer, dynamic array, delegate
 
 
 
Implicitly convertible to immutable(T)
 
  
UniqueShared(T)(T e)
+
;<tt>UniqueImmutable(T)(T e)</tt>
 
+
:T: class, pointer, dynamic array, delegate
T: class, pointer, dynamic array, delegate
+
:Implicitly convertible to immutable(T)
 
 
Implicitly convertible to shared(T)
 
  
 +
;<tt>UniqueShared(T)(T e)</tt>
 +
:T: class, pointer, dynamic array, delegate
 +
:Implicitly convertible to shared(T)
  
 
== Expressions ==
 
== Expressions ==
  
Value
+
;<tt>Value</tt>
This is tried first. If it produces false, the checks for particular
+
:This is tried first. If it produces false, the checks for particular Expression types are then tried.
Expression types are then tried.
 
  
Unique
+
:;<tt>Unique</tt>
If all the fields are non-reference types, then true
+
::If all the fields are non-reference types, then true
  
UniqueImmutable
+
:;<tt>UniqueImmutable</tt>
If type can be implicitly cast to immutable
+
::If type can be implicitly cast to immutable
  
UniqueShared
+
:;<tt>UniqueShared</tt>
If type can be implicitly cast to shared
+
::If type can be implicitly cast to shared
  
Variable
+
;<tt>Variable</tt>
If type is Unique, UniqueImmutable, or UniqueShared
+
:If type is Unique, UniqueImmutable, or UniqueShared
  
CommaExpression
+
;<tt>CommaExpression</tt>
result of right operand
+
:result of right operand
  
=
+
;<tt>=</tt>
+=
+
;<tt>+=</tt>
-=
+
;<tt>-=</tt>
result of left operand
+
:result of left operand
  
ConditionalExpression
+
;<tt>ConditionalExpression</tt>
result of left operand and'ed with result of right operand
+
:result of left operand and'ed with result of right operand
  
AddExpression
+
;<tt>AddExpression</tt>
if one operand is a pointer, and the other an integral constant,
+
:if one operand is a pointer, and the other an integral constant, then the result is the result of the pointer operand
then the result is the result of the pointer operand
 
  
CatExpression
+
;<tt>CatExpression</tt>
CatAssignExpression
+
;<tt>CatAssignExpression</tt>
result is the and'ing of all the elements in the operands
+
:result is the and'ing of all the elements in the operands
  
CallExpression
+
;<tt>CallExpression</tt>
if function is pure, then result is the and'ing of all the arguments to the function
+
:if function is pure, then result is the and'ing of all the arguments to the function
  
NewExpression
+
;<tt>NewExpression</tt>
result is the and'ing of all the arguments. If a constructor is called, and it is
+
:result is the and'ing of all the arguments. If a constructor is called, and it is pure, the result includes the and'ing of all the default initializers for the fields
pure, the result includes the and'ing of all the default initializers for the fields
 
  
CastExpression
+
;<tt>CastExpression</tt>
result of operand being cast
+
:result of operand being cast
  
Lambda
+
;<tt>Lambda</tt>
FunctionLiteral
+
;<tt>FunctionLiteral</tt>
result of the expression used to initialize the .ptr field of delegates
+
:result of the expression used to initialize the .ptr field of delegates
  
IndexExpression
+
;<tt>IndexExpression</tt>
result of operand being indexed
+
:result of operand being indexed
  
SliceExpression
+
;<tt>SliceExpression</tt>
result of operand being sliced
+
:result of operand being sliced
  
ArrayLiteral
+
;<tt>ArrayLiteral</tt>
result is the and'ing of all the array elements
+
:result is the and'ing of all the array elements
  
AssocArrayLiteral
+
;<tt>AssocArrayLiteral</tt>
result is the and'ing of all the array keys and values
+
:result is the and'ing of all the array keys and values
  
StructLiteral
+
;<tt>StructLiteral</tt>
result is the and'ing of all the expressions coupled with
+
:result is the and'ing of all the expressions coupled with the initializers for the rest of the fields
the initializers for the rest of the fields
 
  
  
Line 174: Line 150:
 
Add following member functions to Expression:
 
Add following member functions to Expression:
  
bool isUniqueReference();
+
bool isUniqueReference();
 
+
bool isTransitivelyUniqueReference();
+
bool isTransitivelyUniqueReference();
 
+
bool isImplictlyConvertibleToImmutable();
+
bool isImplictlyConvertibleToImmutable();
 
+
bool isImplictlyConvertibleToShared();
+
bool isImplictlyConvertibleToShared();
 
 
 
 
  
 
== Copyright ==
 
== Copyright ==

Latest revision as of 11:22, 23 February 2014

Title: Unique Pointers
DIP: 29
Version: 1
Status: Draft
Created: 2013-02-28
Last Modified: 2013-06-24
Language: D2
Breaks: Nothing, it enables code that doesn't compile at the moment
Links: Discussion on github

Discussion on n.g. More Discussion on n.g.

Abstract

Currently, pointers cannot be converted to and from shared and immutable without an explicit and unsafe cast. Unique pointers can be implicitly cast to and from shared and immutable in safety. A unique pointer can be discovered by examining the expression that generated the pointer.

Rationale

Requiring switching to unsafe code to do routine things like create immutable references is a glaring problem. By recognizing unique pointers much of this can be done safely. More advanced analysis can uncover more cases that can be done safely.

Definition

Unique Value
Rvalues are always unique.
Unique Reference
A reference is unique if there are no other references to the same object (including references to the object's interior).
Transitively Unique Reference
A Unique Reference and there are no external references to any values transitively accessible through it.
Implicitly Convertible To Immutable
One of:
  1. The type is implicitly convertible to Immutable.
  2. Transitively Unique Reference
  3. Transitive graph is reachable only via immutable references
Implicitly Convertible To Shared
One of:
  1. Type is implicitly convertible to Shared
  2. Transitively Unique Reference; head is not immutable
  3. Transitive graph is reachable only via shared or immutable references; head is not immutable

Library Types

Each of these statically verifies that Expression e has the desired properties. Using the result as an rvalue results in overwriting the value with T.init. The compiler statically recognizes these types as having the desired characteristic, i.e. they are magic types.

Each has a static assume(T e) method which unsafely assumes the properties of the argument Expression e and returns an instance of the type.

Unique(T)(T e)
T: class, pointer, dynamic array, delegate
Forms a transitively unique reference
UniqueImmutable(T)(T e)
T: class, pointer, dynamic array, delegate
Implicitly convertible to immutable(T)
UniqueShared(T)(T e)
T: class, pointer, dynamic array, delegate
Implicitly convertible to shared(T)

Expressions

Value
This is tried first. If it produces false, the checks for particular Expression types are then tried.
Unique
If all the fields are non-reference types, then true
UniqueImmutable
If type can be implicitly cast to immutable
UniqueShared
If type can be implicitly cast to shared
Variable
If type is Unique, UniqueImmutable, or UniqueShared
CommaExpression
result of right operand
=
+=
-=
result of left operand
ConditionalExpression
result of left operand and'ed with result of right operand
AddExpression
if one operand is a pointer, and the other an integral constant, then the result is the result of the pointer operand
CatExpression
CatAssignExpression
result is the and'ing of all the elements in the operands
CallExpression
if function is pure, then result is the and'ing of all the arguments to the function
NewExpression
result is the and'ing of all the arguments. If a constructor is called, and it is pure, the result includes the and'ing of all the default initializers for the fields
CastExpression
result of operand being cast
Lambda
FunctionLiteral
result of the expression used to initialize the .ptr field of delegates
IndexExpression
result of operand being indexed
SliceExpression
result of operand being sliced
ArrayLiteral
result is the and'ing of all the array elements
AssocArrayLiteral
result is the and'ing of all the array keys and values
StructLiteral
result is the and'ing of all the expressions coupled with the initializers for the rest of the fields


Implementation

Add following member functions to Expression:

bool isUniqueReference();

bool isTransitivelyUniqueReference();

bool isImplictlyConvertibleToImmutable();

bool isImplictlyConvertibleToShared();

Copyright

This document has been placed in the Public Domain.