Commit 693a54ea authored by skvadrik's avatar skvadrik Committed by Ben Gamari

Improved error message about exported type operators.

There is ambiguty between (1) type constructors and (2) data
constructors in export lists, e.g. '%%' can stand for both of them. This
ambiguity is resolved in favor of (2).

If the exported data constructor is not in scope, but type constructor
with the same name is in scope, GHC should suggest adding 'type' keyword
to resolve ambiguity in favor of (1) and enabling 'TypeOperators'
extension.

The patch only extends the error message.

See Trac #11432.

Test Plan: `make test`

Reviewers: simonpj, bgamari, austin

Reviewed By: simonpj

Subscribers: mpickering, thomie, goldfire, kosmikus

Differential Revision: https://phabricator.haskell.org/D1902

GHC Trac Issues: #11432
parent 525a304f
......@@ -13,7 +13,7 @@ module RnEnv (
lookupLocalOccRn_maybe, lookupInfoOccRn,
lookupLocalOccThLvl_maybe,
lookupTypeOccRn, lookupKindOccRn,
lookupGlobalOccRn, lookupGlobalOccRn_maybe,
lookupGlobalOccRn, lookupGlobalOccRnExport, lookupGlobalOccRn_maybe,
lookupOccRn_overloaded, lookupGlobalOccRn_overloaded,
reportUnboundName, unknownNameSuggestions,
addNameClashErrRn,
......@@ -853,6 +853,27 @@ lookupGlobalOccRn rdr_name
Nothing -> do { traceRn (text "lookupGlobalOccRn" <+> ppr rdr_name)
; unboundName WL_Global rdr_name } }
-- like lookupGlobalOccRn but suggests adding 'type' keyword
-- to export type constructors mistaken for data constructors
lookupGlobalOccRnExport :: RdrName -> RnM Name
lookupGlobalOccRnExport rdr_name
= do { mb_name <- lookupGlobalOccRn_maybe rdr_name
; case mb_name of
Just n -> return n
Nothing -> do { env <- getGlobalRdrEnv
; let tycon = setOccNameSpace tcClsName (rdrNameOcc rdr_name)
msg = case lookupOccEnv env tycon of
Just (gre : _) -> make_msg gre
_ -> Outputable.empty
make_msg gre = hang
(hsep [text "Note: use",
quotes (text "type"),
text "keyword to export type constructor",
quotes (ppr (gre_name gre))])
2 (vcat [pprNameProvenance gre,
text "(requires TypeOperators extension)"])
; unboundNameX WL_Global rdr_name msg } }
lookupInfoOccRn :: RdrName -> RnM [Name]
-- lookupInfoOccRn is intended for use in GHCi's ":info" command
-- It finds all the GREs that RdrName could mean, not complaining
......
......@@ -1346,7 +1346,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
lookup_ie_with :: IE RdrName -> Located RdrName -> [Located RdrName]
-> RnM (Located Name, [Located Name], [Name], [FieldLabel])
lookup_ie_with ie (L l rdr) sub_rdrs
= do name <- lookupGlobalOccRn rdr
= do name <- lookupGlobalOccRnExport rdr
let gres = findChildren kids_env name
mchildren =
lookupChildren (map classifyGRE (gres ++ pat_syns)) sub_rdrs
......@@ -1366,7 +1366,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
lookup_ie_all :: IE RdrName -> Located RdrName
-> RnM (Located Name, [Name], [FieldLabel])
lookup_ie_all ie (L l rdr) =
do name <- lookupGlobalOccRn rdr
do name <- lookupGlobalOccRnExport rdr
let gres = findChildren kids_env name
(non_flds, flds) = classifyGREs gres
addUsedKids rdr gres
......
{-
We expect to get a suggestion to add 'type' keyword
and enable TypeOperators extension.
-}
{-# LANGUAGE TypeOperators #-}
module T11432 ((-.->)(..)) where
newtype (f -.-> g) a = Fn { apFn :: f a -> g a }
T11432.hs:7:16:
Not in scope: ‘-.->’
Note: use ‘type’ keyword to export type constructor ‘-.->’
defined at T11432.hs:9:1
(requires TypeOperators extension)
T11432.hs:7:16:
The export item ‘(-.->)(..)’
attempts to export constructors or class methods that are not visible here
......@@ -347,3 +347,4 @@ test('T9061', normal, compile, [''])
test('T9997', normal, compile, [''])
test('T10233', extra_clean(['T01233a.hi', 'T01233a.o']),
multimod_compile, ['T10233', '-v0'])
test('T11432', normal, compile_fail, [''])
mod89.hs:5:1: warning:
The import item ‘map(..)’ suggests that
‘map’ has (in-scope) constructors or class methods,
but it has none
mod89.hs:5:1: warning:
The import of ‘Prelude’ is redundant
except perhaps to import instances from ‘Prelude’
To import instances alone, use: import Prelude()
mod89.hs:5:1: warning:
The import item ‘map(..)’ suggests that
‘map’ has (in-scope) constructors or class methods,
but it has none
mod89.hs:5:1: warning:
The import of ‘Prelude’ is redundant
except perhaps to import instances from ‘Prelude’
To import instances alone, use: import Prelude()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment