Split up RnEnv into 4 modules, RnUnbound, RnUtils and RnFixity
[ghc.git] / compiler / rename / RnFixity.hs
1 {-
2
3 This module contains code which maintains and manipulates the
4 fixity environment during renaming.
5
6 -}
7 module RnFixity ( MiniFixityEnv,
8 addLocalFixities,
9 lookupFixityRn, lookupFixityRn_help,
10 lookupFieldFixityRn, lookupTyFixityRn ) where
11
12 import LoadIface
13 import HsSyn
14 import RdrName
15 import HscTypes
16 import TcRnMonad
17 import Name
18 import NameEnv
19 import Module
20 import BasicTypes ( Fixity(..), FixityDirection(..), minPrecedence,
21 defaultFixity, SourceText(..) )
22 import SrcLoc
23 import Outputable
24 import Maybes
25 import Data.List
26 import Data.Function ( on )
27 import RnUnbound
28
29 {-
30 *********************************************************
31 * *
32 Fixities
33 * *
34 *********************************************************
35
36 Note [Fixity signature lookup]
37 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38 A fixity declaration like
39
40 infixr 2 ?
41
42 can refer to a value-level operator, e.g.:
43
44 (?) :: String -> String -> String
45
46 or a type-level operator, like:
47
48 data (?) a b = A a | B b
49
50 so we extend the lookup of the reader name '?' to the TcClsName namespace, as
51 well as the original namespace.
52
53 The extended lookup is also used in other places, like resolution of
54 deprecation declarations, and lookup of names in GHCi.
55 -}
56
57 --------------------------------
58 type MiniFixityEnv = FastStringEnv (Located Fixity)
59 -- Mini fixity env for the names we're about
60 -- to bind, in a single binding group
61 --
62 -- It is keyed by the *FastString*, not the *OccName*, because
63 -- the single fixity decl infix 3 T
64 -- affects both the data constructor T and the type constrctor T
65 --
66 -- We keep the location so that if we find
67 -- a duplicate, we can report it sensibly
68
69 --------------------------------
70 -- Used for nested fixity decls to bind names along with their fixities.
71 -- the fixities are given as a UFM from an OccName's FastString to a fixity decl
72
73 addLocalFixities :: MiniFixityEnv -> [Name] -> RnM a -> RnM a
74 addLocalFixities mini_fix_env names thing_inside
75 = extendFixityEnv (mapMaybe find_fixity names) thing_inside
76 where
77 find_fixity name
78 = case lookupFsEnv mini_fix_env (occNameFS occ) of
79 Just (L _ fix) -> Just (name, FixItem occ fix)
80 Nothing -> Nothing
81 where
82 occ = nameOccName name
83
84 {-
85 --------------------------------
86 lookupFixity is a bit strange.
87
88 * Nested local fixity decls are put in the local fixity env, which we
89 find with getFixtyEnv
90
91 * Imported fixities are found in the PIT
92
93 * Top-level fixity decls in this module may be for Names that are
94 either Global (constructors, class operations)
95 or Local/Exported (everything else)
96 (See notes with RnNames.getLocalDeclBinders for why we have this split.)
97 We put them all in the local fixity environment
98 -}
99
100 lookupFixityRn :: Name -> RnM Fixity
101 lookupFixityRn name = lookupFixityRn' name (nameOccName name)
102
103 lookupFixityRn' :: Name -> OccName -> RnM Fixity
104 lookupFixityRn' name = fmap snd . lookupFixityRn_help' name
105
106 -- | 'lookupFixityRn_help' returns @(True, fixity)@ if it finds a 'Fixity'
107 -- in a local environment or from an interface file. Otherwise, it returns
108 -- @(False, fixity)@ (e.g., for unbound 'Name's or 'Name's without
109 -- user-supplied fixity declarations).
110 lookupFixityRn_help :: Name
111 -> RnM (Bool, Fixity)
112 lookupFixityRn_help name =
113 lookupFixityRn_help' name (nameOccName name)
114
115 lookupFixityRn_help' :: Name
116 -> OccName
117 -> RnM (Bool, Fixity)
118 lookupFixityRn_help' name occ
119 | isUnboundName name
120 = return (False, Fixity NoSourceText minPrecedence InfixL)
121 -- Minimise errors from ubound names; eg
122 -- a>0 `foo` b>0
123 -- where 'foo' is not in scope, should not give an error (Trac #7937)
124
125 | otherwise
126 = do { local_fix_env <- getFixityEnv
127 ; case lookupNameEnv local_fix_env name of {
128 Just (FixItem _ fix) -> return (True, fix) ;
129 Nothing ->
130
131 do { this_mod <- getModule
132 ; if nameIsLocalOrFrom this_mod name
133 -- Local (and interactive) names are all in the
134 -- fixity env, and don't have entries in the HPT
135 then return (False, defaultFixity)
136 else lookup_imported } } }
137 where
138 lookup_imported
139 -- For imported names, we have to get their fixities by doing a
140 -- loadInterfaceForName, and consulting the Ifaces that comes back
141 -- from that, because the interface file for the Name might not
142 -- have been loaded yet. Why not? Suppose you import module A,
143 -- which exports a function 'f', thus;
144 -- module CurrentModule where
145 -- import A( f )
146 -- module A( f ) where
147 -- import B( f )
148 -- Then B isn't loaded right away (after all, it's possible that
149 -- nothing from B will be used). When we come across a use of
150 -- 'f', we need to know its fixity, and it's then, and only
151 -- then, that we load B.hi. That is what's happening here.
152 --
153 -- loadInterfaceForName will find B.hi even if B is a hidden module,
154 -- and that's what we want.
155 = do { iface <- loadInterfaceForName doc name
156 ; let mb_fix = mi_fix_fn iface occ
157 ; let msg = case mb_fix of
158 Nothing ->
159 text "looking up name" <+> ppr name
160 <+> text "in iface, but found no fixity for it."
161 <+> text "Using default fixity instead."
162 Just f ->
163 text "looking up name in iface and found:"
164 <+> vcat [ppr name, ppr f]
165 ; traceRn "lookupFixityRn_either:" msg
166 ; return (maybe (False, defaultFixity) (\f -> (True, f)) mb_fix) }
167
168 doc = text "Checking fixity for" <+> ppr name
169
170 ---------------
171 lookupTyFixityRn :: Located Name -> RnM Fixity
172 lookupTyFixityRn (L _ n) = lookupFixityRn n
173
174 -- | Look up the fixity of a (possibly ambiguous) occurrence of a record field
175 -- selector. We use 'lookupFixityRn'' so that we can specifiy the 'OccName' as
176 -- the field label, which might be different to the 'OccName' of the selector
177 -- 'Name' if @DuplicateRecordFields@ is in use (Trac #1173). If there are
178 -- multiple possible selectors with different fixities, generate an error.
179 lookupFieldFixityRn :: AmbiguousFieldOcc Name -> RnM Fixity
180 lookupFieldFixityRn (Unambiguous (L _ rdr) n)
181 = lookupFixityRn' n (rdrNameOcc rdr)
182 lookupFieldFixityRn (Ambiguous (L _ rdr) _) = get_ambiguous_fixity rdr
183 where
184 get_ambiguous_fixity :: RdrName -> RnM Fixity
185 get_ambiguous_fixity rdr_name = do
186 traceRn "get_ambiguous_fixity" (ppr rdr_name)
187 rdr_env <- getGlobalRdrEnv
188 let elts = lookupGRE_RdrName rdr_name rdr_env
189
190 fixities <- groupBy ((==) `on` snd) . zip elts
191 <$> mapM lookup_gre_fixity elts
192
193 case fixities of
194 -- There should always be at least one fixity.
195 -- Something's very wrong if there are no fixity candidates, so panic
196 [] -> panic "get_ambiguous_fixity: no candidates for a given RdrName"
197 [ (_, fix):_ ] -> return fix
198 ambigs -> addErr (ambiguous_fixity_err rdr_name ambigs)
199 >> return (Fixity NoSourceText minPrecedence InfixL)
200
201 lookup_gre_fixity gre = lookupFixityRn' (gre_name gre) (greOccName gre)
202
203 ambiguous_fixity_err rn ambigs
204 = vcat [ text "Ambiguous fixity for record field" <+> quotes (ppr rn)
205 , hang (text "Conflicts: ") 2 . vcat .
206 map format_ambig $ concat ambigs ]
207
208 format_ambig (elt, fix) = hang (ppr fix)
209 2 (pprNameProvenance elt)