On Friday, December 8, 2023 10:13:21 AM MST Dmitry Ponyatov via Digitalmars-d- learn wrote: > What's wrong with using non@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