pegged: non at safe semantic actions

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Dec 9 02:36:00 UTC 2023


On Friday, December 8, 2023 10:13:21 AM MST Dmitry Ponyatov via Digitalmars-d-
learn wrote:
> What's wrong with using non at safe actions which creates and
> modifies some external objects?
>
> ```D
> class Layer {
>      int index;
>      string name;
>      this(int index, string name) {
>
> class SignalLayer : Layer {
> class UserLayer : Layer {
>
> class PCB {
>      Layer[] layer;
>
> PT _deflayer(PT)(PT p) {
>      auto index = to!int(p.matches[0]);
>      switch (p.matches[2]) {
>      case "signal":
>          pcb.layer ~= new SignalLayer(index, p.matches[1]); break;
>      case "user":
>          pcb.layer ~= new UserLayer(index, p.matches[1]); break;
>      default:
>          break;
>      }
>      return p;
> }
>
> mixin(grammar(`
>      parser:
>          kicad_pcb <  :l :'kicad_pcb' verzion host general page
> layers
>          layers    <  :l :'layers' (deflayer {_deflayer})+ :r
>          deflayer  <  :l unum layer ('signal'|'user') :r
>
> ```
> ```
> ../.dub/packages/pegged/0.4.9/pegged/pegged/peg.d(3049,19):
> Error: `@safe` function `pegged.peg.action!(wrapAround,
> _deflayer).action` cannot call `@system` function
> `kicad._deflayer!(ParseTree)._deflayer`
> src/kicad.d(27,5):        which calls `kicad.SignalLayer.this`
> src/kicad.d(68,4):        `kicad._deflayer!(ParseTree)._deflayer`
> is declared here
> src/kicad.d-mixin-83(219,289): Error: template instance
> `pegged.peg.action!(wrapAround, _deflayer)` error instantiating
> src/kicad.d-mixin-83(932,7):        instantiated from here:
> `Genericparser!(ParseTree)`
> ../.dub/packages/pegged/0.4.9/pegged/pegged/peg.d(544,20): Error:
> none of the overloads of `layers` are callable using argument
> types `(GetName)`
> src/kicad.d-mixin-83(215,23):        Candidates are:
> `kicad.Genericparser!(ParseTree).Genericparser.parser.layers(ParseTree p)`
> src/kicad.d-mixin-83(234,23):
> `kicad.Genericparser!(ParseTree).Genericparser.parser.layers(string s)`
> ../.dub/packages/pegged/0.4.9/pegged/pegged/peg.d(1598,24):
> Error: template instance `pegged.peg.getName!(layers)` error
> instantiating
> src/kicad.d-mixin-83(183,436):        instantiated from here:
> `wrapAround!(named, layers, named)`
> src/kicad.d-mixin-83(932,7):        instantiated from here:
> `Genericparser!(ParseTree)`
> ```

Since I've never used pegged, I can't really comment on the specific
semantics of what you're trying to do. However, any function which is marked
as @safe cannot call any functions that are @system. So, if pegged is
marking a function as @safe, and it is then trying to call your function,
your function then needs to be @safe or @trusted, regardless of what it's
actually doing, which means that you need to then make it so that your
function either isn't doing anything that's @system so that it can be @safe,
or you need to vet what it's doing to make sure that it's actually
memory-safe in spite of the fact that the compiler can't verify it, in which
case, you would need to mark it as @trusted.

The default for functions is @system, and none of the code you've shown is
marked with @safe. Templated functions and functions which return auto will
have their attributes inferred, which includes @safe, so if _deflayer is not
calling any @system functions or doing any operations which are @system, it
will be inferred as @safe. However, it looks like the constructors that it's
calling are not marked with @safe and are not templated. So, they will not
infer their attributes and will be @system, which will in turn mean that
_deflayer gets inferred as @system. And if pegged is calling _deflayer from
code that's marked with @safe, then you're going to get a compilation error.

So, based on what I can see here, it looks like you need to be marking your
functions with @safe where you can, and if any of your code is doing stuff
that isn't guaranteed to be memory-safe (and thus can't be @safe), then
you'll need to make sure that what it's doing is actually memory-safe (in
spite of the fact that the compiler can't guarantee it) and mark it with
@trusted to indicate that you've verified it, and then @safe code can call
it.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list