Opened 4 years ago

Last modified 7 months ago

#4980 new feature request

Warning about module abbreviation clashes

Reported by: Lemming Owned by:
Priority: low Milestone: 7.12.1
Component: Compiler Version: 7.0.1
Keywords: Cc: ghc@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

Please add the option -fwarn-module-rename-collision that makes GHC to do the following: If GHC encounters an import situation like

module Main where

import qualified Data.A as A
import qualified Control.A as A

then GHC should emit a warning like

Main.hs:3:0:
Main.hs:4:0:
    Warning: Both Data.A and Control.A are renamed to A.
             An identifier like A.ident can only be resolved,
             if it is either in Data.A or Control.A.
             Better rename both modules to different names.

Reason for this warning is, that if 'ident' is from Data.A as of writing Main, and later another variable named 'ident' is added to Control.A, then A.ident can no longer be resolved in Main. That is, by accidental module rename collisions even qualified imports carry the risk of future name collisions.

Related to #4977

Change History (9)

comment:1 follow-up: Changed 4 years ago by simonpj

Hmm. It's sometimes very useful to do just that!

And indeed sometimes the two really do export ident, but in both cases it's the same ident, so it's fine.

I'm a bit skeptical myself, but let's see if others like it.

Simon

comment:2 in reply to: ↑ 1 Changed 4 years ago by Lemming

Replying to simonpj:

Hmm. It's sometimes very useful to do just that!

Because of that, I do not propose this option to be part of -Wall. But the way I import modules it is almost sure, that renaming a module to the same abbrevation was an accident (e.g. when merging two import lists).

And indeed sometimes the two really do export ident, but in both cases it's the same ident, so it's fine.

But it would also be no problem to use two different renamings, say

import qualified Data.A as DA
import qualified Control.A as CA

and then being able to refer to ident by both DA.ident and CA.ident, right? I mean, why do two modules export the same identifier? E.g. because one module is meant as central module like Foreign that exports identifiers of sub-modules like Foreign.Ptr. In this case I would decide for one style, either importing all identifiers from the central module Foreign or importing all of them from the specific sub-modules like Foreign.Ptr, Foreign.Storable etc. Another reason might be that a module was split and the identifiers are exported from the unsplit module for compatibility reasons. In this case programmers are encouraged to use the split modules exclusively.

comment:3 Changed 4 years ago by igloo

  • Milestone set to 7.4.1

comment:4 follow-up: Changed 4 years ago by malcolm.wallace@…

I can see no case in which a shared module abbreviation could ever lead to a program doing the wrong thing. If there is a genuine ambiguity about the referent of an identifier, it will already be reported as an error. This warning request seems to be about avoiding future compile errors in this module, due to changes in other modules. But if you are refactoring code in other modules, you should always at least expect the possibility of consequent breakage in the modules that import them - that is part of the joy of static checking. It seems just as likely to me that the future refactoring could *erroneously* introduce a clashing identifier, as that the clashing identifier would be deliberate.

comment:5 in reply to: ↑ 4 Changed 4 years ago by Lemming

Replying to malcolm.wallace@…:

This warning request seems to be about avoiding future compile errors in this module, due to changes in other modules.

Right, this warning is intended to avoid compilation errors if something in the imported modules is added. This is especially important if the imported modules are from another package. If I want to import a PVP compliant package X with

Build-Depends: X >= A.B.C && < A.(B+1)

then I have to make sure that additions to the APIs of the imported modules do not lead to compilation errors.

The goal is the same as in #4977.
Btw. Modula forbids clashing module abbreviations and only allows unqualified import with explicit enumeration and qualified import (as in #4977) in order to protect against compilation failure if something is added to imported modules.

comment:6 Changed 3 years ago by igloo

  • Milestone changed from 7.4.1 to 7.6.1
  • Priority changed from normal to low

comment:7 Changed 3 years ago by igloo

  • Milestone changed from 7.6.1 to 7.6.2

comment:8 Changed 12 months ago by thoughtpolice

  • Milestone changed from 7.6.2 to 7.10.1

Moving to 7.10.1.

comment:9 Changed 7 months ago by thoughtpolice

  • Milestone changed from 7.10.1 to 7.12.1

Moving to 7.12.1 milestone; if you feel this is an error and should be addressed sooner, please move it back to the 7.10.1 milestone.

Note: See TracTickets for help on using tickets.