makes DuplicateModuleImport back to an error (#25178)

fixes #24998

Basically it retraces back to the situation before
https://github.com/nim-lang/Nim/pull/18366 and
https://github.com/nim-lang/Nim/pull/18362, i.e.

```nim
import fuzz/a
import fuzz/a
```

```nim
import fuzz/a
from buzz/a
```

```nim
import fuzz/a except nil
from fuzz/a import addInt
```

All of these cases are now flagged as invalid and triggers a
redefinition error, i.e., each module name importing is treated as
consistent as the symbol definition

kinda annoying for importing/exporting with `when conditions` though

ref https://github.com/nim-lang/Nim/issues/18762
https://github.com/nim-lang/Nim/issues/20907

```nim
from std/strutils import toLower
when not defined(js):
  from std/strutils import toUpper
```

(cherry picked from commit 87ee9c84cb)
This commit is contained in:
ringabout
2025-09-19 02:50:46 +08:00
committed by narimiran
parent 79e9634369
commit ee2b480da6
8 changed files with 10 additions and 12 deletions

View File

@@ -25,6 +25,8 @@ errors.
- `std/parsesql` has been moved to a nimble package, use `nimble` or `atlas` to install it.
- With `-d:nimPreviewDuplicateModuleError`, importing two modules that share the same name becomes a compile-time error. This includes importing the same module more than once. Use `import foo as foo1` (or other aliases) to avoid collisions.
## Standard library additions and changes
[//]: # "Additions:"

View File

@@ -171,3 +171,5 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasJsNoLambdaLifting")
defineSymbol("nimHasDefaultFloatRoundtrip")
defineSymbol("nimHasXorSet")
defineSymbol("nimHasPreviewDuplicateModuleError")

View File

@@ -388,7 +388,7 @@ proc addDeclAt*(c: PContext; scope: PScope, sym: PSym, info: TLineInfo) =
if sym.name.id == ord(wUnderscore): return
let conflict = scope.addUniqueSym(sym)
if conflict != nil:
if sym.kind == skModule and conflict.kind == skModule:
if sym.kind == skModule and conflict.kind == skModule and not c.config.isDefined("nimPreviewDuplicateModuleError"):
# e.g.: import foo; import foo
# xxx we could refine this by issuing a different hint for the case
# where a duplicate import happens inside an include.

View File

@@ -12,6 +12,8 @@ define:nimPreviewNonVarDestructor
define:nimPreviewCheckedClose
define:nimPreviewAsmSemSymbol
define:nimPreviewCStringComparisons
define:nimPreviewDuplicateModuleError
threads:off
#import:"$projectpath/testability"

View File

@@ -35,7 +35,7 @@
import prefixmatches, suggestsymdb
from wordrecg import wDeprecated, wError, wAddr, wYield
import std/[algorithm, sets, parseutils, tables, os]
import std/[algorithm, sets, parseutils, os]
when defined(nimsuggest):
import pathutils # importer

View File

@@ -100,7 +100,7 @@ const
stylePrefix = "\e["
when defined(windows):
import std/[winlean, os]
import std/os
const
DUPLICATE_SAME_ACCESS = 2
@@ -926,8 +926,6 @@ when defined(windows):
stdout.write "\n"
else:
import std/termios
proc readPasswordFromStdin*(prompt: string, password: var string):
bool {.tags: [ReadIOEffect, WriteIOEffect].} =
password.setLen(0)
@@ -981,9 +979,6 @@ proc isTrueColorSupported*(): bool =
## Returns true if a terminal supports true color.
return getTerminal().trueColorIsSupported
when defined(windows):
import std/os
proc enableTrueColors*() =
## Enables true color.
var term = getTerminal()

View File

@@ -12,7 +12,6 @@
include osalloc
import std/private/syslocks
import std/sysatomics
template track(op, address, size) =
when defined(memTracker):

View File

@@ -8,9 +8,7 @@
#
# Compilerprocs for strings that do not depend on the string implementation.
import std/private/digitsutils
import std/private/digitsutils as digitsutils2
proc cmpStrings(a, b: string): int {.inline, compilerproc.} =
let alen = a.len