mirror of
https://github.com/unisonweb/unison.git
synced 2024-10-04 05:37:14 +03:00
Improve error LSP ranges on type mismatches
This commit is contained in:
parent
b6e12d086c
commit
6f9bda9528
@ -369,7 +369,7 @@ renderTypeError e env src = case e of
|
|||||||
Mismatch {..} ->
|
Mismatch {..} ->
|
||||||
mconcat
|
mconcat
|
||||||
[ Pr.lines
|
[ Pr.lines
|
||||||
[ "I found a value of type: " <> style Type1 (renderType' env foundLeaf),
|
[ "I found a value of type: " <> style Type1 (renderType' env foundLeaf),
|
||||||
"where I expected to find: " <> style Type2 (renderType' env expectedLeaf)
|
"where I expected to find: " <> style Type2 (renderType' env expectedLeaf)
|
||||||
],
|
],
|
||||||
"\n\n",
|
"\n\n",
|
||||||
|
@ -216,7 +216,10 @@ analyseNotes fileUri ppe src notes = do
|
|||||||
Result.TypeError errNote@(Context.ErrorNote {cause}) -> do
|
Result.TypeError errNote@(Context.ErrorNote {cause}) -> do
|
||||||
let typeErr = TypeError.typeErrorFromNote errNote
|
let typeErr = TypeError.typeErrorFromNote errNote
|
||||||
ranges = case typeErr of
|
ranges = case typeErr of
|
||||||
TypeError.Mismatch {mismatchSite} -> singleRange $ ABT.annotation mismatchSite
|
TypeError.Mismatch {mismatchSite} -> do
|
||||||
|
let locs = ABT.annotation <$> expressionLeafNodes mismatchSite
|
||||||
|
(r, rs) <- withNeighbours (locs >>= aToR)
|
||||||
|
pure (r, ("mismatch",) <$> rs)
|
||||||
TypeError.BooleanMismatch {mismatchSite} -> singleRange $ ABT.annotation mismatchSite
|
TypeError.BooleanMismatch {mismatchSite} -> singleRange $ ABT.annotation mismatchSite
|
||||||
TypeError.ExistentialMismatch {mismatchSite} -> singleRange $ ABT.annotation mismatchSite
|
TypeError.ExistentialMismatch {mismatchSite} -> singleRange $ ABT.annotation mismatchSite
|
||||||
TypeError.FunctionApplication {f} -> singleRange $ ABT.annotation f
|
TypeError.FunctionApplication {f} -> singleRange $ ABT.annotation f
|
||||||
@ -471,3 +474,38 @@ mkTypeSignatureHints parsedFile typecheckedFile = do
|
|||||||
pure $ TypeSignatureHint name (Referent.fromTermReferenceId ref) newRange typ
|
pure $ TypeSignatureHint name (Referent.fromTermReferenceId ref) newRange typ
|
||||||
)
|
)
|
||||||
in typeHints
|
in typeHints
|
||||||
|
|
||||||
|
-- | Crawl a term and find the nodes which actually influence its return type. This is useful for narrowing down a giant
|
||||||
|
-- "This let/do block has the wrong type" into "This specific line returns the wrong type"
|
||||||
|
-- This is just a heuristic.
|
||||||
|
expressionLeafNodes :: Term.Term2 vt at ap v a -> [Term.Term2 vt at ap v a]
|
||||||
|
expressionLeafNodes abt =
|
||||||
|
case ABT.out abt of
|
||||||
|
ABT.Var {} -> [abt]
|
||||||
|
ABT.Cycle r -> expressionLeafNodes r
|
||||||
|
ABT.Abs _ r -> expressionLeafNodes r
|
||||||
|
ABT.Tm f -> case f of
|
||||||
|
Term.Int {} -> [abt]
|
||||||
|
Term.Nat {} -> [abt]
|
||||||
|
Term.Float {} -> [abt]
|
||||||
|
Term.Boolean {} -> [abt]
|
||||||
|
Term.Text {} -> [abt]
|
||||||
|
Term.Char {} -> [abt]
|
||||||
|
Term.Blank {} -> [abt]
|
||||||
|
Term.Ref {} -> [abt]
|
||||||
|
Term.Constructor {} -> [abt]
|
||||||
|
Term.Request {} -> [abt]
|
||||||
|
-- Not 100% sure whether the error should appear on the handler or action, maybe both?
|
||||||
|
Term.Handle handler _action -> expressionLeafNodes handler
|
||||||
|
Term.App _a _b -> [abt]
|
||||||
|
Term.Ann a _ -> expressionLeafNodes a
|
||||||
|
Term.List {} -> [abt]
|
||||||
|
Term.If _cond a b -> expressionLeafNodes a <> expressionLeafNodes b
|
||||||
|
Term.And {} -> [abt]
|
||||||
|
Term.Or {} -> [abt]
|
||||||
|
Term.Lam a -> expressionLeafNodes a
|
||||||
|
Term.LetRec _isTop _bindings body -> expressionLeafNodes body
|
||||||
|
Term.Let _isTop _bindings body -> expressionLeafNodes body
|
||||||
|
Term.Match _a cases -> cases & foldMap \(Term.MatchCase {matchBody}) -> expressionLeafNodes matchBody
|
||||||
|
Term.TermLink {} -> [abt]
|
||||||
|
Term.TypeLink {} -> [abt]
|
||||||
|
@ -72,21 +72,21 @@ data F typeVar typeAnn patternAnn a
|
|||||||
| Ref Reference
|
| Ref Reference
|
||||||
| Constructor ConstructorReference
|
| Constructor ConstructorReference
|
||||||
| Request ConstructorReference
|
| Request ConstructorReference
|
||||||
| Handle a a
|
| Handle a {- <- the handler -} a {- <- the action to run -}
|
||||||
| App a a
|
| App a {- <- func -} a {- <- arg -}
|
||||||
| Ann a (Type typeVar typeAnn)
|
| Ann a (Type typeVar typeAnn)
|
||||||
| List (Seq a)
|
| List (Seq a)
|
||||||
| If a a a
|
| If a {- <- cond -} a {- <- then -} a {- <- else -}
|
||||||
| And a a
|
| And a a
|
||||||
| Or a a
|
| Or a a
|
||||||
| Lam a
|
| Lam a
|
||||||
| -- Note: let rec blocks have an outer ABT.Cycle which introduces as many
|
| -- Note: let rec blocks have an outer ABT.Cycle which introduces as many
|
||||||
-- variables as there are bindings
|
-- variables as there are bindings
|
||||||
LetRec IsTop [a] a
|
LetRec IsTop [a {- <- bindings -}] a {- <- body -}
|
||||||
| -- Note: first parameter is the binding, second is the expression which may refer
|
-- Note: first parameter is the binding, second is the expression which may refer
|
||||||
-- to this let bound variable. Constructed as `Let b (abs v e)`
|
| -- to this let bound variable. Constructed as `Let b (abs v e)`
|
||||||
Let IsTop a a
|
Let IsTop a {- <- binding -} a {- <- body -}
|
||||||
| -- Pattern matching / eliminating data types, example:
|
-- Pattern matching / eliminating data types, example:
|
||||||
-- case x of
|
-- case x of
|
||||||
-- Just n -> rhs1
|
-- Just n -> rhs1
|
||||||
-- Nothing -> rhs2
|
-- Nothing -> rhs2
|
||||||
@ -94,7 +94,7 @@ data F typeVar typeAnn patternAnn a
|
|||||||
-- translates to
|
-- translates to
|
||||||
--
|
--
|
||||||
-- Match x
|
-- Match x
|
||||||
-- [ (Constructor 0 [Var], ABT.abs n rhs1)
|
| -- [ (Constructor 0 [Var], ABT.abs n rhs1)
|
||||||
-- , (Constructor 1 [], rhs2) ]
|
-- , (Constructor 1 [], rhs2) ]
|
||||||
Match a [MatchCase patternAnn a]
|
Match a [MatchCase patternAnn a]
|
||||||
| TermLink Referent
|
| TermLink Referent
|
||||||
|
Loading…
Reference in New Issue
Block a user