nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.55k stars 1.47k forks source link

import os + use of existsDir/dirExists/existsFile/fileExists/findExe in config.nims causes "ambiguous call' error #14142

Closed kaushalmodi closed 4 years ago

kaushalmodi commented 4 years ago

In config.nims, when the os module is imported and one of these procs are used:

we get the "ambiguous call" error (because these are defined in both system and os.

Example config.nims

  1. Create this config.nims in any directory
  2. Run nim temp123
# config.nims
import os # commenting this out fixes the error
# import os except existsDir, dirExists, existsFile, fileExists, findExe # this also does not give that error

task temp123, "Temp task":
  echo existsDir("/usr")
  echo dirExists("/usr")
  echo existsFile("/usr/foo")
  echo fileExists("/usr/foo")
  echo findExe("nim")

Current Output

/home/kmodi/sandbox/nim/bug_reports/nimscript_import_os/config.nims(4, 6) template/generic instantiation of `task` from here
/home/kmodi/sandbox/nim/bug_reports/nimscript_import_os/config.nims(5, 17) Error: ambiguous call; both system.existsDir(dir: string) [declared in /home/kmodi/usr_local/apps/6/nim/devel/lib/system/nimscript.nim(135, 6)] and os.existsDir(dir: string) [declared in /home/kmodi/usr_local/apps/6/nim/devel/lib/pure/os.nim(1109, 6)] match for: (string)

Expected Output

Outputs of the echo statements in the above example.

Workaround

Additional Information

This issue is very closely related to https://github.com/nim-lang/Nim/issues/12835 .

$ nim -v
Nim Compiler Version 1.3.1 [Linux: amd64]
Compiled at 2020-04-27
Copyright (c) 2006-2020 by Andreas Rumpf

git hash: 2f1aad02642576d13df018c9e5869c8de7e3a539
active boot switches: -d:release

This used to work at some point (probably around Nim 19.x).

timotheecour commented 4 years ago

reduced example: nim e foo.nim

# foo.nim
import os
echo dirExists("/tmp")

This used to work at some point (probably around Nim 19.x).

when ? 1.0.0 gives same error and 0.19.0 gives Error: cannot 'importc' variable at compile time

however, this is annoying so I'm (hopefully) fixing it here: https://github.com/nim-lang/Nim/pull/14143

metagn commented 4 years ago

Also getEnv, existsEnv, putEnv, delEnv, getCurrentDir. The following procs are also the same idea in os and nimscript but are renamed: removeDir -> rmDir, removeFile -> rmFile, moveDir -> mvDir, moveFile -> mvFile, createDir -> mkDir, copyFile -> cpFile, copyDir -> cpDir.

Araq commented 4 years ago

They are renamed for a reason!

metagn commented 4 years ago

Yes, I advocate for that. I don't think any procs should be deleted from nimscript, I just think they should be moved to os then import/exported. That will allow the renamed procs to be imported with an alias like from os import removeDir as rmDir, then export rmDir. This makes maintaining nimscript procs easier, you can find their declarations in the same place their compiled Nim versions are declared. Of course they aren't implemented there, but that's easy to clarify with a doc comment or a code comment in the when defined(nimscript) branch.

Araq commented 4 years ago

The rmDir set of operatings could be in a new module std / scripting but shouldn't be part of os.nim, their design is based on the idea that you can have a "what if" emulation run that doesn't touch your FS.

kaushalmodi commented 4 years ago

@Araq Would a fix similar to https://github.com/nim-lang/Nim/commit/3d2459bdc0b6d6236a2cd9209ed81c965ee411a5 fix this too?

Araq commented 4 years ago

I think my fix mostly works. :-)