Skip to content

Commit 87cf3ea

Browse files
committed
Slightly better constraint solving error messages with locations
1 parent c439b4d commit 87cf3ea

File tree

1 file changed

+48
-30
lines changed

1 file changed

+48
-30
lines changed

src/Hell.hs

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,11 @@ data TypeCheckError
535535
| LambdaIsNotAFunBug
536536
| InferredCheckedDisagreeBug
537537
| LambdaMustBeStarBug
538+
| ConstraintResolutionProblem HSE.SrcSpanInfo Forall String
538539
deriving (Show)
539540

541+
instance Show Forall where show = showR
542+
540543
typed :: (Type.Typeable a) => a -> Typed (Term g)
541544
typed l = Typed (Type.typeOf l) (Lit l)
542545

@@ -586,7 +589,7 @@ tc (UApp _ _ e1 e2) env =
586589
_ -> Left TypeCheckMismatch
587590
Right {} -> Left TypeOfApplicandIsNotFunction
588591
-- Polytyped terms, must be, syntactically, fully-saturated
589-
tc (UForall _ _ _ _ fall _ _ reps0) _env = go reps0 fall
592+
tc (UForall _ forallLoc _ _ fall _ _ reps0) _env = go reps0 fall
590593
where
591594
go :: [SomeTypeRep] -> Forall -> Either TypeCheckError (Typed (Term g))
592595
go [] (Final typed') = pure typed'
@@ -597,7 +600,7 @@ tc (UForall _ _ _ _ fall _ _ reps0) _env = go reps0 fall
597600
| Just Type.HRefl <- Type.eqTypeRep (typeRepKind rep) (typeRep @Symbol) = go reps (f rep)
598601
go (SomeTypeRep rep : reps) (StreamTypeOf f)
599602
| Just Type.HRefl <- Type.eqTypeRep (typeRepKind rep) (typeRep @StreamType) = go reps (f rep)
600-
go (StarTypeRep rep : reps) (OrdEqShow f) =
603+
go (StarTypeRep rep : reps) fa@(OrdEqShow f) =
601604
if
602605
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @Int) -> go reps (f rep)
603606
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @Double) -> go reps (f rep)
@@ -606,8 +609,9 @@ tc (UForall _ _ _ _ fall _ _ reps0) _env = go reps0 fall
606609
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @Text) -> go reps (f rep)
607610
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @ByteString) -> go reps (f rep)
608611
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @ExitCode) -> go reps (f rep)
609-
| otherwise -> error $ "[OrdEqShow] type doesn't have enough instances " ++ show rep
610-
go (SomeTypeRep rep : reps) (Monadic f) =
612+
| otherwise -> problem fa $ "type doesn't have enough instances " ++ show rep
613+
614+
go (SomeTypeRep rep : reps) fa@(Monadic f) =
611615
if
612616
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @IO) -> go reps (f rep)
613617
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @Maybe) -> go reps (f rep)
@@ -616,8 +620,8 @@ tc (UForall _ _ _ _ fall _ _ reps0) _env = go reps0 fall
616620
| Type.App either' _ <- rep,
617621
Just Type.HRefl <- Type.eqTypeRep either' (typeRep @Either) ->
618622
go reps (f rep)
619-
| otherwise -> error $ "[Monad] type doesn't have enough instances " ++ show rep
620-
go (SomeTypeRep rep : reps) (Applicable f) =
623+
| otherwise -> problem fa $ "type doesn't have enough instances " ++ show rep
624+
go (SomeTypeRep rep : reps) fa@(Applicable f) =
621625
if
622626
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @IO) -> go reps (f rep)
623627
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @Options.Parser) -> go reps (f rep)
@@ -627,8 +631,8 @@ tc (UForall _ _ _ _ fall _ _ reps0) _env = go reps0 fall
627631
| Type.App either' _ <- rep,
628632
Just Type.HRefl <- Type.eqTypeRep either' (typeRep @Either) ->
629633
go reps (f rep)
630-
| otherwise -> error $ "[Applicative] type doesn't have enough instances " ++ show rep
631-
go (SomeTypeRep rep : reps) (Monoidal f) =
634+
| otherwise -> problem fa $ "type doesn't have enough instances " ++ show rep
635+
go (SomeTypeRep rep : reps) fa@(Monoidal f) =
632636
if
633637
| Type.App either' _ <- rep,
634638
Just Type.HRefl <- Type.eqTypeRep either' (typeRep @Vector) ->
@@ -640,34 +644,38 @@ tc (UForall _ _ _ _ fall _ _ reps0) _env = go reps0 fall
640644
Just Type.HRefl <- Type.eqTypeRep either' (typeRep @[]) ->
641645
go reps (f rep)
642646
| Just Type.HRefl <- Type.eqTypeRep rep (typeRep @Text) -> go reps (f rep)
643-
| otherwise -> error $ "[Monoid] type doesn't have enough instances " ++ show rep
644-
go reps (GetOf k0 a0 t0 r0 f) =
647+
| otherwise -> problem fa $ "type doesn't have enough instances " ++ show rep
648+
go reps fa@(GetOf k0 a0 t0 r0 f) =
645649
case makeAccessor k0 r0 a0 t0 of
646650
Just accessor -> go reps (f accessor)
647-
Nothing -> error $ "missing field for field access"
648-
go reps (SetOf k0 a0 t0 r0 f) =
651+
Nothing -> problem fa $ "missing field for field access"
652+
go reps fa@(SetOf k0 a0 t0 r0 f) =
649653
case makeSetter k0 r0 a0 t0 of
650654
Just accessor -> go reps (f accessor)
651-
Nothing -> error $ "missing field for field set"
652-
go reps (ModifyOf k0 a0 t0 r0 f) =
655+
Nothing -> problem fa $ "missing field for field set"
656+
go reps fa@(ModifyOf k0 a0 t0 r0 f) =
653657
case makeModify k0 r0 a0 t0 of
654658
Just accessor -> go reps (f accessor)
655-
Nothing -> error $ "missing field for field modify"
656-
go tys r = error $ "forall type arguments mismatch: " ++ show tys ++ " for " ++ showR r
657-
where
658-
showR = \case
659-
NoClass {} -> "NoClass"
660-
SymbolOf {} -> "SymbolOf"
661-
StreamTypeOf {} -> "StreamTypeOf"
662-
ListOf {} -> "ListOf"
663-
OrdEqShow {} -> "OrdEqShow"
664-
Monadic {} -> "Monadic"
665-
Applicable {} -> "Applicable"
666-
Monoidal {} -> "Monoidal"
667-
GetOf {} -> "GetOf"
668-
SetOf {} -> "SetOf"
669-
ModifyOf {} -> "ModifyOf"
670-
Final {} -> "Final"
659+
Nothing -> problem fa $ "missing field for field modify"
660+
go tys r = problem r $ "forall type arguments mismatch: " ++ show tys ++ " for " ++ showR r
661+
662+
problem :: Forall -> String -> Either TypeCheckError a
663+
problem fa = Left . ConstraintResolutionProblem forallLoc fa
664+
665+
showR :: Forall -> String
666+
showR = \case
667+
NoClass {} -> "forall a."
668+
SymbolOf {} -> "forall s. s :: Symbol"
669+
StreamTypeOf {} -> "forall s. s :: StreamType"
670+
ListOf {} -> "forall l. l :: List"
671+
OrdEqShow {} -> "forall a. (Ord a, Eq a, Show a)"
672+
Monadic {} -> "forall a. Monad a"
673+
Applicable {} -> "forall a. Applicable a"
674+
Monoidal {} -> "forall a. Monoid a"
675+
GetOf {} -> "<record getter>"
676+
SetOf {} -> "<record setter>"
677+
ModifyOf {} -> "<record modifier>"
678+
Final {} -> "<final>"
671679

672680
-- Make a well-typed literal - e.g. @lit Text.length@ - which can be
673681
-- embedded in the untyped AST.
@@ -2334,6 +2342,16 @@ instance Pretty TypeCheckError where
23342342
LambdaIsNotAFunBug -> "BUG: LambdaIsNotAFunBug. Please report."
23352343
InferredCheckedDisagreeBug -> "BUG: Inferred type disagrees with checked type. Please report."
23362344
LambdaMustBeStarBug -> "BUG: Lambda should be of kind *, but isn't. Please report."
2345+
ConstraintResolutionProblem loc forall' msg ->
2346+
mconcat $
2347+
List.intersperse
2348+
"\n\n"
2349+
[ "Couldn't resolve constraint",
2350+
" " <> pretty (showR forall'),
2351+
"due to problem",
2352+
" " <> pretty msg,
2353+
"arising from " <> pretty loc
2354+
]
23372355

23382356
instance Pretty DesugarError where
23392357
pretty = \case

0 commit comments

Comments
 (0)