Skip to content

Commit b8fac60

Browse files
schveiguy0xEAB
andcommitted
Fix #10607 - Structs lines and ByLineCopy cannot be usefully constructed in @safe code
Originally known as "Properly mark lines constructor". Co-authored-by: Elias Batek <15967408+0xEAB@users.noreply.github.com>
1 parent 262645b commit b8fac60

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

std/stdio.d

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,13 +2409,13 @@ void main()
24092409
private struct ByLineCopy(Char, Terminator)
24102410
{
24112411
private:
2412-
import std.typecons : RefCounted, RefCountedAutoInitialize;
2412+
import std.typecons : SafeRefCounted, RefCountedAutoInitialize;
24132413

24142414
/* Ref-counting stops the source range's ByLineCopyImpl
24152415
* from getting out of sync after the range is copied, e.g.
24162416
* when accessing range.front, then using std.range.take,
24172417
* then accessing range.front again. */
2418-
alias Impl = RefCounted!(ByLineCopyImpl!(Char, Terminator),
2418+
alias Impl = SafeRefCounted!(ByLineCopyImpl!(Char, Terminator),
24192419
RefCountedAutoInitialize.no);
24202420
Impl impl;
24212421

@@ -4626,7 +4626,7 @@ struct lines
46264626
f = File to read lines from.
46274627
terminator = Line separator (`'\n'` by default).
46284628
*/
4629-
this(File f, dchar terminator = '\n')
4629+
this(File f, dchar terminator = '\n') @safe
46304630
{
46314631
this.f = f;
46324632
this.terminator = terminator;
@@ -4721,6 +4721,47 @@ struct lines
47214721
}
47224722
}
47234723

4724+
@safe unittest
4725+
{
4726+
/*
4727+
As pointed out in <https://github.com/dlang/phobos/issues/10605>,
4728+
it's a pity that `byLine()` & co. aren't @safe to use yet.
4729+
4730+
This is a first attempt at working towards that goal.
4731+
For now, this test doesn't do much; as there isn't much to do safely yet.
4732+
*/
4733+
auto deleteMe = testFilename();
4734+
scope(exit) { imported!"std.file".remove(deleteMe); }
4735+
4736+
// Setup
4737+
{
4738+
auto f = File(deleteMe, "w");
4739+
scope(exit) { f.close(); }
4740+
foreach (i; 1 .. 11)
4741+
f.writeln(i);
4742+
}
4743+
4744+
// Actual tests
4745+
{
4746+
auto f = File(deleteMe, "r");
4747+
scope(exit) { f.close(); }
4748+
4749+
auto myLines = lines(f);
4750+
foreach (string line; myLines)
4751+
continue;
4752+
4753+
auto myByLineCopy = f.byLineCopy; // but cannot safely iterate yet
4754+
/*
4755+
still `@system`:
4756+
- cannot call `@system` function `std.stdio.File.ByLineCopy!(immutable(char), char).ByLineCopy.empty`
4757+
- cannot call `@system` function `std.stdio.File.ByLineCopy!(immutable(char), char).ByLineCopy.popFront`
4758+
- cannot call `@system` function `std.stdio.File.ByLineCopy!(immutable(char), char).ByLineCopy.front`
4759+
*/
4760+
//foreach (line; myByLineCopy)
4761+
// continue;
4762+
}
4763+
}
4764+
47244765
@system unittest
47254766
{
47264767
static import std.file;

0 commit comments

Comments
 (0)