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