Thread overview
[Issue 20607] [shared] static constructor & co can be called as regular function
Feb 25, 2020
Dlang Bot
Nov 25, 2020
Vladimir Panteleev
Dec 08, 2020
Mathias LANG
Dec 08, 2020
Vladimir Panteleev
Dec 08, 2020
Mathias LANG
Dec 08, 2020
Vladimir Panteleev
Dec 17, 2022
Iain Buclaw
February 25, 2020
https://issues.dlang.org/show_bug.cgi?id=20607

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull

--- Comment #1 from Dlang Bot <dlang-bot@dlang.rocks> ---
@Geod24 created dlang/dmd pull request #10834 "Fix issue 20607 - Module constructors are visible as regular function" fixing this issue:

- Fix issue 20607 - Module constructors are visible as regular function

  This breaks the type system pretty easily.
  If the user *really* want to do something funky,
  they can still declare those as `extern(C)` and there isn't
  much we can (or will) do about it.

  But having those functions available in the symtab
  means they show up in `impHint` and can be called by
  accident (e.g. a bug in code generation that use `__allMembers`).

  There is still an issue with variable, but since it doesn't
  break the type system, and comes with a refactor,
  it is left for a later PR.

https://github.com/dlang/dmd/pull/10834

--
November 25, 2020
https://issues.dlang.org/show_bug.cgi?id=20607

Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dlang-bugzilla@thecybershad
                   |                            |ow.net

--- Comment #2 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
I don't see why this is a problem as long as it's @system.

Allowing users to access D implementation plumbing at various levels is useful for things like custom unittest runners, allocation libraries, things like std.algorithm.move, etc.

--
December 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20607

--- Comment #3 from Mathias LANG <pro.mathias.lang@gmail.com> ---
> I don't see why this is a problem as long as it's @system.

Because it breaks the type system, and even in `@system` code it is not allowed.

> Allowing users to access D implementation plumbing at various levels is useful for things like custom unittest runners, allocation libraries, things like std.algorithm.move, etc.

Agreed, but accessing it should be conscious, not an accident. It was clearly never intended to be accessed this way. I would prefer if we had a pragma for this, for example, instead of magic names (we have the same problem with ctors / dtors in aggregate, where we can't name them but sometimes want to access them).

--
December 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20607

--- Comment #4 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
(In reply to Mathias LANG from comment #3)
> > I don't see why this is a problem as long as it's @system.
> 
> Because it breaks the type system, and even in `@system` code it is not allowed.

I don't see how. @system is designed to allow breaking the type system. @trusted code is not allowed to do so.

> Agreed, but accessing it should be conscious, not an accident.

How is accessing identifiers by internal names accidental? The __allMembers example seems farfetched and based on bad assumptions - code enumerating __allMembers should already be checking the kind of member it is handling. Module constructors ought to be viewed as any other kind of module members.

I think the PR is going in the wrong direction. Instead of removing functionality, I would suggest to instead ensure that it's not accessible in @safe code, and that special members are clearly identified as such (i.e. not functions), but not change anything else.

--
December 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20607

--- Comment #5 from Mathias LANG <pro.mathias.lang@gmail.com> ---
> I don't see how. @system is designed to allow breaking the type system. @trusted code is not allowed to do so.

The compiler doesn't let you change `immutable` values in `@system` functions.

> How is accessing identifiers by internal names accidental?

*Exposing* them was accidental. You can access them at runtime with module info. It would be good to have a way to access them at compile-time too, and I'm fine with this being a blocker to solve this issue. E.g. adding `__traits({ctors, dtor}, SYM)`.

--
December 08, 2020
https://issues.dlang.org/show_bug.cgi?id=20607

--- Comment #6 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
(In reply to Mathias LANG from comment #5)
> > I don't see how. @system is designed to allow breaking the type system. @trusted code is not allowed to do so.
> 
> The compiler doesn't let you change `immutable` values in `@system` functions.

It does with a cast. It doesn't seem to me that calling a compiler-generated function with an internal name is too different from that.

> > How is accessing identifiers by internal names accidental?
> 
> *Exposing* them was accidental.

What makes you say this?

> You can access them at runtime with module
> info. It would be good to have a way to access them at compile-time too, and
> I'm fine with this being a blocker to solve this issue. E.g. adding
> `__traits({ctors, dtor}, SYM)`.

It really seems unwarranted to me.

If they are callable in @safe, then that is a bug and I agree that it should be fixed.

If the introspection says that the constructors are naught but regular functions, then it's lying and that ought to be fixed. (Though, technically you could have already inferred that from the name.)

But, if the code is calling it like a function (a valid operation for other things in D, like function pointers / delegates / functors), that's surely intentional. It seems really far-fetched that this could be something accidental and we have to break things in order to "protect" users from it.

Another improvement could be to implicitly declare the constructors as private. Currently, access modifiers apply to static constructors "predictably": public constructors are "callable" from other modules, but private ones aren't.

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=20607

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P3

--