Thread overview
Making sense out of scope and function calls
Nov 13, 2022
0xEAB
Nov 13, 2022
Imperatorn
Nov 13, 2022
Dennis
Nov 13, 2022
0xEAB
Nov 14, 2022
Dukc
November 13, 2022
struct Foo { /* … */
    hstring[] getHeader(LowerCaseToken name) scope return
    {
        return _headers[name].values;
    }

    hstring[] getHeader(hstring name)() scope return
    {
        enum token = LowerCaseToken.makeConverted(name);
        return this.getHeader(token); // line 605
    }
}
struct Foo { /* … */
    hstring[] getHeader(LowerCaseToken name) scope return
    {
        return _headers[name].values;
    }

    hstring[] getHeader(hstring name)() scope return
    {
        enum token = LowerCaseToken.makeConverted(name);
        return _headers[token].values; // line 605
    }
}

Why does only the latter sample compile?
The former leads to the following warning:

beyond.d(605,30): Deprecation: cannot take address of `scope` variable `this` since `scope` applies to first indirection only
beyond.d(605,30): Deprecation: cannot take address of `scope` variable `this` since `scope` applies to first indirection only

(and why is the deprecation message printed twice?)

November 13, 2022

On Sunday, 13 November 2022 at 19:06:40 UTC, 0xEAB wrote:

>
struct Foo { /* … */
    hstring[] getHeader(LowerCaseToken name) scope return
    {
        return _headers[name].values;
    }

[...]

There's an old saying "you can't make sense out of scope"

November 13, 2022

On Sunday, 13 November 2022 at 19:06:40 UTC, 0xEAB wrote:

>

Why does only the latter sample compile?
The former leads to the following warning:

Can you please provide a full example? I'm missing the definitions of _headers, hstring, values, and I suspect there's at least one @safe annotation somewhere.

November 13, 2022

On Sunday, 13 November 2022 at 19:36:48 UTC, Dennis wrote:

>

Can you please provide a full example? I'm missing the definitions of _headers, hstring, values

/++
    “HTTP message string” – short-hand for `const(char)[]``.

    $(SIDEBAR
        Not sure about the name.
        Would have prefered *cstring* (*const string* as opposed to D’s default immutable one),
        but the common association with that term would be “zero-terminated string (as made famous by C)”.
    )
 +/
alias hstring = const(char)[];

struct Foo {
    private Headers _headers;

Headers was basically like the one here[0], just annoted with scope scope return etc. all over the place. I’m sorry, I don’t have any copy of that around anymore (as I’ve never commited it and already discarded my code + the idea of using scope – in its current state – in real world code).

>

and I suspect there's at least one @safe annotation somewhere.

yeah, everything is @safe here.

[0] https://github.com/oceandrift/http/blob/982030123bdbfb64681264d42ade15d0ccc9ebe9/message/oceandrift/http/message.d#L264

November 14, 2022

On Sunday, 13 November 2022 at 19:06:40 UTC, 0xEAB wrote:

>

Why does only the latter sample compile?
The former leads to the following warning:

Are you using the -preview=dip1000 compiler flag?

I didn't manage to reproduce this in a simple example of my own. The closest I equivalent I accomplished is this:

enum LowerCaseToken { u, l, c }

struct Foo {
    @safe:
    int* dummy;
    string[int][LowerCaseToken] _headers;

    this(return ref int i)
    {
        dummy = &i;
    }

    string[] getHeader(LowerCaseToken name) scope return
    {
        return _headers[name].values;
    }

    string[] getHeader(string name)() scope return
    {
        enum token = LowerCaseToken.l;
        // Error. Remove to compile
        auto x = &this;
        return this.getHeader(token);
    }
}

@safe void main()
{
    int x;
    auto foo = Foo(x);
    foo.getHeader!"h1"();
}

With -preview=dip1000 this fails, but with a slightly different message to yours, "cannot take address of scope parameter this in @safe function getHeader". It's right to fail, because you cannot have any pointer (or array, or class) to point to a scope variable. D does not have any storage class for x that would protect the int pointed to by dummy, because scope(Foo*) means address of Foo is protected, not the address of whatever dummy and _headers point to.

However, this error only happens if I try to create a pointer to this, not when simply using this, plus the error is a bit different, so I'm not sure what's going on.

>

(and why is the deprecation message printed twice?)

The function is a template. Perhaps it's instantiated twice. Another possibility, you have instantiated the mixin template that contains that function in your project twice.