Fix incorrect ambiguity error on identically-named data constructors
authorSoham Chowdhury <chow.soham@gmail.com>
Thu, 11 May 2017 19:40:18 +0000 (15:40 -0400)
committerBen Gamari <ben@smart-cactus.org>
Thu, 11 May 2017 21:26:18 +0000 (17:26 -0400)
Given multiple in-scope constructors with the same name, say `A`, and a
function of type `A -> Int`, say, the compiler reports both a "type `A`
is not in scope" and (incorrectly) an ambiguity error. The latter
shouldn't be there if `DataKinds` isn't enabled.

This issue was recommended to me by @mpickering as a suitable first
task, and the fix was also outlined in the original Trac ticket. It
involved a simple reordering of the steps taken in `lookup_demoted` in
`RnEnv.hs`. The fix is to make the `DataKinds` check happen earlier,
ensuring that the ambiguity check doesn't happen at all if we know the
constructors couldn't have been promoted.

Signed-off-by: Soham Chowdhury <chow.soham@gmail.com>
Reviewers: mpickering, austin, bgamari

Reviewed By: mpickering, bgamari

Subscribers: rwbarton, thomie

GHC Trac Issues: #13568

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

18 files changed:
compiler/rename/RnEnv.hs
testsuite/tests/module/mod122.stderr
testsuite/tests/module/mod123.stderr
testsuite/tests/module/mod124.stderr
testsuite/tests/module/mod127.stderr
testsuite/tests/module/mod29.stderr
testsuite/tests/module/mod50.stderr
testsuite/tests/parser/should_fail/readFail001.stderr
testsuite/tests/rename/prog003/rename.prog003.stderr
testsuite/tests/rename/should_fail/T13568.hs [new file with mode: 0644]
testsuite/tests/rename/should_fail/T13568.stderr [new file with mode: 0644]
testsuite/tests/rename/should_fail/T13568a.hs [new file with mode: 0644]
testsuite/tests/rename/should_fail/T1595a.stderr
testsuite/tests/rename/should_fail/T5745.stderr
testsuite/tests/rename/should_fail/all.T
testsuite/tests/typecheck/should_fail/T1595.stderr
testsuite/tests/typecheck/should_fail/tcfail048.stderr
testsuite/tests/typecheck/should_fail/tcfail053.stderr

index 570c6c0..12c8557 100644 (file)
@@ -706,16 +706,17 @@ lookup_demoted rdr_name dflags
   | Just demoted_rdr <- demoteRdrName rdr_name
     -- Maybe it's the name of a *data* constructor
   = do { data_kinds <- xoptM LangExt.DataKinds
-       ; mb_demoted_name <- lookupOccRn_maybe demoted_rdr
-       ; case mb_demoted_name of
-           Nothing -> unboundNameX WL_Any rdr_name star_info
-           Just demoted_name
-             | data_kinds ->
-             do { whenWOptM Opt_WarnUntickedPromotedConstructors $
-                  addWarn (Reason Opt_WarnUntickedPromotedConstructors)
-                          (untickedPromConstrWarn demoted_name)
-                ; return demoted_name }
-             | otherwise  -> unboundNameX WL_Any rdr_name suggest_dk }
+       ; if data_kinds
+            then do { mb_demoted_name <- lookupOccRn_maybe demoted_rdr
+                    ; case mb_demoted_name of
+                        Nothing -> unboundNameX WL_Any rdr_name star_info
+                        Just demoted_name ->
+                          do { whenWOptM Opt_WarnUntickedPromotedConstructors $
+                               addWarn
+                                 (Reason Opt_WarnUntickedPromotedConstructors)
+                                 (untickedPromConstrWarn demoted_name)
+                             ; return demoted_name } }
+            else unboundNameX WL_Any rdr_name suggest_dk }
 
   | otherwise
   = reportUnboundName rdr_name
index 90719ec..66aaaf2 100644 (file)
@@ -1,2 +1,4 @@
 
-mod122.hs:5:6: Not in scope: type constructor or class ‘C’
+mod122.hs:5:6: error:
+    Not in scope: type constructor or class ‘C’
+    A data constructor of that name is in scope; did you mean DataKinds?
index 9d9de6b..38390d0 100644 (file)
@@ -1,2 +1,4 @@
 
-mod123.hs:5:6: Not in scope: type constructor or class ‘T’
+mod123.hs:5:6: error:
+    Not in scope: type constructor or class ‘T’
+    A data constructor of that name is in scope; did you mean DataKinds?
index a052a50..cbf9f45 100644 (file)
@@ -1,5 +1,6 @@
 
 mod124.hs:6:6: error:
     Not in scope: type constructor or class ‘T’
+    A data constructor of that name is in scope; did you mean DataKinds?
     Perhaps you want to remove ‘T’ from the explicit hiding list
     in the import of ‘Mod124_A’ (mod124.hs:4:1-26).
index 861d492..462ebbc 100644 (file)
@@ -1,5 +1,6 @@
 
 mod127.hs:6:6: error:
     Not in scope: type constructor or class ‘T’
+    A data constructor of that name is in scope; did you mean DataKinds?
     Perhaps you want to remove ‘T’ from the explicit hiding list
     in the import of ‘Mod127_A’ (mod127.hs:4:1-26).
index e70c5df..08a019e 100644 (file)
@@ -1,5 +1,6 @@
 
 mod29.hs:6:12: error:
     Not in scope: type constructor or class ‘Char’
+    A data constructor of that name is in scope; did you mean DataKinds?
     Perhaps you want to add ‘Char’ to the import list in the import of
     ‘Prelude’ (mod29.hs:5:1-19).
index 593148e..94878a8 100644 (file)
@@ -1,2 +1,4 @@
 
-mod50.hs:3:22: Not in scope: type constructor or class ‘Foo’
+mod50.hs:3:22: error:
+    Not in scope: type constructor or class ‘Foo’
+    A data constructor of that name is in scope; did you mean DataKinds?
index 6425d16..3284c1b 100644 (file)
@@ -16,3 +16,4 @@ readFail001.hs:107:42: error: Not in scope: data constructor ‘Bar’
 
 readFail001.hs:112:23: error:
     Not in scope: type constructor or class ‘Foo’
+    A data constructor of that name is in scope; did you mean DataKinds?
index 7a0b524..6babd03 100644 (file)
@@ -1,2 +1,4 @@
 
-B.hs:4:6: Not in scope: type constructor or class ‘Class’
+B.hs:4:6: error:
+    Not in scope: type constructor or class ‘Class’
+    A data constructor of that name is in scope; did you mean DataKinds?
diff --git a/testsuite/tests/rename/should_fail/T13568.hs b/testsuite/tests/rename/should_fail/T13568.hs
new file mode 100644 (file)
index 0000000..f815c83
--- /dev/null
@@ -0,0 +1,8 @@
+module T13568 where
+
+import T13568a
+
+data S = A
+
+foo :: A -> ()
+foo = undefined
diff --git a/testsuite/tests/rename/should_fail/T13568.stderr b/testsuite/tests/rename/should_fail/T13568.stderr
new file mode 100644 (file)
index 0000000..63ee184
--- /dev/null
@@ -0,0 +1,4 @@
+
+T13568.hs:7:8: error:
+    Not in scope: type constructor or class ‘A’
+    A data constructor of that name is in scope; did you mean DataKinds?
diff --git a/testsuite/tests/rename/should_fail/T13568a.hs b/testsuite/tests/rename/should_fail/T13568a.hs
new file mode 100644 (file)
index 0000000..c25a48a
--- /dev/null
@@ -0,0 +1,3 @@
+module T13568a where
+
+data T = A
index 9705293..9b19421 100644 (file)
@@ -1,2 +1,4 @@
 
-T1595a.hs:3:20: Not in scope: type constructor or class ‘Tpyo’
+T1595a.hs:3:20: error:
+    Not in scope: type constructor or class ‘Tpyo’
+    A data constructor of that name is in scope; did you mean DataKinds?
index 577ae06..94e3bd5 100644 (file)
@@ -1,2 +1,4 @@
 
-T5745.hs:5:6: Not in scope: type constructor or class ‘T’
+T5745.hs:5:6: error:
+    Not in scope: type constructor or class ‘T’
+    A data constructor of that name is in scope; did you mean DataKinds?
index 517d23d..457f401 100644 (file)
@@ -126,3 +126,4 @@ test('T12686', normal, compile_fail, [''])
 test('T11592', normal, compile_fail, [''])
 test('T12879', normal, compile_fail, [''])
 test('T13644', expect_broken(13644), multimod_compile_fail, ['T13644','-v0'])
+test('T13568', normal, multimod_compile_fail, ['T13568','-v0'])
index 1f999c6..bed30c4 100644 (file)
@@ -1,6 +1,8 @@
 
-T1595.hs:8:15:
+T1595.hs:8:15: error:
     Not in scope: type constructor or class ‘DoesNotExist’
+    A data constructor of that name is in scope; did you mean DataKinds?
 
-T1595.hs:13:22:
+T1595.hs:13:22: error:
     Not in scope: type constructor or class ‘DoesNotExist’
+    A data constructor of that name is in scope; did you mean DataKinds?
index eaa2e52..4c1c300 100644 (file)
@@ -1,2 +1,4 @@
 
-tcfail048.hs:3:8: Not in scope: type constructor or class ‘B’
+tcfail048.hs:3:8: error:
+    Not in scope: type constructor or class ‘B’
+    A data constructor of that name is in scope; did you mean DataKinds?
index a9b13bd..edd1537 100644 (file)
@@ -1,2 +1,4 @@
 
-tcfail053.hs:3:12: Not in scope: type constructor or class ‘A’
+tcfail053.hs:3:12: error:
+    Not in scope: type constructor or class ‘A’
+    A data constructor of that name is in scope; did you mean DataKinds?