[Issue 20483] New: std.uni.byGrapheme & Grapheme.opSlice requires obscure REF parameters.
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon Jan 6 08:25:26 UTC 2020
https://issues.dlang.org/show_bug.cgi?id=20483
Issue ID: 20483
Summary: std.uni.byGrapheme & Grapheme.opSlice requires obscure
REF parameters.
Product: D
Version: D2
Hardware: x86_64
OS: Windows
Status: NEW
Severity: enhancement
Priority: P1
Component: phobos
Assignee: nobody at puremagic.com
Reporter: robert.muench at saphirion.com
There is the "What type does byGrapheme() return?" thread in d.learn from which
I copy different statements and findings:
```
string r1 = "Robert M. Münch";
// Code-Units = 16
// Code-Points = 15
// Graphemes = 15
Grapheme[] gr1 = r1.byGrapheme.array;
writeln(" Text = ", gr1.map!(g => g[]).joiner.to!string);
// Text = obert M. Münch
writeln("wText = ", gr1.map!(g => g[]).joiner.to!wstring);
// wText = obert M. Münch
writeln("dText = ", gr1.map!(g => g[]).joiner.to!dstring);
// dText = obert M. Münch
```
Looks like when you use .map over the Grapheme, it gets copied into a
temporary, which gets invalidated when map.front returns.
compiling with dmd -dip1000 produces this error message:
test.d(15): Error: returning g.opSlice() escapes a reference to
parameter g, perhaps annotate with return
/usr/src/d/phobos/std/algorithm/iteration.d(499): instantiated
from here: MapResult!(__lambda1, Grapheme[])
test.d(15): instantiated from here: map!(Grapheme[])
Not the most helpful message (the annotation has to go in Phobos code, not in
user code), but it does at least point to the cause of the problem.
The original example is fixable by putting "ref" in for all the lambdas. But
this is kind of disturbing. Why does the grapheme do this? The original data is
not scoped.
e.g.:
```
writeln(" Text = ", gr1.map!((ref g) => g[]).joiner.to!string);
```
The fact that a Grapheme's return requires you keep the grapheme in scope for
operations seems completely incorrect and dangerous IMO (note that operators
are going to always have a ref this, even when called on an rvalue). So even
though using ref works, I think the underlying issue here really is the
lifetime problem.
Investigate whether Grapheme.opSlice can be implemented differently, such that
we avoid this obscure referential behaviour that makes it hard to work with in
complex
code.
--
More information about the Digitalmars-d-bugs
mailing list