Skip to content

Commit f86fb64

Browse files
committed
add basic support for error messages during misuse
1 parent 399b643 commit f86fb64

File tree

5 files changed

+93
-22
lines changed

5 files changed

+93
-22
lines changed

src/Core/Context.idr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,8 @@ HasNames Error where
836836
full gam (OperatorBindingMismatch {print} fc expected actual (Right opName) rhs candidates)
837837
= OperatorBindingMismatch {print} fc expected actual
838838
<$> (Right <$> full gam opName) <*> pure rhs <*> pure candidates
839+
full gam (BindingApplicationMismatch fc used bind others)
840+
= BindingApplicationMismatch fc used <$> traverse (full gam) bind <*> traverse (full gam) others
839841

840842
resolved gam (Fatal err) = Fatal <$> resolved gam err
841843
resolved _ (CantConvert fc gam rho s t)
@@ -934,7 +936,8 @@ HasNames Error where
934936
resolved gam (OperatorBindingMismatch {print} fc expected actual (Right opName) rhs candidates)
935937
= OperatorBindingMismatch {print} fc expected actual
936938
<$> (Right <$> resolved gam opName) <*> pure rhs <*> pure candidates
937-
939+
resolved gam (BindingApplicationMismatch fc used bind others)
940+
= BindingApplicationMismatch fc used <$> traverse (resolved gam) bind <*> traverse (resolved gam) others
938941
export
939942
HasNames Totality where
940943
full gam (MkTotality t c) = pure $ MkTotality !(full gam t) !(full gam c)

src/Core/Core.idr

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,12 @@ data Error : Type where
175175
FC -> (expectedFixity : FixityDeclarationInfo) -> (use_site : OperatorLHSInfo a) ->
176176
-- left: backticked, right: op symbolds
177177
(opName : Either Name Name) -> (rhs : a) -> (candidates : List String) -> Error
178+
BindingApplicationMismatch :
179+
FC ->
180+
(bindingUsed : BindingModifier) ->
181+
(bindingCandidates : List Name) ->
182+
(nonBindingCandidates : List Name) ->
183+
Error
178184
TTCError : TTCErrorMsg -> Error
179185
FileErr : String -> FileError -> Error
180186
CantFindPackage : String -> Error
@@ -414,6 +420,8 @@ Show Error where
414420
show (OperatorBindingMismatch fc UndeclaredFixity actual opName rhs _)
415421
= show fc ++ ": Operator " ++ show opName ++ " has no declared fixity"
416422
++ " but used as a " ++ show actual ++ " operator"
423+
show (BindingApplicationMismatch fc used binding notBinding)
424+
= show fc ++ ": Application used \{show used} syntax but no such function exists"
417425

418426
export
419427
getWarningLoc : Warning -> FC
@@ -505,6 +513,7 @@ getErrorLoc (InRHS _ _ err) = getErrorLoc err
505513
getErrorLoc (MaybeMisspelling err _) = getErrorLoc err
506514
getErrorLoc (WarningAsError warn) = Just (getWarningLoc warn)
507515
getErrorLoc (OperatorBindingMismatch loc _ _ _ _ _) = Just loc
516+
getErrorLoc (BindingApplicationMismatch loc _ _ _) = Just loc
508517

509518
export
510519
killWarningLoc : Warning -> Warning
@@ -596,7 +605,8 @@ killErrorLoc (MaybeMisspelling err xs) = MaybeMisspelling (killErrorLoc err) xs
596605
killErrorLoc (WarningAsError wrn) = WarningAsError (killWarningLoc wrn)
597606
killErrorLoc (OperatorBindingMismatch {print} fc expected actual opName rhs candidates)
598607
= OperatorBindingMismatch {print} emptyFC expected actual opName rhs candidates
599-
608+
killErrorLoc (BindingApplicationMismatch _ a b c)
609+
= BindingApplicationMismatch emptyFC a b c
600610

601611
-- Core is a wrapper around IO that is specialised for efficiency.
602612
export

src/Idris/Error.idr

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ perrorRaw (GenericMsgSol fc header solutionHeader solutions)
628628
<+> indent 1 (vsep (map (\s => "-" <++> pretty0 s) solutions))
629629
perrorRaw (OperatorBindingMismatch fc {print=p} expected actual opName rhs candidates)
630630
= pure $ "Operator" <++> pretty0 !(getFullName (fromEither opName)) <++> "is"
631-
<++> printBindingInfo expected-- .bindingInfo
631+
<++> printBindingInfo expected
632632
<++> "operator, but is used as" <++> printBindingModifier actual.getBinder
633633
<++> "operator."
634634
<+> line <+> !(ploc fc)
@@ -703,7 +703,23 @@ perrorRaw (OperatorBindingMismatch fc {print=p} expected actual opName rhs candi
703703
printBindingInfo : FixityDeclarationInfo -> Doc IdrisAnn
704704
printBindingInfo UndeclaredFixity = "a regular"
705705
printBindingInfo (DeclaredFixity x) = printBindingModifier x.bindingInfo
706-
706+
perrorRaw (BindingApplicationMismatch fc used bind others)
707+
= pure $ errorDesc $ reflow "Using \{show used} syntax but no function in scope is marked \{show used}"
708+
<+> line
709+
<+> !(ploc fc)
710+
<+> line
711+
<+> footer bind others
712+
where
713+
footer : List Name -> List Name -> Doc IdrisAnn
714+
footer [] [] = reflow "There are no functions in scope that could match the current situation"
715+
footer [] (x :: xs) =
716+
reflow "Did you mean any of:"
717+
<++> concatWith (surround (comma <+> space)) (map (code . pretty0) xs)
718+
<+> comma <++> "or" <++> code (pretty0 x) <+> "?"
719+
footer (x :: xs) ns1 =
720+
reflow "Did you mean any of:"
721+
<++> concatWith (surround (comma <+> space)) (map (code . pretty0) xs)
722+
<+> comma <++> "or" <++> code (pretty0 x) <+> "?"
707723

708724
perrorRaw (TTCError msg)
709725
= pure $ errorDesc (reflow "Error in TTC file" <+> colon <++> byShow msg)

src/TTImp/Elab/BindingApp.idr

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,53 @@ import Core.Metadata
99
import Core.Name
1010
import Core.Normalise
1111

12+
import Data.List
13+
1214
import TTImp.Elab.Check
1315
import TTImp.Elab.App
1416
import TTImp.TTImp
1517

1618
import Idris.REPL.Opts
1719
import Idris.Syntax
1820

19-
keepBinding : BindingModifier -> List GlobalDef -> List GlobalDef
20-
keepBinding mode = filter (\x => x.bindingMode == mode)
2121

22-
parameters (originalName : WithFC Name) {auto c : Ref Ctxt Defs}
23-
checkUnique : List GlobalDef -> Core GlobalDef
24-
checkUnique [ def ] = pure def
25-
checkUnique [] = throw $ UndefinedName originalName.fc originalName.val
26-
checkUnique defs = throw $ AmbiguousName originalName.fc (map fullname defs)
22+
23+
record BindingModes (a : Type) where
24+
constructor MkBindingModes
25+
everythingMatches : List a
26+
bindingDoesNotMatch : List a
27+
notBinding : List a
28+
29+
keepBinding : BindingModifier -> List GlobalDef -> BindingModes GlobalDef
30+
keepBinding mode = foldl sortBinding (MkBindingModes [] [] [])
31+
where
32+
sortBinding : BindingModes GlobalDef -> GlobalDef -> BindingModes GlobalDef
33+
sortBinding modes def = if def.bindingMode == mode
34+
then {everythingMatches $= (def ::)} modes
35+
else if def.bindingMode == NotBinding
36+
then {notBinding $= (def ::)} modes
37+
else {bindingDoesNotMatch $= (def ::)} modes
38+
39+
40+
parameters (originalName : WithFC Name) (mode : BindingModifier) {auto c : Ref Ctxt Defs}
41+
checkUnique : BindingModes GlobalDef -> Core GlobalDef
42+
checkUnique (MkBindingModes [ def ] _ _ ) = pure def
43+
checkUnique (MkBindingModes [] may others) = do
44+
coreLift $ putStrLn (show $ map fullname others)
45+
throw $ BindingApplicationMismatch originalName.fc mode (map fullname may) (map fullname others)
46+
checkUnique (MkBindingModes defs _ _) = throw $ AmbiguousName originalName.fc (map fullname defs)
2747

2848
typecheckCandidates : List GlobalDef -> Core (List GlobalDef)
29-
typecheckCandidates xs = pure xs -- todo
49+
typecheckCandidates xs = pure xs -- todo: emit errors when the type doesn't match
3050

31-
checkBinding : (mode : BindingModifier) -> (candidates : List GlobalDef) -> Core GlobalDef
32-
checkBinding mode candidates = do
51+
checkBinding : (candidates : List GlobalDef) -> Core GlobalDef
52+
checkBinding candidates = do
3353
log "elab.bindApp" 10 $ "Potential candidates for binding identifer : \{show (map fullname candidates)}"
3454
log "elab.bindApp" 10 $ "Checking if candidates have binding \{show mode}"
35-
let bindingCandidates = keepBinding mode candidates
36-
log "elab.bindApp" 10 $ "Final list of binding identifers : \{show (map fullname bindingCandidates)}"
37-
wellTypedCandidates <- typecheckCandidates bindingCandidates
38-
checkUnique bindingCandidates
55+
let candidates = keepBinding mode candidates
56+
log "elab.bindApp" 10 $ "Final list of binding identifers : \{show (map fullname candidates.everythingMatches)}"
57+
-- wellTypedCandidates <- typecheckCandidates bindingCandidates
58+
checkUnique candidates
3959

4060
typeForBinder : BindingInfo RawImp -> FC -> RawImp
4161
typeForBinder (BindType name type) = const type
Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,30 @@
11
1/1: Building Test (Test.idr)
2-
SHould warn about declaring typebind instead of autobind
2+
Should warn about declaring typebind instead of autobind
33
1/1: Building Test2 (Test2.idr)
4-
Shouwl warn about autobind instead of typebind
4+
[]
5+
Error: While processing right hand side of List. Using autobind syntax but no function in scope is marked autobind
6+
7+
Test2:12:10--12:15
8+
08 | p2 : sy p1
9+
09 |
10+
10 |
11+
11 | List : Type -> Type
12+
12 | List a = Sigma (n <- Nat) | Fin n -> a
13+
^^^^^
14+
15+
Did you mean to write: `Sigma (x : range)` using `Sigma` from module `Test3` on line 6?
516
1/1: Building Test3 (Test3.idr)
6-
should warn about using typebind insteaf of autobind
17+
[Prelude.Interfaces.for]
18+
Error: While processing right hand side of main. Using typebind syntax but no function in scope is marked typebind
19+
20+
Test3:10:8--10:11
21+
06 | range : List Nat
22+
07 | range = [1 .. 10]
23+
08 |
24+
09 | main : IO ()
25+
10 | main = for (x : range) | printLn x
26+
^^^
27+
28+
Did you mean to write: `for (x <- range)` using `for` from module `Test3` on line 4?
729
1/1: Building Test4 (Test4.idr)
8-
should warn about declaring auto instead of typebind
30+
Should warn about declaring autobind instead of typebind

0 commit comments

Comments
 (0)