Skip to content

Commit 0c4e92c

Browse files
committed
Disambiguate method in instance based on class name.
1 parent 7004ca7 commit 0c4e92c

File tree

5 files changed

+93
-70
lines changed

5 files changed

+93
-70
lines changed

src/Language/Haskell/Names/Annotated.hs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import Language.Haskell.Names.Open.Base
1717
import Language.Haskell.Names.Open.Instances ()
1818
import qualified Language.Haskell.Names.GlobalSymbolTable as Global
1919
import qualified Language.Haskell.Names.LocalSymbolTable as Local
20-
import Language.Haskell.Names.SyntaxUtils (dropAnn, setAnn)
20+
import Language.Haskell.Names.SyntaxUtils (
21+
dropAnn, setAnn, nameQualification, qNameToName)
2122
import Language.Haskell.Exts
2223
import Data.Proxy
2324
import Data.Lens.Light
@@ -89,7 +90,8 @@ lookupQName qname scope = Scoped nameInfo (ann qname) where
8990
ReferenceUT ->
9091
checkUniqueness (Global.lookupMethodOrAssociate qname' globalTable) where
9192
qname' = case qname of
92-
UnQual _ name -> qualifyName (getL instQual scope) name
93+
UnQual _ name -> qualifyName maybeQualification name where
94+
maybeQualification = maybe Nothing nameQualification (getL instClassName scope)
9395
_ -> qname
9496

9597
ReferenceRS ->
@@ -132,8 +134,10 @@ lookupName name scope = Scoped nameInfo (ann name) where
132134
Nothing -> case getL nameCtx scope of
133135

134136
ReferenceUV ->
135-
checkUniqueness qname (Global.lookupMethodOrAssociate qname globalTable) where
136-
qname = qualifyName (getL instQual scope) name
137+
disambiguateMethod maybeClassName qname (Global.lookupMethodOrAssociate qname globalTable) where
138+
qname = qualifyName maybeQualification name
139+
maybeQualification = maybe Nothing nameQualification maybeClassName
140+
maybeClassName = getL instClassName scope
137141

138142
SignatureV ->
139143
checkUniqueness qname (Global.lookupValue qname globalTable) where
@@ -163,11 +167,19 @@ lookupName name scope = Scoped nameInfo (ann name) where
163167

164168
globalTable = getL gTable scope
165169

166-
checkUniqueness qname symbols = case symbols of
167-
[] -> ScopeError (ENotInScope qname)
168-
[symbol] -> GlobalSymbol symbol (dropAnn qname)
169-
_ -> ScopeError (EAmbiguous qname symbols)
170170

171+
checkUniqueness :: QName l -> [Symbol] -> NameInfo l
172+
checkUniqueness qname symbols = case symbols of
173+
[] -> ScopeError (ENotInScope qname)
174+
[symbol] -> GlobalSymbol symbol (dropAnn qname)
175+
_ -> ScopeError (EAmbiguous qname symbols)
176+
177+
178+
disambiguateMethod :: Maybe (QName ()) -> QName l -> [Symbol] -> NameInfo l
179+
disambiguateMethod Nothing _ _ = ScopeError (EInternal "method in instance of unknown class")
180+
disambiguateMethod (Just instanceClassName) qname symbols = checkUniqueness qname disambiguatedSymbols where
181+
disambiguatedSymbols =
182+
filter (\symbol -> className symbol == qNameToName instanceClassName) symbols
171183

172184
qualifyName :: Maybe (ModuleName ()) -> Name l -> QName l
173185
qualifyName Nothing n = UnQual (ann n) n

src/Language/Haskell/Names/Open/Base.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ data Scope = Scope
6161
, _gTable :: Global.Table
6262
, _lTable :: Local.Table
6363
, _nameCtx :: NameContext
64-
, _instQual :: Maybe (ModuleName ())
64+
, _instClassName :: Maybe (QName ())
6565
, _wcNames :: WcNames
6666
, _patSynMode :: Maybe PatSynMode
6767
}
@@ -171,8 +171,8 @@ exprUT = setNameCtx ReferenceUT
171171
exprRS :: Scope -> Scope
172172
exprRS = setNameCtx ReferenceRS
173173

174-
instQ :: Maybe (ModuleName ()) -> Scope -> Scope
175-
instQ m = setL instQual m
174+
setInstClassName :: Maybe (QName ()) -> Scope -> Scope
175+
setInstClassName m = setL instClassName m
176176

177177
setPatSynMode :: PatSynMode -> Scope -> Scope
178178
setPatSynMode = setL patSynMode . Just

src/Language/Haskell/Names/Open/Instances.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ instance (Resolvable l, SrcInfo l, D.Data l) => Resolvable (Decl l) where
8181
<| sc -: mp
8282
<| exprV sc -: ops
8383
InstDecl l mOverlap rule mInstDecls ->
84-
let sc' = instQ (nameQualification (instanceRuleClass rule)) sc
84+
let sc' = setInstClassName (Just (dropAnn (instanceRuleClass rule))) sc
8585
in c InstDecl
8686
<| sc' -: l
8787
<| sc' -: mOverlap

tests/annotations/ClassInstances.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
module ClassInstances where
22

3-
data D a = D Bool a
3+
data D a = D DataType a
44

55
class C a where
66
wiggle :: a -> a
77
woe :: a
8+
method1 :: a
89
($$$) :: a -> a -> a
910

1011
instance (C a) => C (D a) where
1112
wiggle (D b a) = D b (f a)
12-
woe = D False woe
13+
woe = D Constructor1 woe
14+
method1 = D Constructor1 woe
1315
f $$$ x = ($$$) f x
1416

1517
f :: (C a) => a -> a
Lines changed: 65 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,75 @@
11
D at 3:6 is a type or class defined here
22
a at 3:8 is none
33
D at 3:12 is a value bound here
4-
Bool at 3:14 is not in scope
5-
Bool at 3:14 is not in scope
6-
a at 3:19 is none
4+
DataType at 3:14 is a global data type, Prelude.DataType
5+
DataType at 3:14 is a global data type, Prelude.DataType
6+
a at 3:23 is none
77
C at 5:7 is a type or class defined here
88
a at 5:9 is none
99
wiggle at 6:5 is a value bound here
1010
a at 6:15 is none
1111
a at 6:20 is none
1212
woe at 7:5 is a value bound here
1313
a at 7:12 is none
14-
$$$ at 8:5 is a value bound here
15-
a at 8:14 is none
16-
a at 8:19 is none
17-
a at 8:24 is none
18-
C at 10:11 is a global type class, ClassInstances.C
19-
C at 10:11 is a global type class, ClassInstances.C
20-
a at 10:13 is none
21-
C at 10:19 is a global type class, ClassInstances.C
22-
C at 10:19 is a global type class, ClassInstances.C
23-
D at 10:22 is a global data type, ClassInstances.D
24-
D at 10:22 is a global data type, ClassInstances.D
25-
a at 10:24 is none
26-
wiggle at 11:5 is a global method, ClassInstances.wiggle
27-
D at 11:13 is a global constructor, ClassInstances.D
28-
D at 11:13 is a global constructor, ClassInstances.D
29-
b at 11:15 is a value bound here
30-
a at 11:17 is a value bound here
31-
D at 11:22 is a global constructor, ClassInstances.D
32-
D at 11:22 is a global constructor, ClassInstances.D
33-
b at 11:24 is a local value defined at 11:15
34-
b at 11:24 is a local value defined at 11:15
35-
f at 11:27 is a global value, ClassInstances.f
36-
f at 11:27 is a global value, ClassInstances.f
37-
a at 11:29 is a local value defined at 11:17
38-
a at 11:29 is a local value defined at 11:17
39-
woe at 12:5 is a global method, ClassInstances.woe
40-
D at 12:11 is a global constructor, ClassInstances.D
41-
D at 12:11 is a global constructor, ClassInstances.D
42-
False at 12:13 is not in scope
43-
False at 12:13 is not in scope
44-
woe at 12:19 is a global method, ClassInstances.woe
45-
woe at 12:19 is a global method, ClassInstances.woe
46-
f at 13:5 is a value bound here
47-
$$$ at 13:7 is a global method, ClassInstances.($$$)
48-
x at 13:11 is a value bound here
49-
$$$ at 13:15 is a global method, ClassInstances.($$$)
50-
$$$ at 13:15 is a global method, ClassInstances.($$$)
51-
f at 13:21 is a local value defined at 13:5
52-
f at 13:21 is a local value defined at 13:5
53-
x at 13:23 is a local value defined at 13:11
54-
x at 13:23 is a local value defined at 13:11
55-
f at 15:1 is a global value, ClassInstances.f
56-
C at 15:7 is a global type class, ClassInstances.C
57-
C at 15:7 is a global type class, ClassInstances.C
58-
a at 15:9 is none
59-
a at 15:15 is none
60-
a at 15:20 is none
61-
f at 16:1 is a value bound here
62-
x at 16:3 is a value bound here
63-
wiggle at 16:7 is a global method, ClassInstances.wiggle
64-
wiggle at 16:7 is a global method, ClassInstances.wiggle
65-
x at 16:14 is a local value defined at 16:3
66-
x at 16:14 is a local value defined at 16:3
14+
method1 at 8:5 is a value bound here
15+
a at 8:16 is none
16+
$$$ at 9:5 is a value bound here
17+
a at 9:14 is none
18+
a at 9:19 is none
19+
a at 9:24 is none
20+
C at 11:11 is a global type class, ClassInstances.C
21+
C at 11:11 is a global type class, ClassInstances.C
22+
a at 11:13 is none
23+
C at 11:19 is a global type class, ClassInstances.C
24+
C at 11:19 is a global type class, ClassInstances.C
25+
D at 11:22 is a global data type, ClassInstances.D
26+
D at 11:22 is a global data type, ClassInstances.D
27+
a at 11:24 is none
28+
wiggle at 12:5 is a global method, ClassInstances.wiggle
29+
D at 12:13 is a global constructor, ClassInstances.D
30+
D at 12:13 is a global constructor, ClassInstances.D
31+
b at 12:15 is a value bound here
32+
a at 12:17 is a value bound here
33+
D at 12:22 is a global constructor, ClassInstances.D
34+
D at 12:22 is a global constructor, ClassInstances.D
35+
b at 12:24 is a local value defined at 12:15
36+
b at 12:24 is a local value defined at 12:15
37+
f at 12:27 is a global value, ClassInstances.f
38+
f at 12:27 is a global value, ClassInstances.f
39+
a at 12:29 is a local value defined at 12:17
40+
a at 12:29 is a local value defined at 12:17
41+
woe at 13:5 is a global method, ClassInstances.woe
42+
D at 13:11 is a global constructor, ClassInstances.D
43+
D at 13:11 is a global constructor, ClassInstances.D
44+
Constructor1 at 13:13 is a global constructor, Prelude.Constructor1
45+
Constructor1 at 13:13 is a global constructor, Prelude.Constructor1
46+
woe at 13:26 is a global method, ClassInstances.woe
47+
woe at 13:26 is a global method, ClassInstances.woe
48+
method1 at 14:5 is a global method, ClassInstances.method1
49+
D at 14:15 is a global constructor, ClassInstances.D
50+
D at 14:15 is a global constructor, ClassInstances.D
51+
Constructor1 at 14:17 is a global constructor, Prelude.Constructor1
52+
Constructor1 at 14:17 is a global constructor, Prelude.Constructor1
53+
woe at 14:30 is a global method, ClassInstances.woe
54+
woe at 14:30 is a global method, ClassInstances.woe
55+
f at 15:5 is a value bound here
56+
$$$ at 15:7 is a global method, ClassInstances.($$$)
57+
x at 15:11 is a value bound here
58+
$$$ at 15:15 is a global method, ClassInstances.($$$)
59+
$$$ at 15:15 is a global method, ClassInstances.($$$)
60+
f at 15:21 is a local value defined at 15:5
61+
f at 15:21 is a local value defined at 15:5
62+
x at 15:23 is a local value defined at 15:11
63+
x at 15:23 is a local value defined at 15:11
64+
f at 17:1 is a global value, ClassInstances.f
65+
C at 17:7 is a global type class, ClassInstances.C
66+
C at 17:7 is a global type class, ClassInstances.C
67+
a at 17:9 is none
68+
a at 17:15 is none
69+
a at 17:20 is none
70+
f at 18:1 is a value bound here
71+
x at 18:3 is a value bound here
72+
wiggle at 18:7 is a global method, ClassInstances.wiggle
73+
wiggle at 18:7 is a global method, ClassInstances.wiggle
74+
x at 18:14 is a local value defined at 18:3
75+
x at 18:14 is a local value defined at 18:3

0 commit comments

Comments
 (0)