Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow instances for synonyms #3539

Merged
merged 7 commits into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/Language/PureScript/Errors.hs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ data SimpleErrorMessage
| ExprDoesNotHaveType Expr SourceType
| PropertyIsMissing Label
| AdditionalProperty Label
| TypeSynonymInstance
| OrphanInstance Ident (Qualified (ProperName 'ClassName)) (S.Set ModuleName) [SourceType]
| InvalidNewtype (ProperName 'TypeName)
| InvalidInstanceHead SourceType
Expand Down Expand Up @@ -294,7 +293,6 @@ errorCode em = case unwrapErrorMessage em of
ExprDoesNotHaveType{} -> "ExprDoesNotHaveType"
PropertyIsMissing{} -> "PropertyIsMissing"
AdditionalProperty{} -> "AdditionalProperty"
TypeSynonymInstance -> "TypeSynonymInstance"
OrphanInstance{} -> "OrphanInstance"
InvalidNewtype{} -> "InvalidNewtype"
InvalidInstanceHead{} -> "InvalidInstanceHead"
Expand Down Expand Up @@ -1012,8 +1010,6 @@ prettyPrintSingleError (PPEOptions codeColor full level showDocs relPath) e = fl
line $ "Type of expression lacks required label " <> markCode (prettyPrintLabel prop) <> "."
renderSimpleErrorMessage (AdditionalProperty prop) =
line $ "Type of expression contains additional label " <> markCode (prettyPrintLabel prop) <> "."
renderSimpleErrorMessage TypeSynonymInstance =
line "Type class instances for type synonyms are disallowed."
renderSimpleErrorMessage (OrphanInstance nm cnm nonOrphanModules ts) =
paras [ line $ "Orphan instance " <> markCode (showIdent nm) <> " found for "
, markCodeBox $ indent $ Box.hsep 1 Box.left
Expand Down
16 changes: 7 additions & 9 deletions src/Language/PureScript/TypeChecker.hs
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,7 @@ checkTypeClassInstance cls i = check where
check = \case
TypeVar _ _ -> return ()
TypeLevelString _ _ -> return ()
TypeConstructor _ ctor -> do
env <- getEnv
when (ctor `M.member` typeSynonyms env) . throwError . errorMessage $ TypeSynonymInstance
return ()
TypeConstructor _ _ -> return ()
TypeApp _ t1 t2 -> check t1 >> check t2
KindApp _ t k -> check t >> check k
KindedType _ t _ -> check t
Expand Down Expand Up @@ -408,14 +405,15 @@ typeCheckAll moduleName _ = traverse go
Just typeClass -> do
checkInstanceArity dictName className typeClass tys
(deps', kinds', tys', vars) <- withFreshSubstitution $ checkInstanceDeclaration moduleName (sa, deps, className, tys)
sequence_ (zipWith (checkTypeClassInstance typeClass) [0..] tys')
let nonOrphanModules = findNonOrphanModules className typeClass tys'
checkOrphanInstance dictName className tys' nonOrphanModules
tys'' <- traverse replaceAllTypeSynonyms tys'
sequence_ (zipWith (checkTypeClassInstance typeClass) [0..] tys'')
let nonOrphanModules = findNonOrphanModules className typeClass tys''
checkOrphanInstance dictName className tys'' nonOrphanModules
let qualifiedChain = Qualified (Just moduleName) <$> ch
checkOverlappingInstance qualifiedChain dictName className typeClass tys' nonOrphanModules
checkOverlappingInstance qualifiedChain dictName className typeClass tys'' nonOrphanModules
_ <- traverseTypeInstanceBody checkInstanceMembers body
deps'' <- (traverse . overConstraintArgs . traverse) replaceAllTypeSynonyms deps'
let dict = TypeClassDictionaryInScope qualifiedChain idx qualifiedDictName [] className vars kinds' tys' (Just deps'')
let dict = TypeClassDictionaryInScope qualifiedChain idx qualifiedDictName [] className vars kinds' tys'' (Just deps'')
addTypeClassDictionaries (Just moduleName) . M.singleton className $ M.singleton (tcdValue dict) (pure dict)
return d

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Error found:
at tests/purs/failing/TypeSynonyms6.purs:4:1 - 4:11 (line 4, column 1 - line 4, column 11)
at tests/purs/failing/TypeSynonymCycle.purs:4:1 - 4:11 (line 4, column 1 - line 4, column 11)

A cycle appears in a set of type synonym definitions:

Expand Down
14 changes: 0 additions & 14 deletions tests/purs/failing/TypeSynonyms2.out

This file was deleted.

12 changes: 0 additions & 12 deletions tests/purs/failing/TypeSynonyms2.purs

This file was deleted.

14 changes: 0 additions & 14 deletions tests/purs/failing/TypeSynonyms3.out

This file was deleted.

12 changes: 0 additions & 12 deletions tests/purs/failing/TypeSynonyms3.purs

This file was deleted.

20 changes: 20 additions & 0 deletions tests/purs/failing/TypeSynonyms7.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Error found:
in module Main
at tests/purs/failing/TypeSynonyms7.purs:8:1 - 9:14 (line 8, column 1 - line 9, column 14)

Type class instance head is invalid due to use of type
 
 ( x :: Int
 | r 
 ) 
 
All types appearing in instance declarations must be of the form T a_1 .. a_n, where each type a_i is of the same form, unless the type is fully determined by other type class arguments via functional dependencies.

in type class instance
 
 Data.Show.Show (X r)
 

See https://github.com/purescript/documentation/blob/master/errors/InvalidInstanceHead.md for more information,
or to contribute content related to this error.

9 changes: 9 additions & 0 deletions tests/purs/failing/TypeSynonyms7.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- @shouldFailWith InvalidInstanceHead
module Main where

import Prelude

type X r = {x :: Int | r}

instance showX :: Show (X r) where
show _ = ""
24 changes: 24 additions & 0 deletions tests/purs/failing/TypeSynonymsOverlappingInstance.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Error found:
in module Main
at tests/purs/failing/TypeSynonymsOverlappingInstance.purs:14:1 - 15:16 (line 14, column 1 - line 15, column 16)

Overlapping type class instances found for
 
 Main.Convert String
 String
 
The following instances were found:

Main.convertSB
Main.convertSS


in type class instance
 
 Main.Convert String
 String
 

See https://github.com/purescript/documentation/blob/master/errors/OverlappingInstances.md for more information,
or to contribute content related to this error.

15 changes: 15 additions & 0 deletions tests/purs/failing/TypeSynonymsOverlappingInstance.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- @shouldFailWith OverlappingInstances
module Main where

import Prelude

class Convert a b | a -> b where
convert :: a -> b

type Bar = String

instance convertSB :: Convert String Bar where
convert s = s

instance convertSS :: Convert String String where
convert s = s
16 changes: 16 additions & 0 deletions tests/purs/passing/TypeSynonymInstance.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Main where

import Prelude

import Effect.Console (log)

class Convert a b | a -> b where
convert :: a -> b

type Words = String

instance convertSB :: Convert Int Words where
convert 0 = "Nope"
convert _ = "Done"

main = log $ convert 1