Skip to content

Commit 1b24204

Browse files
0xEABdlang-bot
authored andcommitted
Fix #10605 - Make File.byLine usable in @safe contexts
1 parent 5f39350 commit 1b24204

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

std/stdio.d

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,13 +2169,13 @@ Allows to directly use range operations on lines of a file.
21692169
private struct ByLineImpl(Char, Terminator)
21702170
{
21712171
private:
2172-
import std.typecons : RefCounted, RefCountedAutoInitialize;
2172+
import std.typecons : borrow, RefCountedAutoInitialize, SafeRefCounted;
21732173

21742174
/* Ref-counting stops the source range's Impl
21752175
* from getting out of sync after the range is copied, e.g.
21762176
* when accessing range.front, then using std.range.take,
21772177
* then accessing range.front again. */
2178-
alias PImpl = RefCounted!(Impl, RefCountedAutoInitialize.no);
2178+
alias PImpl = SafeRefCounted!(Impl, RefCountedAutoInitialize.no);
21792179
PImpl impl;
21802180

21812181
static if (isScalarType!Terminator)
@@ -2190,19 +2190,24 @@ Allows to directly use range operations on lines of a file.
21902190
impl = PImpl(f, kt, terminator);
21912191
}
21922192

2193-
@property bool empty()
2193+
/* Verifiably `@safe` when built with -preview=DIP1000. */
2194+
@property bool empty() @trusted
21942195
{
2195-
return impl.refCountedPayload.empty;
2196+
// Using `ref` is actually necessary here.
2197+
return impl.borrow!((ref i) => i.empty);
21962198
}
21972199

2198-
@property Char[] front()
2200+
/* Verifiably `@safe` when built with -preview=DIP1000. */
2201+
@property Char[] front() @trusted
21992202
{
2200-
return impl.refCountedPayload.front;
2203+
// Using `ref` is likely optional here.
2204+
return impl.borrow!((ref i) => i.front);
22012205
}
22022206

2203-
void popFront()
2207+
/* Verifiably `@safe` when built with -preview=DIP1000. */
2208+
void popFront() @trusted
22042209
{
2205-
impl.refCountedPayload.popFront();
2210+
return impl.borrow!((ref i) => i.popFront());
22062211
}
22072212

22082213
private:
@@ -2216,6 +2221,7 @@ Allows to directly use range operations on lines of a file.
22162221
KeepTerminator keepTerminator;
22172222
bool haveLine;
22182223

2224+
@safe:
22192225
public:
22202226
this(File f, KeepTerminator kt, Terminator terminator)
22212227
{
@@ -2375,7 +2381,7 @@ void main()
23752381
return ByLineImpl!(Char, Terminator)(this, keepTerminator, terminator);
23762382
}
23772383

2378-
@system unittest
2384+
@safe unittest
23792385
{
23802386
static import std.file;
23812387
auto deleteme = testFilename();
@@ -2393,7 +2399,7 @@ void main()
23932399
}
23942400

23952401
// https://issues.dlang.org/show_bug.cgi?id=19980
2396-
@system unittest
2402+
@safe unittest
23972403
{
23982404
static import std.file;
23992405
auto deleteme = testFilename();
@@ -2541,12 +2547,11 @@ $(REF readText, std,file)
25412547
is(typeof(File("").byLineCopy!(char, char).front) == char[]));
25422548
}
25432549

2544-
@system unittest
2550+
@safe unittest
25452551
{
25462552
import std.algorithm.comparison : equal;
25472553
static import std.file;
25482554

2549-
scope(failure) printf("Failed test at line %d\n", __LINE__);
25502555
auto deleteme = testFilename();
25512556
std.file.write(deleteme, "");
25522557
scope(success) std.file.remove(deleteme);
@@ -2620,7 +2625,7 @@ $(REF readText, std,file)
26202625
test("sue\r", ["sue\r"], kt, '\r');
26212626
}
26222627

2623-
@system unittest
2628+
@safe unittest
26242629
{
26252630
import std.algorithm.comparison : equal;
26262631
import std.range : drop, take;
@@ -4765,6 +4770,15 @@ struct lines
47654770
foreach (line; myByLineCopy)
47664771
continue;
47674772
}
4773+
4774+
{
4775+
auto f = File(deleteMe, "r");
4776+
scope(exit) { f.close(); }
4777+
4778+
auto myByLine = f.byLine;
4779+
foreach (line; myByLine)
4780+
continue;
4781+
}
47684782
}
47694783

47704784
@system unittest

0 commit comments

Comments
 (0)