Skip to content

Commit

Permalink
Improve record pattern handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
athas committed Apr 10, 2018
1 parent a04da13 commit e2d9629
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/Language/Futhark/TypeChecker/Terms.hs
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,15 @@ checkPattern' (RecordPattern p_fs loc) (Ascribed (Record t_fs))
RecordPattern . M.toList <$> check <*> pure loc
where check = traverse (uncurry checkPattern') $ M.intersectionWith (,)
(M.fromList p_fs) (fmap Ascribed t_fs)
checkPattern' p@RecordPattern{} (Ascribed t) =
typeError (srclocOf p) $ "Pattern " ++ pretty p ++ " cannot match " ++ pretty t
checkPattern' p@(RecordPattern fields loc) (Ascribed t) = do
fields' <- traverse (const $ newTypeVar loc "t") $ M.fromList fields

when (sort (M.keys fields') /= sort (map fst fields)) $
typeError loc $ "Duplicate fields in record pattern " ++ pretty p

unify loc (Record fields') $ toStructural t
t' <- normaliseType t
checkPattern' p $ Ascribed t'
checkPattern' (RecordPattern fs loc) NoneInferred =
RecordPattern . M.toList <$> traverse (`checkPattern'` NoneInferred) (M.fromList fs) <*> pure loc

Expand Down
7 changes: 7 additions & 0 deletions tests/records-error6.fut
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- It is not OK to match the same field twice.
-- ==
-- error: Duplicate fields

let main(x: i32) =
let {x=a, x=b} = {x}
in a+b
5 changes: 5 additions & 0 deletions tests/types/inference26.fut
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Record inference via let binding.

let main x =
let {a,b} = x
in a + 1 + b

0 comments on commit e2d9629

Please sign in to comment.