On 12/4/2014 1:52 PM, H. S. Teoh via Digitalmars-d wrote:
On Thu, Dec 04, 2014 at 01:10:31PM -0800, Walter Bright via Digitalmars-d wrote:
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 :-)

Recently there was a bug filed by Andrei himself, and a bunch of merged
PRs, that renamed "type constructor" to "type qualifier". The general
sense I got was that we're deprecating "type constructor" in preference
for "type qualifier".

Looks like Andrei Hath Spaketh!


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.
Are there any use cases for bypassing scope semantics in @system code?

One is to interface with legacy code that does not use 'scope' properly in its declarations. There are probably more.

How common are they?

I don't know.

Maybe such code *should* look ugly -- to draw
attention to the fact that something un-@safe is going on.

@system is ugly enough.

Or perhaps we can make cast() strip away scope? I much rather require
explicit annotation for potentially unsafe operations, than to have
subtle bugs creep into the code just because I forgot to mark something
as @safe.

Start your modules with:

  @safe:


There are, though probably incomplete, and there's also an ongoing
stream of Phobos PR's for marking things @safe that ought not to be
@system.  There's a *lot* of Phobos code that needs to be cleaned up in
this way before this can be workable. (Unless we abuse @trusted as a
temporary workaround -- but that's not an approach I'd like to
recommend!)

As long as there's ongoing progress!


Still not sure how it would address the RC folks' request for compiler
support, but I suppose that's a different topic.

Yup, different issue.


I think it's a fairly important issue, since making this work correctly
will also open up optimization opportunities for a good chunk of
delegate-based code.

See my other reply with resolution.


I was thinking more of what implications may hold in the loop body for
references to (local) variables outside the loop, since that presents
another potential optimization opportunity if we do it right.

Yes. I think there are a number of optimization properties we can exploit over 
time.


Overloaded operators are treated like calls to the functions that back
them.
OK. You might want to state this explicitly in the DIP, just so it isn't
left up to interpretation. :-)

Ok.

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.
[...]

I'm not quite sure I see how this could be implemented. When the
compiler is compiling func(), say it's in a different module, there's
nothing about the function that says it's illegal to return a reference
to the member of an incoming argument.

That's right, so the compiler assumes it does, unless the parameter is marked as scope.

First of all, this isn't a
template function so scope inference isn't in effect; secondly, even of
it were in effect (say we write it as `func()(ref S s)` instead), it
wouldn't be able to infer the return value as scope, since it's
obviously escaping a reference to a function argument.

'scope ref' parameters cannot be returned by 'ref' or by 'scope ref'. The only distinction between 'ref' and 'scope ref' parameters is the latter cannot be returned by 'ref' or 'scope ref'.

So, unless I'm
missing something obvious, func() will be accepted by the compiler (as
it should, since we didn't mark anything as scope here).

The compiler assumes func(s) returns a ref to s, and so it won't allow func(s) to be returned from foo().


Now when the compiler compiles foo(), it can no longer see what's inside
func(), so there's no way for it to know that the ref int being returned
actually comes from the ref S parameter.

It assumes it does, unless 'ref S' is marked 'scope ref S'. It's the whole point of 'scope ref'.

Reply via email to