Skip to content

WIP: Add '-Wpuns' warning

Artyom Kuznetsov requested to merge hithroc/ghc:hithroc/wpuns into master

This change introduces a new warning '-Wpuns' which fires whenever punnend names are used. Punning is the use of names that occur both in the type namespace and the data namespace. For example:

data T = T

f = T

Because of punning this code is valid and the renamer knows that the 'T' in 'f' refers to the term-level T. This is often confusing, especially when DataKinds is used throughout the code.

This warning is intended to warn the user about the usage of punning as if GHC had a single unified namespace (no separation between terms and types).

This is achieved by adding a new unified OccEnv to the local renamer environment. Whenever a new variable is bound, it is added to the unified OccEnv. Whenever the renamer needs to lookup an RdrName, in addition to looking in the regular OccEnv it also looks up in the unified OccEnv regardless of the RdrName's namespace. If the results of the lookup are different, the warning is triggered. Global lookups have a different logic, whenever we look up a global name, the renamer also looks for the same name with a "flipped" namespace (variables <-> type variables, data constructors <-> type constructors). If a name in the opposite namespace is found, the warning is triggered.

There's also a special case with implicit type variable bindings:

Consider the following code:

a = 15
f :: forall a. a -> a -- not punning

f' :: a -> a -- punning

However, if there's no top level 'a' bound 'f' :: a -> a' is no longer punning.

This case solved by not adding the implicitly bound type variable to the unified OccEnv if there's a variable with the same name bound at the top level.

Edited by Ben Gamari

Merge request reports