Skip to content

Commit 6c8cfc8

Browse files
authored
Add locations to equality constraints (#43)
1 parent 65bc6a7 commit 6c8cfc8

File tree

1 file changed

+29
-23
lines changed

1 file changed

+29
-23
lines changed

src/Hell.hs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,14 +1350,14 @@ data Elaborate = Elaborate {
13501350
equalities :: Set (Equality (IRep IMetaVar))
13511351
}
13521352

1353-
data Equality a = Equality a a
1353+
data Equality a = Equality HSE.SrcSpanInfo a a
13541354
deriving (Show, Functor)
13551355

13561356
-- Equality/ordering that is symmetric.
13571357
instance (Ord a) => Eq (Equality a) where
1358-
Equality a b == Equality c d = Set.fromList [a,b] == Set.fromList [c,d]
1358+
Equality _ a b == Equality _ c d = Set.fromList [a,b] == Set.fromList [c,d]
13591359
instance (Ord a) => Ord (Equality a) where
1360-
Equality a b `compare` Equality c d = Set.fromList [a,b] `compare` Set.fromList [c,d]
1360+
Equality _ a b `compare` Equality _ c d = Set.fromList [a,b] `compare` Set.fromList [c,d]
13611361

13621362
data ElaborateError = UnsupportedTupleSize | BadInstantiationBug | VariableNotInScope String
13631363
deriving (Show)
@@ -1385,13 +1385,13 @@ elaborate = fmap getEqualities . flip runStateT empty . flip runReaderT mempty .
13851385
f' <- go f
13861386
x' <- go x
13871387
b <- fmap IVar freshIMetaVar
1388-
equal (typeOf f') (IFun (typeOf x') b)
1388+
equal l (typeOf f') (IFun (typeOf x') b)
13891389
pure $ UApp l b f' x'
13901390
ULam l () binding mstarType body -> do
13911391
a <- case mstarType of
13921392
Just ty -> pure $ fromSomeStarType ty
13931393
Nothing -> fmap IVar freshIMetaVar
1394-
vars <- lift $ bindingVars a binding
1394+
vars <- lift $ bindingVars l a binding
13951395
body' <- local (Map.union vars) $ go body
13961396
let ty = IFun a (typeOf body')
13971397
pure $ ULam l ty binding mstarType body'
@@ -1407,18 +1407,18 @@ elaborate = fmap getEqualities . flip runStateT empty . flip runReaderT mempty .
14071407
Just var -> pure var
14081408
-- Order of types is position-dependent, apply the ones we have.
14091409
for_ (zip vars types) \((_uniq, var), someTypeRep) ->
1410-
equal (fromSomeType someTypeRep) (IVar var)
1410+
equal l (fromSomeType someTypeRep) (IVar var)
14111411
-- Done!
14121412
pure $ UForall l monoType types forall' uniqs polyRep (map (IVar . snd) vars)
14131413

1414-
bindingVars :: IRep IMetaVar -> Binding -> StateT Elaborate (Either ElaborateError) (Map String (IRep IMetaVar))
1415-
bindingVars irep (Singleton name) = pure $ Map.singleton name irep
1416-
bindingVars tupleVar (Tuple names) = do
1414+
bindingVars :: HSE.SrcSpanInfo -> IRep IMetaVar -> Binding -> StateT Elaborate (Either ElaborateError) (Map String (IRep IMetaVar))
1415+
bindingVars _ irep (Singleton name) = pure $ Map.singleton name irep
1416+
bindingVars l tupleVar (Tuple names) = do
14171417
varsTypes <- for names \name -> fmap (name, ) (fmap IVar freshIMetaVar)
14181418
-- it's a left-fold:
14191419
-- IApp (IApp (ICon (,)) x) y
14201420
cons <- makeCons
1421-
equal tupleVar $ foldl IApp (ICon cons) (map snd varsTypes)
1421+
equal l tupleVar $ foldl IApp (ICon cons) (map snd varsTypes)
14221422
pure $ Map.fromList varsTypes
14231423

14241424
where makeCons = case length names of
@@ -1427,8 +1427,8 @@ bindingVars tupleVar (Tuple names) = do
14271427
4 -> pure $ SomeTypeRep (typeRep @(,,,))
14281428
_ -> lift $ Left $ UnsupportedTupleSize
14291429

1430-
equal :: MonadState Elaborate m => IRep IMetaVar -> IRep IMetaVar -> m ()
1431-
equal x y = modify \elaborate' -> elaborate' { equalities = equalities elaborate' <> Set.singleton (Equality x y) }
1430+
equal :: MonadState Elaborate m => HSE.SrcSpanInfo -> IRep IMetaVar -> IRep IMetaVar -> m ()
1431+
equal l x y = modify \elaborate' -> elaborate' { equalities = equalities elaborate' <> Set.singleton (Equality l x y) }
14321432

14331433
freshIMetaVar :: MonadState Elaborate m => m IMetaVar
14341434
freshIMetaVar = do
@@ -1441,8 +1441,7 @@ freshIMetaVar = do
14411441

14421442
data UnifyError =
14431443
OccursCheck
1444-
| TypeConMismatch SomeTypeRep SomeTypeRep
1445-
| TypeMismatch (IRep IMetaVar) (IRep IMetaVar)
1444+
| TypeMismatch HSE.SrcSpanInfo (IRep IMetaVar) (IRep IMetaVar)
14461445
deriving (Show)
14471446

14481447
-- | Unification of equality constraints, a ~ b, to substitutions.
@@ -1451,20 +1450,20 @@ unify = foldM update mempty where
14511450
update existing equality =
14521451
fmap (`extends` existing)
14531452
(examine (fmap (substitute existing) equality))
1454-
examine (Equality a b)
1453+
examine (Equality l a b)
14551454
| a == b = pure mempty
14561455
| IVar ivar <- a = bindMetaVar ivar b
14571456
| IVar ivar <- b = bindMetaVar ivar a
14581457
| IFun a1 b1 <- a,
14591458
IFun a2 b2 <- b =
1460-
unify (Set.fromList [Equality a1 a2, Equality b1 b2])
1459+
unify (Set.fromList [Equality l a1 a2, Equality l b1 b2])
14611460
| IApp a1 b1 <- a,
14621461
IApp a2 b2 <- b =
1463-
unify (Set.fromList [Equality a1 a2, Equality b1 b2])
1462+
unify (Set.fromList [Equality l a1 a2, Equality l b1 b2])
14641463
| ICon x <- a, ICon y <- b =
14651464
if x == y then pure mempty
1466-
else Left $ TypeConMismatch x y
1467-
| otherwise = Left $ TypeMismatch a b
1465+
else Left $ TypeMismatch l a b
1466+
| otherwise = Left $ TypeMismatch l a b
14681467

14691468
-- | Apply new substitutions to the old ones, and expand the set to old+new.
14701469
extends :: Map IMetaVar (IRep IMetaVar) -> Map IMetaVar (IRep IMetaVar) -> Map IMetaVar (IRep IMetaVar)
@@ -1509,7 +1508,7 @@ zonk = \case
15091508
parseFile :: String -> IO (Either String [(String, HSE.Exp HSE.SrcSpanInfo)])
15101509
parseFile filePath = do
15111510
string <- ByteString.readFile filePath
1512-
pure $ case HSE.parseModuleWithMode HSE.defaultParseMode { HSE.extensions = HSE.extensions HSE.defaultParseMode ++ [HSE.EnableExtension HSE.PatternSignatures, HSE.EnableExtension HSE.DataKinds, HSE.EnableExtension HSE.BlockArguments, HSE.EnableExtension HSE.TypeApplications] } (Text.unpack (dropShebang (Text.decodeUtf8 string))) >>= parseModule of
1511+
pure $ case HSE.parseModuleWithMode HSE.defaultParseMode { HSE.parseFilename = filePath, HSE.extensions = HSE.extensions HSE.defaultParseMode ++ [HSE.EnableExtension HSE.PatternSignatures, HSE.EnableExtension HSE.DataKinds, HSE.EnableExtension HSE.BlockArguments, HSE.EnableExtension HSE.TypeApplications] } (Text.unpack (dropShebang (Text.decodeUtf8 string))) >>= parseModule of
15131512
HSE.ParseFailed l e -> Left $ "Parse error: " <> HSE.prettyPrint l <> ": " <> e
15141513
HSE.ParseOk binds -> Right binds
15151514

@@ -1646,14 +1645,21 @@ instance Pretty ElaborateError where
16461645
instance Pretty UnifyError where
16471646
pretty = \case
16481647
OccursCheck -> "Occurs check failed: Infinite type."
1649-
TypeMismatch a b ->
1648+
TypeMismatch l a b ->
16501649
mconcat $ List.intersperse "\n\n" [
16511650
"Couldn't match type",
16521651
" " <> pretty a,
16531652
"against type",
16541653
" " <> pretty b,
1655-
""]
1656-
TypeConMismatch a b -> "Couldn't match type constructor " <> pretty a <> " against type constructor " <> pretty b
1654+
"arising from " <> pretty l
1655+
]
1656+
1657+
instance Pretty HSE.SrcSpanInfo where
1658+
pretty l =
1659+
mconcat [pretty (HSE.fileName l),":",
1660+
pretty $ show $ HSE.startLine l,
1661+
":",
1662+
pretty $ show $ HSE.startColumn l]
16571663

16581664
instance Pretty TypeCheckError where
16591665
pretty = \case

0 commit comments

Comments
 (0)