Refactor default methods (Trac #11105)
[ghc.git] / compiler / basicTypes / FieldLabel.hs
1 {-
2 %
3 % (c) Adam Gundry 2013-2015
4 %
5
6 This module defines the representation of FieldLabels as stored in
7 TyCons. As well as a selector name, these have some extra structure
8 to support the DuplicateRecordFields extension.
9
10 In the normal case (with NoDuplicateRecordFields), a datatype like
11
12 data T = MkT { foo :: Int }
13
14 has
15
16 FieldLabel { flLabel = "foo"
17 , flIsOverloaded = False
18 , flSelector = foo }.
19
20 In particular, the Name of the selector has the same string
21 representation as the label. If DuplicateRecordFields
22 is enabled, however, the same declaration instead gives
23
24 FieldLabel { flLabel = "foo"
25 , flIsOverloaded = True
26 , flSelector = $sel:foo:MkT }.
27
28 Now the name of the selector ($sel:foo:MkT) does not match the label of
29 the field (foo). We must be careful not to show the selector name to
30 the user! The point of mangling the selector name is to allow a
31 module to define the same field label in different datatypes:
32
33 data T = MkT { foo :: Int }
34 data U = MkU { foo :: Bool }
35
36 Now there will be two FieldLabel values for 'foo', one in T and one in
37 U. They share the same label (FieldLabelString), but the selector
38 functions differ.
39
40 See also Note [Representing fields in AvailInfo] in Avail.
41
42 Note [Why selector names include data constructors]
43 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44
45 As explained above, a selector name includes the name of the first
46 data constructor in the type, so that the same label can appear
47 multiple times in the same module. (This is irrespective of whether
48 the first constructor has that field, for simplicity.)
49
50 We use a data constructor name, rather than the type constructor name,
51 because data family instances do not have a representation type
52 constructor name generated until relatively late in the typechecking
53 process.
54
55 Of course, datatypes with no constructors cannot have any fields.
56
57 -}
58
59 {-# LANGUAGE CPP #-}
60 {-# LANGUAGE DeriveDataTypeable #-}
61 {-# LANGUAGE DeriveFunctor #-}
62 {-# LANGUAGE DeriveFoldable #-}
63 {-# LANGUAGE DeriveTraversable #-}
64 {-# LANGUAGE StandaloneDeriving #-}
65
66 module FieldLabel ( FieldLabelString
67 , FieldLabelEnv
68 , FieldLbl(..)
69 , FieldLabel
70 , mkFieldLabelOccs
71 ) where
72
73 import OccName
74 import Name
75
76 import FastString
77 import Outputable
78 import Binary
79
80 import Data.Data
81
82 #if __GLASGOW_HASKELL__ < 709
83 import Data.Foldable ( Foldable )
84 import Data.Traversable ( Traversable )
85 #endif
86
87 -- | Field labels are just represented as strings;
88 -- they are not necessarily unique (even within a module)
89 type FieldLabelString = FastString
90
91 -- | A map from labels to all the auxiliary information
92 type FieldLabelEnv = FastStringEnv FieldLabel
93
94
95 type FieldLabel = FieldLbl Name
96
97 -- | Fields in an algebraic record type
98 data FieldLbl a = FieldLabel {
99 flLabel :: FieldLabelString, -- ^ User-visible label of the field
100 flIsOverloaded :: Bool, -- ^ Was DuplicateRecordFields on
101 -- in the defining module for this datatype?
102 flSelector :: a -- ^ Record selector function
103 }
104 deriving (Eq, Functor, Foldable, Traversable, Typeable)
105 deriving instance Data a => Data (FieldLbl a)
106
107 instance Outputable a => Outputable (FieldLbl a) where
108 ppr fl = ppr (flLabel fl) <> braces (ppr (flSelector fl))
109
110 instance Binary a => Binary (FieldLbl a) where
111 put_ bh (FieldLabel aa ab ac) = do
112 put_ bh aa
113 put_ bh ab
114 put_ bh ac
115 get bh = do
116 ab <- get bh
117 ac <- get bh
118 ad <- get bh
119 return (FieldLabel ab ac ad)
120
121
122 -- | Record selector OccNames are built from the underlying field name
123 -- and the name of the first data constructor of the type, to support
124 -- duplicate record field names.
125 -- See Note [Why selector names include data constructors].
126 mkFieldLabelOccs :: FieldLabelString -> OccName -> Bool -> FieldLbl OccName
127 mkFieldLabelOccs lbl dc is_overloaded
128 = FieldLabel lbl is_overloaded sel_occ
129 where
130 str = ":" ++ unpackFS lbl ++ ":" ++ occNameString dc
131 sel_occ | is_overloaded = mkRecFldSelOcc str
132 | otherwise = mkVarOccFS lbl