digitalmars.D.learn - pegged: non safe semantic actions
- Dmitry Ponyatov (57/57) Dec 08 2023 What's wrong with using non@safe actions which creates and
- Jonathan M Davis (29/86) Dec 08 2023 Since I've never used pegged, I can't really comment on the specific
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)`
```
Dec 08 2023
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
Dec 08 2023








Jonathan M Davis <newsgroup.d jmdavisprog.com>