Bug 4563 – [module system] Error messages for missing package or missing name

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2010-08-01T15:10:25Z
Last change time
2018-05-18T07:38:44Z
Keywords
diagnostic
Assigned to
No Owner
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-08-01T15:10:25Z
This is a wrong D2 program ("bitmanips" name doesn't exist): import std.bitmanips: bitfields; void main() {} This is the error message given by dmd 2.047: test.d(1): Error: module bitmanips is in file 'std\bitmanips.d' which cannot be read But a better error message can be: test.d(1): Error: module 'bitmanips' not found in package 'std'. --------------------- This is another wrong D2 program (the 'bitfield' name is missing inside std.bimanip): import std.bitmanip: bitfield; void main() {} This is the error message given by dmd 2.047: test.d(1): Error: import bitfield not found test.d(1): Error: alias test.bitfield recursive alias declaration But the second error message can be omitted, it's useless and quite confusing. So DMD can print just: test.d(1): Error: import name 'bitfield' not found inside 'std.bitmanip' module. See also bug 3845
Comment #1 by andrej.mitrovich — 2010-08-01T15:43:08Z
Agreed. There's an example in the docs (which I've filed a bug report for) that imports std.hiddenfunc which doesn't exist anymore. "File cannot be read" is pretty ambiguous in it's meaning.
Comment #2 by bearophile_hugs — 2011-08-10T14:05:55Z
Giving code to a D newbie such person didn't know what this error message means: foo.d(3): Error: module ascii is in file 'std/ascii.d' which cannot be read import path[0] = /usr/include/d import path[1] = /usr/include/d/druntime/import The problem was simple, he has used dmd 2.053 instead of the successive one, so std.ascii was not present yet. This error message is not clear enough. In a similar situation Python2 gives: ImportError: No module named foo I suggest an error message like: foo.d(3): Error: module "std.ascii" not found (file 'std/ascii.d').
Comment #3 by bearophile_hugs — 2011-11-25T16:36:00Z
Now the situation is worse (DMD 2.057head): import std.math: foo; void main() {} Gives: test.d(1): Error: import __anonymous foo not found test.d(1): Error: alias test.foo recursive alias declaration
Comment #4 by bearophile_hugs — 2012-01-04T03:11:27Z
The situation is not improved. Wrong D2 code: import core.stdc.stdlib: puts; import std.stdio: reverse; void main() { puts("hello"); int[] a = [1, 2, 3]; reverse(a); } After the recent changes in import semantics DMD 2.058head gives: test.d(4): Error: undefined identifier puts test.d(6): Error: undefined identifier reverse But instead of such errors at the usage point I suggest to give import errors, something like: test.d(1): Error: name 'puts' not present in 'core.stdc.stdlib' module. test.d(2): Error: name 'reverse' not present in 'std.stdio' module.
Comment #5 by leandro.lucarella — 2012-01-10T04:40:42Z
*** Issue 7253 has been marked as a duplicate of this issue. ***
Comment #6 by andrej.mitrovich — 2012-10-23T18:53:44Z
(In reply to comment #0) > import std.bitmanips; > void main() {} > > test.d(1): Error: module bitmanips is in file 'std\bitmanips.d' which cannot be read This is the only test-case left to fix in this Issue (the others seem to be fixed).
Comment #7 by bearophile_hugs — 2012-10-24T05:09:04Z
(In reply to comment #6) > This is the only test-case left to fix in this Issue (the others seem to be > fixed). This is the current situation: ---------------- // Case#1 import std.bitmanips: bitfields; void main() {} test.d(1): Error: module bitmanips is in file 'std\bitmanips.d' which cannot be read import path[0] = C:\dmd2\src\phobos\ import path[1] = C:\dmd2\src\druntime\import\ import path[2] = C:\leonardo\d_bugs\ import path[3] = C:\dmd2\windows\bin\..\..\src\phobos import path[4] = C:\dmd2\windows\bin\..\..\src\druntime\import ---------------- // Case#2 import std.bitmanip: bitfield; void main() {} test.d(1): Error: module std.bitmanip import 'bitfield' not found, did you mean 'template bitfields(T...)'? ---------------- // Case#3 import std.math: foo; void main() {} test.d(1): Error: module std.math import 'foo' not found, did you mean 'function fma'? ---------------- The Case#1 probably needs a better error message. The messages in cases #2 and #3 seem acceptable, it's not bad. But they sub-optimal, in Case#3 this seems better: test.d(1): Error: name 'foo' not found in module std.math, did you mean function 'fma'?
Comment #8 by andrej.mitrovich — 2012-10-24T06:48:43Z
(In reply to comment #7) > test.d(1): Error: module bitmanips is in file 'std\bitmanips.d' which cannot be > read > The Case#1 probably needs a better error message. Yes, it can be: test.d(1): Error: module bitmanips not found in package 'std' However what if the module is not in any package? Example: import bitmanips; void main() { } => test.d(1): Error: module bitmanips is in file 'bitmanips.d' which cannot be read What should we do here? > test.d(1): Error: name 'foo' not found in module std.math, did you mean > function 'fma'? I would replace 'name' with 'symbol' here.
Comment #9 by bearophile_hugs — 2012-10-24T10:13:27Z
(In reply to comment #8) > However what if the module is not in any package? Example: > > import bitmanips; void main() { } > > => test.d(1): Error: module bitmanips is in file 'bitmanips.d' which cannot be > read > > What should we do here? Instead of writing: test.d(1): Error: module bitmanips cannot be found in package 'std'. It omits the last part of the message: test.d(1): Error: module bitmanips cannot be found. (Unrelated: do you know why D error messages don't have an ending full stop "." as in correct English?)
Comment #10 by andrej.mitrovich — 2012-10-24T10:21:54Z
(In reply to comment #9) > test.d(1): Error: module bitmanips cannot be found. Ok, I'll implement a pull and see what others think about it. > (Unrelated: do you know why D error messages don't have an ending full stop "." > as in correct English?) GCC and DMC don't add a period either. I think it's purely accidental, some tools do, others don't (and sometimes it's mixed). I don't mind such issues though. Personally I worry much more about things like this: void main() { void function(int x, int y, float z) funcC; void function(int x, float y, int z) funcD; funcC = funcD; } Error: cannot implicitly convert expression (funcD) of type void function(int x, float y, int z) to void function(int x, int y, float z) It would make it much easier to debug such cases if the error spanned multiple lines and aligned the types, for example: Error: cannot implicitly convert expression (funcD) of type void function(int x, float y, int z) to void function(int x, int y, float z)
Comment #11 by bearophile_hugs — 2012-10-24T11:10:27Z
(In reply to comment #10) > Ok, I'll implement a pull and see what others think about it. Thank you. > It would make it much easier to debug such cases if the error spanned multiple > lines and aligned the types, for example: > > Error: cannot implicitly convert expression (funcD) of type > void function(int x, float y, int z) to > void function(int x, int y, float z) Better: Error: cannot implicitly convert expression (funcD) of type: void function(int x, float y, int z) to type: void function(int x, int y, float z)
Comment #12 by bearophile_hugs — 2012-10-24T11:17:33Z
(In reply to comment #10) > > test.d(1): Error: module bitmanips cannot be found. > > Ok, I'll implement a pull and see what others think about it. Or: test.d(1): Error: module 'bitmanips' cannot be found.
Comment #13 by andrej.mitrovich — 2012-10-24T11:19:11Z
(In reply to comment #11) > (In reply to comment #10) > > > Ok, I'll implement a pull and see what others think about it. > > Thank you. I think we can do even better: import foo.bar.doo; Now it's test.d(3): Error: module doo is in file 'foo\bar\doo.d' which cannot be read If 'foo' doesn't exist the error should probably be: test.d(3): Error: package 'foo' not found If 'bar' doesn't exist it should be: test.d(3): Error: package 'bar' not found in package 'foo' If 'doo' doesn't exist: test.d(3): Error: module 'doo' not found in package 'foo.bar' Also, we might consider doing informative spellchecker errors, e.g.: import std.stddio; test.d(3): Error: module 'stddio' not found in package 'std', did you mean 'stdio'? The above should probably try finding D modules that are similar to 'stddio', read their module declaration (because it might be different from the filename), and if the module declaration is similar to 'stddio' it should print that module name as a recommendation. import stdd.stdio; test.d(3): Error: package 'stdd' not found, did you mean 'std'? Here we might try finding non-empty folders with .d or .di files named similarly to 'stdd' and recommend such a folder. I don't know how hard this will be but I think it's worth pursuing.
Comment #14 by dmitry.olsh — 2018-05-18T07:38:26Z
▶ dmd -O saa.d saa.d(1): Error: module `bitmanips` is in file 'std/bitmanips.d' which cannot be read import path[0] = /home/olshanskiy/dmd2/linux/bin64/../../src/phobos import path[1] = /home/olshanskiy/dmd2/linux/bin64/../../src/druntime/import --- ▶ dmd -O saa.d saa.d(1): Error: module `std.bitmanip` import bitfield not found, did you mean template std.bitmanip.bitfields(T...)? Both of which are pretty good and cover the request here rather well (esp. the 2nd one)