rename: hadle type signatures with typos
authorWojciech Baranowski <wbaranowski@protonmail.com>
Sun, 7 Apr 2019 16:25:05 +0000 (19:25 +0300)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Tue, 30 Apr 2019 01:02:38 +0000 (21:02 -0400)
When encountering type signatures for unknown names, suggest similar
alternatives.

This fixes issue #16504

compiler/rename/RnEnv.hs
testsuite/tests/parser/should_fail/readFail001.stderr
testsuite/tests/rename/should_fail/T16504.hs [new file with mode: 0644]
testsuite/tests/rename/should_fail/T16504.stderr [new file with mode: 0644]
testsuite/tests/rename/should_fail/all.T

index 638f7df..381ba2b 100644 (file)
@@ -1472,18 +1472,21 @@ lookupBindGroupOcc ctxt what rdr_name
     lookup_top keep_me
       = do { env <- getGlobalRdrEnv
            ; let all_gres = lookupGlobalRdrEnv env (rdrNameOcc rdr_name)
+           ; let candidates_msg = candidates $ map gre_name $ globalRdrEnvElts env
            ; case filter (keep_me . gre_name) all_gres of
-               [] | null all_gres -> bale_out_with Outputable.empty
+               [] | null all_gres -> bale_out_with candidates_msg
                   | otherwise     -> bale_out_with local_msg
                (gre:_)            -> return (Right (gre_name gre)) }
 
     lookup_group bound_names  -- Look in the local envt (not top level)
       = do { mname <- lookupLocalOccRn_maybe rdr_name
+           ; env <- getLocalRdrEnv
+           ; let candidates_msg = candidates $ localRdrEnvElts env
            ; case mname of
                Just n
                  | n `elemNameSet` bound_names -> return (Right n)
                  | otherwise                   -> bale_out_with local_msg
-               Nothing                         -> bale_out_with Outputable.empty }
+               Nothing                         -> bale_out_with candidates_msg }
 
     bale_out_with msg
         = return (Left (sep [ text "The" <+> what
@@ -1494,6 +1497,19 @@ lookupBindGroupOcc ctxt what rdr_name
     local_msg = parens $ text "The"  <+> what <+> ptext (sLit "must be given where")
                            <+> quotes (ppr rdr_name) <+> text "is declared"
 
+    candidates names_in_scope
+      = case similar_names of
+          [] -> Outputable.empty
+          _  -> vcat $ map (\x -> text "Perhaps you meant" <+>
+                                  quotes (ppr x) <+>
+                                  parens (pprDefinedAt x))
+                           similar_names
+      where
+        similar_names
+          = fuzzyLookup (unpackFS $ occNameFS $ rdrNameOcc rdr_name)
+                        $ map (\x -> ((unpackFS $ occNameFS $ nameOccName x), x))
+                              names_in_scope
+
 
 ---------------
 lookupLocalTcNames :: HsSigCtxt -> SDoc -> RdrName -> RnM [(RdrName, Name)]
index 6425d16..0b6d4b4 100644 (file)
@@ -1,6 +1,8 @@
 
 readFail001.hs:25:11: error:
     The fixity signature for ‘+#’ lacks an accompanying binding
+      Perhaps you meant ‘+’ (Defined in ‘GHC.Num’)
+      Perhaps you meant ‘++’ (Defined in ‘GHC.Base’)
 
 readFail001.hs:38:32: error:
     Not in scope: type constructor or class ‘Leaf’
diff --git a/testsuite/tests/rename/should_fail/T16504.hs b/testsuite/tests/rename/should_fail/T16504.hs
new file mode 100644 (file)
index 0000000..1bb6a08
--- /dev/null
@@ -0,0 +1,16 @@
+-- Type signature and definition with name typo
+module M where
+
+-- Both in global scope
+simpleFuntcion :: Int -> Bool
+simpleFunction i = i > 5
+
+-- Both in local scope
+f x = anotherFunction x
+  where anotherFunction :: Int -> Bool
+        anotherFuntcion i = i > 5
+
+-- Global signature, local definition
+nonexistentFuntcion :: Int -> Bool
+g x = nonexistentFunction x
+  where nonexistentFunction i = i > 5
diff --git a/testsuite/tests/rename/should_fail/T16504.stderr b/testsuite/tests/rename/should_fail/T16504.stderr
new file mode 100644 (file)
index 0000000..7bc59bd
--- /dev/null
@@ -0,0 +1,14 @@
+
+T16504.hs:5:1: error:
+    The type signature for ‘simpleFuntcion’
+      lacks an accompanying binding
+      Perhaps you meant ‘simpleFunction’ (Defined at T16504.hs:6:1)
+
+T16504.hs:10:9: error:
+    The type signature for ‘anotherFunction’
+      lacks an accompanying binding
+      Perhaps you meant ‘anotherFuntcion’ (Defined at T16504.hs:11:9)
+
+T16504.hs:14:1: error:
+    The type signature for ‘nonexistentFuntcion’
+      lacks an accompanying binding
index 5bfded1..52a4f45 100644 (file)
@@ -148,3 +148,4 @@ test('T16116b', normal, compile_fail, [''])
 test('ExplicitForAllRules2', normal, compile_fail, [''])
 test('T15957_Fail', normal, compile_fail, ['-Werror -Wall -Wno-missing-signatures'])
 test('T16385', normal, compile_fail, [''])
+test('T16504', normal, compile_fail, [''])