Thread overview
std_exception.html#enforce: example does not compile
Jan 27, 2018
kdevel
Jan 27, 2018
Jonathan M Davis
Jan 27, 2018
kdevel
Jan 27, 2018
Jonathan M Davis
Jan 27, 2018
kdevel
Jan 27, 2018
Jonathan M Davis
Jan 27, 2018
kdevel
Jan 28, 2018
Seb
January 27, 2018
https://dlang.org/phobos/std_exception.html#enforce and also https://dlang.org/library/std/exception/enforce.html present this example:

---
auto f = enforce(fopen("data.txt"));
auto line = readln(f);
enforce(line.length, "Expected a non-empty line.");
---

fopen, readln and enforce need imports, fopen needs a mode parameter:

enforce.d
---
import core.stdc.stdio : fopen;
import std.stdio : readln;
import std.exception;

void main ()
{
   auto f = enforce(fopen("data.txt", "r"));
   auto line = readln(f);
   enforce(line.length, "Expected a non-empty line.");
}
---

$ dmd enforce
enforce.d(7): Error: function expected before (), not module enforce of type void

According to https://tour.dlang.org/tour/en/basics/exceptions I changed the import (not knowing why):

enforce.d
---
import core.stdc.stdio : fopen;
import std.stdio : readln;
import std.exception : enforce;

void main ()
{
   auto f = enforce(fopen("data.txt", "r"));
   auto line = readln(f);
   enforce(line.length, "Expected a non-empty line.");
}
---

Now I get:

$ dmd enforce
enforce.d(8): Error: template std.stdio.readln cannot deduce function from argument types !()(shared(_IO_FILE)*), candidates are:
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3921):        std.stdio.readln(S = string)(dchar terminator = '\x0a') if (isSomeString!S)
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3955):        std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3962):        std.stdio.readln(C, R)(ref C[] buf, R terminator) if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && isBidirectionalRange!R && is(typeof(terminator.front == (dchar).init)))

What's wrong here? And why is the "selective import" of enforce necessary?
January 27, 2018
On Saturday, January 27, 2018 13:29:00 kdevel via Digitalmars-d-learn wrote:
> What's wrong here? And why is the "selective import" of enforce necessary?

Because you named your module enforce. As such, by default, referring to enforce inside of the module refers to the module. Having the selective import overrides that.

It's generally not a good idea to name your module the same name something that you would refer to inside the module. It's usually not an issue in real programs, because in that case, aside from maybe the module with main, modules aren't at the top-level, but if you're doing something like naming your test program after a function that you're using in it, you're going to have problems.

- Jonathan M Davis

January 27, 2018
On Saturday, 27 January 2018 at 16:10:29 UTC, Jonathan M Davis wrote:
> On Saturday, January 27, 2018 13:29:00 kdevel via Digitalmars-d-learn wrote:
>> What's wrong here? And why is the "selective import" of enforce necessary?
>
> Because you named your module enforce. As such, by default, referring to enforce inside of the module refers to the module. Having the selective import overrides that.

Okay. But what about that persisting error message:

zz.d
---
import core.stdc.stdio : fopen;
import std.stdio : readln, writeln;
import std.exception; // : enforce;

void main ()
{
   auto f = enforce(fopen("data.txt", "r"));
   auto line = readln(f);
   enforce(line.length, "Expected a non-empty line.");
}
---

$ dmd zz
zz.d(8): Error: template std.stdio.readln cannot deduce function from argument types !()(shared(_IO_FILE)*), candidates are:
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3921):        std.stdio.readln(S = string)(dchar terminator = '\x0a') if (isSomeString!S)
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3955):        std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
/.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3962):        std.stdio.readln(C, R)(ref C[] buf, R terminator) if (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) && isBidirectionalRange!R && is(typeof(terminator.front == (dchar).init)))

The example still does not compile.
January 27, 2018
On Saturday, January 27, 2018 17:57:54 kdevel via Digitalmars-d-learn wrote:
> On Saturday, 27 January 2018 at 16:10:29 UTC, Jonathan M Davis
>
> wrote:
> > On Saturday, January 27, 2018 13:29:00 kdevel via
> >
> > Digitalmars-d-learn wrote:
> >> What's wrong here? And why is the "selective import" of enforce necessary?
> >
> > Because you named your module enforce. As such, by default, referring to enforce inside of the module refers to the module. Having the selective import overrides that.
>
> Okay. But what about that persisting error message:
>
> zz.d
> ---
> import core.stdc.stdio : fopen;
> import std.stdio : readln, writeln;
> import std.exception; // : enforce;
>
> void main ()
> {
>     auto f = enforce(fopen("data.txt", "r"));
>     auto line = readln(f);
>     enforce(line.length, "Expected a non-empty line.");
> }
> ---
>
> $ dmd zz
> zz.d(8): Error: template std.stdio.readln cannot deduce function
> from argument types !()(shared(_IO_FILE)*), candidates are:
> /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3921):
> std.stdio.readln(S = string)(dchar terminator = '\x0a') if
> (isSomeString!S)
> /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3955):
> std.stdio.readln(C)(ref C[] buf, dchar terminator = '\x0a') if
> (isSomeChar!C && is(Unqual!C == C) && !is(C == enum))
> /.../dmd2/linux/bin64/../../src/phobos/std/stdio.d(3962):
> std.stdio.readln(C, R)(ref C[] buf, R terminator) if
> (isSomeChar!C && is(Unqual!C == C) && !is(C == enum) &&
> isBidirectionalRange!R && is(typeof(terminator.front ==
> (dchar).init)))
>
> The example still does not compile.

That has nothing to do with enforce. std.stdio.readln does not take a FILE*. In general, you shouldn't mix core.stdc.stdio and std.stdio.

https://dlang.org/phobos/std_stdio.html#.readln

readln has 3 overloads, all of which read from stdin.

If you want to use readln on a file, then you need to use std.stdio.File and its member function, readln, not core.stdc.stdio.FILE.

- Jonathan M Davis

January 27, 2018
On Saturday, 27 January 2018 at 18:34:35 UTC, Jonathan M Davis wrote:
>> The example still does not compile.
>
> That has nothing to do with enforce. std.stdio.readln does not take a FILE*. In general, you shouldn't mix core.stdc.stdio and std.stdio.

The code is from the official documentation:

- https://dlang.org/phobos/std_exception.html#enforce, and
- https://dlang.org/library/std/exception/enforce.html

Shall I file a bug report?
January 27, 2018
On Saturday, January 27, 2018 20:11:29 kdevel via Digitalmars-d-learn wrote:
> On Saturday, 27 January 2018 at 18:34:35 UTC, Jonathan M Davis
>
> wrote:
> >> The example still does not compile.
> >
> > That has nothing to do with enforce. std.stdio.readln does not take a FILE*. In general, you shouldn't mix core.stdc.stdio and std.stdio.
>
> The code is from the official documentation:
>
> - https://dlang.org/phobos/std_exception.html#enforce, and - https://dlang.org/library/std/exception/enforce.html
>
> Shall I file a bug report?

Yes. Any time that code in the official docs doesn't compile, please report it. In most cases, the examples in the documentation are ddoc-ed unittest blocks, which catches such problems, but they aren't always.

- Jonathan M Davis

January 27, 2018
On Saturday, 27 January 2018 at 20:33:46 UTC, Jonathan M Davis wrote:
>> Shall I file a bug report?
>
> Yes.

https://issues.dlang.org/show_bug.cgi?id=18319

January 28, 2018
On Saturday, 27 January 2018 at 21:27:44 UTC, kdevel wrote:
> On Saturday, 27 January 2018 at 20:33:46 UTC, Jonathan M Davis wrote:
>>> Shall I file a bug report?
>>
>> Yes.
>
> https://issues.dlang.org/show_bug.cgi?id=18319

Thanks.
Addressed and already merged: https://github.com/dlang/phobos/pull/6080

https://dlang.org/phobos-prerelease/std_exception.html#enforce