DIP69 - Implement scope for escape proof references

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Thu Dec 4 13:10:31 PST 2014


On 12/4/2014 11:41 AM, H. S. Teoh via Digitalmars-d wrote:
> Can we pretty please use the term "type qualifier" instead of "type
> constructor"? ;-)

I think "type constructor" is the more pedantically correct term, but you'll 
have to ask Andrei :-)


> 1) Why are scope violations only reported for @safe code?? IMO this
> greatly limits the usefulness of this DIP.  If I mark something as
> scope, I'd expect it should be enforced by the compiler regardless of
> @safe annotations, otherwise what's the point??

Because there are inevitably cases where you'll need to wrap unsafe code with a 
safe interface. By screwing this down too tightly for @system code, you'll force 
people to use really ugly workarounds.


> Currently, due to the incompleteness of @safe, it's difficult to use
> @safe annotations everywhere I'd like to (e.g. I need to use some
> un- at safe Phobos functions that really ought to be @safe, but aren't due
> to various reasons, like compiler limitations, etc.). This greatly
> limits the usefulness of this DIP, if scope is only enforced in @safe
> code!

Are there bug reports on this?


> 2) Is there a way to detect if something is marked as scope?

Using __traits(compiles,...) ought to work.

> If not, how
> does this proposal actually enable ref-counted types? (I'm assuming a
> library ref-counting type here; or are we expecting further compiler
> enhancements for ref counting?)

The ref counting would be done by a wrapper, which implicitly converts to the 
wrappee by exposing a scope ref.


> 3) What does scope mean for delegate parameters? To what does the scope
> apply, the delegate itself, its body, or its return value, or ...?
>
> 	struct S {
> 		void opApply(scope void delegate(ref int) loopBody) {
> 			...
> 			// what restrictions (might) apply here w.r.t.
> 			// how loopBody can be called?
> 		}
> 	}

Hmmm, looks like a problem I didn't think of. darnit!


> And what would be the effect on the caller's side?
>
> 	S s;
> 	foreach (i; s) {
> 		// what restrictions (might) apply here?
> 	}

i would get its scope inferred as necessary, so restrictions would apply as they 
would to a 'scope i'.


> 4) Under "Expressions", how does scope interact with overloaded
> operators? Do the same rules apply to expressions that use overloaded
> operators as they apply to built-in operators, or do they apply as
> though the overloaded operators were written out in function-call
> syntax?  What happens if some overloaded operators take a mix of scope
> and non-scope parameters?

Overloaded operators are treated like calls to the functions that back them.


> Finally, the following isn't directly related to this DIP, since scope
> is intended to solve this problem, but I thought I should bring it up.
> :-) In the section "escaping via return", 5 points are listed as
> sufficient for detecting the "return func(t);" case. The following
> section "scope ref" states that these 5 points are "correct" (in
> implementing escaping reference detection). However, isn't the following
> a loophole?
>
> 	struct S {
> 		int x;
> 	}
> 	ref int func(ref S s) {
> 		return s.x;
> 	}
> 	ref T foo() {
> 		S s;
> 		return func(s); // escaping reference
> 	}
>
> Since S cannot implicitly convert to int, it would appear that this
> circumvents escaping reference detection.

No, because under this proposal, s.x is treated as if it were just s as far a 
scope rules are concerned.

> (In fact, dmd happily accepts
> this code, even if everything is annotated with @safe.)

I know, the current escape detection is quite inadequate - hence this proposal.

> Note that the
> escaping reference to x can be arbitrarily deeply nested inside S, so
> it's non-trivial to decide whether there's no possibility for references
> to (parts of) S to leak from func().

This proposal should lock that down.



More information about the Digitalmars-d mailing list