summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorgaryb <>2018-05-21 23:08:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2018-05-21 23:08:00 (GMT)
commit25a279f1e1a547125036fd4b81f0549bf37f5339 (patch)
tree275459e96260851ddd35286594daebedf769bfb1 /tests
parentb725646839c21c8b8d698c862b6f3b7e88acaa8e (diff)
version 0.12.00.12.0
Diffstat (limited to 'tests')
-rw-r--r--tests/Language/PureScript/Ide/ImportsSpec.hs18
-rw-r--r--tests/Language/PureScript/Ide/StateSpec.hs4
-rw-r--r--tests/Language/PureScript/Ide/Test.hs10
-rw-r--r--tests/Language/PureScript/Ide/UsageSpec.hs82
-rw-r--r--tests/Main.hs33
-rw-r--r--tests/TestCompiler.hs33
-rw-r--r--tests/TestCoreFn.hs247
-rw-r--r--tests/TestDocs.hs132
-rw-r--r--tests/TestHierarchy.hs10
-rw-r--r--tests/TestIde.hs19
-rw-r--r--tests/TestPrimDocs.hs19
-rw-r--r--tests/TestPscIde.hs13
-rw-r--r--tests/TestPscPublish.hs2
-rw-r--r--tests/TestPsci.hs8
-rw-r--r--tests/TestPsci/CommandTest.hs10
-rw-r--r--tests/TestPsci/CompletionTest.hs109
-rw-r--r--tests/TestPsci/EvalTest.hs2
-rw-r--r--tests/TestPsci/TestEnv.hs13
-rw-r--r--tests/purs/docs/bower.json21
-rw-r--r--tests/purs/docs/bower_components/purescript-prelude/src/Prelude.purs8
-rw-r--r--tests/purs/docs/output/ConstrainedArgument/externs.json1
-rw-r--r--tests/purs/docs/output/ConstrainedArgument/index.js5
-rw-r--r--tests/purs/docs/resolutions.json21
-rw-r--r--tests/purs/docs/src/ChildDeclOrder.purs27
-rw-r--r--tests/purs/docs/src/Clash.purs4
-rw-r--r--tests/purs/docs/src/Clash1.purs3
-rw-r--r--tests/purs/docs/src/Clash1a.purs9
-rw-r--r--tests/purs/docs/src/Clash2.purs3
-rw-r--r--tests/purs/docs/src/Clash2a.purs9
-rw-r--r--tests/purs/docs/src/ConstrainedArgument.purs8
-rw-r--r--tests/purs/docs/src/DeclOrder.purs17
-rw-r--r--tests/purs/docs/src/DeclOrderNoExportList.purs10
-rw-r--r--tests/purs/docs/src/Desugar.purs8
-rw-r--r--tests/purs/docs/src/DocComments.purs11
-rw-r--r--tests/purs/docs/src/DuplicateNames.purs9
-rw-r--r--tests/purs/docs/src/Example.purs7
-rw-r--r--tests/purs/docs/src/Example2.purs7
-rw-r--r--tests/purs/docs/src/ExplicitExport.purs7
-rw-r--r--tests/purs/docs/src/ExplicitTypeSignatures.purs16
-rw-r--r--tests/purs/docs/src/ImportedTwice.purs13
-rw-r--r--tests/purs/docs/src/ImportedTwiceA.purs8
-rw-r--r--tests/purs/docs/src/ImportedTwiceB.purs4
-rw-r--r--tests/purs/docs/src/MultiVirtual.purs6
-rw-r--r--tests/purs/docs/src/MultiVirtual1.purs4
-rw-r--r--tests/purs/docs/src/MultiVirtual2.purs9
-rw-r--r--tests/purs/docs/src/MultiVirtual3.purs4
-rw-r--r--tests/purs/docs/src/NewOperators.purs5
-rw-r--r--tests/purs/docs/src/NewOperators2.purs6
-rw-r--r--tests/purs/docs/src/NotAllCtors.purs5
-rw-r--r--tests/purs/docs/src/PrimSubmodules.purs11
-rw-r--r--tests/purs/docs/src/ReExportedTypeClass.purs5
-rw-r--r--tests/purs/docs/src/SolitaryTypeClassMember.purs6
-rw-r--r--tests/purs/docs/src/SomeTypeClass.purs5
-rw-r--r--tests/purs/docs/src/Transitive1.purs5
-rw-r--r--tests/purs/docs/src/Transitive2.purs5
-rw-r--r--tests/purs/docs/src/Transitive3.purs4
-rw-r--r--tests/purs/docs/src/TypeClassWithFunDeps.purs5
-rw-r--r--tests/purs/docs/src/TypeClassWithoutMembers.purs5
-rw-r--r--tests/purs/docs/src/TypeClassWithoutMembersIntermediate.purs5
-rw-r--r--tests/purs/docs/src/TypeLevelString.purs9
-rw-r--r--tests/purs/docs/src/TypeOpAliases.purs44
-rw-r--r--tests/purs/docs/src/UTF8.purs7
-rw-r--r--tests/purs/docs/src/Virtual.purs5
-rw-r--r--tests/purs/failing/1071.purs8
-rw-r--r--tests/purs/failing/1169.purs12
-rw-r--r--tests/purs/failing/1175.purs11
-rw-r--r--tests/purs/failing/1310.purs18
-rw-r--r--tests/purs/failing/1570.purs6
-rw-r--r--tests/purs/failing/1733.purs6
-rw-r--r--tests/purs/failing/1733/Thingy.purs4
-rw-r--r--tests/purs/failing/1825.purs9
-rw-r--r--tests/purs/failing/1881.purs6
-rw-r--r--tests/purs/failing/2128-class.purs5
-rw-r--r--tests/purs/failing/2128-instance.purs8
-rw-r--r--tests/purs/failing/2197-shouldFail.purs10
-rw-r--r--tests/purs/failing/2197-shouldFail2.purs7
-rw-r--r--tests/purs/failing/2378.purs6
-rw-r--r--tests/purs/failing/2378/Lib.purs3
-rw-r--r--tests/purs/failing/2379.purs6
-rw-r--r--tests/purs/failing/2379/Lib.purs9
-rw-r--r--tests/purs/failing/2434.purs5
-rw-r--r--tests/purs/failing/2534.purs8
-rw-r--r--tests/purs/failing/2542.purs9
-rw-r--r--tests/purs/failing/2567.purs7
-rw-r--r--tests/purs/failing/2601.purs7
-rw-r--r--tests/purs/failing/2616.purs9
-rw-r--r--tests/purs/failing/2806.purs7
-rw-r--r--tests/purs/failing/2874-forall.purs8
-rw-r--r--tests/purs/failing/2874-forall2.purs10
-rw-r--r--tests/purs/failing/2874-wildcard.purs11
-rw-r--r--tests/purs/failing/2947.purs10
-rw-r--r--tests/purs/failing/3132.purs18
-rw-r--r--tests/purs/failing/3275-BindingGroupErrorPos.purs12
-rw-r--r--tests/purs/failing/3275-DataBindingGroupErrorPos.purs8
-rw-r--r--tests/purs/failing/3335-TypeOpAssociativityError.purs7
-rw-r--r--tests/purs/failing/365.purs14
-rw-r--r--tests/purs/failing/438.purs15
-rw-r--r--tests/purs/failing/881.purs13
-rw-r--r--tests/purs/failing/AnonArgument1.purs5
-rw-r--r--tests/purs/failing/AnonArgument2.purs7
-rw-r--r--tests/purs/failing/AnonArgument3.purs5
-rw-r--r--tests/purs/failing/ArgLengthMismatch.purs7
-rw-r--r--tests/purs/failing/ArrayType.purs13
-rw-r--r--tests/purs/failing/Arrays.purs6
-rw-r--r--tests/purs/failing/BindInDo-2.purs9
-rw-r--r--tests/purs/failing/BindInDo.purs9
-rw-r--r--tests/purs/failing/CannotDeriveNewtypeForData.purs8
-rw-r--r--tests/purs/failing/CaseBinderLengthsDiffer.purs6
-rw-r--r--tests/purs/failing/CaseDoesNotMatchAllConstructorArgs.purs15
-rw-r--r--tests/purs/failing/ConflictingExports.purs6
-rw-r--r--tests/purs/failing/ConflictingExports/A.purs4
-rw-r--r--tests/purs/failing/ConflictingExports/B.purs4
-rw-r--r--tests/purs/failing/ConflictingImports.purs9
-rw-r--r--tests/purs/failing/ConflictingImports/A.purs4
-rw-r--r--tests/purs/failing/ConflictingImports/B.purs4
-rw-r--r--tests/purs/failing/ConflictingImports2.purs10
-rw-r--r--tests/purs/failing/ConflictingImports2/A.purs4
-rw-r--r--tests/purs/failing/ConflictingImports2/B.purs4
-rw-r--r--tests/purs/failing/ConflictingQualifiedImports.purs7
-rw-r--r--tests/purs/failing/ConflictingQualifiedImports/A.purs4
-rw-r--r--tests/purs/failing/ConflictingQualifiedImports/B.purs4
-rw-r--r--tests/purs/failing/ConflictingQualifiedImports2.purs5
-rw-r--r--tests/purs/failing/ConflictingQualifiedImports2/A.purs4
-rw-r--r--tests/purs/failing/ConflictingQualifiedImports2/B.purs4
-rw-r--r--tests/purs/failing/ConstraintFailure.purs13
-rw-r--r--tests/purs/failing/ConstraintInference.purs10
-rw-r--r--tests/purs/failing/DctorOperatorAliasExport.purs6
-rw-r--r--tests/purs/failing/DeclConflictClassCtor.purs6
-rw-r--r--tests/purs/failing/DeclConflictClassSynonym.purs8
-rw-r--r--tests/purs/failing/DeclConflictClassType.purs6
-rw-r--r--tests/purs/failing/DeclConflictCtorClass.purs6
-rw-r--r--tests/purs/failing/DeclConflictCtorCtor.purs6
-rw-r--r--tests/purs/failing/DeclConflictDuplicateCtor.purs5
-rw-r--r--tests/purs/failing/DeclConflictSynonymClass.purs8
-rw-r--r--tests/purs/failing/DeclConflictSynonymType.purs8
-rw-r--r--tests/purs/failing/DeclConflictTypeClass.purs6
-rw-r--r--tests/purs/failing/DeclConflictTypeSynonym.purs8
-rw-r--r--tests/purs/failing/DeclConflictTypeType.purs6
-rw-r--r--tests/purs/failing/DiffKindsSameName.purs15
-rw-r--r--tests/purs/failing/DiffKindsSameName/LibA.purs4
-rw-r--r--tests/purs/failing/DiffKindsSameName/LibB.purs6
-rw-r--r--tests/purs/failing/Do.purs12
-rw-r--r--tests/purs/failing/DoNotSuggestComposition.purs13
-rw-r--r--tests/purs/failing/DoNotSuggestComposition2.purs7
-rw-r--r--tests/purs/failing/DuplicateDeclarationsInLet.purs12
-rw-r--r--tests/purs/failing/DuplicateInstance.purs6
-rw-r--r--tests/purs/failing/DuplicateModule.purs2
-rw-r--r--tests/purs/failing/DuplicateModule/M1.purs1
-rw-r--r--tests/purs/failing/DuplicateProperties.purs12
-rw-r--r--tests/purs/failing/DuplicateTypeClass.purs4
-rw-r--r--tests/purs/failing/DuplicateTypeVars.purs6
-rw-r--r--tests/purs/failing/EmptyCase.purs4
-rw-r--r--tests/purs/failing/EmptyClass.purs7
-rw-r--r--tests/purs/failing/EmptyDo.purs6
-rw-r--r--tests/purs/failing/ExpectedWildcard.purs8
-rw-r--r--tests/purs/failing/ExportConflictClass.purs5
-rw-r--r--tests/purs/failing/ExportConflictClass/A.purs3
-rw-r--r--tests/purs/failing/ExportConflictClass/B.purs3
-rw-r--r--tests/purs/failing/ExportConflictCtor.purs5
-rw-r--r--tests/purs/failing/ExportConflictCtor/A.purs3
-rw-r--r--tests/purs/failing/ExportConflictCtor/B.purs3
-rw-r--r--tests/purs/failing/ExportConflictType.purs5
-rw-r--r--tests/purs/failing/ExportConflictType/A.purs3
-rw-r--r--tests/purs/failing/ExportConflictType/B.purs3
-rw-r--r--tests/purs/failing/ExportConflictTypeOp.purs5
-rw-r--r--tests/purs/failing/ExportConflictTypeOp/A.purs5
-rw-r--r--tests/purs/failing/ExportConflictTypeOp/B.purs5
-rw-r--r--tests/purs/failing/ExportConflictValue.purs5
-rw-r--r--tests/purs/failing/ExportConflictValue/A.purs4
-rw-r--r--tests/purs/failing/ExportConflictValue/B.purs4
-rw-r--r--tests/purs/failing/ExportConflictValueOp.purs5
-rw-r--r--tests/purs/failing/ExportConflictValueOp/A.purs6
-rw-r--r--tests/purs/failing/ExportConflictValueOp/B.purs6
-rw-r--r--tests/purs/failing/ExportExplicit.purs8
-rw-r--r--tests/purs/failing/ExportExplicit1.purs12
-rw-r--r--tests/purs/failing/ExportExplicit1/M1.purs3
-rw-r--r--tests/purs/failing/ExportExplicit2.purs8
-rw-r--r--tests/purs/failing/ExportExplicit3.purs10
-rw-r--r--tests/purs/failing/ExportExplicit3/M1.purs4
-rw-r--r--tests/purs/failing/ExtraRecordField.purs9
-rw-r--r--tests/purs/failing/ExtraneousClassMember.purs11
-rw-r--r--tests/purs/failing/Foldable.purs17
-rw-r--r--tests/purs/failing/Generalization1.purs11
-rw-r--r--tests/purs/failing/Generalization2.purs8
-rw-r--r--tests/purs/failing/ImportExplicit.purs4
-rw-r--r--tests/purs/failing/ImportExplicit/M1.purs3
-rw-r--r--tests/purs/failing/ImportExplicit2.purs4
-rw-r--r--tests/purs/failing/ImportExplicit2/M1.purs3
-rw-r--r--tests/purs/failing/ImportHidingModule.purs4
-rw-r--r--tests/purs/failing/ImportHidingModule/A.purs2
-rw-r--r--tests/purs/failing/ImportHidingModule/B.purs3
-rw-r--r--tests/purs/failing/ImportModule.purs4
-rw-r--r--tests/purs/failing/ImportModule/M2.purs3
-rw-r--r--tests/purs/failing/InfiniteKind.purs5
-rw-r--r--tests/purs/failing/InfiniteKind2.purs5
-rw-r--r--tests/purs/failing/InfiniteType.purs5
-rw-r--r--tests/purs/failing/InstanceChainBothUnknownAndMatch.purs18
-rw-r--r--tests/purs/failing/InstanceChainSkolemUnknownMatch.purs15
-rw-r--r--tests/purs/failing/InstanceExport.purs7
-rw-r--r--tests/purs/failing/InstanceExport/InstanceExport.purs11
-rw-r--r--tests/purs/failing/InstanceSigsBodyIncorrect.purs10
-rw-r--r--tests/purs/failing/InstanceSigsDifferentTypes.purs10
-rw-r--r--tests/purs/failing/InstanceSigsIncorrectType.purs10
-rw-r--r--tests/purs/failing/InstanceSigsOrphanTypeDeclaration.purs10
-rw-r--r--tests/purs/failing/IntOutOfRange.purs6
-rw-r--r--tests/purs/failing/InvalidDerivedInstance.purs8
-rw-r--r--tests/purs/failing/InvalidDerivedInstance2.purs6
-rw-r--r--tests/purs/failing/InvalidOperatorInBinder.purs12
-rw-r--r--tests/purs/failing/KindError.purs6
-rw-r--r--tests/purs/failing/KindStar.purs8
-rw-r--r--tests/purs/failing/LacksWithSubGoal.purs16
-rw-r--r--tests/purs/failing/LeadingZeros1.purs6
-rw-r--r--tests/purs/failing/LeadingZeros2.purs6
-rw-r--r--tests/purs/failing/Let.purs6
-rw-r--r--tests/purs/failing/LetPatterns1.purs10
-rw-r--r--tests/purs/failing/LetPatterns2.purs14
-rw-r--r--tests/purs/failing/LetPatterns3.purs13
-rw-r--r--tests/purs/failing/LetPatterns4.purs6
-rw-r--r--tests/purs/failing/MPTCs.purs10
-rw-r--r--tests/purs/failing/MissingClassExport.purs7
-rw-r--r--tests/purs/failing/MissingClassMember.purs11
-rw-r--r--tests/purs/failing/MissingClassMemberExport.purs7
-rw-r--r--tests/purs/failing/MissingFFIImplementations.js1
-rw-r--r--tests/purs/failing/MissingFFIImplementations.purs5
-rw-r--r--tests/purs/failing/MissingRecordField.purs10
-rw-r--r--tests/purs/failing/MixedAssociativityError.purs6
-rw-r--r--tests/purs/failing/MultipleErrors.purs13
-rw-r--r--tests/purs/failing/MultipleErrors2.purs9
-rw-r--r--tests/purs/failing/MultipleTypeOpFixities.purs9
-rw-r--r--tests/purs/failing/MultipleValueOpFixities.purs9
-rw-r--r--tests/purs/failing/MutRec.purs9
-rw-r--r--tests/purs/failing/MutRec2.purs6
-rw-r--r--tests/purs/failing/NewtypeInstance.purs8
-rw-r--r--tests/purs/failing/NewtypeInstance2.purs8
-rw-r--r--tests/purs/failing/NewtypeInstance3.purs8
-rw-r--r--tests/purs/failing/NewtypeInstance4.purs8
-rw-r--r--tests/purs/failing/NewtypeInstance5.purs8
-rw-r--r--tests/purs/failing/NewtypeInstance6.purs8
-rw-r--r--tests/purs/failing/NewtypeMultiArgs.purs6
-rw-r--r--tests/purs/failing/NewtypeMultiCtor.purs6
-rw-r--r--tests/purs/failing/NonAssociativeError.purs8
-rw-r--r--tests/purs/failing/NonExhaustivePatGuard.purs5
-rw-r--r--tests/purs/failing/NullaryAbs.purs6
-rw-r--r--tests/purs/failing/Object.purs8
-rw-r--r--tests/purs/failing/OperatorAliasNoExport.purs7
-rw-r--r--tests/purs/failing/OperatorSections.purs7
-rw-r--r--tests/purs/failing/OrphanInstance.purs7
-rw-r--r--tests/purs/failing/OrphanInstance/Class.purs4
-rw-r--r--tests/purs/failing/OrphanInstanceFunDepCycle.purs5
-rw-r--r--tests/purs/failing/OrphanInstanceFunDepCycle/Lib.purs4
-rw-r--r--tests/purs/failing/OrphanInstanceNullary.purs4
-rw-r--r--tests/purs/failing/OrphanInstanceNullary/Lib.purs2
-rw-r--r--tests/purs/failing/OrphanInstanceWithDetermined.purs5
-rw-r--r--tests/purs/failing/OrphanInstanceWithDetermined/Lib.purs5
-rw-r--r--tests/purs/failing/OrphanTypeDecl.purs4
-rw-r--r--tests/purs/failing/OverlapAcrossModules.purs7
-rw-r--r--tests/purs/failing/OverlapAcrossModules/Class.purs2
-rw-r--r--tests/purs/failing/OverlapAcrossModules/X.purs4
-rw-r--r--tests/purs/failing/OverlappingArguments.purs6
-rw-r--r--tests/purs/failing/OverlappingBinders.purs9
-rw-r--r--tests/purs/failing/OverlappingInstances.purs17
-rw-r--r--tests/purs/failing/OverlappingVars.purs14
-rw-r--r--tests/purs/failing/PrimModuleReserved.purs4
-rw-r--r--tests/purs/failing/PrimModuleReserved/Prim.purs1
-rw-r--r--tests/purs/failing/PrimRow.purs13
-rw-r--r--tests/purs/failing/PrimSubModuleReserved.purs4
-rw-r--r--tests/purs/failing/PrimSubModuleReserved/Prim_Foobar.purs1
-rw-r--r--tests/purs/failing/ProgrammableTypeErrors.purs17
-rw-r--r--tests/purs/failing/ProgrammableTypeErrorsTypeString.purs24
-rw-r--r--tests/purs/failing/Rank2Types.purs8
-rw-r--r--tests/purs/failing/RequiredHiddenType.purs9
-rw-r--r--tests/purs/failing/Reserved.purs7
-rw-r--r--tests/purs/failing/RowConstructors1.purs9
-rw-r--r--tests/purs/failing/RowConstructors2.purs9
-rw-r--r--tests/purs/failing/RowConstructors3.purs9
-rw-r--r--tests/purs/failing/RowInInstanceNotDetermined0.purs9
-rw-r--r--tests/purs/failing/RowInInstanceNotDetermined1.purs9
-rw-r--r--tests/purs/failing/RowInInstanceNotDetermined2.purs9
-rw-r--r--tests/purs/failing/RowLacks.purs18
-rw-r--r--tests/purs/failing/SkolemEscape.purs8
-rw-r--r--tests/purs/failing/SkolemEscape2.purs11
-rw-r--r--tests/purs/failing/SuggestComposition.purs7
-rw-r--r--tests/purs/failing/Superclasses1.purs14
-rw-r--r--tests/purs/failing/Superclasses2.purs13
-rw-r--r--tests/purs/failing/Superclasses3.purs8
-rw-r--r--tests/purs/failing/Superclasses5.purs26
-rw-r--r--tests/purs/failing/TooFewClassInstanceArgs.purs8
-rw-r--r--tests/purs/failing/TopLevelCaseNoArgs.purs8
-rw-r--r--tests/purs/failing/TransitiveDctorExport.purs5
-rw-r--r--tests/purs/failing/TransitiveKindExport.purs6
-rw-r--r--tests/purs/failing/TransitiveSynonymExport.purs5
-rw-r--r--tests/purs/failing/TypeClasses2.purs9
-rw-r--r--tests/purs/failing/TypeError.purs6
-rw-r--r--tests/purs/failing/TypeOperatorAliasNoExport.purs6
-rw-r--r--tests/purs/failing/TypeSynonyms.purs8
-rw-r--r--tests/purs/failing/TypeSynonyms2.purs12
-rw-r--r--tests/purs/failing/TypeSynonyms3.purs12
-rw-r--r--tests/purs/failing/TypeSynonyms4.purs11
-rw-r--r--tests/purs/failing/TypeSynonyms5.purs6
-rw-r--r--tests/purs/failing/TypeWildcards1.purs7
-rw-r--r--tests/purs/failing/TypeWildcards2.purs7
-rw-r--r--tests/purs/failing/TypeWildcards3.purs9
-rw-r--r--tests/purs/failing/TypedBinders.purs10
-rw-r--r--tests/purs/failing/TypedBinders2.purs9
-rw-r--r--tests/purs/failing/TypedBinders3.purs13
-rw-r--r--tests/purs/failing/TypedHole.purs8
-rw-r--r--tests/purs/failing/UnderscoreModuleName.purs6
-rw-r--r--tests/purs/failing/UnknownType.purs7
-rw-r--r--tests/purs/failing/UnusableTypeClassMethod.purs7
-rw-r--r--tests/purs/failing/UnusableTypeClassMethodConflictingIdent.purs7
-rw-r--r--tests/purs/failing/UnusableTypeClassMethodSynonym.purs9
-rw-r--r--tests/purs/passing/1110.purs26
-rw-r--r--tests/purs/passing/1185.purs15
-rw-r--r--tests/purs/passing/1335.purs14
-rw-r--r--tests/purs/passing/1570.purs8
-rw-r--r--tests/purs/passing/1664.purs16
-rw-r--r--tests/purs/passing/1697.purs25
-rw-r--r--tests/purs/passing/1807.purs14
-rw-r--r--tests/purs/passing/1881.purs19
-rw-r--r--tests/purs/passing/1991.purs22
-rw-r--r--tests/purs/passing/2018.purs12
-rw-r--r--tests/purs/passing/2018/A.purs7
-rw-r--r--tests/purs/passing/2018/B.purs3
-rw-r--r--tests/purs/passing/2049.purs14
-rw-r--r--tests/purs/passing/2136.purs9
-rw-r--r--tests/purs/passing/2138.purs7
-rw-r--r--tests/purs/passing/2138/Lib.purs3
-rw-r--r--tests/purs/passing/2172.js5
-rw-r--r--tests/purs/passing/2172.purs10
-rw-r--r--tests/purs/passing/2197-1.purs12
-rw-r--r--tests/purs/passing/2197-2.purs11
-rw-r--r--tests/purs/passing/2252.purs15
-rw-r--r--tests/purs/passing/2288.purs19
-rw-r--r--tests/purs/passing/2378.purs9
-rw-r--r--tests/purs/passing/2438.purs8
-rw-r--r--tests/purs/passing/2609.purs12
-rw-r--r--tests/purs/passing/2609/Eg.purs6
-rw-r--r--tests/purs/passing/2616.purs13
-rw-r--r--tests/purs/passing/2626.purs13
-rw-r--r--tests/purs/passing/2663.purs10
-rw-r--r--tests/purs/passing/2689.purs36
-rw-r--r--tests/purs/passing/2756.purs20
-rw-r--r--tests/purs/passing/2787.purs8
-rw-r--r--tests/purs/passing/2795.purs14
-rw-r--r--tests/purs/passing/2803.purs17
-rw-r--r--tests/purs/passing/2806.purs14
-rw-r--r--tests/purs/passing/2947.purs11
-rw-r--r--tests/purs/passing/2958.purs14
-rw-r--r--tests/purs/passing/2972.purs13
-rw-r--r--tests/purs/passing/3114.purs53
-rw-r--r--tests/purs/passing/3114/VendoredVariant.purs42
-rw-r--r--tests/purs/passing/3125.purs16
-rw-r--r--tests/purs/passing/3187-UnusedNameClash.purs12
-rw-r--r--tests/purs/passing/652.purs18
-rw-r--r--tests/purs/passing/810.purs14
-rw-r--r--tests/purs/passing/862.purs8
-rw-r--r--tests/purs/passing/922.purs20
-rw-r--r--tests/purs/passing/Ado.purs77
-rw-r--r--tests/purs/passing/AppendInReverse.purs38
-rw-r--r--tests/purs/passing/Applicative.purs16
-rw-r--r--tests/purs/passing/ArrayType.purs12
-rw-r--r--tests/purs/passing/Auto.purs16
-rw-r--r--tests/purs/passing/AutoPrelude.purs11
-rw-r--r--tests/purs/passing/AutoPrelude2.purs10
-rw-r--r--tests/purs/passing/BindersInFunctions.purs16
-rw-r--r--tests/purs/passing/BindingGroups.purs11
-rw-r--r--tests/purs/passing/BlockString.purs9
-rw-r--r--tests/purs/passing/CaseInDo.purs21
-rw-r--r--tests/purs/passing/CaseInputWildcard.purs18
-rw-r--r--tests/purs/passing/CaseMultipleExpressions.purs21
-rw-r--r--tests/purs/passing/CaseStatement.purs22
-rw-r--r--tests/purs/passing/CheckFunction.purs8
-rw-r--r--tests/purs/passing/CheckSynonymBug.purs13
-rw-r--r--tests/purs/passing/CheckTypeClass.purs18
-rw-r--r--tests/purs/passing/Church.purs18
-rw-r--r--tests/purs/passing/ClassRefSyntax.purs9
-rw-r--r--tests/purs/passing/ClassRefSyntax/Lib.purs4
-rw-r--r--tests/purs/passing/Collatz.purs21
-rw-r--r--tests/purs/passing/Comparisons.purs15
-rw-r--r--tests/purs/passing/Conditional.purs9
-rw-r--r--tests/purs/passing/Console.purs15
-rw-r--r--tests/purs/passing/ConstraintInference.purs10
-rw-r--r--tests/purs/passing/ConstraintParens.purs12
-rw-r--r--tests/purs/passing/ConstraintParsingIssue.purs9
-rw-r--r--tests/purs/passing/ContextSimplification.purs15
-rw-r--r--tests/purs/passing/DataAndType.purs10
-rw-r--r--tests/purs/passing/DataConsClassConsOverlapOk.purs8
-rw-r--r--tests/purs/passing/DctorName.purs33
-rw-r--r--tests/purs/passing/DctorOperatorAlias.purs34
-rw-r--r--tests/purs/passing/DctorOperatorAlias/List.purs5
-rw-r--r--tests/purs/passing/DeepArrayBinder.purs17
-rw-r--r--tests/purs/passing/DeepCase.purs15
-rw-r--r--tests/purs/passing/DeriveNewtype.purs29
-rw-r--r--tests/purs/passing/DeriveWithNestedSynonyms.purs29
-rw-r--r--tests/purs/passing/Deriving.purs36
-rw-r--r--tests/purs/passing/DerivingFunctor.purs36
-rw-r--r--tests/purs/passing/Do.purs68
-rw-r--r--tests/purs/passing/Dollar.purs16
-rw-r--r--tests/purs/passing/DuplicateProperties.purs27
-rw-r--r--tests/purs/passing/EffFn.js1
-rw-r--r--tests/purs/passing/EffFn.purs22
-rw-r--r--tests/purs/passing/EmptyDataDecls.purs20
-rw-r--r--tests/purs/passing/EmptyRow.purs11
-rw-r--r--tests/purs/passing/EmptyTypeClass.purs11
-rw-r--r--tests/purs/passing/EntailsKindedType.purs11
-rw-r--r--tests/purs/passing/Eq1Deriving.purs12
-rw-r--r--tests/purs/passing/Eq1InEqDeriving.purs11
-rw-r--r--tests/purs/passing/EqOrd.purs18
-rw-r--r--tests/purs/passing/ExplicitImportReExport.purs11
-rw-r--r--tests/purs/passing/ExplicitImportReExport/Bar.purs3
-rw-r--r--tests/purs/passing/ExplicitImportReExport/Foo.purs4
-rw-r--r--tests/purs/passing/ExplicitOperatorSections.purs15
-rw-r--r--tests/purs/passing/ExportExplicit.purs10
-rw-r--r--tests/purs/passing/ExportExplicit/M1.purs10
-rw-r--r--tests/purs/passing/ExportExplicit2.purs8
-rw-r--r--tests/purs/passing/ExportExplicit2/M1.purs7
-rw-r--r--tests/purs/passing/ExportedInstanceDeclarations.purs45
-rw-r--r--tests/purs/passing/ExtendedInfixOperators.purs17
-rw-r--r--tests/purs/passing/Fib.purs20
-rw-r--r--tests/purs/passing/FieldConsPuns.purs13
-rw-r--r--tests/purs/passing/FieldPuns.purs10
-rw-r--r--tests/purs/passing/FinalTagless.purs25
-rw-r--r--tests/purs/passing/ForeignKind.purs10
-rw-r--r--tests/purs/passing/ForeignKind/Lib.purs60
-rw-r--r--tests/purs/passing/FunWithFunDeps.js32
-rw-r--r--tests/purs/passing/FunWithFunDeps.purs41
-rw-r--r--tests/purs/passing/FunctionScope.purs13
-rw-r--r--tests/purs/passing/FunctionalDependencies.purs21
-rw-r--r--tests/purs/passing/Functions.purs12
-rw-r--r--tests/purs/passing/Functions2.purs13
-rw-r--r--tests/purs/passing/Generalization1.purs11
-rw-r--r--tests/purs/passing/GenericsRep.purs43
-rw-r--r--tests/purs/passing/Guards.purs64
-rw-r--r--tests/purs/passing/HasOwnProperty.purs5
-rw-r--r--tests/purs/passing/HoistError.purs12
-rw-r--r--tests/purs/passing/IfThenElseMaybe.purs12
-rw-r--r--tests/purs/passing/IfWildcard.purs19
-rw-r--r--tests/purs/passing/ImplicitEmptyImport.purs9
-rw-r--r--tests/purs/passing/Import.purs6
-rw-r--r--tests/purs/passing/Import/M1.purs8
-rw-r--r--tests/purs/passing/Import/M2.purs6
-rw-r--r--tests/purs/passing/ImportExplicit.purs10
-rw-r--r--tests/purs/passing/ImportExplicit/M1.purs4
-rw-r--r--tests/purs/passing/ImportHiding.purs19
-rw-r--r--tests/purs/passing/ImportQualified.purs8
-rw-r--r--tests/purs/passing/ImportQualified/M1.purs3
-rw-r--r--tests/purs/passing/InferRecFunWithConstrainedArgument.purs11
-rw-r--r--tests/purs/passing/InstanceBeforeClass.purs12
-rw-r--r--tests/purs/passing/InstanceChain.purs71
-rw-r--r--tests/purs/passing/InstanceSigs.purs12
-rw-r--r--tests/purs/passing/InstanceSigsGeneral.purs12
-rw-r--r--tests/purs/passing/IntAndChar.purs19
-rw-r--r--tests/purs/passing/JSReserved.purs13
-rw-r--r--tests/purs/passing/KindedType.purs34
-rw-r--r--tests/purs/passing/LargeSumType.purs35
-rw-r--r--tests/purs/passing/Let.purs58
-rw-r--r--tests/purs/passing/Let2.purs20
-rw-r--r--tests/purs/passing/LetInInstance.purs15
-rw-r--r--tests/purs/passing/LetPattern.purs196
-rw-r--r--tests/purs/passing/LiberalTypeSynonyms.purs22
-rw-r--r--tests/purs/passing/MPTCs.purs21
-rw-r--r--tests/purs/passing/Match.purs10
-rw-r--r--tests/purs/passing/Module.purs7
-rw-r--r--tests/purs/passing/Module/M1.purs14
-rw-r--r--tests/purs/passing/Module/M2.purs10
-rw-r--r--tests/purs/passing/ModuleDeps.purs6
-rw-r--r--tests/purs/passing/ModuleDeps/M1.purs5
-rw-r--r--tests/purs/passing/ModuleDeps/M2.purs5
-rw-r--r--tests/purs/passing/ModuleDeps/M3.purs3
-rw-r--r--tests/purs/passing/ModuleExport.purs8
-rw-r--r--tests/purs/passing/ModuleExport/A.purs3
-rw-r--r--tests/purs/passing/ModuleExportDupes.purs11
-rw-r--r--tests/purs/passing/ModuleExportDupes/A.purs3
-rw-r--r--tests/purs/passing/ModuleExportDupes/B.purs3
-rw-r--r--tests/purs/passing/ModuleExportDupes/C.purs4
-rw-r--r--tests/purs/passing/ModuleExportExcluded.purs11
-rw-r--r--tests/purs/passing/ModuleExportExcluded/A.purs6
-rw-r--r--tests/purs/passing/ModuleExportQualified.purs9
-rw-r--r--tests/purs/passing/ModuleExportQualified/A.purs3
-rw-r--r--tests/purs/passing/ModuleExportSelf.purs11
-rw-r--r--tests/purs/passing/ModuleExportSelf/A.purs5
-rw-r--r--tests/purs/passing/Monad.purs32
-rw-r--r--tests/purs/passing/MonadState.purs63
-rw-r--r--tests/purs/passing/MultiArgFunctions.purs27
-rw-r--r--tests/purs/passing/MutRec.purs20
-rw-r--r--tests/purs/passing/MutRec2.purs20
-rw-r--r--tests/purs/passing/MutRec3.purs20
-rw-r--r--tests/purs/passing/NakedConstraint.purs10
-rw-r--r--tests/purs/passing/NamedPatterns.purs10
-rw-r--r--tests/purs/passing/NegativeBinder.purs10
-rw-r--r--tests/purs/passing/NegativeIntInRange.purs9
-rw-r--r--tests/purs/passing/Nested.purs10
-rw-r--r--tests/purs/passing/NestedRecordUpdate.purs24
-rw-r--r--tests/purs/passing/NestedRecordUpdateWildcards.purs20
-rw-r--r--tests/purs/passing/NestedTypeSynonyms.purs12
-rw-r--r--tests/purs/passing/NestedWhere.purs13
-rw-r--r--tests/purs/passing/NewConsClass.purs12
-rw-r--r--tests/purs/passing/Newtype.purs23
-rw-r--r--tests/purs/passing/NewtypeClass.purs40
-rw-r--r--tests/purs/passing/NewtypeEff.purs29
-rw-r--r--tests/purs/passing/NewtypeInstance.purs61
-rw-r--r--tests/purs/passing/NewtypeWithRecordUpdate.purs16
-rw-r--r--tests/purs/passing/NonConflictingExports.purs10
-rw-r--r--tests/purs/passing/NonConflictingExports/A.purs4
-rw-r--r--tests/purs/passing/NonOrphanInstanceFunDepExtra.purs8
-rw-r--r--tests/purs/passing/NonOrphanInstanceFunDepExtra/Lib.purs4
-rw-r--r--tests/purs/passing/NonOrphanInstanceMulti.purs7
-rw-r--r--tests/purs/passing/NonOrphanInstanceMulti/Lib.purs4
-rw-r--r--tests/purs/passing/NumberLiterals.purs39
-rw-r--r--tests/purs/passing/ObjectGetter.purs14
-rw-r--r--tests/purs/passing/ObjectSynonym.purs16
-rw-r--r--tests/purs/passing/ObjectUpdate.purs23
-rw-r--r--tests/purs/passing/ObjectUpdate2.purs18
-rw-r--r--tests/purs/passing/ObjectUpdater.purs26
-rw-r--r--tests/purs/passing/ObjectWildcards.purs20
-rw-r--r--tests/purs/passing/Objects.purs36
-rw-r--r--tests/purs/passing/OneConstructor.purs10
-rw-r--r--tests/purs/passing/OperatorAlias.purs11
-rw-r--r--tests/purs/passing/OperatorAliasElsewhere.purs9
-rw-r--r--tests/purs/passing/OperatorAliasElsewhere/Def.purs4
-rw-r--r--tests/purs/passing/OperatorAssociativity.purs25
-rw-r--r--tests/purs/passing/OperatorInlining.purs48
-rw-r--r--tests/purs/passing/OperatorSections.purs18
-rw-r--r--tests/purs/passing/Operators.purs91
-rw-r--r--tests/purs/passing/Operators/Other.purs7
-rw-r--r--tests/purs/passing/OptimizerBug.purs10
-rw-r--r--tests/purs/passing/OptionalQualified.purs12
-rw-r--r--tests/purs/passing/Ord1Deriving.purs16
-rw-r--r--tests/purs/passing/Ord1InOrdDeriving.purs13
-rw-r--r--tests/purs/passing/ParensInType.purs14
-rw-r--r--tests/purs/passing/ParensInTypedBinder.purs14
-rw-r--r--tests/purs/passing/PartialFunction.purs11
-rw-r--r--tests/purs/passing/Patterns.purs23
-rw-r--r--tests/purs/passing/PendingConflictingImports.purs8
-rw-r--r--tests/purs/passing/PendingConflictingImports/A.purs4
-rw-r--r--tests/purs/passing/PendingConflictingImports/B.purs4
-rw-r--r--tests/purs/passing/PendingConflictingImports2.purs10
-rw-r--r--tests/purs/passing/PendingConflictingImports2/A.purs4
-rw-r--r--tests/purs/passing/Person.purs12
-rw-r--r--tests/purs/passing/PolyLabels.js17
-rw-r--r--tests/purs/passing/PolyLabels.purs66
-rw-r--r--tests/purs/passing/PrimedTypeName.purs20
-rw-r--r--tests/purs/passing/QualifiedNames.purs11
-rw-r--r--tests/purs/passing/QualifiedNames/Either.purs5
-rw-r--r--tests/purs/passing/QualifiedQualifiedImports.purs6
-rw-r--r--tests/purs/passing/Rank2Data.purs30
-rw-r--r--tests/purs/passing/Rank2Object.purs11
-rw-r--r--tests/purs/passing/Rank2TypeSynonym.purs17
-rw-r--r--tests/purs/passing/Rank2Types.purs12
-rw-r--r--tests/purs/passing/ReExportQualified.purs7
-rw-r--r--tests/purs/passing/ReExportQualified/A.purs3
-rw-r--r--tests/purs/passing/ReExportQualified/B.purs3
-rw-r--r--tests/purs/passing/ReExportQualified/C.purs4
-rw-r--r--tests/purs/passing/RebindableSyntax.purs43
-rw-r--r--tests/purs/passing/Recursion.purs11
-rw-r--r--tests/purs/passing/RedefinedFixity.purs6
-rw-r--r--tests/purs/passing/RedefinedFixity/M1.purs6
-rw-r--r--tests/purs/passing/RedefinedFixity/M2.purs5
-rw-r--r--tests/purs/passing/RedefinedFixity/M3.purs6
-rw-r--r--tests/purs/passing/ReservedWords.purs19
-rw-r--r--tests/purs/passing/ResolvableScopeConflict.purs13
-rw-r--r--tests/purs/passing/ResolvableScopeConflict/A.purs4
-rw-r--r--tests/purs/passing/ResolvableScopeConflict/B.purs7
-rw-r--r--tests/purs/passing/ResolvableScopeConflict2.purs15
-rw-r--r--tests/purs/passing/ResolvableScopeConflict2/A.purs7
-rw-r--r--tests/purs/passing/ResolvableScopeConflict3.purs9
-rw-r--r--tests/purs/passing/ResolvableScopeConflict3/A.purs4
-rw-r--r--tests/purs/passing/RowConstructors.purs43
-rw-r--r--tests/purs/passing/RowInInstanceHeadDetermined.purs40
-rw-r--r--tests/purs/passing/RowLacks.purs23
-rw-r--r--tests/purs/passing/RowNub.purs23
-rw-r--r--tests/purs/passing/RowPolyInstanceContext.purs23
-rw-r--r--tests/purs/passing/RowUnion.js10
-rw-r--r--tests/purs/passing/RowUnion.purs69
-rw-r--r--tests/purs/passing/RowsInInstanceContext.purs25
-rw-r--r--tests/purs/passing/RunFnInline.purs11
-rw-r--r--tests/purs/passing/RuntimeScopeIssue.purs22
-rw-r--r--tests/purs/passing/ScopedTypeVariables.purs37
-rw-r--r--tests/purs/passing/Sequence.purs16
-rw-r--r--tests/purs/passing/SequenceDesugared.purs38
-rw-r--r--tests/purs/passing/ShadowedModuleName.purs8
-rw-r--r--tests/purs/passing/ShadowedModuleName/Test.purs6
-rw-r--r--tests/purs/passing/ShadowedName.purs11
-rw-r--r--tests/purs/passing/ShadowedRename.purs14
-rw-r--r--tests/purs/passing/ShadowedTCO.purs21
-rw-r--r--tests/purs/passing/ShadowedTCOLet.purs15
-rw-r--r--tests/purs/passing/SignedNumericLiterals.purs18
-rw-r--r--tests/purs/passing/SolvingAppendSymbol.purs34
-rw-r--r--tests/purs/passing/SolvingCompareSymbol.purs33
-rw-r--r--tests/purs/passing/SolvingIsSymbol.purs13
-rw-r--r--tests/purs/passing/SolvingIsSymbol/Lib.purs10
-rw-r--r--tests/purs/passing/Stream.purs26
-rw-r--r--tests/purs/passing/StringEdgeCases.purs9
-rw-r--r--tests/purs/passing/StringEdgeCases/Records.purs39
-rw-r--r--tests/purs/passing/StringEdgeCases/Symbols.purs32
-rw-r--r--tests/purs/passing/StringEscapes.purs26
-rw-r--r--tests/purs/passing/Superclasses1.purs23
-rw-r--r--tests/purs/passing/Superclasses3.purs41
-rw-r--r--tests/purs/passing/TCO.purs28
-rw-r--r--tests/purs/passing/TCOCase.purs13
-rw-r--r--tests/purs/passing/TailCall.purs20
-rw-r--r--tests/purs/passing/Tick.purs8
-rw-r--r--tests/purs/passing/TopLevelCase.purs19
-rw-r--r--tests/purs/passing/TransitiveImport.purs9
-rw-r--r--tests/purs/passing/TransitiveImport/Middle.purs5
-rw-r--r--tests/purs/passing/TransitiveImport/Test.purs9
-rw-r--r--tests/purs/passing/TypeClassMemberOrderChange.purs16
-rw-r--r--tests/purs/passing/TypeClasses.purs71
-rw-r--r--tests/purs/passing/TypeClassesInOrder.purs12
-rw-r--r--tests/purs/passing/TypeClassesWithOverlappingTypeVariables.purs12
-rw-r--r--tests/purs/passing/TypeDecl.purs13
-rw-r--r--tests/purs/passing/TypeOperators.purs20
-rw-r--r--tests/purs/passing/TypeOperators/A.purs22
-rw-r--r--tests/purs/passing/TypeSynonymInData.purs12
-rw-r--r--tests/purs/passing/TypeSynonyms.purs28
-rw-r--r--tests/purs/passing/TypeWildcards.purs16
-rw-r--r--tests/purs/passing/TypeWildcardsRecordExtension.purs9
-rw-r--r--tests/purs/passing/TypeWithoutParens.purs12
-rw-r--r--tests/purs/passing/TypeWithoutParens/Lib.purs4
-rw-r--r--tests/purs/passing/TypedBinders.purs68
-rw-r--r--tests/purs/passing/TypedWhere.purs18
-rw-r--r--tests/purs/passing/UTF8Sourcefile.purs8
-rw-r--r--tests/purs/passing/UnderscoreIdent.purs13
-rw-r--r--tests/purs/passing/UnicodeIdentifier.purs7
-rw-r--r--tests/purs/passing/UnicodeOperators.purs22
-rw-r--r--tests/purs/passing/UnicodeType.purs22
-rw-r--r--tests/purs/passing/UnifyInTypeInstanceLookup.purs25
-rw-r--r--tests/purs/passing/Unit.purs8
-rw-r--r--tests/purs/passing/UnknownInTypeClassLookup.purs15
-rw-r--r--tests/purs/passing/UnsafeCoerce.purs16
-rw-r--r--tests/purs/passing/UntupledConstraints.purs17
-rw-r--r--tests/purs/passing/UsableTypeClassMethods.purs35
-rw-r--r--tests/purs/passing/Where.purs49
-rw-r--r--tests/purs/passing/WildcardInInstance.purs21
-rw-r--r--tests/purs/passing/WildcardType.purs12
-rw-r--r--tests/purs/passing/iota.purs11
-rw-r--r--tests/purs/passing/s.purs8
-rw-r--r--tests/purs/psci/BasicEval.purs10
-rw-r--r--tests/purs/psci/Multiline.purs10
-rw-r--r--tests/purs/warning/2140.purs5
-rw-r--r--tests/purs/warning/2383.purs12
-rw-r--r--tests/purs/warning/2411.purs15
-rw-r--r--tests/purs/warning/2542.purs16
-rw-r--r--tests/purs/warning/CustomWarning.purs11
-rw-r--r--tests/purs/warning/CustomWarning2.purs13
-rw-r--r--tests/purs/warning/CustomWarning3.purs15
-rw-r--r--tests/purs/warning/DuplicateExportRef.purs30
-rw-r--r--tests/purs/warning/DuplicateImport.purs10
-rw-r--r--tests/purs/warning/DuplicateImportRef.purs18
-rw-r--r--tests/purs/warning/DuplicateSelectiveImport.purs10
-rw-r--r--tests/purs/warning/HidingImport.purs9
-rw-r--r--tests/purs/warning/ImplicitImport.purs9
-rw-r--r--tests/purs/warning/ImplicitQualifiedImport.purs11
-rw-r--r--tests/purs/warning/ImplicitQualifiedImportReExport.purs13
-rw-r--r--tests/purs/warning/MissingTypeDeclaration.purs4
-rw-r--r--tests/purs/warning/NewtypeInstance.purs8
-rw-r--r--tests/purs/warning/NewtypeInstance2.purs15
-rw-r--r--tests/purs/warning/NewtypeInstance3.purs21
-rw-r--r--tests/purs/warning/NewtypeInstance4.purs23
-rw-r--r--tests/purs/warning/OverlappingPattern.purs15
-rw-r--r--tests/purs/warning/ScopeShadowing.purs13
-rw-r--r--tests/purs/warning/ScopeShadowing2.purs10
-rw-r--r--tests/purs/warning/ShadowedBinderPatternGuard.purs7
-rw-r--r--tests/purs/warning/ShadowedNameParens.purs5
-rw-r--r--tests/purs/warning/ShadowedTypeVar.purs5
-rw-r--r--tests/purs/warning/UnnecessaryFFIModule.js1
-rw-r--r--tests/purs/warning/UnnecessaryFFIModule.purs5
-rw-r--r--tests/purs/warning/UnusedDctorExplicitImport.purs8
-rw-r--r--tests/purs/warning/UnusedDctorImportAll.purs7
-rw-r--r--tests/purs/warning/UnusedDctorImportExplicit.purs7
-rw-r--r--tests/purs/warning/UnusedExplicitImport.purs8
-rw-r--r--tests/purs/warning/UnusedExplicitImportTypeOp.purs9
-rw-r--r--tests/purs/warning/UnusedExplicitImportTypeOp/Lib.purs8
-rw-r--r--tests/purs/warning/UnusedExplicitImportValOp.purs8
-rw-r--r--tests/purs/warning/UnusedFFIImplementations.js2
-rw-r--r--tests/purs/warning/UnusedFFIImplementations.purs4
-rw-r--r--tests/purs/warning/UnusedImport.purs14
-rw-r--r--tests/purs/warning/UnusedTypeVar.purs5
-rw-r--r--tests/purs/warning/WildcardInferredType.purs23
-rw-r--r--tests/support/bower.json109
-rw-r--r--tests/support/package-lock.json171
-rw-r--r--tests/support/pscide/src/FindUsage.purs12
-rw-r--r--tests/support/pscide/src/FindUsage/Definition.purs13
-rw-r--r--tests/support/pscide/src/FindUsage/Recursive.purs8
-rw-r--r--tests/support/pscide/src/FindUsage/RecursiveShadowed.purs10
-rw-r--r--tests/support/pscide/src/FindUsage/Reexport.purs3
-rwxr-xr-x[-rw-r--r--]tests/support/setup-win.cmd0
687 files changed, 9607 insertions, 150 deletions
diff --git a/tests/Language/PureScript/Ide/ImportsSpec.hs b/tests/Language/PureScript/Ide/ImportsSpec.hs
index b7c8196..f84d088 100644
--- a/tests/Language/PureScript/Ide/ImportsSpec.hs
+++ b/tests/Language/PureScript/Ide/ImportsSpec.hs
@@ -9,6 +9,7 @@ import qualified Language.PureScript as P
import Language.PureScript.Ide.Command as Command
import Language.PureScript.Ide.Error
import Language.PureScript.Ide.Imports
+import Language.PureScript.Ide.Filter (moduleFilter)
import qualified Language.PureScript.Ide.Test as Test
import Language.PureScript.Ide.Types
import System.FilePath
@@ -62,7 +63,7 @@ preludeImport, arrayImport, listImport, consoleImport, maybeImport :: Import
preludeImport = testParseImport "import Prelude"
arrayImport = testParseImport "import Data.Array (head, cons)"
listImport = testParseImport "import Data.List as List"
-consoleImport = testParseImport "import Control.Monad.Eff.Console (log) as Console"
+consoleImport = testParseImport "import Effect.Console (log) as Console"
maybeImport = testParseImport "import Data.Maybe (Maybe(Just))"
spec :: Spec
@@ -103,7 +104,7 @@ spec = do
it "pretty prints a qualified import" $
shouldBe (prettyPrintImport' listImport) "import Data.List as List"
it "pretty prints a qualified explicit import" $
- shouldBe (prettyPrintImport' consoleImport) "import Control.Monad.Eff.Console (log) as Console"
+ shouldBe (prettyPrintImport' consoleImport) "import Effect.Console (log) as Console"
it "pretty prints an import with a datatype (and PositionedRef's for the dtors)" $
shouldBe (prettyPrintImport' maybeImport) "import Data.Maybe (Maybe(Just))"
@@ -343,6 +344,10 @@ addExplicitImport :: Text -> Command
addExplicitImport i =
Command.Import ("src" </> "ImportsSpec.purs") Nothing [] (Command.AddImportForIdentifier i Nothing)
+addExplicitImportFiltered :: Text -> [P.ModuleName] -> Command
+addExplicitImportFiltered i ms =
+ Command.Import ("src" </> "ImportsSpec.purs") Nothing [moduleFilter ms] (Command.AddImportForIdentifier i Nothing)
+
importShouldBe :: [Text] -> [Text] -> Expectation
importShouldBe res importSection =
res `shouldBe` [ "module ImportsSpec where" , ""] ++ importSection ++ [ "" , "myId x = x"]
@@ -393,3 +398,12 @@ importFromIdeState = do
\write to the output file" $ do
result <- runIdeLoaded (addExplicitImport "doesnExist")
result `shouldSatisfy` isLeft
+ it "doesn't import things from the Prim modules" $ do
+ Right (MultilineTextResult result) <- runIdeLoaded (addExplicitImport "String")
+ result `importShouldBe` []
+ it "imports classes from Prim.* modules" $ do
+ Right (MultilineTextResult result) <- runIdeLoaded (addExplicitImportFiltered "Cons" [Test.mn "Prim.Row"])
+ result `importShouldBe` ["import Prim.Row (class Cons)"]
+ it "imports types from Prim.* modules" $ do
+ Right (MultilineTextResult result) <- runIdeLoaded (addExplicitImportFiltered "Cons" [Test.mn "Prim.RowList"])
+ result `importShouldBe` ["import Prim.RowList (Cons)"]
diff --git a/tests/Language/PureScript/Ide/StateSpec.hs b/tests/Language/PureScript/Ide/StateSpec.hs
index 0a31331..67a6671 100644
--- a/tests/Language/PureScript/Ide/StateSpec.hs
+++ b/tests/Language/PureScript/Ide/StateSpec.hs
@@ -62,6 +62,10 @@ ef = P.ExternsFile
mempty
-- , edInstanceConstraints =
mempty
+ -- , edInstanceChain =
+ mempty
+ -- , edInstanceChainIndex =
+ 0
-- }
]
--, efSourceSpan =
diff --git a/tests/Language/PureScript/Ide/Test.hs b/tests/Language/PureScript/Ide/Test.hs
index d9d50ae..cca8e99 100644
--- a/tests/Language/PureScript/Ide/Test.hs
+++ b/tests/Language/PureScript/Ide/Test.hs
@@ -23,7 +23,7 @@ defConfig =
IdeConfiguration
{ confLogLevel = LogNone
, confOutputPath = "output/"
- , confGlobs = ["src/*.purs"]
+ , confGlobs = ["src/**/*.purs"]
, confEditorMode = False
}
@@ -115,10 +115,16 @@ ss x y = P.SourceSpan "Test.purs" (P.SourcePos x y) (P.SourcePos x y)
mn :: Text -> P.ModuleName
mn = P.moduleNameFromString
+projectDir :: FilePath
+projectDir = "." </> "tests" </> "support" </> "pscide"
+
+getProjectDirectory :: IO FilePath
+getProjectDirectory = makeAbsolute projectDir
+
inProject :: IO a -> IO a
inProject f = do
cwd' <- getCurrentDirectory
- setCurrentDirectory ("." </> "tests" </> "support" </> "pscide")
+ setCurrentDirectory projectDir
a <- f
setCurrentDirectory cwd'
pure a
diff --git a/tests/Language/PureScript/Ide/UsageSpec.hs b/tests/Language/PureScript/Ide/UsageSpec.hs
new file mode 100644
index 0000000..d1e83eb
--- /dev/null
+++ b/tests/Language/PureScript/Ide/UsageSpec.hs
@@ -0,0 +1,82 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+module Language.PureScript.Ide.UsageSpec where
+
+import Protolude
+
+import qualified Data.Text as Text
+import Language.PureScript.Ide.Command
+import Language.PureScript.Ide.Types
+import qualified Language.PureScript.Ide.Test as Test
+import qualified Language.PureScript as P
+import Test.Hspec
+import Data.Text.Read (decimal)
+import System.FilePath
+
+load :: [Text] -> Command
+load = LoadSync . map Test.mn
+
+usage :: P.ModuleName -> Text -> IdeNamespace -> Command
+usage mn ident ns = FindUsages mn ident ns
+
+shouldBeUsage :: P.SourceSpan -> (FilePath, Text) -> Expectation
+shouldBeUsage usage' (fp, range) =
+ let
+ [ start, end] = Text.splitOn "-" range
+ unsafeReadInt = fst . either (panic "") identity . decimal
+ [ startLine, startColumn ] = map unsafeReadInt (Text.splitOn ":" start)
+ [ endLine, endColumn ] = map unsafeReadInt (Text.splitOn ":" end)
+ in
+ do
+ projectDir <- Test.getProjectDirectory
+ projectDir </> fp `shouldBe` P.spanName usage'
+
+ (P.sourcePosLine (P.spanStart usage'), P.sourcePosColumn (P.spanStart usage'))
+ `shouldBe`
+ (startLine, startColumn)
+
+ (P.sourcePosLine (P.spanEnd usage'), P.sourcePosColumn (P.spanEnd usage'))
+ `shouldBe`
+ (endLine, endColumn)
+
+spec :: Spec
+spec = describe "Finding Usages" $ do
+ it "finds a simple usage" $ do
+ ([_, Right (UsagesResult [usage1, usage2])], _) <- Test.inProject $
+ Test.runIde [ load ["FindUsage", "FindUsage.Definition", "FindUsage.Reexport"]
+ , usage (Test.mn "FindUsage.Definition") "usageId" IdeNSValue
+ ]
+ usage1 `shouldBeUsage` ("src" </> "FindUsage.purs", "12:11-12:18")
+ usage2 `shouldBeUsage` ("src" </> "FindUsage" </> "Definition.purs", "13:18-13:18")
+ it "finds a simple recursive usage" $ do
+ ([_, Right (UsagesResult [usage1])], _) <- Test.inProject $
+ Test.runIde [ load ["FindUsage.Recursive"]
+ , usage (Test.mn "FindUsage.Recursive") "recursiveUsage" IdeNSValue
+ ]
+ usage1 `shouldBeUsage` ("src" </> "FindUsage" </> "Recursive.purs", "7:12-7:26")
+ it "ignores a locally shadowed recursive usage" $ do
+ ([_, Right (UsagesResult usageResult)], _) <- Test.inProject $
+ Test.runIde [ load ["FindUsage.RecursiveShadowed"]
+ , usage (Test.mn "FindUsage.RecursiveShadowed") "recursiveUsage" IdeNSValue
+ ]
+ usageResult `shouldBe` []
+ it "finds a constructor usage" $ do
+ ([_, Right (UsagesResult [usage1])], _) <- Test.inProject $
+ Test.runIde [ load ["FindUsage", "FindUsage.Definition", "FindUsage.Reexport"]
+ , usage (Test.mn "FindUsage.Definition") "Used" IdeNSValue
+ ]
+ usage1 `shouldBeUsage` ("src" </> "FindUsage.purs", "8:3-8:9")
+ it "finds a constructor alias usage" $ do
+ ([_, Right (UsagesResult [usage1])], _) <- Test.inProject $
+ Test.runIde [ load ["FindUsage", "FindUsage.Definition", "FindUsage.Reexport"]
+ , usage (Test.mn "FindUsage.Definition") "$%" IdeNSValue
+ ]
+ usage1 `shouldBeUsage` ("src" </> "FindUsage.purs", "9:5-9:7")
+ it "finds a reexported usage" $ do
+ ([_, Right (UsagesResult [usage1])], _) <- Test.inProject $
+ Test.runIde [ load ["FindUsage", "FindUsage.Definition", "FindUsage.Reexport"]
+ , usage (Test.mn "FindUsage.Reexport") "toBeReexported" IdeNSValue
+ ]
+ -- TODO(Christoph): Interesting parser bug here. It seems the position
+ -- of the last token in the file has the wrong ending span
+ usage1 `shouldBeUsage` ("src" </> "FindUsage.purs", "12:19-12:19")
diff --git a/tests/Main.hs b/tests/Main.hs
index 1622bd4..c026938 100644
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -8,12 +8,15 @@ module Main (main) where
import Prelude ()
import Prelude.Compat
+import Test.Tasty
+
import qualified TestCompiler
+import qualified TestCoreFn
import qualified TestDocs
import qualified TestHierarchy
import qualified TestPrimDocs
import qualified TestPsci
-import qualified TestPscIde
+import qualified TestIde
import qualified TestPscPublish
import qualified TestUtils
@@ -26,20 +29,28 @@ main = do
heading "Updating support code"
TestUtils.updateSupportCode
- heading "Main compiler test suite"
- TestCompiler.main
- heading "Documentation test suite"
- TestDocs.main
- heading "Hierarchy test suite"
- TestHierarchy.main
heading "Prim documentation test suite"
TestPrimDocs.main
heading "psc-publish test suite"
TestPscPublish.main
- heading "psci test suite"
- TestPsci.main
- heading "psc-ide test suite"
- TestPscIde.main
+
+ ideTests <- TestIde.main
+ compilerTests <- TestCompiler.main
+ psciTests <- TestPsci.main
+ coreFnTests <- TestCoreFn.main
+ docsTests <- TestDocs.main
+ hierarchyTests <- TestHierarchy.main
+
+ defaultMain $
+ testGroup
+ "Tests"
+ [ compilerTests
+ , psciTests
+ , ideTests
+ , coreFnTests
+ , docsTests
+ , hierarchyTests
+ ]
where
heading msg = do
diff --git a/tests/TestCompiler.hs b/tests/TestCompiler.hs
index de8f19f..9c3bed7 100644
--- a/tests/TestCompiler.hs
+++ b/tests/TestCompiler.hs
@@ -49,23 +49,23 @@ import System.FilePath
import System.Directory
import System.IO
import System.IO.UTF8
-import System.IO.Silently
import qualified System.FilePath.Glob as Glob
import TestUtils
-import Test.Hspec
+import Test.Tasty
+import Test.Tasty.Hspec
-main :: IO ()
-main = hspec spec
+main :: IO TestTree
+main = testSpec "compiler" spec
spec :: Spec
spec = do
(supportModules, supportExterns, supportForeigns, passingTestCases, warningTestCases, failingTestCases) <- runIO $ do
cwd <- getCurrentDirectory
- let passing = cwd </> "examples" </> "passing"
- let warning = cwd </> "examples" </> "warning"
- let failing = cwd </> "examples" </> "failing"
+ let passing = cwd </> "tests" </> "purs" </> "passing"
+ let warning = cwd </> "tests" </> "purs" </> "warning"
+ let failing = cwd </> "tests" </> "purs" </> "failing"
passingFiles <- getTestFiles passing <$> testGlob passing
warningFiles <- getTestFiles warning <$> testGlob warning
failingFiles <- getTestFiles failing <$> testGlob failing
@@ -169,6 +169,7 @@ makeActions :: [P.Module] -> M.Map P.ModuleName FilePath -> P.MakeActions P.Make
makeActions modules foreigns = (P.buildMakeActions modulesDir (P.internalError "makeActions: input file map was read.") foreigns False)
{ P.getInputTimestamp = getInputTimestamp
, P.getOutputTimestamp = getOutputTimestamp
+ , P.progress = const (pure ())
}
where
getInputTimestamp :: P.ModuleName -> P.Make (Either P.RebuildPolicy (Maybe UTCTime))
@@ -194,7 +195,7 @@ compile
-> [FilePath]
-> ([P.Module] -> IO ())
-> IO (Either P.MultipleErrors [P.ExternsFile], P.MultipleErrors)
-compile supportModules supportExterns supportForeigns inputFiles check = silence $ runTest $ do
+compile supportModules supportExterns supportForeigns inputFiles check = runTest $ do
fs <- liftIO $ readInput inputFiles
ms <- P.parseModulesFromFiles id fs
foreigns <- inferForeignModules ms
@@ -226,8 +227,20 @@ checkShouldFailWith :: [String] -> P.MultipleErrors -> Maybe String
checkShouldFailWith expected errs =
let actual = map P.errorCode $ P.runMultipleErrors errs
in if sort expected == sort (map T.unpack actual)
- then Nothing
- else Just $ "Expected these errors: " ++ show expected ++ ", but got these: " ++ show actual
+ then checkPositioned errs
+ else Just $ "Expected these errors: " ++ show expected ++ ", but got these: "
+ ++ show actual ++ ", full error messages: \n"
+ ++ unlines (map (P.renderBox . P.prettyPrintSingleError P.defaultPPEOptions) (P.runMultipleErrors errs))
+
+checkPositioned :: P.MultipleErrors -> Maybe String
+checkPositioned errs =
+ case mapMaybe (\err -> maybe (Just err) (const Nothing) (P.errorSpan err)) (P.runMultipleErrors errs) of
+ [] ->
+ Nothing
+ errs' ->
+ Just
+ $ "Found errors with missing source spans:\n"
+ ++ unlines (map (P.renderBox . P.prettyPrintSingleError P.defaultPPEOptions) errs')
assertCompiles
:: [P.Module]
diff --git a/tests/TestCoreFn.hs b/tests/TestCoreFn.hs
new file mode 100644
index 0000000..7c27220
--- /dev/null
+++ b/tests/TestCoreFn.hs
@@ -0,0 +1,247 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DoAndIfThenElse #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module TestCoreFn (main) where
+
+import Prelude ()
+import Prelude.Compat
+
+import Data.Aeson
+import Data.Aeson.Types
+import Data.Version
+
+import Language.PureScript.AST.Literals
+import Language.PureScript.AST.SourcePos
+import Language.PureScript.Comments
+import Language.PureScript.CoreFn
+import Language.PureScript.CoreFn.FromJSON
+import Language.PureScript.CoreFn.ToJSON
+import Language.PureScript.Names
+import Language.PureScript.PSString
+
+import Test.Tasty
+import Test.Tasty.Hspec
+
+main :: IO TestTree
+main = testSpec "corefn" spec
+
+parseModule :: Value -> Result (Version, Module Ann)
+parseModule = parse moduleFromJSON
+
+-- convert a module to its json CoreFn representation and back
+parseMod :: Module Ann -> Result (Module Ann)
+parseMod m =
+ let v = Version [0] []
+ in snd <$> parseModule (moduleToJSON v m)
+
+isSuccess :: Result a -> Bool
+isSuccess (Success _) = True
+isSuccess _ = False
+
+spec :: Spec
+spec = context "CoreFnFromJsonTest" $ do
+ let mn = ModuleName [ProperName "Example", ProperName "Main"]
+ mp = "src/Example/Main.purs"
+ ss = SourceSpan mp (SourcePos 0 0) (SourcePos 0 0)
+ ann = ssAnn ss
+
+ specify "should parse an empty module" $ do
+ let r = parseMod $ Module ss [] mn mp [] [] [] []
+ r `shouldSatisfy` isSuccess
+ case r of
+ Error _ -> return ()
+ Success m -> moduleName m `shouldBe` mn
+
+ specify "should parse source span" $ do
+ let r = parseMod $ Module ss [] mn mp [] [] [] []
+ r `shouldSatisfy` isSuccess
+ case r of
+ Error _ -> return ()
+ Success m -> moduleSourceSpan m `shouldBe` ss
+
+ specify "should parse module path" $ do
+ let r = parseMod $ Module ss [] mn mp [] [] [] []
+ r `shouldSatisfy` isSuccess
+ case r of
+ Error _ -> return ()
+ Success m -> modulePath m `shouldBe` mp
+
+ specify "should parse imports" $ do
+ let r = parseMod $ Module ss [] mn mp [(ann, mn)] [] [] []
+ r `shouldSatisfy` isSuccess
+ case r of
+ Error _ -> return ()
+ Success m -> moduleImports m `shouldBe` [(ann, mn)]
+
+ specify "should parse exports" $ do
+ let r = parseMod $ Module ss [] mn mp [] [Ident "exp"] [] []
+ r `shouldSatisfy` isSuccess
+ case r of
+ Error _ -> return ()
+ Success m -> moduleExports m `shouldBe` [Ident "exp"]
+
+ specify "should parse foreign" $ do
+ let r = parseMod $ Module ss [] mn mp [] [] [Ident "exp"] []
+ r `shouldSatisfy` isSuccess
+ case r of
+ Error _ -> return ()
+ Success m -> moduleForeign m `shouldBe` [Ident "exp"]
+
+ context "Expr" $ do
+ specify "should parse literals" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "x1") $ Literal ann (NumericLiteral (Left 1))
+ , NonRec ann (Ident "x2") $ Literal ann (NumericLiteral (Right 1.0))
+ , NonRec ann (Ident "x3") $ Literal ann (StringLiteral (mkString "abc"))
+ , NonRec ann (Ident "x4") $ Literal ann (CharLiteral 'c')
+ , NonRec ann (Ident "x5") $ Literal ann (BooleanLiteral True)
+ , NonRec ann (Ident "x6") $ Literal ann (ArrayLiteral [Literal ann (CharLiteral 'a')])
+ , NonRec ann (Ident "x7") $ Literal ann (ObjectLiteral [(mkString "a", Literal ann (CharLiteral 'a'))])
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse Constructor" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "constructor") $ Constructor ann (ProperName "Either") (ProperName "Left") [Ident "value0"] ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse Accessor" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "x") $
+ Accessor ann (mkString "field") (Literal ann $ ObjectLiteral [(mkString "field", Literal ann (NumericLiteral (Left 1)))]) ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse ObjectUpdate" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "objectUpdate") $
+ ObjectUpdate ann
+ (Literal ann $ ObjectLiteral [(mkString "field", Literal ann (StringLiteral (mkString "abc")))])
+ [(mkString "field", Literal ann (StringLiteral (mkString "xyz")))]
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse Abs" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "abs")
+ $ Abs ann (Ident "x") (Var ann (Qualified (Just mn) (Ident "x")))
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse App" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "app")
+ $ App ann
+ (Abs ann (Ident "x") (Var ann (Qualified Nothing (Ident "x"))))
+ (Literal ann (CharLiteral 'c'))
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse Case" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "case") $
+ Case ann [Var ann (Qualified Nothing (Ident "x"))]
+ [ CaseAlternative
+ [ NullBinder ann ]
+ (Right (Literal ann (CharLiteral 'a')))
+ ]
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse Case with guards" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "case") $
+ Case ann [Var ann (Qualified Nothing (Ident "x"))]
+ [ CaseAlternative
+ [ NullBinder ann ]
+ (Left [(Literal ann (BooleanLiteral True), Literal ann (CharLiteral 'a'))])
+ ]
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse Let" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "case") $
+ Let ann
+ [ Rec [((ann, Ident "a"), Var ann (Qualified Nothing (Ident "x")))] ]
+ (Literal ann (BooleanLiteral True))
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ context "Meta" $ do
+ specify "should parse IsConstructor" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec (ss, [], Nothing, Just (IsConstructor ProductType [Ident "x"])) (Ident "x") $
+ Literal (ss, [], Nothing, Just (IsConstructor SumType [])) (CharLiteral 'a')
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse IsNewtype" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec (ss, [], Nothing, Just IsNewtype) (Ident "x") $
+ Literal ann (CharLiteral 'a')
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse IsTypeClassConstructor" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec (ss, [], Nothing, Just IsTypeClassConstructor) (Ident "x") $
+ Literal ann (CharLiteral 'a')
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse IsForeign" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec (ss, [], Nothing, Just IsForeign) (Ident "x") $
+ Literal ann (CharLiteral 'a')
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ context "Binders" $ do
+ specify "should parse LiteralBinder" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "case") $
+ Case ann [Var ann (Qualified Nothing (Ident "x"))]
+ [ CaseAlternative
+ [ LiteralBinder ann (BooleanLiteral True) ]
+ (Right (Literal ann (CharLiteral 'a')))
+ ]
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse VarBinder" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "case") $
+ Case ann [Var ann (Qualified Nothing (Ident "x"))]
+ [ CaseAlternative
+ [ ConstructorBinder
+ ann
+ (Qualified (Just (ModuleName [ProperName "Data", ProperName "Either"])) (ProperName "Either"))
+ (Qualified Nothing (ProperName "Left"))
+ [VarBinder ann (Ident "z")]
+ ]
+ (Right (Literal ann (CharLiteral 'a')))
+ ]
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse NamedBinder" $ do
+ let m = Module ss [] mn mp [] [] []
+ [ NonRec ann (Ident "case") $
+ Case ann [Var ann (Qualified Nothing (Ident "x"))]
+ [ CaseAlternative
+ [ NamedBinder ann (Ident "w") (NamedBinder ann (Ident "w'") (VarBinder ann (Ident "w''"))) ]
+ (Right (Literal ann (CharLiteral 'a')))
+ ]
+ ]
+ parseMod m `shouldSatisfy` isSuccess
+
+ context "Comments" $ do
+ specify "should parse LineComment" $ do
+ let m = Module ss [ LineComment "line" ] mn mp [] [] [] []
+ parseMod m `shouldSatisfy` isSuccess
+
+ specify "should parse BlockComment" $ do
+ let m = Module ss [ BlockComment "block" ] mn mp [] [] [] []
+ parseMod m `shouldSatisfy` isSuccess
diff --git a/tests/TestDocs.hs b/tests/TestDocs.hs
index e486988..8bd082e 100644
--- a/tests/TestDocs.hs
+++ b/tests/TestDocs.hs
@@ -15,6 +15,7 @@ import Control.Monad.IO.Class (liftIO)
import Data.List (findIndex)
import Data.Foldable
import Safe (headMay)
+import qualified Data.Map as Map
import Data.Maybe (fromMaybe, mapMaybe)
import Data.Monoid
import Data.Text (Text)
@@ -32,7 +33,9 @@ import qualified Language.PureScript.Publish.ErrorsWarnings as Publish
import Web.Bower.PackageMeta (parsePackageName, runPackageName)
import TestUtils
-import Test.Hspec (Spec, it, context, expectationFailure, runIO, hspec)
+
+import Test.Tasty
+import Test.Tasty.Hspec (Spec, it, context, expectationFailure, runIO, testSpec)
publishOpts :: Publish.PublishOptions
publishOpts = Publish.defaultPublishOptions
@@ -44,11 +47,11 @@ publishOpts = Publish.defaultPublishOptions
getPackage :: IO (Either Publish.PackageError (Docs.Package Docs.NotYetKnown))
getPackage =
- pushd "examples/docs" $
+ pushd "tests/purs/docs" $
Publish.preparePackage "bower.json" "resolutions.json" publishOpts
-main :: IO ()
-main = hspec spec
+main :: IO TestTree
+main = testSpec "docs" spec
spec :: Spec
spec = do
@@ -62,18 +65,31 @@ spec = do
let linksCtx = Docs.getLinksContext pkg
- context "Language.PureScript.Docs" $
- forM_ testCases $ \(mnString, assertions) -> do
- let mn = P.moduleNameFromString mnString
- mdl = find ((==) mn . Docs.modName) pkgModules
+ context "Language.PureScript.Docs" $ do
+ context "Doc generation tests:" $
+ forM_ testCases $ \(mnString, assertions) -> do
+ let mn = P.moduleNameFromString mnString
+ mdl = find ((==) mn . Docs.modName) pkgModules
- context ("in module " ++ T.unpack mnString) $ do
- case mdl of
- Nothing ->
- it "exists in docs output" $
- expectationFailure ("module not found in docs: " ++ T.unpack mnString)
- Just mdl' ->
- toHspec linksCtx mdl' assertions
+ context ("in module " ++ T.unpack mnString) $
+ case mdl of
+ Nothing ->
+ it "exists in docs output" $
+ expectationFailure ("module not found in docs: " ++ T.unpack mnString)
+ Just mdl' ->
+ toHspec linksCtx mdl' assertions
+
+ context "Tag generation tests:" $
+ forM_ testTagsCases $ \(mnString, assertions) -> do
+ let mn = P.moduleNameFromString mnString
+ mdl = find ((==) mn . Docs.modName) pkgModules
+ context ("in module " ++ T.unpack mnString) $
+ case mdl of
+ Nothing ->
+ it "exists in docs output" $
+ expectationFailure ("module not found in docs: " ++ T.unpack mnString)
+ Just mdl' ->
+ tagAssertionsToHspec mdl' assertions
where
toHspec :: Docs.LinksContext -> Docs.Module -> [DocsAssertion] -> Spec
@@ -86,6 +102,17 @@ spec = do
Fail reason ->
expectationFailure (T.unpack (displayAssertionFailure reason))
+ tagAssertionsToHspec :: Docs.Module -> [TagsAssertion] -> Spec
+ tagAssertionsToHspec mdl assertions =
+ let tags = Map.fromList $ Docs.tags mdl
+ in forM_ assertions $ \a ->
+ it (T.unpack (displayTagsAssertion a)) $ do
+ case runTagsAssertion a tags of
+ TagsPass ->
+ pure ()
+ TagsFail reason ->
+ expectationFailure (T.unpack (displayTagsAssertionFailure reason))
+
takeJust :: String -> Maybe a -> a
takeJust msg = fromMaybe (error msg)
@@ -128,6 +155,12 @@ data DocsAssertion
-- | Assert that a given declaration comes before another in the output
| ShouldComeBefore P.ModuleName Text Text
+data TagsAssertion
+ -- | Assert that a particular declaration is tagged
+ = ShouldBeTagged Text Int
+ -- | Assert that a particular declaration is not tagged
+ | ShouldNotBeTagged Text
+
displayAssertion :: DocsAssertion -> Text
displayAssertion = \case
ShouldBeDocumented mn decl children ->
@@ -165,6 +198,13 @@ displayAssertion = \case
showQual mn declA <> " should come before " <> showQual mn declB <>
" in the docs"
+displayTagsAssertion :: TagsAssertion -> Text
+displayTagsAssertion = \case
+ ShouldBeTagged decl l ->
+ decl <> " should be tagged at line " <> T.pack (show l)
+ ShouldNotBeTagged decl ->
+ decl <> " should not be tagged"
+
data DocsAssertionFailure
-- | A declaration was not documented, but should have been
= NotDocumented P.ModuleName Text
@@ -209,6 +249,14 @@ data DocsAssertionFailure
-- | Declarations were in the wrong order
| WrongOrder P.ModuleName Text Text
+data TagsAssertionFailure
+ -- | A declaration was not tagged, but should have been
+ = NotTagged Text
+ -- | A declaration was tagged, but should not have been
+ | Tagged Text Int
+ -- | A declaration was tagged on the wrong line
+ | TaggedWrongLine Text Int Int
+
displayAssertionFailure :: DocsAssertionFailure -> Text
displayAssertionFailure = \case
NotDocumented _ decl ->
@@ -249,10 +297,25 @@ displayAssertionFailure = \case
WrongOrder _ before after ->
"expected to see " <> before <> " before " <> after
+displayTagsAssertionFailure :: TagsAssertionFailure -> Text
+displayTagsAssertionFailure = \case
+ NotTagged decl ->
+ decl <> " was not tagged, but should have been"
+ Tagged decl line ->
+ decl <> " was tagged at line " <> T.pack (show line) <>
+ ", but should not have been"
+ TaggedWrongLine decl taggedLine desiredLine ->
+ decl <> " was tagged at line " <> T.pack (show taggedLine) <>
+ ", but should have been tagged at line " <> T.pack (show desiredLine)
+
data DocsAssertionResult
= Pass
| Fail DocsAssertionFailure
+data TagsAssertionResult
+ = TagsPass
+ | TagsFail TagsAssertionFailure
+
runAssertion :: DocsAssertion -> Docs.LinksContext -> Docs.Module -> DocsAssertionResult
runAssertion assertion linksCtx Docs.Module{..} =
case assertion of
@@ -421,6 +484,22 @@ runAssertion assertion linksCtx Docs.Module{..} =
_ ->
Nothing
+runTagsAssertion :: TagsAssertion -> Map.Map String Int -> TagsAssertionResult
+runTagsAssertion assertion tags =
+ case assertion of
+ ShouldBeTagged decl line ->
+ case Map.lookup (T.unpack decl) tags of
+ Just taggedLine ->
+ if taggedLine == line
+ then TagsPass
+ else TagsFail $ TaggedWrongLine decl taggedLine line
+ Nothing -> TagsFail $ NotTagged decl
+
+ ShouldNotBeTagged decl ->
+ case Map.lookup (T.unpack decl) tags of
+ Just taggedLine -> TagsFail $ Tagged decl taggedLine
+ Nothing -> TagsPass
+
checkConstrained :: P.Type -> Text -> Bool
checkConstrained ty tyClass =
case ty of
@@ -582,6 +661,29 @@ testCases =
shouldBeOrdered mn declNames =
zipWith (ShouldComeBefore mn) declNames (tail declNames)
+testTagsCases :: [(Text, [TagsAssertion])]
+testTagsCases =
+ [ ("DeclOrder",
+ [ -- explicit exports
+ ShouldBeTagged "x1" 10
+ , ShouldBeTagged "x3" 11
+ , ShouldBeTagged "X2" 13
+ , ShouldBeTagged "X4" 14
+ , ShouldBeTagged "A" 16
+ , ShouldBeTagged "B" 17
+ ])
+ , ("Example2",
+ [ -- all symbols exported
+ ShouldBeTagged "one" 3
+ , ShouldBeTagged "two" 6
+ ])
+ , ("ExplicitExport",
+ [ -- only one of two symbols exported
+ ShouldBeTagged "one" 3
+ , ShouldNotBeTagged "two"
+ ])
+ ]
+
showQual :: P.ModuleName -> Text -> Text
showQual mn decl =
P.runModuleName mn <> "." <> decl
diff --git a/tests/TestHierarchy.hs b/tests/TestHierarchy.hs
index 98bea9a..898f869 100644
--- a/tests/TestHierarchy.hs
+++ b/tests/TestHierarchy.hs
@@ -1,12 +1,16 @@
{-# LANGUAGE OverloadedStrings #-}
module TestHierarchy where
+import Prelude
+
import Language.PureScript.Hierarchy
import qualified Language.PureScript as P
-import Test.Hspec (describe, hspec, it, shouldBe)
-main :: IO ()
-main = hspec $ do
+import Test.Tasty
+import Test.Tasty.Hspec (describe, it, shouldBe, testSpec)
+
+main :: IO TestTree
+main = testSpec "hierarchy" $ do
describe "Language.PureScript.Hierarchy" $ do
describe "prettyPrint" $ do
it "creates just the node when there is no relation" $ do
diff --git a/tests/TestIde.hs b/tests/TestIde.hs
new file mode 100644
index 0000000..8879d85
--- /dev/null
+++ b/tests/TestIde.hs
@@ -0,0 +1,19 @@
+module TestIde where
+
+import Prelude
+
+import Control.Monad (unless)
+import Language.PureScript.Ide.Test
+import qualified PscIdeSpec
+import Test.Tasty
+import Test.Tasty.Hspec
+
+main :: IO TestTree
+main =
+ testSpec "ide" (beforeAll_ setup PscIdeSpec.spec)
+ where
+ setup = do
+ deleteOutputFolder
+ s <- compileTestProject
+ unless s (fail "Failed to compile .purs sources")
+
diff --git a/tests/TestPrimDocs.hs b/tests/TestPrimDocs.hs
index 9309684..1eb68d5 100644
--- a/tests/TestPrimDocs.hs
+++ b/tests/TestPrimDocs.hs
@@ -1,6 +1,9 @@
module TestPrimDocs where
+import Prelude
+
import Control.Monad
+import Data.Monoid ((<>))
import Data.List ((\\))
import qualified Data.Map as Map
import qualified Data.Set as Set
@@ -11,14 +14,20 @@ import qualified Language.PureScript.Docs.AsMarkdown as D
main :: IO ()
main = do
putStrLn "Test that there are no bottoms hiding in primDocsModule"
- seq (D.runDocs (D.modulesAsMarkdown [D.primDocsModule])) (return ())
+ seq (D.runDocs (D.modulesAsMarkdown D.primModules)) (return ())
putStrLn "Test that Prim is fully documented"
let actualPrimNames =
-- note that prim type classes are listed in P.primTypes
- (map (P.runProperName . P.disqualify . fst) $ Map.toList P.primTypes) ++
- (map (P.runProperName . P.disqualify) $ Set.toList P.primKinds)
- let documentedPrimNames = map D.declTitle (D.modDeclarations D.primDocsModule)
+ (map (P.runProperName . P.disqualify . fst) $ Map.toList
+ ( P.primTypes <>
+ P.primOrderingTypes <>
+ P.primRowTypes <>
+ P.primRowListTypes <>
+ P.primTypeErrorTypes <>
+ P.primSymbolTypes )) ++
+ (map (P.runProperName . P.disqualify) $ Set.toList P.allPrimKinds)
+ let documentedPrimNames = map D.declTitle (concatMap D.modDeclarations D.primModules)
let undocumentedNames = actualPrimNames \\ documentedPrimNames
let extraNames = documentedPrimNames \\ actualPrimNames
@@ -27,4 +36,4 @@ main = do
error $ "Undocumented Prim names: " ++ show undocumentedNames
when (not (null extraNames)) $
- error $ "Extra Prim names: " ++ show undocumentedNames
+ error $ "Extra Prim names: " ++ show extraNames
diff --git a/tests/TestPscIde.hs b/tests/TestPscIde.hs
deleted file mode 100644
index 97ff41f..0000000
--- a/tests/TestPscIde.hs
+++ /dev/null
@@ -1,13 +0,0 @@
-module TestPscIde where
-
-import Control.Monad (unless)
-import qualified PscIdeSpec
-import Language.PureScript.Ide.Test
-import Test.Hspec
-
-main :: IO ()
-main = do
- deleteOutputFolder
- s <- compileTestProject
- unless s (fail "Failed to compile .purs sources")
- hspec PscIdeSpec.spec
diff --git a/tests/TestPscPublish.hs b/tests/TestPscPublish.hs
index 89c6f4c..9126d36 100644
--- a/tests/TestPscPublish.hs
+++ b/tests/TestPscPublish.hs
@@ -4,6 +4,8 @@
module TestPscPublish where
+import Prelude
+
import Control.Monad.IO.Class (liftIO)
import System.Exit (exitFailure)
import Data.ByteString.Lazy (ByteString)
diff --git a/tests/TestPsci.hs b/tests/TestPsci.hs
index c5017f1..1f985c1 100644
--- a/tests/TestPsci.hs
+++ b/tests/TestPsci.hs
@@ -3,13 +3,15 @@ module TestPsci where
import Prelude ()
import Prelude.Compat
-import Test.Hspec
import TestPsci.CommandTest (commandTests)
import TestPsci.CompletionTest (completionTests)
import TestPsci.EvalTest (evalTests)
-main :: IO ()
-main = hspec $ do
+import Test.Tasty
+import Test.Tasty.Hspec
+
+main :: IO TestTree
+main = testSpec "repl" $ do
completionTests
commandTests
evalTests
diff --git a/tests/TestPsci/CommandTest.hs b/tests/TestPsci/CommandTest.hs
index 57e7742..a84fdca 100644
--- a/tests/TestPsci/CommandTest.hs
+++ b/tests/TestPsci/CommandTest.hs
@@ -35,6 +35,12 @@ commandTests = context "commandTests" $ do
specPSCi ":complete" $ do
":complete ma" `prints` []
- ":complete Data.Functor.ma" `prints` (unlines (map ("Data.Functor." ++ ) ["map", "mapFlipped"]))
+ ":complete Data.Functor.ma" `prints` []
run "import Data.Functor"
- ":complete ma" `prints` (unlines ["map", "mapFlipped"])
+ ":complete ma" `prints` unlines ["map", "mapFlipped"]
+ run "import Control.Monad as M"
+ ":complete M.a" `prints` unlines ["M.ap", "M.apply"]
+
+ specPSCi ":browse" $ do
+ ":browse Mirp" `printed` flip shouldContain "is not valid"
+ ":browse Prim" `printed` flip shouldContain "class Partial"
diff --git a/tests/TestPsci/CompletionTest.hs b/tests/TestPsci/CompletionTest.hs
index 1040561..c513cb4 100644
--- a/tests/TestPsci/CompletionTest.hs
+++ b/tests/TestPsci/CompletionTest.hs
@@ -17,8 +17,9 @@ import TestUtils (getSupportModuleNames)
completionTests :: Spec
completionTests = context "completionTests" $ do
- mns <- runIO $ getSupportModuleNames
- mapM_ assertCompletedOk (completionTestData mns)
+ mns <- runIO getSupportModuleNames
+ psciState <- runIO getPSCiStateForCompletion
+ mapM_ (assertCompletedOk psciState) (completionTestData mns)
-- If the cursor is at the right end of the line, with the 1st element of the
-- pair as the text in the line, then pressing tab should offer all the
@@ -33,12 +34,12 @@ completionTestData supportModuleNames =
, (":b", [":browse"])
-- :browse should complete module names
- , (":b Control.Monad.E", map (":b Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console", ".Uncurried"])
- , (":b Control.Monad.Eff.", map (":b Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console", ".Uncurried"])
+ , (":b Eff", map (":b Effect" ++) ["", ".Unsafe", ".Class", ".Console", ".Uncurried", ".Ref"])
+ , (":b Effect.", map (":b Effect" ++) [".Unsafe", ".Class", ".Console", ".Uncurried", ".Ref"])
-- import should complete module names
- , ("import Control.Monad.E", map ("import Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console", ".Uncurried"])
- , ("import Control.Monad.Eff.", map ("import Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console", ".Uncurried"])
+ , ("import Eff", map ("import Effect" ++) ["", ".Unsafe", ".Class", ".Console", ".Uncurried", ".Ref"])
+ , ("import Effect.", map ("import Effect" ++) [".Unsafe", ".Class", ".Console", ".Uncurried", ".Ref"])
-- :quit, :help, :reload, :clear should not complete
, (":help ", [])
@@ -50,19 +51,26 @@ completionTestData supportModuleNames =
, (":show ", [":show import", ":show loaded"])
, (":show a", [])
- -- :type should complete values and data constructors in scope
- , (":type Control.Monad.Eff.Console.lo", [":type Control.Monad.Eff.Console.log", ":type Control.Monad.Eff.Console.logShow"])
- --, (":type uni", [":type unit"])
- --, (":type E", [":type EQ"])
+ -- :type should complete next word from values and constructors in scope
+ , (":type uni", [":type unit"])
+ , (":type E", [":type EQ"])
+ , (":type P.", map (":type P." ++) ["EQ", "GT", "LT", "unit"]) -- import Prelude (unit, Ordering(..)) as P
+ , (":type Effect.Console.lo", [])
+ , (":type voi", [])
- -- :kind should complete types in scope
- --, (":kind C", [":kind Control.Monad.Eff.Pure"])
- --, (":kind O", [":kind Ordering"])
+ -- :kind should complete next word from types in scope
+ , (":kind Str", [":kind String"])
+ , (":kind ST.", [":kind ST.ST"]) -- import Control.Monad.ST as ST
+ , (":kind STRef.", [":kind STRef.STRef"]) -- import Control.Monad.ST.Ref as STRef
+ , (":kind Effect.", [])
- -- Only one argument for directives should be completed
+ -- Only one argument for these directives should be completed
, (":show import ", [])
- , (":type EQ ", [])
- , (":kind Ordering ", [])
+ , (":browse Data.List ", [])
+
+ -- These directives take any number of completable terms
+ , (":type const compa", [":type const compare", ":type const comparing"])
+ , (":kind Array In", [":kind Array Int"])
-- a few other import tests
, ("impor", ["import"])
@@ -73,36 +81,57 @@ completionTestData supportModuleNames =
, ("\"hi", [])
, ("34", [])
- -- Identifiers and data constructors should be completed
- --, ("uni", ["unit"])
- , ("Control.Monad.Eff.Class.", ["Control.Monad.Eff.Class.liftEff"])
- --, ("G", ["GT"])
- , ("Data.Ordering.L", ["Data.Ordering.LT"])
-
- -- if a module is imported qualified, values should complete under the
- -- qualified name, as well as the original name.
- , ("ST.new", ["ST.newSTRef"])
- , ("Control.Monad.ST.new", ["Control.Monad.ST.newSTRef"])
+ -- Identifiers and data constructors in scope should be completed
+ , ("uni", ["unit"])
+ , ("G", ["GT"])
+ , ("P.G", ["P.GT"])
+ , ("P.uni", ["P.unit"])
+ , ("voi", []) -- import Prelude hiding (void)
+ , ("Effect.Class.", [])
+
+ -- complete first name after type annotation symbol
+ , ("1 :: I", ["1 :: Int"])
+ , ("1 ::I", ["1 ::Int"])
+ , ("1:: I", ["1:: Int"])
+ , ("1::I", ["1::Int"])
+ , ("(1::Int) uni", ["(1::Int) unit"]) -- back to completing values
+
+ -- Parens and brackets aren't considered part of the current identifier
+ , ("map id [uni", ["map id [unit"])
+ , ("map (cons", ["map (const"])
]
-assertCompletedOk :: (String, [String]) -> Spec
-assertCompletedOk (line, expecteds) = specify line $ do
- results <- runCM (completion' (reverse line, ""))
+assertCompletedOk :: PSCiState -> (String, [String]) -> Spec
+assertCompletedOk psciState (line, expecteds) = specify line $ do
+ results <- runCM psciState (completion' (reverse line, ""))
let actuals = formatCompletions results
sort actuals `shouldBe` sort expecteds
-runCM :: CompletionM a -> IO a
-runCM act = do
- psciState <- getPSCiStateForCompletion
- evalStateT (liftCompletionM act) psciState
+runCM :: PSCiState -> CompletionM a -> IO a
+runCM psciState act = evalStateT (liftCompletionM act) psciState
getPSCiStateForCompletion :: IO PSCiState
getPSCiStateForCompletion = do
- (PSCiState _ bs es, _) <- initTestPSCiEnv
- let imports = [controlMonadSTasST, (P.ModuleName [P.ProperName "Prelude"], P.Implicit, Nothing)]
- return $ PSCiState imports bs es
-
-controlMonadSTasST :: ImportedModule
-controlMonadSTasST = (s "Control.Monad.ST", P.Implicit, Just (s "ST"))
+ (st, _) <- initTestPSCiEnv
+ let imports = [-- import Control.Monad.ST as S
+ (qualName "Control.Monad.ST"
+ ,P.Implicit
+ ,Just (qualName "ST"))
+ , -- import Control.Monad.ST.Ref as STRef
+ (qualName "Control.Monad.ST.Ref"
+ ,P.Implicit
+ ,Just (qualName "STRef"))
+ -- import Prelude hiding (void)
+ ,(qualName "Prelude"
+ ,P.Hiding [valName "void"]
+ ,Nothing)
+ -- import Prelude (unit, Ordering(..)) as P
+ ,(qualName "Prelude"
+ ,P.Explicit [valName "unit", typeName "Ordering"]
+ ,Just (qualName "P"))]
+ return $ updateImportedModules (const imports) st
where
- s = P.moduleNameFromString
+ qualName = P.moduleNameFromString
+ valName = P.ValueRef srcSpan . P.Ident
+ typeName t = P.TypeRef srcSpan (P.ProperName t) Nothing
+ srcSpan = P.internalModuleSourceSpan "<internal>"
diff --git a/tests/TestPsci/EvalTest.hs b/tests/TestPsci/EvalTest.hs
index 82b566f..5aae8ab 100644
--- a/tests/TestPsci/EvalTest.hs
+++ b/tests/TestPsci/EvalTest.hs
@@ -23,7 +23,7 @@ evalTests = context "evalTests" $ do
evalTestFiles :: IO [FilePath]
evalTestFiles = do
cwd <- getCurrentDirectory
- let psciExamples = cwd </> "examples" </> "psci"
+ let psciExamples = cwd </> "tests" </> "purs" </> "psci"
Glob.globDir1 (Glob.compile "**/*.purs") psciExamples
data EvalLine = Line String
diff --git a/tests/TestPsci/TestEnv.hs b/tests/TestPsci/TestEnv.hs
index fdf0ca9..a41c018 100644
--- a/tests/TestPsci/TestEnv.hs
+++ b/tests/TestPsci/TestEnv.hs
@@ -3,6 +3,7 @@ module TestPsci.TestEnv where
import Prelude ()
import Prelude.Compat
+import Control.Monad (void)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.RWS.Strict (evalRWST, RWST)
import qualified Language.PureScript as P
@@ -12,7 +13,7 @@ import System.Exit
import System.FilePath ((</>))
import qualified System.FilePath.Glob as Glob
import System.Process (readProcessWithExitCode)
-import Test.Hspec (shouldBe)
+import Test.Hspec (shouldBe, Expectation)
-- | A monad transformer for handle PSCi actions in tests
type TestPSCi a = RWST PSCiConfig () PSCiState IO a
@@ -35,7 +36,7 @@ initTestPSCiEnv = do
case makeResultOrError of
Left errs -> putStrLn (P.prettyPrintMultipleErrors P.defaultPPEOptions errs) >> exitFailure
Right (externs, env) ->
- return (PSCiState [] [] (zip (map snd modules) externs), PSCiConfig pursFiles env)
+ return (updateLoadedExterns (const (zip (map snd modules) externs)) initialPSCiState, PSCiConfig pursFiles env)
-- | Execute a TestPSCi, returning IO
execTestPSCi :: TestPSCi a -> IO a
@@ -90,7 +91,7 @@ evaluatesTo command expected = runAndEval command evalJsAndCompare ignorePrinted
-- | An assertion to check command PSCi printed output against a given string
prints :: String -> String -> TestPSCi ()
-prints command expected = runAndEval command evalJsAndIgnore evalPrinted
- where
- evalJsAndIgnore = jsEval *> return ()
- evalPrinted s = s `equalsTo` expected
+prints command expected = printed command (`shouldBe` expected)
+
+printed :: String -> (String -> Expectation) -> TestPSCi ()
+printed command f = runAndEval command (void jsEval) (liftIO . f)
diff --git a/tests/purs/docs/bower.json b/tests/purs/docs/bower.json
new file mode 100644
index 0000000..a6a0385
--- /dev/null
+++ b/tests/purs/docs/bower.json
@@ -0,0 +1,21 @@
+{
+ "name": "docs-test-package",
+ "version": "1.0.0",
+ "moduleType": [
+ "node"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/not-real/not-a-real-repo.git"
+ },
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "output"
+ ],
+ "dependencies": {
+ "purescript-prelude": "./bower_components/purescript-prelude"
+ },
+ "license": "MIT"
+}
diff --git a/tests/purs/docs/bower_components/purescript-prelude/src/Prelude.purs b/tests/purs/docs/bower_components/purescript-prelude/src/Prelude.purs
new file mode 100644
index 0000000..84b40b0
--- /dev/null
+++ b/tests/purs/docs/bower_components/purescript-prelude/src/Prelude.purs
@@ -0,0 +1,8 @@
+module Prelude where
+
+newtype Unit = Unit {}
+
+unit :: Unit
+unit = Unit {}
+
+data Boolean2 = True | False
diff --git a/tests/purs/docs/output/ConstrainedArgument/externs.json b/tests/purs/docs/output/ConstrainedArgument/externs.json
new file mode 100644
index 0000000..ec85b9f
--- /dev/null
+++ b/tests/purs/docs/output/ConstrainedArgument/externs.json
@@ -0,0 +1 @@
+{"efVersion":"0.10.7","efModuleName":["ConstrainedArgument"],"efExports":[{"TypeRef":["MultiWithArgs",[]]},{"TypeRef":["MultiWithoutArgs",[]]},{"TypeRef":["WithArgs",[]]},{"TypeRef":["WithoutArgs",[]]},{"TypeClassRef":"Foo"}],"efImports":[{"eiModule":["Prim"],"eiImportType":{"Implicit":[]},"eiImportedAs":null}],"efFixities":[],"efTypeFixities":[],"efDeclarations":[{"EDType":{"edTypeName":"MultiWithArgs","edTypeKind":{"tag":"NamedKind","contents":[["Prim"],"Type"]},"edTypeDeclarationKind":{"TypeSynonym":[]}}},{"EDTypeSynonym":{"edTypeSynonymName":"MultiWithArgs","edTypeSynonymArguments":[],"edTypeSynonymType":{"tag":"ForAll","contents":["b",{"tag":"ForAll","contents":["a",{"tag":"TypeApp","contents":[{"tag":"TypeApp","contents":[{"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"tag":"ConstrainedType","contents":[[{"constraintClass":[["ConstrainedArgument"],"Foo"],"constraintArgs":[{"tag":"TypeVar","contents":"a"}],"constraintData":null}],{"tag":"ConstrainedType","contents":[[{"constraintClass":[["ConstrainedArgument"],"Foo"],"constraintArgs":[{"tag":"TypeVar","contents":"b"}],"constraintData":null}],{"tag":"TypeVar","contents":"a"}]}]}]},{"tag":"TypeVar","contents":"a"}]},null]},null]}}},{"EDType":{"edTypeName":"MultiWithoutArgs","edTypeKind":{"tag":"NamedKind","contents":[["Prim"],"Type"]},"edTypeDeclarationKind":{"TypeSynonym":[]}}},{"EDTypeSynonym":{"edTypeSynonymName":"MultiWithoutArgs","edTypeSynonymArguments":[],"edTypeSynonymType":{"tag":"ForAll","contents":["a",{"tag":"TypeApp","contents":[{"tag":"TypeApp","contents":[{"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"tag":"ConstrainedType","contents":[[{"constraintClass":[["Prim"],"Partial"],"constraintArgs":[],"constraintData":null}],{"tag":"ConstrainedType","contents":[[{"constraintClass":[["Prim"],"Partial"],"constraintArgs":[],"constraintData":null}],{"tag":"TypeVar","contents":"a"}]}]}]},{"tag":"TypeVar","contents":"a"}]},null]}}},{"EDType":{"edTypeName":"WithArgs","edTypeKind":{"tag":"NamedKind","contents":[["Prim"],"Type"]},"edTypeDeclarationKind":{"TypeSynonym":[]}}},{"EDTypeSynonym":{"edTypeSynonymName":"WithArgs","edTypeSynonymArguments":[],"edTypeSynonymType":{"tag":"ForAll","contents":["a",{"tag":"TypeApp","contents":[{"tag":"TypeApp","contents":[{"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"tag":"ConstrainedType","contents":[[{"constraintClass":[["ConstrainedArgument"],"Foo"],"constraintArgs":[{"tag":"TypeVar","contents":"a"}],"constraintData":null}],{"tag":"TypeVar","contents":"a"}]}]},{"tag":"TypeVar","contents":"a"}]},null]}}},{"EDType":{"edTypeName":"WithoutArgs","edTypeKind":{"tag":"NamedKind","contents":[["Prim"],"Type"]},"edTypeDeclarationKind":{"TypeSynonym":[]}}},{"EDTypeSynonym":{"edTypeSynonymName":"WithoutArgs","edTypeSynonymArguments":[],"edTypeSynonymType":{"tag":"ForAll","contents":["a",{"tag":"TypeApp","contents":[{"tag":"TypeApp","contents":[{"tag":"TypeConstructor","contents":[["Prim"],"Function"]},{"tag":"ConstrainedType","contents":[[{"constraintClass":[["Prim"],"Partial"],"constraintArgs":[],"constraintData":null}],{"tag":"TypeVar","contents":"a"}]}]},{"tag":"TypeVar","contents":"a"}]},null]}}},{"EDType":{"edTypeName":"Foo","edTypeKind":{"tag":"FunKind","contents":[{"tag":"NamedKind","contents":[["Prim"],"Type"]},{"tag":"NamedKind","contents":[["Prim"],"Type"]}]},"edTypeDeclarationKind":{"TypeSynonym":[]}}},{"EDTypeSynonym":{"edTypeSynonymName":"Foo","edTypeSynonymArguments":[["t",null]],"edTypeSynonymType":{"tag":"TypeApp","contents":[{"tag":"TypeConstructor","contents":[["Prim"],"Record"]},{"tag":"REmpty","contents":[]}]}}},{"EDClass":{"edClassName":"Foo","edClassTypeArguments":[["t",null]],"edClassMembers":[],"edClassConstraints":[],"edFunctionalDependencies":[]}}]} \ No newline at end of file
diff --git a/tests/purs/docs/output/ConstrainedArgument/index.js b/tests/purs/docs/output/ConstrainedArgument/index.js
new file mode 100644
index 0000000..4879a62
--- /dev/null
+++ b/tests/purs/docs/output/ConstrainedArgument/index.js
@@ -0,0 +1,5 @@
+"use strict";
+var Foo = {};
+module.exports = {
+ Foo: Foo
+};
diff --git a/tests/purs/docs/resolutions.json b/tests/purs/docs/resolutions.json
new file mode 100644
index 0000000..c3fced5
--- /dev/null
+++ b/tests/purs/docs/resolutions.json
@@ -0,0 +1,21 @@
+{
+ "canonicalDir": ".",
+ "pkgMeta": {
+ "dependencies": {
+ "purescript-prelude": "./bower_components/purescript-prelude"
+ }
+ },
+ "dependencies": {
+ "purescript-prelude": {
+ "canonicalDir": "bower_components/purescript-prelude",
+ "pkgMeta": {
+ "_resolution": {
+ "type": "version",
+ "tag": "v2.4.0",
+ "commit": "21067a4c782f42d08bc877214f85b92ce6769b21"
+ }
+ },
+ "dependencies": {}
+ }
+ }
+}
diff --git a/tests/purs/docs/src/ChildDeclOrder.purs b/tests/purs/docs/src/ChildDeclOrder.purs
new file mode 100644
index 0000000..7f67785
--- /dev/null
+++ b/tests/purs/docs/src/ChildDeclOrder.purs
@@ -0,0 +1,27 @@
+-- Tests should ensure that, in the docs:
+-- - First should come before Second
+-- - foo1 should be listed before foo2
+-- - the instances should be listed in the same order as this source file
+module ChildDeclOrder where
+
+data Two
+ = First
+ | Second
+
+class Show a where
+ show :: a -> String
+
+class Foo a where
+ foo1 :: a
+ foo2 :: a
+
+instance showTwo :: Show Two where
+ show _ = ""
+
+instance fooTwo :: Foo Two where
+ foo1 = First
+ foo2 = Second
+
+instance fooInt :: Foo Int where
+ foo1 = 1
+ foo2 = 2
diff --git a/tests/purs/docs/src/Clash.purs b/tests/purs/docs/src/Clash.purs
new file mode 100644
index 0000000..a2fef87
--- /dev/null
+++ b/tests/purs/docs/src/Clash.purs
@@ -0,0 +1,4 @@
+module Clash (module Clash1) where
+
+import Clash1 as Clash1
+import Clash2 as Clash2
diff --git a/tests/purs/docs/src/Clash1.purs b/tests/purs/docs/src/Clash1.purs
new file mode 100644
index 0000000..b3fc771
--- /dev/null
+++ b/tests/purs/docs/src/Clash1.purs
@@ -0,0 +1,3 @@
+module Clash1 (module Clash1a) where
+
+import Clash1a
diff --git a/tests/purs/docs/src/Clash1a.purs b/tests/purs/docs/src/Clash1a.purs
new file mode 100644
index 0000000..c21260f
--- /dev/null
+++ b/tests/purs/docs/src/Clash1a.purs
@@ -0,0 +1,9 @@
+module Clash1a where
+
+value :: Int
+value = 0
+
+type Type = Int
+
+class TypeClass a where
+ typeClassMember :: a
diff --git a/tests/purs/docs/src/Clash2.purs b/tests/purs/docs/src/Clash2.purs
new file mode 100644
index 0000000..9c531ea
--- /dev/null
+++ b/tests/purs/docs/src/Clash2.purs
@@ -0,0 +1,3 @@
+module Clash2 (module Clash2a) where
+
+import Clash2a
diff --git a/tests/purs/docs/src/Clash2a.purs b/tests/purs/docs/src/Clash2a.purs
new file mode 100644
index 0000000..5405daf
--- /dev/null
+++ b/tests/purs/docs/src/Clash2a.purs
@@ -0,0 +1,9 @@
+module Clash2a where
+
+value :: String
+value = "hello"
+
+type Type = String
+
+class TypeClass a b where
+ typeClassMember :: a -> b
diff --git a/tests/purs/docs/src/ConstrainedArgument.purs b/tests/purs/docs/src/ConstrainedArgument.purs
new file mode 100644
index 0000000..00bc5be
--- /dev/null
+++ b/tests/purs/docs/src/ConstrainedArgument.purs
@@ -0,0 +1,8 @@
+module ConstrainedArgument where
+
+class Foo t
+
+type WithoutArgs = forall a. (Partial => a) -> a
+type WithArgs = forall a. (Foo a => a) -> a
+type MultiWithoutArgs = forall a. (Partial => Partial => a) -> a
+type MultiWithArgs = forall a b. (Foo a => Foo b => a) -> a
diff --git a/tests/purs/docs/src/DeclOrder.purs b/tests/purs/docs/src/DeclOrder.purs
new file mode 100644
index 0000000..9ec2d21
--- /dev/null
+++ b/tests/purs/docs/src/DeclOrder.purs
@@ -0,0 +1,17 @@
+module DeclOrder
+ ( class A
+ , x1
+ , X2
+ , x3
+ , X4
+ , class B
+ ) where
+
+x1 = 0
+x3 = 0
+
+data X2
+data X4
+
+class A
+class B
diff --git a/tests/purs/docs/src/DeclOrderNoExportList.purs b/tests/purs/docs/src/DeclOrderNoExportList.purs
new file mode 100644
index 0000000..2cfed5d
--- /dev/null
+++ b/tests/purs/docs/src/DeclOrderNoExportList.purs
@@ -0,0 +1,10 @@
+module DeclOrderNoExportList where
+
+x1 = 0
+x3 = 0
+
+data X2
+data X4
+
+class A
+class B
diff --git a/tests/purs/docs/src/Desugar.purs b/tests/purs/docs/src/Desugar.purs
new file mode 100644
index 0000000..cc6061a
--- /dev/null
+++ b/tests/purs/docs/src/Desugar.purs
@@ -0,0 +1,8 @@
+module Desugar where
+
+data X a b = X a b
+
+test :: forall a b. X (a -> b) a -> b
+test x =
+ let X a b = x
+ in a b
diff --git a/tests/purs/docs/src/DocComments.purs b/tests/purs/docs/src/DocComments.purs
new file mode 100644
index 0000000..4bc2e93
--- /dev/null
+++ b/tests/purs/docs/src/DocComments.purs
@@ -0,0 +1,11 @@
+module DocComments where
+
+-- | This declaration has a code block:
+-- |
+-- | example == 0
+-- |
+-- | Here we are really testing that the leading whitespace is not stripped, as
+-- | this ensures that we don't accidentally change code blocks into normal
+-- | paragraphs.
+example :: Int
+example = 0
diff --git a/tests/purs/docs/src/DuplicateNames.purs b/tests/purs/docs/src/DuplicateNames.purs
new file mode 100644
index 0000000..879fec0
--- /dev/null
+++ b/tests/purs/docs/src/DuplicateNames.purs
@@ -0,0 +1,9 @@
+module DuplicateNames
+ ( module DuplicateNames
+ , module Prelude
+ ) where
+
+import Prelude (Unit)
+
+unit :: Int
+unit = 0
diff --git a/tests/purs/docs/src/Example.purs b/tests/purs/docs/src/Example.purs
new file mode 100644
index 0000000..0babd1d
--- /dev/null
+++ b/tests/purs/docs/src/Example.purs
@@ -0,0 +1,7 @@
+module Example
+ ( module Prelude
+ , module Example2
+ ) where
+
+import Prelude (Unit())
+import Example2 (one)
diff --git a/tests/purs/docs/src/Example2.purs b/tests/purs/docs/src/Example2.purs
new file mode 100644
index 0000000..f038961
--- /dev/null
+++ b/tests/purs/docs/src/Example2.purs
@@ -0,0 +1,7 @@
+module Example2 where
+
+one :: Int
+one = 1
+
+two :: Int
+two = 2
diff --git a/tests/purs/docs/src/ExplicitExport.purs b/tests/purs/docs/src/ExplicitExport.purs
new file mode 100644
index 0000000..43e7ba6
--- /dev/null
+++ b/tests/purs/docs/src/ExplicitExport.purs
@@ -0,0 +1,7 @@
+module ExplicitExport (one) where
+
+one :: Int
+one = 1
+
+two :: Int
+two = 2
diff --git a/tests/purs/docs/src/ExplicitTypeSignatures.purs b/tests/purs/docs/src/ExplicitTypeSignatures.purs
new file mode 100644
index 0000000..396ca14
--- /dev/null
+++ b/tests/purs/docs/src/ExplicitTypeSignatures.purs
@@ -0,0 +1,16 @@
+
+module ExplicitTypeSignatures where
+
+-- This should use the explicit type signature so that the type variable name
+-- is preserved.
+explicit :: forall something. something -> something
+explicit x
+ | true = x
+ | false = x
+
+-- This should use the inferred type.
+anInt :: _
+anInt = 0
+
+-- This should infer a type.
+aNumber = 1.0
diff --git a/tests/purs/docs/src/ImportedTwice.purs b/tests/purs/docs/src/ImportedTwice.purs
new file mode 100644
index 0000000..c8b297d
--- /dev/null
+++ b/tests/purs/docs/src/ImportedTwice.purs
@@ -0,0 +1,13 @@
+-- See also an example in the wild: purescript-transformers v0.8.4.
+-- Control.Monad.RWS.Trans re-exports `lift` from both Control.Monad.Trans
+-- (where it is originally defined) and Control.Monad.RWS.Class (which
+-- re-exports it from Control.Monad.Trans).
+
+module ImportedTwice
+ ( module ImportedTwiceA
+ , module ImportedTwiceB
+ )
+ where
+
+import ImportedTwiceA
+import ImportedTwiceB
diff --git a/tests/purs/docs/src/ImportedTwiceA.purs b/tests/purs/docs/src/ImportedTwiceA.purs
new file mode 100644
index 0000000..9acf57e
--- /dev/null
+++ b/tests/purs/docs/src/ImportedTwiceA.purs
@@ -0,0 +1,8 @@
+module ImportedTwiceA
+ ( module ImportedTwiceB )
+ where
+
+import ImportedTwiceB
+
+bar :: Int
+bar = 1
diff --git a/tests/purs/docs/src/ImportedTwiceB.purs b/tests/purs/docs/src/ImportedTwiceB.purs
new file mode 100644
index 0000000..6212793
--- /dev/null
+++ b/tests/purs/docs/src/ImportedTwiceB.purs
@@ -0,0 +1,4 @@
+module ImportedTwiceB where
+
+foo :: Int
+foo = 0
diff --git a/tests/purs/docs/src/MultiVirtual.purs b/tests/purs/docs/src/MultiVirtual.purs
new file mode 100644
index 0000000..19b766f
--- /dev/null
+++ b/tests/purs/docs/src/MultiVirtual.purs
@@ -0,0 +1,6 @@
+module MultiVirtual
+ ( module X )
+ where
+
+import MultiVirtual1 as X
+import MultiVirtual2 as X
diff --git a/tests/purs/docs/src/MultiVirtual1.purs b/tests/purs/docs/src/MultiVirtual1.purs
new file mode 100644
index 0000000..eb756c0
--- /dev/null
+++ b/tests/purs/docs/src/MultiVirtual1.purs
@@ -0,0 +1,4 @@
+module MultiVirtual1 where
+
+foo :: Int
+foo = 1
diff --git a/tests/purs/docs/src/MultiVirtual2.purs b/tests/purs/docs/src/MultiVirtual2.purs
new file mode 100644
index 0000000..1d1dcd7
--- /dev/null
+++ b/tests/purs/docs/src/MultiVirtual2.purs
@@ -0,0 +1,9 @@
+module MultiVirtual2
+ ( module MultiVirtual2
+ , module MultiVirtual3
+ ) where
+
+import MultiVirtual3
+
+bar :: Int
+bar = 2
diff --git a/tests/purs/docs/src/MultiVirtual3.purs b/tests/purs/docs/src/MultiVirtual3.purs
new file mode 100644
index 0000000..9da3b75
--- /dev/null
+++ b/tests/purs/docs/src/MultiVirtual3.purs
@@ -0,0 +1,4 @@
+module MultiVirtual3 where
+
+baz :: Int
+baz = 3
diff --git a/tests/purs/docs/src/NewOperators.purs b/tests/purs/docs/src/NewOperators.purs
new file mode 100644
index 0000000..61c0a7b
--- /dev/null
+++ b/tests/purs/docs/src/NewOperators.purs
@@ -0,0 +1,5 @@
+module NewOperators
+ ( module NewOperators2 )
+ where
+
+import NewOperators2
diff --git a/tests/purs/docs/src/NewOperators2.purs b/tests/purs/docs/src/NewOperators2.purs
new file mode 100644
index 0000000..67cc46c
--- /dev/null
+++ b/tests/purs/docs/src/NewOperators2.purs
@@ -0,0 +1,6 @@
+module NewOperators2 where
+
+infixl 8 _compose as >>>
+
+_compose :: forall a b c. (b -> c) -> (a -> b) -> (a -> c)
+_compose f g x = f (g x)
diff --git a/tests/purs/docs/src/NotAllCtors.purs b/tests/purs/docs/src/NotAllCtors.purs
new file mode 100644
index 0000000..bfe9ffc
--- /dev/null
+++ b/tests/purs/docs/src/NotAllCtors.purs
@@ -0,0 +1,5 @@
+module NotAllCtors
+ ( module Prelude )
+ where
+
+import Prelude (Boolean2(True))
diff --git a/tests/purs/docs/src/PrimSubmodules.purs b/tests/purs/docs/src/PrimSubmodules.purs
new file mode 100644
index 0000000..ee3c4fd
--- /dev/null
+++ b/tests/purs/docs/src/PrimSubmodules.purs
@@ -0,0 +1,11 @@
+module PrimSubmodules (Lol(..), x, y, module O) where
+
+import Prim.Ordering (kind Ordering, LT, EQ, GT) as O
+
+data Lol (a :: O.Ordering) = Lol Int
+
+x :: Lol O.LT
+x = Lol 0
+
+y :: Lol O.EQ
+y = Lol 1
diff --git a/tests/purs/docs/src/ReExportedTypeClass.purs b/tests/purs/docs/src/ReExportedTypeClass.purs
new file mode 100644
index 0000000..17d5c4d
--- /dev/null
+++ b/tests/purs/docs/src/ReExportedTypeClass.purs
@@ -0,0 +1,5 @@
+module ReExportedTypeClass
+ ( module SomeTypeClass )
+ where
+
+import SomeTypeClass
diff --git a/tests/purs/docs/src/SolitaryTypeClassMember.purs b/tests/purs/docs/src/SolitaryTypeClassMember.purs
new file mode 100644
index 0000000..2e94edc
--- /dev/null
+++ b/tests/purs/docs/src/SolitaryTypeClassMember.purs
@@ -0,0 +1,6 @@
+module SolitaryTypeClassMember
+ ( module SomeTypeClass )
+ where
+
+import SomeTypeClass (member)
+
diff --git a/tests/purs/docs/src/SomeTypeClass.purs b/tests/purs/docs/src/SomeTypeClass.purs
new file mode 100644
index 0000000..204820f
--- /dev/null
+++ b/tests/purs/docs/src/SomeTypeClass.purs
@@ -0,0 +1,5 @@
+
+module SomeTypeClass where
+
+class SomeClass a where
+ member :: a
diff --git a/tests/purs/docs/src/Transitive1.purs b/tests/purs/docs/src/Transitive1.purs
new file mode 100644
index 0000000..862f128
--- /dev/null
+++ b/tests/purs/docs/src/Transitive1.purs
@@ -0,0 +1,5 @@
+module Transitive1
+ ( module Transitive2 )
+ where
+
+import Transitive2
diff --git a/tests/purs/docs/src/Transitive2.purs b/tests/purs/docs/src/Transitive2.purs
new file mode 100644
index 0000000..e607d1e
--- /dev/null
+++ b/tests/purs/docs/src/Transitive2.purs
@@ -0,0 +1,5 @@
+module Transitive2
+ ( module Transitive3 )
+ where
+
+import Transitive3
diff --git a/tests/purs/docs/src/Transitive3.purs b/tests/purs/docs/src/Transitive3.purs
new file mode 100644
index 0000000..abf974b
--- /dev/null
+++ b/tests/purs/docs/src/Transitive3.purs
@@ -0,0 +1,4 @@
+module Transitive3 where
+
+transitive3 :: Int
+transitive3 = 0
diff --git a/tests/purs/docs/src/TypeClassWithFunDeps.purs b/tests/purs/docs/src/TypeClassWithFunDeps.purs
new file mode 100644
index 0000000..3aee885
--- /dev/null
+++ b/tests/purs/docs/src/TypeClassWithFunDeps.purs
@@ -0,0 +1,5 @@
+
+module TypeClassWithFunDeps where
+
+class TypeClassWithFunDeps a b c d e | a b -> c, c -> d e where
+ aMember :: a -> b
diff --git a/tests/purs/docs/src/TypeClassWithoutMembers.purs b/tests/purs/docs/src/TypeClassWithoutMembers.purs
new file mode 100644
index 0000000..fd06102
--- /dev/null
+++ b/tests/purs/docs/src/TypeClassWithoutMembers.purs
@@ -0,0 +1,5 @@
+module TypeClassWithoutMembers
+ ( module TypeClassWithoutMembersIntermediate )
+ where
+
+import TypeClassWithoutMembersIntermediate
diff --git a/tests/purs/docs/src/TypeClassWithoutMembersIntermediate.purs b/tests/purs/docs/src/TypeClassWithoutMembersIntermediate.purs
new file mode 100644
index 0000000..5aefd35
--- /dev/null
+++ b/tests/purs/docs/src/TypeClassWithoutMembersIntermediate.purs
@@ -0,0 +1,5 @@
+module TypeClassWithoutMembersIntermediate
+ ( module SomeTypeClass )
+ where
+
+import SomeTypeClass (class SomeClass)
diff --git a/tests/purs/docs/src/TypeLevelString.purs b/tests/purs/docs/src/TypeLevelString.purs
new file mode 100644
index 0000000..7c55068
--- /dev/null
+++ b/tests/purs/docs/src/TypeLevelString.purs
@@ -0,0 +1,9 @@
+module TypeLevelString where
+
+import Prim.TypeError (class Fail, Text)
+
+data Foo
+
+class Bar a
+
+instance fooBar :: Fail (Text "oops") => Bar Foo
diff --git a/tests/purs/docs/src/TypeOpAliases.purs b/tests/purs/docs/src/TypeOpAliases.purs
new file mode 100644
index 0000000..6d76c4e
--- /dev/null
+++ b/tests/purs/docs/src/TypeOpAliases.purs
@@ -0,0 +1,44 @@
+module TypeOpAliases where
+
+type AltFn a b = a -> b
+
+infixr 6 type AltFn as ~>
+
+foreign import test1 :: forall a b. a ~> b
+foreign import test2 :: forall a b c. a ~> b ~> c
+foreign import test3 :: forall a b c d. a ~> (b ~> c) ~> d
+foreign import test4 :: forall a b c d. ((a ~> b) ~> c) ~> d
+
+data Tuple a b = Tuple a b
+
+infixl 6 Tuple as ×
+infixl 6 type Tuple as ×
+
+data Either a b = Left a | Right b
+
+infixl 5 type Either as ⊕
+
+third ∷ ∀ a b c. a × b × c → c
+third (a × b × c) = c
+
+class Show a where
+ show :: a -> String
+
+instance showTuple :: Show a => Show (a × b) where
+ show (a × _) = show a
+
+-- Test that precedence is taken into account while desugaring type operators
+
+class TestL a where
+ testL :: a
+
+class TestR a where
+ testR :: a
+
+-- Note: this type is Either Int (Tuple Int String)
+instance testLEither :: TestL (Int ⊕ Int × String) where
+ testL = Right (0 × "hi")
+
+-- Note: this type is Either (Tuple Int Int) String
+instance testREither :: TestR (Int × Int ⊕ String) where
+ testR = Left (0 × 1)
diff --git a/tests/purs/docs/src/UTF8.purs b/tests/purs/docs/src/UTF8.purs
new file mode 100644
index 0000000..258c6e1
--- /dev/null
+++ b/tests/purs/docs/src/UTF8.purs
@@ -0,0 +1,7 @@
+module UTF8 where
+
+import Prelude (Unit, unit)
+
+-- | üÜäÄ 😰
+thing :: Unit
+thing = unit
diff --git a/tests/purs/docs/src/Virtual.purs b/tests/purs/docs/src/Virtual.purs
new file mode 100644
index 0000000..35f454a
--- /dev/null
+++ b/tests/purs/docs/src/Virtual.purs
@@ -0,0 +1,5 @@
+module Virtual
+ ( module VirtualPrelude )
+ where
+
+import Prelude as VirtualPrelude
diff --git a/tests/purs/failing/1071.purs b/tests/purs/failing/1071.purs
new file mode 100644
index 0000000..1f560d1
--- /dev/null
+++ b/tests/purs/failing/1071.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith KindsDoNotUnify
+module Main where
+
+class Foo a b where
+ foo :: a -> b
+
+bar :: forall a. Foo a => a -> a
+bar a = a
diff --git a/tests/purs/failing/1169.purs b/tests/purs/failing/1169.purs
new file mode 100644
index 0000000..6382925
--- /dev/null
+++ b/tests/purs/failing/1169.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith IncorrectConstructorArity
+module Test where
+
+data Outer a = Outer a
+
+data Inner a b = Inner a b
+
+test1 :: forall a b. Outer (Inner a b) -> Boolean
+test1 (Outer (Inner _)) = true
+
+test2 :: forall a b. Inner a b -> Boolean
+test2 (Inner _) = true
diff --git a/tests/purs/failing/1175.purs b/tests/purs/failing/1175.purs
new file mode 100644
index 0000000..13f1f70
--- /dev/null
+++ b/tests/purs/failing/1175.purs
@@ -0,0 +1,11 @@
+-- @shouldFailWith TypesDoNotUnify
+module X where
+
+class Foo where
+ foo :: String
+
+instance f :: Foo where
+ foo = "a"
+ where
+ bar :: String
+ bar = 1
diff --git a/tests/purs/failing/1310.purs b/tests/purs/failing/1310.purs
new file mode 100644
index 0000000..1f4ff96
--- /dev/null
+++ b/tests/purs/failing/1310.purs
@@ -0,0 +1,18 @@
+-- @shouldFailWith NoInstanceFound
+
+module Issue1310 where
+
+import Prelude
+import Effect
+import Effect.Console
+
+class Inject f g where
+ inj :: forall a. f a -> g a
+
+instance inject :: Inject f f where
+ inj x = x
+
+newtype Oops a = Oops (Effect a)
+
+main :: Effect Unit
+main = inj (Oops (log "Oops"))
diff --git a/tests/purs/failing/1570.purs b/tests/purs/failing/1570.purs
new file mode 100644
index 0000000..3855838
--- /dev/null
+++ b/tests/purs/failing/1570.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ExpectedType
+module M where
+
+data F a = F a
+
+test = \(x :: F) -> x
diff --git a/tests/purs/failing/1733.purs b/tests/purs/failing/1733.purs
new file mode 100644
index 0000000..683bb4b
--- /dev/null
+++ b/tests/purs/failing/1733.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith UnknownName
+module Main where
+
+import Thingy as Thing
+
+main = Thing.doesntExist "hi"
diff --git a/tests/purs/failing/1733/Thingy.purs b/tests/purs/failing/1733/Thingy.purs
new file mode 100644
index 0000000..1803a5f
--- /dev/null
+++ b/tests/purs/failing/1733/Thingy.purs
@@ -0,0 +1,4 @@
+module Thingy where
+
+foo :: Int
+foo = 1
diff --git a/tests/purs/failing/1825.purs b/tests/purs/failing/1825.purs
new file mode 100644
index 0000000..5641ecc
--- /dev/null
+++ b/tests/purs/failing/1825.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith UnknownName
+
+module Main where
+
+data W = X | Y | Z
+
+bad X a = a
+bad Y _ = a
+bad Z a = a
diff --git a/tests/purs/failing/1881.purs b/tests/purs/failing/1881.purs
new file mode 100644
index 0000000..aee7bd5
--- /dev/null
+++ b/tests/purs/failing/1881.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+foo =
+bar :: Int
+bar = 3
diff --git a/tests/purs/failing/2128-class.purs b/tests/purs/failing/2128-class.purs
new file mode 100644
index 0000000..a46135b
--- /dev/null
+++ b/tests/purs/failing/2128-class.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+class Foo a where
+ foo :: a -> !!!
diff --git a/tests/purs/failing/2128-instance.purs b/tests/purs/failing/2128-instance.purs
new file mode 100644
index 0000000..9ec9758
--- /dev/null
+++ b/tests/purs/failing/2128-instance.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+class Foo a where
+ foo :: a
+
+instance fooInt :: Foo Int where
+ foo = !!!
diff --git a/tests/purs/failing/2197-shouldFail.purs b/tests/purs/failing/2197-shouldFail.purs
new file mode 100644
index 0000000..a211f19
--- /dev/null
+++ b/tests/purs/failing/2197-shouldFail.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith ScopeConflict
+module Main where
+
+import Prim as P
+import Prim (Number)
+
+type Number = P.Number
+
+z :: Number
+z = 0.0
diff --git a/tests/purs/failing/2197-shouldFail2.purs b/tests/purs/failing/2197-shouldFail2.purs
new file mode 100644
index 0000000..fb1b11b
--- /dev/null
+++ b/tests/purs/failing/2197-shouldFail2.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith UnknownName
+module Main where
+
+import Prim (Boolean)
+
+z :: Number
+z = 0.0
diff --git a/tests/purs/failing/2378.purs b/tests/purs/failing/2378.purs
new file mode 100644
index 0000000..59de79c
--- /dev/null
+++ b/tests/purs/failing/2378.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith OrphanInstance
+module Main where
+
+import Lib
+
+instance fooX :: Foo "x"
diff --git a/tests/purs/failing/2378/Lib.purs b/tests/purs/failing/2378/Lib.purs
new file mode 100644
index 0000000..8890d66
--- /dev/null
+++ b/tests/purs/failing/2378/Lib.purs
@@ -0,0 +1,3 @@
+module Lib (class Foo) where
+
+class Foo (a :: Symbol)
diff --git a/tests/purs/failing/2379.purs b/tests/purs/failing/2379.purs
new file mode 100644
index 0000000..f124dd3
--- /dev/null
+++ b/tests/purs/failing/2379.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith UnknownClass
+module Main where
+
+import Lib
+
+test = x [1, 2, 3]
diff --git a/tests/purs/failing/2379/Lib.purs b/tests/purs/failing/2379/Lib.purs
new file mode 100644
index 0000000..eb69e86
--- /dev/null
+++ b/tests/purs/failing/2379/Lib.purs
@@ -0,0 +1,9 @@
+module Lib (class X, x) where
+
+class X a where
+ x :: a -> String
+
+class Y a
+
+instance xArray :: Y a => X (Array a) where
+ x _ = "[]"
diff --git a/tests/purs/failing/2434.purs b/tests/purs/failing/2434.purs
new file mode 100644
index 0000000..87c41ff
--- /dev/null
+++ b/tests/purs/failing/2434.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+x :: Char
+x = '\x10000'
diff --git a/tests/purs/failing/2534.purs b/tests/purs/failing/2534.purs
new file mode 100644
index 0000000..a4a4f27
--- /dev/null
+++ b/tests/purs/failing/2534.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InfiniteType
+module Main where
+
+foo :: Array Int -> Int
+foo xs = go xs where
+ go :: Array _ -> Int
+ go [] = 0
+ go xs = go [xs]
diff --git a/tests/purs/failing/2542.purs b/tests/purs/failing/2542.purs
new file mode 100644
index 0000000..9c2b347
--- /dev/null
+++ b/tests/purs/failing/2542.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith UndefinedTypeVariable
+module Main where
+
+type T = forall a. Array a
+
+foo :: T
+foo = bar where
+ bar :: Array a
+ bar = []
diff --git a/tests/purs/failing/2567.purs b/tests/purs/failing/2567.purs
new file mode 100644
index 0000000..4d601cc
--- /dev/null
+++ b/tests/purs/failing/2567.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith NoInstanceFound
+module Main where
+
+import Prim.TypeError
+
+foo :: Int
+foo = (0 :: Fail (Text "This constraint should be checked") => Int)
diff --git a/tests/purs/failing/2601.purs b/tests/purs/failing/2601.purs
new file mode 100644
index 0000000..988e3d8
--- /dev/null
+++ b/tests/purs/failing/2601.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith KindsDoNotUnify
+module Main where
+
+type Syn (a :: Type -> Type) = String
+
+val :: Syn Int
+val = "bad"
diff --git a/tests/purs/failing/2616.purs b/tests/purs/failing/2616.purs
new file mode 100644
index 0000000..55ff188
--- /dev/null
+++ b/tests/purs/failing/2616.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith NoInstanceFound
+module Main where
+
+import Prelude
+
+newtype Foo r = Foo { | r }
+
+derive instance eqFoo :: Eq (Foo r)
+derive instance ordFoo :: Ord (Foo r)
diff --git a/tests/purs/failing/2806.purs b/tests/purs/failing/2806.purs
new file mode 100644
index 0000000..52103e1
--- /dev/null
+++ b/tests/purs/failing/2806.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith NoInstanceFound
+module X where
+
+data E a b = L a | R b
+
+g :: forall a b . E a b -> a
+g e | L x <- e = x
diff --git a/tests/purs/failing/2874-forall.purs b/tests/purs/failing/2874-forall.purs
new file mode 100644
index 0000000..0bb935e
--- /dev/null
+++ b/tests/purs/failing/2874-forall.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+class T a b | a -> b
+instance tT :: (T Int (forall a. a)) => T Int String
+
+ddd :: Int
+ddd = 0 :: forall t. T Int t => Int
diff --git a/tests/purs/failing/2874-forall2.purs b/tests/purs/failing/2874-forall2.purs
new file mode 100644
index 0000000..704aca2
--- /dev/null
+++ b/tests/purs/failing/2874-forall2.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+class X a b | a -> b
+class X a (forall t. t) <= Y a b | a -> b
+instance tX :: X Int String
+instance tY :: Y Int Boolean
+
+ggg :: Int
+ggg = 0 :: forall t. Y Int t => Int
diff --git a/tests/purs/failing/2874-wildcard.purs b/tests/purs/failing/2874-wildcard.purs
new file mode 100644
index 0000000..d5f001e
--- /dev/null
+++ b/tests/purs/failing/2874-wildcard.purs
@@ -0,0 +1,11 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+class Foo a where
+ foo :: a
+
+class Baz b where
+ baz :: b
+
+instance bazFoo :: (Baz _) => Foo b where
+ foo = baz
diff --git a/tests/purs/failing/2947.purs b/tests/purs/failing/2947.purs
new file mode 100644
index 0000000..c0f191b
--- /dev/null
+++ b/tests/purs/failing/2947.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith ErrorParsingModule
+
+module Main where
+
+import Prelude
+
+data Foo = Foo
+
+instance eqFoo :: Eq Foo where
+eq _ _ = true
diff --git a/tests/purs/failing/3132.purs b/tests/purs/failing/3132.purs
new file mode 100644
index 0000000..7c76d70
--- /dev/null
+++ b/tests/purs/failing/3132.purs
@@ -0,0 +1,18 @@
+-- @shouldFailWith TransitiveExportError
+module Main (class C3) where
+
+import Prelude
+
+import Effect (Effect)
+import Effect.Console (log)
+
+class C1
+instance inst1 :: C1
+
+class C1 <= C2 a
+
+class (C2 a) <= C3 a b
+
+main :: Effect Unit
+main = do
+ log "Done"
diff --git a/tests/purs/failing/3275-BindingGroupErrorPos.purs b/tests/purs/failing/3275-BindingGroupErrorPos.purs
new file mode 100644
index 0000000..1717906
--- /dev/null
+++ b/tests/purs/failing/3275-BindingGroupErrorPos.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith KindsDoNotUnify
+module BindingGroupErrorPos where
+
+-- This isn't really about KindsDoNotUnify, it's about positioning errors
+-- that occur in binding groups
+
+import Prelude
+
+type Result = Array Int
+
+wrong :: Int -> Result String
+wrong n = wrong (n - 1)
diff --git a/tests/purs/failing/3275-DataBindingGroupErrorPos.purs b/tests/purs/failing/3275-DataBindingGroupErrorPos.purs
new file mode 100644
index 0000000..fd8e906
--- /dev/null
+++ b/tests/purs/failing/3275-DataBindingGroupErrorPos.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith KindsDoNotUnify
+module DataBindingGroupErrorPos where
+
+-- This isn't really about KindsDoNotUnify, it's about positioning errors
+-- that occur in data binding groups
+
+data Foo a = Foo (Bar a a)
+data Bar a = Bar (Foo a)
diff --git a/tests/purs/failing/3335-TypeOpAssociativityError.purs b/tests/purs/failing/3335-TypeOpAssociativityError.purs
new file mode 100644
index 0000000..1e104a0
--- /dev/null
+++ b/tests/purs/failing/3335-TypeOpAssociativityError.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith NonAssociativeError
+module Main where
+
+infix 6 type Function as >>
+
+const :: forall a b. a >> b >> a
+const a _ = a
diff --git a/tests/purs/failing/365.purs b/tests/purs/failing/365.purs
new file mode 100644
index 0000000..86a56d3
--- /dev/null
+++ b/tests/purs/failing/365.purs
@@ -0,0 +1,14 @@
+-- @shouldFailWith CycleInDeclaration
+module Main where
+
+import Prelude
+
+class C a where
+ f :: a -> a
+ g :: a -> a
+
+instance cS :: C String where
+ f s = s
+ g = f
+
+main = g "Done"
diff --git a/tests/purs/failing/438.purs b/tests/purs/failing/438.purs
new file mode 100644
index 0000000..e7f080b
--- /dev/null
+++ b/tests/purs/failing/438.purs
@@ -0,0 +1,15 @@
+-- @shouldFailWith PossiblyInfiniteInstance
+
+-- See issue 438 for details: this test is mainly here to test that code like
+-- this doesn't cause the compiler to loop.
+
+module Main where
+
+import Prelude
+
+data Fix f = In (f (Fix f))
+
+instance eqFix :: (Eq (f (Fix f))) => Eq (Fix f) where
+ eq (In f) (In g) = f == g
+
+example = In [] == In []
diff --git a/tests/purs/failing/881.purs b/tests/purs/failing/881.purs
new file mode 100644
index 0000000..2b409cd
--- /dev/null
+++ b/tests/purs/failing/881.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith DuplicateValueDeclaration
+module Main where
+
+data X = X | Y
+
+class Foo a where
+ foo :: a -> a
+ bar :: a
+
+instance fooX :: Foo X where
+ foo X = X
+ bar = X
+ foo Y = Y
diff --git a/tests/purs/failing/AnonArgument1.purs b/tests/purs/failing/AnonArgument1.purs
new file mode 100644
index 0000000..74759b0
--- /dev/null
+++ b/tests/purs/failing/AnonArgument1.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith IncorrectAnonymousArgument
+module Main where
+
+test :: Int -> Int
+test = _
diff --git a/tests/purs/failing/AnonArgument2.purs b/tests/purs/failing/AnonArgument2.purs
new file mode 100644
index 0000000..746a008
--- /dev/null
+++ b/tests/purs/failing/AnonArgument2.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith IncorrectAnonymousArgument
+module Main where
+
+import Prelude
+
+test :: Int -> Int
+test = 1 + 2 * _
diff --git a/tests/purs/failing/AnonArgument3.purs b/tests/purs/failing/AnonArgument3.purs
new file mode 100644
index 0000000..34f9814
--- /dev/null
+++ b/tests/purs/failing/AnonArgument3.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith IncorrectAnonymousArgument
+module Main where
+
+test :: Int -> Int
+test = 1 + _
diff --git a/tests/purs/failing/ArgLengthMismatch.purs b/tests/purs/failing/ArgLengthMismatch.purs
new file mode 100644
index 0000000..0f1abfb
--- /dev/null
+++ b/tests/purs/failing/ArgLengthMismatch.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith ArgListLengthsDiffer
+module ArgLengthMismatch where
+
+import Prelude
+
+f x y = true
+f = false
diff --git a/tests/purs/failing/ArrayType.purs b/tests/purs/failing/ArrayType.purs
new file mode 100644
index 0000000..708fa5c
--- /dev/null
+++ b/tests/purs/failing/ArrayType.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith TypesDoNotUnify
+
+module Main where
+
+import Prelude
+
+bar :: Number -> Number -> Number
+bar n m = n + m
+
+foo = x `bar` y
+ where
+ x = 1
+ y = []
diff --git a/tests/purs/failing/Arrays.purs b/tests/purs/failing/Arrays.purs
new file mode 100644
index 0000000..cb02616
--- /dev/null
+++ b/tests/purs/failing/Arrays.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith TypesDoNotUnify
+module Main where
+
+foreign import ix :: forall a. Array a -> Int -> a
+
+test = \arr -> arr `ix` (0 `ix` 0)
diff --git a/tests/purs/failing/BindInDo-2.purs b/tests/purs/failing/BindInDo-2.purs
new file mode 100644
index 0000000..a8c0d15
--- /dev/null
+++ b/tests/purs/failing/BindInDo-2.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith CannotUseBindWithDo
+module Main where
+
+import Prelude
+
+foo = do
+ let bind = 42
+ x <- [4, 5, 6]
+ pure x
diff --git a/tests/purs/failing/BindInDo.purs b/tests/purs/failing/BindInDo.purs
new file mode 100644
index 0000000..d4f3286
--- /dev/null
+++ b/tests/purs/failing/BindInDo.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith CannotUseBindWithDo
+module Main where
+
+import Prelude
+
+foo = do
+ bind <- [1,2,3]
+ x <- [4, 5, 6]
+ pure x
diff --git a/tests/purs/failing/CannotDeriveNewtypeForData.purs b/tests/purs/failing/CannotDeriveNewtypeForData.purs
new file mode 100644
index 0000000..f40568d
--- /dev/null
+++ b/tests/purs/failing/CannotDeriveNewtypeForData.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith CannotDeriveNewtypeForData
+module CannotDeriveNewtypeForData where
+
+import Data.Newtype
+
+data Test = Test String
+
+derive instance newtypeTest :: Newtype Test _
diff --git a/tests/purs/failing/CaseBinderLengthsDiffer.purs b/tests/purs/failing/CaseBinderLengthsDiffer.purs
new file mode 100644
index 0000000..69e0e0a
--- /dev/null
+++ b/tests/purs/failing/CaseBinderLengthsDiffer.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith CaseBinderLengthDiffers
+module Main where
+
+test = case 1, 2 of
+ 1, 2, 3 -> 42
+ _, _ -> 43
diff --git a/tests/purs/failing/CaseDoesNotMatchAllConstructorArgs.purs b/tests/purs/failing/CaseDoesNotMatchAllConstructorArgs.purs
new file mode 100644
index 0000000..da95c96
--- /dev/null
+++ b/tests/purs/failing/CaseDoesNotMatchAllConstructorArgs.purs
@@ -0,0 +1,15 @@
+-- @shouldFailWith IncorrectConstructorArity
+module Main where
+
+import Prelude
+
+data Person = Person String Int
+
+data TwoPeople = Two Person Person
+
+getName p = case p of
+ (Two (Person n) (Person n2 a2)) -> n
+ _ -> "Unknown"
+
+
+name = getName (Two (Person "Jimmy" 20) (Person "" 1))
diff --git a/tests/purs/failing/ConflictingExports.purs b/tests/purs/failing/ConflictingExports.purs
new file mode 100644
index 0000000..9ef5d67
--- /dev/null
+++ b/tests/purs/failing/ConflictingExports.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ScopeConflict
+-- Fails here because re-exporting forces any scope conflicts to be resolved
+module Main (module A, module B) where
+
+ import A
+ import B
diff --git a/tests/purs/failing/ConflictingExports/A.purs b/tests/purs/failing/ConflictingExports/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/failing/ConflictingExports/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/failing/ConflictingExports/B.purs b/tests/purs/failing/ConflictingExports/B.purs
new file mode 100644
index 0000000..076bf7e
--- /dev/null
+++ b/tests/purs/failing/ConflictingExports/B.purs
@@ -0,0 +1,4 @@
+module B where
+
+thing :: Int
+thing = 2
diff --git a/tests/purs/failing/ConflictingImports.purs b/tests/purs/failing/ConflictingImports.purs
new file mode 100644
index 0000000..00b2b3c
--- /dev/null
+++ b/tests/purs/failing/ConflictingImports.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith ScopeConflict
+module Main where
+
+import A
+import B
+
+-- Error due to referencing `thing` which is in scope as A.thing and B.thing
+what :: Int
+what = thing
diff --git a/tests/purs/failing/ConflictingImports/A.purs b/tests/purs/failing/ConflictingImports/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/failing/ConflictingImports/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/failing/ConflictingImports/B.purs b/tests/purs/failing/ConflictingImports/B.purs
new file mode 100644
index 0000000..076bf7e
--- /dev/null
+++ b/tests/purs/failing/ConflictingImports/B.purs
@@ -0,0 +1,4 @@
+module B where
+
+thing :: Int
+thing = 2
diff --git a/tests/purs/failing/ConflictingImports2.purs b/tests/purs/failing/ConflictingImports2.purs
new file mode 100644
index 0000000..e716da1
--- /dev/null
+++ b/tests/purs/failing/ConflictingImports2.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith ScopeConflict
+module Main where
+
+import A (thing)
+import B (thing)
+
+-- Error due to referencing `thing` which is explicitly in scope as A.thing
+-- and B.thing
+what :: Int
+what = thing
diff --git a/tests/purs/failing/ConflictingImports2/A.purs b/tests/purs/failing/ConflictingImports2/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/failing/ConflictingImports2/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/failing/ConflictingImports2/B.purs b/tests/purs/failing/ConflictingImports2/B.purs
new file mode 100644
index 0000000..076bf7e
--- /dev/null
+++ b/tests/purs/failing/ConflictingImports2/B.purs
@@ -0,0 +1,4 @@
+module B where
+
+thing :: Int
+thing = 2
diff --git a/tests/purs/failing/ConflictingQualifiedImports.purs b/tests/purs/failing/ConflictingQualifiedImports.purs
new file mode 100644
index 0000000..9089cae
--- /dev/null
+++ b/tests/purs/failing/ConflictingQualifiedImports.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith ScopeConflict
+module Main where
+
+import A as X
+import B as X
+
+foo = X.thing
diff --git a/tests/purs/failing/ConflictingQualifiedImports/A.purs b/tests/purs/failing/ConflictingQualifiedImports/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/failing/ConflictingQualifiedImports/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/failing/ConflictingQualifiedImports/B.purs b/tests/purs/failing/ConflictingQualifiedImports/B.purs
new file mode 100644
index 0000000..076bf7e
--- /dev/null
+++ b/tests/purs/failing/ConflictingQualifiedImports/B.purs
@@ -0,0 +1,4 @@
+module B where
+
+thing :: Int
+thing = 2
diff --git a/tests/purs/failing/ConflictingQualifiedImports2.purs b/tests/purs/failing/ConflictingQualifiedImports2.purs
new file mode 100644
index 0000000..11b150e
--- /dev/null
+++ b/tests/purs/failing/ConflictingQualifiedImports2.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ScopeConflict
+module Main (module X) where
+
+import A as X
+import B as X
diff --git a/tests/purs/failing/ConflictingQualifiedImports2/A.purs b/tests/purs/failing/ConflictingQualifiedImports2/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/failing/ConflictingQualifiedImports2/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/failing/ConflictingQualifiedImports2/B.purs b/tests/purs/failing/ConflictingQualifiedImports2/B.purs
new file mode 100644
index 0000000..076bf7e
--- /dev/null
+++ b/tests/purs/failing/ConflictingQualifiedImports2/B.purs
@@ -0,0 +1,4 @@
+module B where
+
+thing :: Int
+thing = 2
diff --git a/tests/purs/failing/ConstraintFailure.purs b/tests/purs/failing/ConstraintFailure.purs
new file mode 100644
index 0000000..b24cb58
--- /dev/null
+++ b/tests/purs/failing/ConstraintFailure.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith NoInstanceFound
+
+module Main where
+
+import Prelude
+
+data Foo = Bar
+
+spin :: forall a. a -> Foo
+spin x = Bar
+
+main = show <<< spin
+
diff --git a/tests/purs/failing/ConstraintInference.purs b/tests/purs/failing/ConstraintInference.purs
new file mode 100644
index 0000000..ef68dbb
--- /dev/null
+++ b/tests/purs/failing/ConstraintInference.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith AmbiguousTypeVariables
+
+module Main where
+
+import Prelude
+
+spin :: forall a b. a -> b
+spin x = spin x
+
+test = show <<< spin
diff --git a/tests/purs/failing/DctorOperatorAliasExport.purs b/tests/purs/failing/DctorOperatorAliasExport.purs
new file mode 100644
index 0000000..0f46596
--- /dev/null
+++ b/tests/purs/failing/DctorOperatorAliasExport.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith TransitiveDctorExportError
+module Data.List (List, (:)) where
+
+ data List a = Cons a (List a) | Nil
+
+ infixr 6 Cons as :
diff --git a/tests/purs/failing/DeclConflictClassCtor.purs b/tests/purs/failing/DeclConflictClassCtor.purs
new file mode 100644
index 0000000..28e5a6e
--- /dev/null
+++ b/tests/purs/failing/DeclConflictClassCtor.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+data T = Fail
+
+class Fail
diff --git a/tests/purs/failing/DeclConflictClassSynonym.purs b/tests/purs/failing/DeclConflictClassSynonym.purs
new file mode 100644
index 0000000..319fa44
--- /dev/null
+++ b/tests/purs/failing/DeclConflictClassSynonym.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+import Prelude
+
+type Fail = Unit
+
+class Fail
diff --git a/tests/purs/failing/DeclConflictClassType.purs b/tests/purs/failing/DeclConflictClassType.purs
new file mode 100644
index 0000000..322265c
--- /dev/null
+++ b/tests/purs/failing/DeclConflictClassType.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+class Fail
+
+data Fail
diff --git a/tests/purs/failing/DeclConflictCtorClass.purs b/tests/purs/failing/DeclConflictCtorClass.purs
new file mode 100644
index 0000000..03c052c
--- /dev/null
+++ b/tests/purs/failing/DeclConflictCtorClass.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+class Fail
+
+data T = Fail
diff --git a/tests/purs/failing/DeclConflictCtorCtor.purs b/tests/purs/failing/DeclConflictCtorCtor.purs
new file mode 100644
index 0000000..a99d8e9
--- /dev/null
+++ b/tests/purs/failing/DeclConflictCtorCtor.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+data T1 = Fail
+
+data T2 = Fail
diff --git a/tests/purs/failing/DeclConflictDuplicateCtor.purs b/tests/purs/failing/DeclConflictDuplicateCtor.purs
new file mode 100644
index 0000000..cc2a28e
--- /dev/null
+++ b/tests/purs/failing/DeclConflictDuplicateCtor.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+data T = Fail | Fail
+
diff --git a/tests/purs/failing/DeclConflictSynonymClass.purs b/tests/purs/failing/DeclConflictSynonymClass.purs
new file mode 100644
index 0000000..6524dc0
--- /dev/null
+++ b/tests/purs/failing/DeclConflictSynonymClass.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+import Prelude
+
+class Fail
+
+type Fail = Unit
diff --git a/tests/purs/failing/DeclConflictSynonymType.purs b/tests/purs/failing/DeclConflictSynonymType.purs
new file mode 100644
index 0000000..f9a6f4d
--- /dev/null
+++ b/tests/purs/failing/DeclConflictSynonymType.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+import Prelude
+
+data Fail
+
+type Fail = Unit
diff --git a/tests/purs/failing/DeclConflictTypeClass.purs b/tests/purs/failing/DeclConflictTypeClass.purs
new file mode 100644
index 0000000..322265c
--- /dev/null
+++ b/tests/purs/failing/DeclConflictTypeClass.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+class Fail
+
+data Fail
diff --git a/tests/purs/failing/DeclConflictTypeSynonym.purs b/tests/purs/failing/DeclConflictTypeSynonym.purs
new file mode 100644
index 0000000..81a7cae
--- /dev/null
+++ b/tests/purs/failing/DeclConflictTypeSynonym.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+import Prelude
+
+type Fail = Unit
+
+data Fail
diff --git a/tests/purs/failing/DeclConflictTypeType.purs b/tests/purs/failing/DeclConflictTypeType.purs
new file mode 100644
index 0000000..2815e84
--- /dev/null
+++ b/tests/purs/failing/DeclConflictTypeType.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DeclConflict
+module Main where
+
+data Fail
+
+data Fail
diff --git a/tests/purs/failing/DiffKindsSameName.purs b/tests/purs/failing/DiffKindsSameName.purs
new file mode 100644
index 0000000..afcf48a
--- /dev/null
+++ b/tests/purs/failing/DiffKindsSameName.purs
@@ -0,0 +1,15 @@
+-- @shouldFailWith KindsDoNotUnify
+module DiffKindsSameName where
+
+import DiffKindsSameName.LibA as LibA
+import DiffKindsSameName.LibB as LibB
+
+-- both `LibA` and `LibB` define a kind locally called `DemoKind`
+-- `LibB` defines `DemoData :: LibB.DemoKind`
+-- if we try to use `DemoData` in a place where `LibA.DemoKind` is expected, it should fail with `KindsDoNotUnify`
+
+data AProxy (m :: LibA.DemoKind) = AProxy
+
+bProxy :: AProxy LibB.DemoData
+bProxy = AProxy
+
diff --git a/tests/purs/failing/DiffKindsSameName/LibA.purs b/tests/purs/failing/DiffKindsSameName/LibA.purs
new file mode 100644
index 0000000..d36b2ec
--- /dev/null
+++ b/tests/purs/failing/DiffKindsSameName/LibA.purs
@@ -0,0 +1,4 @@
+module DiffKindsSameName.LibA where
+
+foreign import kind DemoKind
+
diff --git a/tests/purs/failing/DiffKindsSameName/LibB.purs b/tests/purs/failing/DiffKindsSameName/LibB.purs
new file mode 100644
index 0000000..52bcb0f
--- /dev/null
+++ b/tests/purs/failing/DiffKindsSameName/LibB.purs
@@ -0,0 +1,6 @@
+module DiffKindsSameName.LibB where
+
+foreign import kind DemoKind
+
+foreign import data DemoData :: DemoKind
+
diff --git a/tests/purs/failing/Do.purs b/tests/purs/failing/Do.purs
new file mode 100644
index 0000000..a0140bc
--- /dev/null
+++ b/tests/purs/failing/Do.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith InvalidDoBind
+-- @shouldFailWith InvalidDoLet
+module Main where
+
+import Prelude
+
+test1 = do let x = 1
+
+test2 y = do x <- y
+
+test3 = do pure 1
+ pure 2
diff --git a/tests/purs/failing/DoNotSuggestComposition.purs b/tests/purs/failing/DoNotSuggestComposition.purs
new file mode 100644
index 0000000..c26bafb
--- /dev/null
+++ b/tests/purs/failing/DoNotSuggestComposition.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith TypesDoNotUnify
+-- TODO: Check that this does not produce a "function composition is (<<<)"
+-- suggestion.
+module DoNotSuggestComposition where
+
+import Prelude
+
+x = { y: 3 }
+
+foo :: String -> String
+foo y = y
+
+bar = foo x
diff --git a/tests/purs/failing/DoNotSuggestComposition2.purs b/tests/purs/failing/DoNotSuggestComposition2.purs
new file mode 100644
index 0000000..907d15b
--- /dev/null
+++ b/tests/purs/failing/DoNotSuggestComposition2.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith TypesDoNotUnify
+-- TODO: Check that this does not produce a "function composition is (<<<)"
+-- suggestion.
+
+module DoNotSuggestComposition2 where
+
+foo = let x = { y: 3 } in x 2
diff --git a/tests/purs/failing/DuplicateDeclarationsInLet.purs b/tests/purs/failing/DuplicateDeclarationsInLet.purs
new file mode 100644
index 0000000..fed163d
--- /dev/null
+++ b/tests/purs/failing/DuplicateDeclarationsInLet.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith OverlappingNamesInLet
+module Main where
+
+import Prelude
+
+foo = a
+ where
+ a :: Number
+ a = 1
+
+ a :: Number
+ a = 2
diff --git a/tests/purs/failing/DuplicateInstance.purs b/tests/purs/failing/DuplicateInstance.purs
new file mode 100644
index 0000000..bb3c13e
--- /dev/null
+++ b/tests/purs/failing/DuplicateInstance.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DuplicateInstance
+module Main where
+class X
+class Y
+instance i :: X
+instance i :: Y
diff --git a/tests/purs/failing/DuplicateModule.purs b/tests/purs/failing/DuplicateModule.purs
new file mode 100644
index 0000000..5cd8a13
--- /dev/null
+++ b/tests/purs/failing/DuplicateModule.purs
@@ -0,0 +1,2 @@
+-- @shouldFailWith DuplicateModule
+module M1 where
diff --git a/tests/purs/failing/DuplicateModule/M1.purs b/tests/purs/failing/DuplicateModule/M1.purs
new file mode 100644
index 0000000..5d99c37
--- /dev/null
+++ b/tests/purs/failing/DuplicateModule/M1.purs
@@ -0,0 +1 @@
+module M1 where
diff --git a/tests/purs/failing/DuplicateProperties.purs b/tests/purs/failing/DuplicateProperties.purs
new file mode 100644
index 0000000..6349b30
--- /dev/null
+++ b/tests/purs/failing/DuplicateProperties.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith TypesDoNotUnify
+module DuplicateProperties where
+
+import Prelude
+
+foreign import data Test :: # Type -> Type
+
+foreign import subtractX :: forall r. Test (x :: Unit | r) -> Test r
+
+foreign import hasX :: Test (x :: Unit, y :: Unit)
+
+baz = subtractX (subtractX hasX)
diff --git a/tests/purs/failing/DuplicateTypeClass.purs b/tests/purs/failing/DuplicateTypeClass.purs
new file mode 100644
index 0000000..969c3e3
--- /dev/null
+++ b/tests/purs/failing/DuplicateTypeClass.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith DuplicateTypeClass
+module Main where
+class C
+class C
diff --git a/tests/purs/failing/DuplicateTypeVars.purs b/tests/purs/failing/DuplicateTypeVars.purs
new file mode 100644
index 0000000..d209301
--- /dev/null
+++ b/tests/purs/failing/DuplicateTypeVars.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith DuplicateTypeArgument
+module Main where
+
+import Prelude
+
+type Foo a a = a
diff --git a/tests/purs/failing/EmptyCase.purs b/tests/purs/failing/EmptyCase.purs
new file mode 100644
index 0000000..8a919c8
--- /dev/null
+++ b/tests/purs/failing/EmptyCase.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+error err = case err of \_ -> 1
diff --git a/tests/purs/failing/EmptyClass.purs b/tests/purs/failing/EmptyClass.purs
new file mode 100644
index 0000000..fde8f7e
--- /dev/null
+++ b/tests/purs/failing/EmptyClass.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+class Foo x where
+
+bar :: String
+bar = "hello"
diff --git a/tests/purs/failing/EmptyDo.purs b/tests/purs/failing/EmptyDo.purs
new file mode 100644
index 0000000..926a149
--- /dev/null
+++ b/tests/purs/failing/EmptyDo.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ErrorParsingModule
+
+module Main where
+
+main = do
+
diff --git a/tests/purs/failing/ExpectedWildcard.purs b/tests/purs/failing/ExpectedWildcard.purs
new file mode 100644
index 0000000..72c1365
--- /dev/null
+++ b/tests/purs/failing/ExpectedWildcard.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith ExpectedWildcard
+module ExpectedWildcard where
+
+import Data.Newtype
+
+data Test = Test String
+
+derive instance newtypeTest :: Newtype Test String
diff --git a/tests/purs/failing/ExportConflictClass.purs b/tests/purs/failing/ExportConflictClass.purs
new file mode 100644
index 0000000..fa6e746
--- /dev/null
+++ b/tests/purs/failing/ExportConflictClass.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ExportConflict
+module C (module A, module B) where
+
+import A as A
+import B as B
diff --git a/tests/purs/failing/ExportConflictClass/A.purs b/tests/purs/failing/ExportConflictClass/A.purs
new file mode 100644
index 0000000..48354f7
--- /dev/null
+++ b/tests/purs/failing/ExportConflictClass/A.purs
@@ -0,0 +1,3 @@
+module A where
+
+class X
diff --git a/tests/purs/failing/ExportConflictClass/B.purs b/tests/purs/failing/ExportConflictClass/B.purs
new file mode 100644
index 0000000..f9d4b53
--- /dev/null
+++ b/tests/purs/failing/ExportConflictClass/B.purs
@@ -0,0 +1,3 @@
+module B where
+
+class X
diff --git a/tests/purs/failing/ExportConflictCtor.purs b/tests/purs/failing/ExportConflictCtor.purs
new file mode 100644
index 0000000..fa6e746
--- /dev/null
+++ b/tests/purs/failing/ExportConflictCtor.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ExportConflict
+module C (module A, module B) where
+
+import A as A
+import B as B
diff --git a/tests/purs/failing/ExportConflictCtor/A.purs b/tests/purs/failing/ExportConflictCtor/A.purs
new file mode 100644
index 0000000..c3fadf0
--- /dev/null
+++ b/tests/purs/failing/ExportConflictCtor/A.purs
@@ -0,0 +1,3 @@
+module A where
+
+data T1 = X
diff --git a/tests/purs/failing/ExportConflictCtor/B.purs b/tests/purs/failing/ExportConflictCtor/B.purs
new file mode 100644
index 0000000..092d2ae
--- /dev/null
+++ b/tests/purs/failing/ExportConflictCtor/B.purs
@@ -0,0 +1,3 @@
+module B where
+
+data T2 = X
diff --git a/tests/purs/failing/ExportConflictType.purs b/tests/purs/failing/ExportConflictType.purs
new file mode 100644
index 0000000..fa6e746
--- /dev/null
+++ b/tests/purs/failing/ExportConflictType.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ExportConflict
+module C (module A, module B) where
+
+import A as A
+import B as B
diff --git a/tests/purs/failing/ExportConflictType/A.purs b/tests/purs/failing/ExportConflictType/A.purs
new file mode 100644
index 0000000..6530830
--- /dev/null
+++ b/tests/purs/failing/ExportConflictType/A.purs
@@ -0,0 +1,3 @@
+module A where
+
+data T
diff --git a/tests/purs/failing/ExportConflictType/B.purs b/tests/purs/failing/ExportConflictType/B.purs
new file mode 100644
index 0000000..9d77277
--- /dev/null
+++ b/tests/purs/failing/ExportConflictType/B.purs
@@ -0,0 +1,3 @@
+module B where
+
+data T
diff --git a/tests/purs/failing/ExportConflictTypeOp.purs b/tests/purs/failing/ExportConflictTypeOp.purs
new file mode 100644
index 0000000..fa6e746
--- /dev/null
+++ b/tests/purs/failing/ExportConflictTypeOp.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ExportConflict
+module C (module A, module B) where
+
+import A as A
+import B as B
diff --git a/tests/purs/failing/ExportConflictTypeOp/A.purs b/tests/purs/failing/ExportConflictTypeOp/A.purs
new file mode 100644
index 0000000..b0cb6dd
--- /dev/null
+++ b/tests/purs/failing/ExportConflictTypeOp/A.purs
@@ -0,0 +1,5 @@
+module A where
+
+type T1 a b = a -> b
+
+infixr 4 type T1 as ??
diff --git a/tests/purs/failing/ExportConflictTypeOp/B.purs b/tests/purs/failing/ExportConflictTypeOp/B.purs
new file mode 100644
index 0000000..3e3338d
--- /dev/null
+++ b/tests/purs/failing/ExportConflictTypeOp/B.purs
@@ -0,0 +1,5 @@
+module B where
+
+type T2 a b = a -> b
+
+infixr 4 type T2 as ??
diff --git a/tests/purs/failing/ExportConflictValue.purs b/tests/purs/failing/ExportConflictValue.purs
new file mode 100644
index 0000000..fa6e746
--- /dev/null
+++ b/tests/purs/failing/ExportConflictValue.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ExportConflict
+module C (module A, module B) where
+
+import A as A
+import B as B
diff --git a/tests/purs/failing/ExportConflictValue/A.purs b/tests/purs/failing/ExportConflictValue/A.purs
new file mode 100644
index 0000000..48a3687
--- /dev/null
+++ b/tests/purs/failing/ExportConflictValue/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+x :: Boolean
+x = true
diff --git a/tests/purs/failing/ExportConflictValue/B.purs b/tests/purs/failing/ExportConflictValue/B.purs
new file mode 100644
index 0000000..b5f75b0
--- /dev/null
+++ b/tests/purs/failing/ExportConflictValue/B.purs
@@ -0,0 +1,4 @@
+module B where
+
+x :: Boolean
+x = false
diff --git a/tests/purs/failing/ExportConflictValueOp.purs b/tests/purs/failing/ExportConflictValueOp.purs
new file mode 100644
index 0000000..fa6e746
--- /dev/null
+++ b/tests/purs/failing/ExportConflictValueOp.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith ExportConflict
+module C (module A, module B) where
+
+import A as A
+import B as B
diff --git a/tests/purs/failing/ExportConflictValueOp/A.purs b/tests/purs/failing/ExportConflictValueOp/A.purs
new file mode 100644
index 0000000..3c78f2a
--- /dev/null
+++ b/tests/purs/failing/ExportConflictValueOp/A.purs
@@ -0,0 +1,6 @@
+module A where
+
+f1 :: forall a b. a -> b -> a
+f1 x _ = x
+
+infix 0 f1 as !!
diff --git a/tests/purs/failing/ExportConflictValueOp/B.purs b/tests/purs/failing/ExportConflictValueOp/B.purs
new file mode 100644
index 0000000..8447dd3
--- /dev/null
+++ b/tests/purs/failing/ExportConflictValueOp/B.purs
@@ -0,0 +1,6 @@
+module B where
+
+f2 :: forall a b. a -> b -> a
+f2 x _ = x
+
+infix 0 f2 as !!
diff --git a/tests/purs/failing/ExportExplicit.purs b/tests/purs/failing/ExportExplicit.purs
new file mode 100644
index 0000000..5132aff
--- /dev/null
+++ b/tests/purs/failing/ExportExplicit.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith UnknownExport
+-- should fail as z does not exist in the module
+module M1 (x, y, z) where
+
+import Prelude
+
+x = 1
+y = 2
diff --git a/tests/purs/failing/ExportExplicit1.purs b/tests/purs/failing/ExportExplicit1.purs
new file mode 100644
index 0000000..574a12a
--- /dev/null
+++ b/tests/purs/failing/ExportExplicit1.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith UnknownName
+module Main where
+
+import M1
+import Effect.Console (log)
+
+testX = X
+
+-- should fail as Y constructor is not exported from M1
+testY = Y
+
+main = log "Done"
diff --git a/tests/purs/failing/ExportExplicit1/M1.purs b/tests/purs/failing/ExportExplicit1/M1.purs
new file mode 100644
index 0000000..f20006f
--- /dev/null
+++ b/tests/purs/failing/ExportExplicit1/M1.purs
@@ -0,0 +1,3 @@
+module M1 (X(X)) where
+
+data X = X | Y
diff --git a/tests/purs/failing/ExportExplicit2.purs b/tests/purs/failing/ExportExplicit2.purs
new file mode 100644
index 0000000..503b61c
--- /dev/null
+++ b/tests/purs/failing/ExportExplicit2.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith UnknownExportDataConstructor
+-- should fail as Y is not a data constructor for X
+module M1 (X(Y)) where
+
+import Prelude
+
+data X = X
+data Y = Y
diff --git a/tests/purs/failing/ExportExplicit3.purs b/tests/purs/failing/ExportExplicit3.purs
new file mode 100644
index 0000000..447936b
--- /dev/null
+++ b/tests/purs/failing/ExportExplicit3.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith UnknownName
+module Main where
+
+import M1 as M
+import Effect.Console (log)
+
+-- should fail as Z is not exported from M1
+testZ = M.Z
+
+main = log "Done"
diff --git a/tests/purs/failing/ExportExplicit3/M1.purs b/tests/purs/failing/ExportExplicit3/M1.purs
new file mode 100644
index 0000000..b2362dc
--- /dev/null
+++ b/tests/purs/failing/ExportExplicit3/M1.purs
@@ -0,0 +1,4 @@
+module M1 (X(..)) where
+
+data X = X | Y
+data Z = Z
diff --git a/tests/purs/failing/ExtraRecordField.purs b/tests/purs/failing/ExtraRecordField.purs
new file mode 100644
index 0000000..aa57b05
--- /dev/null
+++ b/tests/purs/failing/ExtraRecordField.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith AdditionalProperty
+module ExtraRecordField where
+
+import Prelude ((<>))
+
+full :: { first :: String, last :: String } -> String
+full p = p.first <> " " <> p.last
+
+oops = full { first: "Jane", last: "Smith", age: 29 }
diff --git a/tests/purs/failing/ExtraneousClassMember.purs b/tests/purs/failing/ExtraneousClassMember.purs
new file mode 100644
index 0000000..9893d7f
--- /dev/null
+++ b/tests/purs/failing/ExtraneousClassMember.purs
@@ -0,0 +1,11 @@
+-- @shouldFailWith ExtraneousClassMember
+module Main where
+
+import Prelude
+
+class A a where
+ a :: a -> String
+
+instance aString :: A String where
+ a s = s
+ b x = x
diff --git a/tests/purs/failing/Foldable.purs b/tests/purs/failing/Foldable.purs
new file mode 100644
index 0000000..daea9d9
--- /dev/null
+++ b/tests/purs/failing/Foldable.purs
@@ -0,0 +1,17 @@
+-- @shouldFailWith CycleInDeclaration
+module Main where
+
+import Prelude
+
+class Foldable f where
+ fold :: forall a b. (a -> b -> b) -> b -> f a -> b
+ size :: forall a. f a -> Number
+
+data L a = C a (L a) | N
+
+instance foldableL :: Foldable L where
+ fold _ z N = z
+ fold f z (C x xs) = x `f` (fold f z xs)
+ size = fold (const ((+) 1.0)) 0.0
+
+x = size (C 1 (C 2 (C 3 N)))
diff --git a/tests/purs/failing/Generalization1.purs b/tests/purs/failing/Generalization1.purs
new file mode 100644
index 0000000..a4a7b9b
--- /dev/null
+++ b/tests/purs/failing/Generalization1.purs
@@ -0,0 +1,11 @@
+-- @shouldFailWith CannotGeneralizeRecursiveFunction
+module Main where
+
+import Prelude
+
+foo 0 x _ = x
+foo n x y = x <> bar (n - 1) x y
+
+bar 0 x _ = x
+bar n x y = y <> foo (n - 1) x y
+
diff --git a/tests/purs/failing/Generalization2.purs b/tests/purs/failing/Generalization2.purs
new file mode 100644
index 0000000..9fa8e1c
--- /dev/null
+++ b/tests/purs/failing/Generalization2.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith CannotGeneralizeRecursiveFunction
+module Main where
+
+import Prelude
+
+test n m | n <= 1 = m
+ | otherwise = test (n - 1) (m <> m)
+
diff --git a/tests/purs/failing/ImportExplicit.purs b/tests/purs/failing/ImportExplicit.purs
new file mode 100644
index 0000000..c6c30e1
--- /dev/null
+++ b/tests/purs/failing/ImportExplicit.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith UnknownImport
+module Main where
+
+import M1 (X(..))
diff --git a/tests/purs/failing/ImportExplicit/M1.purs b/tests/purs/failing/ImportExplicit/M1.purs
new file mode 100644
index 0000000..9b75cf2
--- /dev/null
+++ b/tests/purs/failing/ImportExplicit/M1.purs
@@ -0,0 +1,3 @@
+module M1 where
+
+foo = "foo"
diff --git a/tests/purs/failing/ImportExplicit2.purs b/tests/purs/failing/ImportExplicit2.purs
new file mode 100644
index 0000000..584667d
--- /dev/null
+++ b/tests/purs/failing/ImportExplicit2.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith UnknownImportDataConstructor
+module Main where
+
+import M1 (X(Z, Q))
diff --git a/tests/purs/failing/ImportExplicit2/M1.purs b/tests/purs/failing/ImportExplicit2/M1.purs
new file mode 100644
index 0000000..168e8f2
--- /dev/null
+++ b/tests/purs/failing/ImportExplicit2/M1.purs
@@ -0,0 +1,3 @@
+module M1 where
+
+data X = Y
diff --git a/tests/purs/failing/ImportHidingModule.purs b/tests/purs/failing/ImportHidingModule.purs
new file mode 100644
index 0000000..bda20be
--- /dev/null
+++ b/tests/purs/failing/ImportHidingModule.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith ImportHidingModule
+module Main where
+
+import B hiding (module A)
diff --git a/tests/purs/failing/ImportHidingModule/A.purs b/tests/purs/failing/ImportHidingModule/A.purs
new file mode 100644
index 0000000..ec3490f
--- /dev/null
+++ b/tests/purs/failing/ImportHidingModule/A.purs
@@ -0,0 +1,2 @@
+module A where
+x = 1
diff --git a/tests/purs/failing/ImportHidingModule/B.purs b/tests/purs/failing/ImportHidingModule/B.purs
new file mode 100644
index 0000000..3230bfd
--- /dev/null
+++ b/tests/purs/failing/ImportHidingModule/B.purs
@@ -0,0 +1,3 @@
+module B (module B, module A) where
+import A
+y = 1
diff --git a/tests/purs/failing/ImportModule.purs b/tests/purs/failing/ImportModule.purs
new file mode 100644
index 0000000..28d61b1
--- /dev/null
+++ b/tests/purs/failing/ImportModule.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith ModuleNotFound
+module Main where
+
+import M1
diff --git a/tests/purs/failing/ImportModule/M2.purs b/tests/purs/failing/ImportModule/M2.purs
new file mode 100644
index 0000000..e69cb1f
--- /dev/null
+++ b/tests/purs/failing/ImportModule/M2.purs
@@ -0,0 +1,3 @@
+module M2 where
+
+data X = X
diff --git a/tests/purs/failing/InfiniteKind.purs b/tests/purs/failing/InfiniteKind.purs
new file mode 100644
index 0000000..c2f0e1c
--- /dev/null
+++ b/tests/purs/failing/InfiniteKind.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith InfiniteKind
+
+module Main where
+
+data F a = F (a a)
diff --git a/tests/purs/failing/InfiniteKind2.purs b/tests/purs/failing/InfiniteKind2.purs
new file mode 100644
index 0000000..63c9104
--- /dev/null
+++ b/tests/purs/failing/InfiniteKind2.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith InfiniteKind
+
+module InfiniteKind2 where
+
+data Tree m a = Tree a (m (Tree a))
diff --git a/tests/purs/failing/InfiniteType.purs b/tests/purs/failing/InfiniteType.purs
new file mode 100644
index 0000000..28cd889
--- /dev/null
+++ b/tests/purs/failing/InfiniteType.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith InfiniteType
+
+module Main where
+
+f a = a a
diff --git a/tests/purs/failing/InstanceChainBothUnknownAndMatch.purs b/tests/purs/failing/InstanceChainBothUnknownAndMatch.purs
new file mode 100644
index 0000000..2c9cf6e
--- /dev/null
+++ b/tests/purs/failing/InstanceChainBothUnknownAndMatch.purs
@@ -0,0 +1,18 @@
+-- @shouldFailWith NoInstanceFound
+module InstanceChains.BothUnknownAndMatch where
+
+import Type.Proxy (Proxy)
+import Type.Row (RProxy(..))
+import Data.Symbol (SProxy(..))
+
+class Same l r (o :: Symbol) | l r -> o
+instance sameY :: Same t t "Y" else instance sameN :: Same l r "N"
+same :: forall l r o. Same l r o => l -> r -> SProxy o
+same _ _ = SProxy
+
+-- for label `u`, `t ~ Int` should be Unknown
+-- for label `m`, `Int ~ Int` should be a match
+-- together they should be Unknown
+example :: forall t. Proxy t -> SProxy _
+example _ = same (RProxy :: RProxy (u :: t, m :: Int))
+ (RProxy :: RProxy (u :: Int, m :: Int))
diff --git a/tests/purs/failing/InstanceChainSkolemUnknownMatch.purs b/tests/purs/failing/InstanceChainSkolemUnknownMatch.purs
new file mode 100644
index 0000000..a3111f3
--- /dev/null
+++ b/tests/purs/failing/InstanceChainSkolemUnknownMatch.purs
@@ -0,0 +1,15 @@
+-- @shouldFailWith NoInstanceFound
+module InstanceChainSkolemUnknownMatch where
+
+import Type.Proxy (Proxy(..))
+import Data.Symbol (SProxy(..))
+
+class Same l r (o :: Symbol) | l r -> o
+instance sameY :: Same t t "Y" else instance sameN :: Same l r "N"
+same :: forall l r o. Same l r o => l -> r -> SProxy o
+same _ _ = SProxy
+
+-- shouldn't discard sameY as Apart
+example :: forall t. Proxy t -> SProxy _
+example _ = same (Proxy :: Proxy t) (Proxy :: Proxy Int)
+
diff --git a/tests/purs/failing/InstanceExport.purs b/tests/purs/failing/InstanceExport.purs
new file mode 100644
index 0000000..e680b22
--- /dev/null
+++ b/tests/purs/failing/InstanceExport.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith TransitiveExportError
+module Test where
+
+import InstanceExport
+import Prelude
+
+test = f $ S "Test"
diff --git a/tests/purs/failing/InstanceExport/InstanceExport.purs b/tests/purs/failing/InstanceExport/InstanceExport.purs
new file mode 100644
index 0000000..e428a5c
--- /dev/null
+++ b/tests/purs/failing/InstanceExport/InstanceExport.purs
@@ -0,0 +1,11 @@
+module InstanceExport (S(..), f) where
+
+import Prelude
+
+newtype S = S String
+
+class F a where
+ f :: a -> String
+
+instance fs :: F S where
+ f (S s) = s
diff --git a/tests/purs/failing/InstanceSigsBodyIncorrect.purs b/tests/purs/failing/InstanceSigsBodyIncorrect.purs
new file mode 100644
index 0000000..fd3c437
--- /dev/null
+++ b/tests/purs/failing/InstanceSigsBodyIncorrect.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith TypesDoNotUnify
+
+module Main where
+
+class Foo a where
+ foo :: a
+
+instance fooNumber :: Foo Number where
+ foo :: Number
+ foo = true
diff --git a/tests/purs/failing/InstanceSigsDifferentTypes.purs b/tests/purs/failing/InstanceSigsDifferentTypes.purs
new file mode 100644
index 0000000..0de2109
--- /dev/null
+++ b/tests/purs/failing/InstanceSigsDifferentTypes.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith TypesDoNotUnify
+
+module Main where
+
+class Foo a where
+ foo :: a
+
+instance fooNumber :: Foo Number where
+ foo :: Int
+ foo = 0.0
diff --git a/tests/purs/failing/InstanceSigsIncorrectType.purs b/tests/purs/failing/InstanceSigsIncorrectType.purs
new file mode 100644
index 0000000..f452f2e
--- /dev/null
+++ b/tests/purs/failing/InstanceSigsIncorrectType.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith TypesDoNotUnify
+
+module Main where
+
+class Foo a where
+ foo :: a
+
+instance fooNumber :: Foo Number where
+ foo :: Boolean
+ foo = true
diff --git a/tests/purs/failing/InstanceSigsOrphanTypeDeclaration.purs b/tests/purs/failing/InstanceSigsOrphanTypeDeclaration.purs
new file mode 100644
index 0000000..0871119
--- /dev/null
+++ b/tests/purs/failing/InstanceSigsOrphanTypeDeclaration.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith OrphanTypeDeclaration
+
+module Main where
+
+class Foo a where
+ foo :: a
+
+instance fooNumber :: Foo Number where
+ bar :: Int
+ foo = 0.0
diff --git a/tests/purs/failing/IntOutOfRange.purs b/tests/purs/failing/IntOutOfRange.purs
new file mode 100644
index 0000000..1d22217
--- /dev/null
+++ b/tests/purs/failing/IntOutOfRange.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith IntOutOfRange
+
+module Main where
+
+n :: Int
+n = 2147483648
diff --git a/tests/purs/failing/InvalidDerivedInstance.purs b/tests/purs/failing/InvalidDerivedInstance.purs
new file mode 100644
index 0000000..11b1b46
--- /dev/null
+++ b/tests/purs/failing/InvalidDerivedInstance.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InvalidDerivedInstance
+module Main where
+
+import Prelude
+
+data X = X
+
+derive instance eqX :: Eq X X
diff --git a/tests/purs/failing/InvalidDerivedInstance2.purs b/tests/purs/failing/InvalidDerivedInstance2.purs
new file mode 100644
index 0000000..ec46733
--- /dev/null
+++ b/tests/purs/failing/InvalidDerivedInstance2.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ExpectedTypeConstructor
+module Main where
+
+import Prelude
+
+derive instance eqRecord :: Eq {}
diff --git a/tests/purs/failing/InvalidOperatorInBinder.purs b/tests/purs/failing/InvalidOperatorInBinder.purs
new file mode 100644
index 0000000..5cf6fd8
--- /dev/null
+++ b/tests/purs/failing/InvalidOperatorInBinder.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith InvalidOperatorInBinder
+module Main where
+
+data List a = Cons a (List a) | Nil
+
+cons ∷ ∀ a. a → List a → List a
+cons = Cons
+
+infixl 6 cons as :
+
+get ∷ ∀ a. List a → a
+get (_ : x : _) = x
diff --git a/tests/purs/failing/KindError.purs b/tests/purs/failing/KindError.purs
new file mode 100644
index 0000000..ddc656b
--- /dev/null
+++ b/tests/purs/failing/KindError.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith KindsDoNotUnify
+module Main where
+
+import Prelude
+
+data KindError f a = One f | Two (f a)
diff --git a/tests/purs/failing/KindStar.purs b/tests/purs/failing/KindStar.purs
new file mode 100644
index 0000000..12a1d65
--- /dev/null
+++ b/tests/purs/failing/KindStar.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith ExpectedType
+
+module X where
+
+data List a = Nil | Cons a (List a)
+
+test :: List
+test = Nil
diff --git a/tests/purs/failing/LacksWithSubGoal.purs b/tests/purs/failing/LacksWithSubGoal.purs
new file mode 100644
index 0000000..40db3af
--- /dev/null
+++ b/tests/purs/failing/LacksWithSubGoal.purs
@@ -0,0 +1,16 @@
+-- @shouldFailWith NoInstanceFound
+module LacksWithSubGoal where
+
+import Prim.Row (class Lacks)
+
+data S (r :: Symbol) = S
+
+data R (r :: # Type) = R
+
+union :: forall s r. Lacks s r => S s -> R r
+union S = R
+
+example :: forall r. R (k :: Int | r)
+example = union (S :: S "hello")
+
+
diff --git a/tests/purs/failing/LeadingZeros1.purs b/tests/purs/failing/LeadingZeros1.purs
new file mode 100644
index 0000000..e77cf2d
--- /dev/null
+++ b/tests/purs/failing/LeadingZeros1.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+import Prelude
+
+x = 01
diff --git a/tests/purs/failing/LeadingZeros2.purs b/tests/purs/failing/LeadingZeros2.purs
new file mode 100644
index 0000000..58ff97c
--- /dev/null
+++ b/tests/purs/failing/LeadingZeros2.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+import Prelude
+
+x = 00.1
diff --git a/tests/purs/failing/Let.purs b/tests/purs/failing/Let.purs
new file mode 100644
index 0000000..12d53ae
--- /dev/null
+++ b/tests/purs/failing/Let.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith CycleInDeclaration
+module Main where
+
+import Prelude
+
+test = let x = x in x
diff --git a/tests/purs/failing/LetPatterns1.purs b/tests/purs/failing/LetPatterns1.purs
new file mode 100644
index 0000000..1531ede
--- /dev/null
+++ b/tests/purs/failing/LetPatterns1.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+import Prelude
+
+-- wrong binders for function, the first one should be VarBinder
+x =
+ let (X a b) x y = hoge
+ in
+ a
diff --git a/tests/purs/failing/LetPatterns2.purs b/tests/purs/failing/LetPatterns2.purs
new file mode 100644
index 0000000..ebfd7f0
--- /dev/null
+++ b/tests/purs/failing/LetPatterns2.purs
@@ -0,0 +1,14 @@
+-- @shouldFailWith UnknownName
+module Main where
+
+import Prelude
+
+data X a = X a
+
+-- wrong dependency order
+x =
+ let
+ b = a
+ X a = X 10
+ in
+ b
diff --git a/tests/purs/failing/LetPatterns3.purs b/tests/purs/failing/LetPatterns3.purs
new file mode 100644
index 0000000..58be165
--- /dev/null
+++ b/tests/purs/failing/LetPatterns3.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith IncorrectConstructorArity
+module Main where
+
+import Prelude
+
+data X a = X a
+
+-- a parameter binder should be with nullary constructor, or with parens
+x =
+ let
+ a X b = b
+ in
+ a $ X 10
diff --git a/tests/purs/failing/LetPatterns4.purs b/tests/purs/failing/LetPatterns4.purs
new file mode 100644
index 0000000..a361a43
--- /dev/null
+++ b/tests/purs/failing/LetPatterns4.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+data X a = X a
+
+X a = a
diff --git a/tests/purs/failing/MPTCs.purs b/tests/purs/failing/MPTCs.purs
new file mode 100644
index 0000000..16a7822
--- /dev/null
+++ b/tests/purs/failing/MPTCs.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith ClassInstanceArityMismatch
+module Main where
+
+import Prelude
+
+class Foo a where
+ f :: a -> a
+
+instance fooStringString :: Foo String String where
+ f a = a
diff --git a/tests/purs/failing/MissingClassExport.purs b/tests/purs/failing/MissingClassExport.purs
new file mode 100644
index 0000000..bad7f30
--- /dev/null
+++ b/tests/purs/failing/MissingClassExport.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith TransitiveExportError
+module Test (bar) where
+
+import Prelude
+
+class Foo a where
+ bar :: a -> a
diff --git a/tests/purs/failing/MissingClassMember.purs b/tests/purs/failing/MissingClassMember.purs
new file mode 100644
index 0000000..488fccf
--- /dev/null
+++ b/tests/purs/failing/MissingClassMember.purs
@@ -0,0 +1,11 @@
+-- @shouldFailWith MissingClassMember
+module Main where
+
+import Prelude
+
+class A a where
+ a :: a -> String
+ b :: a -> Number
+
+instance aString :: A String where
+ a s = s
diff --git a/tests/purs/failing/MissingClassMemberExport.purs b/tests/purs/failing/MissingClassMemberExport.purs
new file mode 100644
index 0000000..11ae9b8
--- /dev/null
+++ b/tests/purs/failing/MissingClassMemberExport.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith TransitiveExportError
+module Test (class Foo) where
+
+import Prelude
+
+class Foo a where
+ bar :: a -> a
diff --git a/tests/purs/failing/MissingFFIImplementations.js b/tests/purs/failing/MissingFFIImplementations.js
new file mode 100644
index 0000000..d29ee4c
--- /dev/null
+++ b/tests/purs/failing/MissingFFIImplementations.js
@@ -0,0 +1 @@
+exports.yes = true;
diff --git a/tests/purs/failing/MissingFFIImplementations.purs b/tests/purs/failing/MissingFFIImplementations.purs
new file mode 100644
index 0000000..1f47ef8
--- /dev/null
+++ b/tests/purs/failing/MissingFFIImplementations.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith MissingFFIImplementations
+module Main where
+
+foreign import yes :: Boolean
+foreign import no :: Boolean
diff --git a/tests/purs/failing/MissingRecordField.purs b/tests/purs/failing/MissingRecordField.purs
new file mode 100644
index 0000000..2b865e9
--- /dev/null
+++ b/tests/purs/failing/MissingRecordField.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith PropertyIsMissing
+module MissingRecordField where
+
+import Prelude ((>))
+
+john = { first: "John", last: "Smith" }
+
+isOver50 p = p.age > 50.0
+
+result = isOver50 john
diff --git a/tests/purs/failing/MixedAssociativityError.purs b/tests/purs/failing/MixedAssociativityError.purs
new file mode 100644
index 0000000..db583c5
--- /dev/null
+++ b/tests/purs/failing/MixedAssociativityError.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith MixedAssociativityError
+module Main where
+
+import Prelude
+
+feq f x y = f <$> x == f <$> y
diff --git a/tests/purs/failing/MultipleErrors.purs b/tests/purs/failing/MultipleErrors.purs
new file mode 100644
index 0000000..b1d8a8c
--- /dev/null
+++ b/tests/purs/failing/MultipleErrors.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith TypesDoNotUnify
+-- @shouldFailWith TypesDoNotUnify
+module MultipleErrors where
+
+import Prelude
+
+foo :: Int -> Int
+foo 0 = "Test"
+foo n = bar (n - 1)
+
+bar :: Int -> Int
+bar 0 = "Test"
+bar n = foo (n - 1)
diff --git a/tests/purs/failing/MultipleErrors2.purs b/tests/purs/failing/MultipleErrors2.purs
new file mode 100644
index 0000000..d85439e
--- /dev/null
+++ b/tests/purs/failing/MultipleErrors2.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith UnknownName
+-- @shouldFailWith UnknownName
+module MultipleErrors2 where
+
+import Prelude
+
+foo = itDoesntExist
+
+bar = neitherDoesThis
diff --git a/tests/purs/failing/MultipleTypeOpFixities.purs b/tests/purs/failing/MultipleTypeOpFixities.purs
new file mode 100644
index 0000000..5d1b281
--- /dev/null
+++ b/tests/purs/failing/MultipleTypeOpFixities.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith MultipleTypeOpFixities
+module MultipleTypeOpFixities where
+
+import Prelude
+
+type Op x y = Op x y
+
+infix 2 type Op as !?
+infix 2 type Op as !?
diff --git a/tests/purs/failing/MultipleValueOpFixities.purs b/tests/purs/failing/MultipleValueOpFixities.purs
new file mode 100644
index 0000000..f1e4ccf
--- /dev/null
+++ b/tests/purs/failing/MultipleValueOpFixities.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith MultipleValueOpFixities
+module MultipleValueOpFixities where
+
+import Prelude
+
+add x y = x + y
+
+infix 2 add as !?
+infix 2 add as !?
diff --git a/tests/purs/failing/MutRec.purs b/tests/purs/failing/MutRec.purs
new file mode 100644
index 0000000..8168608
--- /dev/null
+++ b/tests/purs/failing/MutRec.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith CycleInDeclaration
+-- @shouldFailWith CycleInDeclaration
+module MutRec where
+
+import Prelude
+
+x = y
+
+y = x
diff --git a/tests/purs/failing/MutRec2.purs b/tests/purs/failing/MutRec2.purs
new file mode 100644
index 0000000..ad62b20
--- /dev/null
+++ b/tests/purs/failing/MutRec2.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith CycleInDeclaration
+module Main where
+
+import Prelude
+
+x = x
diff --git a/tests/purs/failing/NewtypeInstance.purs b/tests/purs/failing/NewtypeInstance.purs
new file mode 100644
index 0000000..3ffe080
--- /dev/null
+++ b/tests/purs/failing/NewtypeInstance.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InvalidNewtypeInstance
+module Main where
+
+import Prelude
+
+data X = X
+
+derive newtype instance showX :: Show X
diff --git a/tests/purs/failing/NewtypeInstance2.purs b/tests/purs/failing/NewtypeInstance2.purs
new file mode 100644
index 0000000..67b16fc
--- /dev/null
+++ b/tests/purs/failing/NewtypeInstance2.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InvalidNewtypeInstance
+module Main where
+
+import Prelude
+
+data X a = X a a
+
+derive newtype instance showX :: Show a => Show (X a)
diff --git a/tests/purs/failing/NewtypeInstance3.purs b/tests/purs/failing/NewtypeInstance3.purs
new file mode 100644
index 0000000..528eefb
--- /dev/null
+++ b/tests/purs/failing/NewtypeInstance3.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InvalidNewtypeInstance
+module Main where
+
+import Prelude
+
+class Nullary
+
+derive newtype instance nullary :: Nullary
diff --git a/tests/purs/failing/NewtypeInstance4.purs b/tests/purs/failing/NewtypeInstance4.purs
new file mode 100644
index 0000000..4004520
--- /dev/null
+++ b/tests/purs/failing/NewtypeInstance4.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InvalidNewtypeInstance
+module Main where
+
+import Prelude
+
+data X = X | Y
+
+derive newtype instance showX :: Show X
diff --git a/tests/purs/failing/NewtypeInstance5.purs b/tests/purs/failing/NewtypeInstance5.purs
new file mode 100644
index 0000000..5003ee8
--- /dev/null
+++ b/tests/purs/failing/NewtypeInstance5.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InvalidNewtypeInstance
+module Main where
+
+import Prelude
+
+newtype X a = X a
+
+derive newtype instance functorX :: Functor X
diff --git a/tests/purs/failing/NewtypeInstance6.purs b/tests/purs/failing/NewtypeInstance6.purs
new file mode 100644
index 0000000..fe71366
--- /dev/null
+++ b/tests/purs/failing/NewtypeInstance6.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith InvalidNewtypeInstance
+module Main where
+
+import Prelude
+
+newtype X a b = X (Array b)
+
+derive newtype instance functorX :: Functor X
diff --git a/tests/purs/failing/NewtypeMultiArgs.purs b/tests/purs/failing/NewtypeMultiArgs.purs
new file mode 100644
index 0000000..b3ceed3
--- /dev/null
+++ b/tests/purs/failing/NewtypeMultiArgs.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith InvalidNewtype
+module Main where
+
+import Prelude
+
+newtype Thing = Thing String Boolean
diff --git a/tests/purs/failing/NewtypeMultiCtor.purs b/tests/purs/failing/NewtypeMultiCtor.purs
new file mode 100644
index 0000000..04b4cee
--- /dev/null
+++ b/tests/purs/failing/NewtypeMultiCtor.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith InvalidNewtype
+module Main where
+
+import Prelude
+
+newtype Thing = Thing String | Other
diff --git a/tests/purs/failing/NonAssociativeError.purs b/tests/purs/failing/NonAssociativeError.purs
new file mode 100644
index 0000000..6958c60
--- /dev/null
+++ b/tests/purs/failing/NonAssociativeError.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith NonAssociativeError
+-- @shouldFailWith NonAssociativeError
+module Main where
+
+import Prelude
+
+a = true == true == true
+b = true == false /= true
diff --git a/tests/purs/failing/NonExhaustivePatGuard.purs b/tests/purs/failing/NonExhaustivePatGuard.purs
new file mode 100644
index 0000000..cdcfc2f
--- /dev/null
+++ b/tests/purs/failing/NonExhaustivePatGuard.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith NoInstanceFound
+module Main where
+
+f :: Int -> Int
+f x | 1 <- x = x \ No newline at end of file
diff --git a/tests/purs/failing/NullaryAbs.purs b/tests/purs/failing/NullaryAbs.purs
new file mode 100644
index 0000000..9cd0eca
--- /dev/null
+++ b/tests/purs/failing/NullaryAbs.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+import Prelude
+
+func = \ -> "no"
diff --git a/tests/purs/failing/Object.purs b/tests/purs/failing/Object.purs
new file mode 100644
index 0000000..7d8f84c
--- /dev/null
+++ b/tests/purs/failing/Object.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith PropertyIsMissing
+module Main where
+
+import Prelude
+
+test o = o.foo
+
+test1 = test {}
diff --git a/tests/purs/failing/OperatorAliasNoExport.purs b/tests/purs/failing/OperatorAliasNoExport.purs
new file mode 100644
index 0000000..5a089ba
--- /dev/null
+++ b/tests/purs/failing/OperatorAliasNoExport.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith TransitiveExportError
+module Test ((?!)) where
+
+infixl 4 what as ?!
+
+what :: forall a b. a -> b -> a
+what a _ = a
diff --git a/tests/purs/failing/OperatorSections.purs b/tests/purs/failing/OperatorSections.purs
new file mode 100644
index 0000000..14fc674
--- /dev/null
+++ b/tests/purs/failing/OperatorSections.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith TypesDoNotUnify
+module Main where
+
+import Prelude
+
+main = do
+ (true `not` _)
diff --git a/tests/purs/failing/OrphanInstance.purs b/tests/purs/failing/OrphanInstance.purs
new file mode 100644
index 0000000..85c3656
--- /dev/null
+++ b/tests/purs/failing/OrphanInstance.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith OrphanInstance
+module Test where
+
+import Class
+
+instance cBoolean :: C Boolean where
+ op a = a
diff --git a/tests/purs/failing/OrphanInstance/Class.purs b/tests/purs/failing/OrphanInstance/Class.purs
new file mode 100644
index 0000000..0b482d4
--- /dev/null
+++ b/tests/purs/failing/OrphanInstance/Class.purs
@@ -0,0 +1,4 @@
+module Class where
+
+class C a where
+ op :: a -> a
diff --git a/tests/purs/failing/OrphanInstanceFunDepCycle.purs b/tests/purs/failing/OrphanInstanceFunDepCycle.purs
new file mode 100644
index 0000000..c11877c
--- /dev/null
+++ b/tests/purs/failing/OrphanInstanceFunDepCycle.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith OrphanInstance
+module Main where
+import Lib
+data L
+instance clr :: C L R
diff --git a/tests/purs/failing/OrphanInstanceFunDepCycle/Lib.purs b/tests/purs/failing/OrphanInstanceFunDepCycle/Lib.purs
new file mode 100644
index 0000000..5c77a8d
--- /dev/null
+++ b/tests/purs/failing/OrphanInstanceFunDepCycle/Lib.purs
@@ -0,0 +1,4 @@
+module Lib where
+-- covering sets: {{l}, {r}}
+class C l r | l -> r, r -> l
+data R
diff --git a/tests/purs/failing/OrphanInstanceNullary.purs b/tests/purs/failing/OrphanInstanceNullary.purs
new file mode 100644
index 0000000..14c6184
--- /dev/null
+++ b/tests/purs/failing/OrphanInstanceNullary.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith OrphanInstance
+module Test where
+import Lib
+instance c :: C
diff --git a/tests/purs/failing/OrphanInstanceNullary/Lib.purs b/tests/purs/failing/OrphanInstanceNullary/Lib.purs
new file mode 100644
index 0000000..1ba95de
--- /dev/null
+++ b/tests/purs/failing/OrphanInstanceNullary/Lib.purs
@@ -0,0 +1,2 @@
+module Lib where
+class C
diff --git a/tests/purs/failing/OrphanInstanceWithDetermined.purs b/tests/purs/failing/OrphanInstanceWithDetermined.purs
new file mode 100644
index 0000000..f905fd5
--- /dev/null
+++ b/tests/purs/failing/OrphanInstanceWithDetermined.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith OrphanInstance
+module Main where
+import Lib
+data R
+instance cflr :: C F L R
diff --git a/tests/purs/failing/OrphanInstanceWithDetermined/Lib.purs b/tests/purs/failing/OrphanInstanceWithDetermined/Lib.purs
new file mode 100644
index 0000000..03b701f
--- /dev/null
+++ b/tests/purs/failing/OrphanInstanceWithDetermined/Lib.purs
@@ -0,0 +1,5 @@
+module Lib where
+-- covering sets: {{f, l}}
+class C f l r | l -> r
+data F
+data L
diff --git a/tests/purs/failing/OrphanTypeDecl.purs b/tests/purs/failing/OrphanTypeDecl.purs
new file mode 100644
index 0000000..a178e5d
--- /dev/null
+++ b/tests/purs/failing/OrphanTypeDecl.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith OrphanTypeDeclaration
+module OrphanTypeDecl where
+
+fn :: Number -> Boolean
diff --git a/tests/purs/failing/OverlapAcrossModules.purs b/tests/purs/failing/OverlapAcrossModules.purs
new file mode 100644
index 0000000..29c87b8
--- /dev/null
+++ b/tests/purs/failing/OverlapAcrossModules.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith OverlappingInstances
+module OverlapAcrossModules where
+import OverlapAcrossModules.Class
+import OverlapAcrossModules.X
+data Y
+instance cxy :: C X Y
+
diff --git a/tests/purs/failing/OverlapAcrossModules/Class.purs b/tests/purs/failing/OverlapAcrossModules/Class.purs
new file mode 100644
index 0000000..6b4699a
--- /dev/null
+++ b/tests/purs/failing/OverlapAcrossModules/Class.purs
@@ -0,0 +1,2 @@
+module OverlapAcrossModules.Class where
+class C x y
diff --git a/tests/purs/failing/OverlapAcrossModules/X.purs b/tests/purs/failing/OverlapAcrossModules/X.purs
new file mode 100644
index 0000000..df3a6b2
--- /dev/null
+++ b/tests/purs/failing/OverlapAcrossModules/X.purs
@@ -0,0 +1,4 @@
+module OverlapAcrossModules.X where
+import OverlapAcrossModules.Class
+data X
+instance cxy :: C X y
diff --git a/tests/purs/failing/OverlappingArguments.purs b/tests/purs/failing/OverlappingArguments.purs
new file mode 100644
index 0000000..5a64e20
--- /dev/null
+++ b/tests/purs/failing/OverlappingArguments.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith OverlappingArgNames
+module OverlappingArguments where
+
+import Prelude
+
+f x x = x
diff --git a/tests/purs/failing/OverlappingBinders.purs b/tests/purs/failing/OverlappingBinders.purs
new file mode 100644
index 0000000..95452f7
--- /dev/null
+++ b/tests/purs/failing/OverlappingBinders.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith OverlappingArgNames
+module OverlappingBinders where
+
+import Prelude
+
+data S a = S a (S a)
+
+f x = case x of
+ (S y (S y@(S z zs))) -> y
diff --git a/tests/purs/failing/OverlappingInstances.purs b/tests/purs/failing/OverlappingInstances.purs
new file mode 100644
index 0000000..9ae7230
--- /dev/null
+++ b/tests/purs/failing/OverlappingInstances.purs
@@ -0,0 +1,17 @@
+-- @shouldFailWith OverlappingInstances
+module Main where
+
+class Test a where
+ test :: a -> a
+
+instance testRefl :: Test a where
+ test x = x
+
+instance testInt :: Test Int where
+ test _ = 0
+
+-- The OverlappingInstances instances error only arises when there are two
+-- choices for a dictionary, not when the instances are defined. So without
+-- `value` this module would not raise a warning.
+value :: Int
+value = test 1
diff --git a/tests/purs/failing/OverlappingVars.purs b/tests/purs/failing/OverlappingVars.purs
new file mode 100644
index 0000000..78919e8
--- /dev/null
+++ b/tests/purs/failing/OverlappingVars.purs
@@ -0,0 +1,14 @@
+-- @shouldFailWith NoInstanceFound
+module Main where
+
+import Prelude
+
+class OverlappingVars a where
+ f :: a -> a
+
+data Foo a b = Foo a b
+
+instance overlappingVarsFoo :: OverlappingVars (Foo a a) where
+ f a = a
+
+test = f (Foo "" 0)
diff --git a/tests/purs/failing/PrimModuleReserved.purs b/tests/purs/failing/PrimModuleReserved.purs
new file mode 100644
index 0000000..f09fe55
--- /dev/null
+++ b/tests/purs/failing/PrimModuleReserved.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith CannotDefinePrimModules
+module Main where
+
+import Prim
diff --git a/tests/purs/failing/PrimModuleReserved/Prim.purs b/tests/purs/failing/PrimModuleReserved/Prim.purs
new file mode 100644
index 0000000..bac1516
--- /dev/null
+++ b/tests/purs/failing/PrimModuleReserved/Prim.purs
@@ -0,0 +1 @@
+module Prim where
diff --git a/tests/purs/failing/PrimRow.purs b/tests/purs/failing/PrimRow.purs
new file mode 100644
index 0000000..e9dfe05
--- /dev/null
+++ b/tests/purs/failing/PrimRow.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith UnknownName
+module Main where
+
+import Prelude
+
+-- The 'Cons' class is not imported here, so we should not be able to refer to
+-- it in the module.
+import Prim.Row ()
+
+x :: Cons "hello" Int () ("hello" :: Int)
+ => Unit
+x = unit
+
diff --git a/tests/purs/failing/PrimSubModuleReserved.purs b/tests/purs/failing/PrimSubModuleReserved.purs
new file mode 100644
index 0000000..a4d4ae9
--- /dev/null
+++ b/tests/purs/failing/PrimSubModuleReserved.purs
@@ -0,0 +1,4 @@
+-- @shouldFailWith CannotDefinePrimModules
+module Main where
+
+import Prim.Foobar
diff --git a/tests/purs/failing/PrimSubModuleReserved/Prim_Foobar.purs b/tests/purs/failing/PrimSubModuleReserved/Prim_Foobar.purs
new file mode 100644
index 0000000..bab6dab
--- /dev/null
+++ b/tests/purs/failing/PrimSubModuleReserved/Prim_Foobar.purs
@@ -0,0 +1 @@
+module Prim.Foobar where
diff --git a/tests/purs/failing/ProgrammableTypeErrors.purs b/tests/purs/failing/ProgrammableTypeErrors.purs
new file mode 100644
index 0000000..11e7b48
--- /dev/null
+++ b/tests/purs/failing/ProgrammableTypeErrors.purs
@@ -0,0 +1,17 @@
+-- @shouldFailWith NoInstanceFound
+
+module Main where
+
+import Prelude
+import Prim.TypeError
+import Effect (Effect)
+import Effect.Console (log)
+
+class MyShow a where
+ myShow :: a -> String
+
+instance cannotShowFunctions :: Fail (Text "Cannot show functions") => MyShow (a -> b) where
+ myShow _ = "unreachable"
+
+main :: Effect Unit
+main = log (myShow (_ + 1))
diff --git a/tests/purs/failing/ProgrammableTypeErrorsTypeString.purs b/tests/purs/failing/ProgrammableTypeErrorsTypeString.purs
new file mode 100644
index 0000000..d9ba1b2
--- /dev/null
+++ b/tests/purs/failing/ProgrammableTypeErrorsTypeString.purs
@@ -0,0 +1,24 @@
+-- @shouldFailWith NoInstanceFound
+
+module Main where
+
+import Prelude
+import Prim.TypeError
+import Effect (Effect)
+import Effect.Console (log)
+
+newtype MyType a = MyType a
+
+instance cannotShowFunctions ::
+ Fail ( Text "Don't want to show " <>
+ Quote (MyType a) <>
+ Text " because."
+ ) => Show (MyType a)
+ where
+ show _ = "unreachable"
+
+infixl 6 type Beside as <>
+
+main :: Effect Unit
+main = do
+ log $ show (MyType 2)
diff --git a/tests/purs/failing/Rank2Types.purs b/tests/purs/failing/Rank2Types.purs
new file mode 100644
index 0000000..68438fd
--- /dev/null
+++ b/tests/purs/failing/Rank2Types.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith TypesDoNotUnify
+module Main where
+
+import Prelude
+
+foreign import test :: (forall a. a -> a) -> Number
+
+test1 = test (\n -> n + 1)
diff --git a/tests/purs/failing/RequiredHiddenType.purs b/tests/purs/failing/RequiredHiddenType.purs
new file mode 100644
index 0000000..ee86fe6
--- /dev/null
+++ b/tests/purs/failing/RequiredHiddenType.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith TransitiveExportError
+-- exporting `a` should fail as `A` is hidden
+module Foo (B(..), a, b) where
+
+data A = A
+data B = B
+
+a = A
+b = B
diff --git a/tests/purs/failing/Reserved.purs b/tests/purs/failing/Reserved.purs
new file mode 100644
index 0000000..f94733b
--- /dev/null
+++ b/tests/purs/failing/Reserved.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+import Prelude
+
+(<) :: Number -> Number -> Number
+(<) a b = !(a >= b)
diff --git a/tests/purs/failing/RowConstructors1.purs b/tests/purs/failing/RowConstructors1.purs
new file mode 100644
index 0000000..9587fda
--- /dev/null
+++ b/tests/purs/failing/RowConstructors1.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith KindsDoNotUnify
+module Main where
+
+import Effect.Console (log)
+
+data Foo = Bar
+type Baz = { | Foo }
+
+main = log "Done"
diff --git a/tests/purs/failing/RowConstructors2.purs b/tests/purs/failing/RowConstructors2.purs
new file mode 100644
index 0000000..aeec350
--- /dev/null
+++ b/tests/purs/failing/RowConstructors2.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith KindsDoNotUnify
+module Main where
+
+import Effect.Console (log)
+
+type Foo r = (x :: Number | r)
+type Bar = { | Foo }
+
+main = log "Done"
diff --git a/tests/purs/failing/RowConstructors3.purs b/tests/purs/failing/RowConstructors3.purs
new file mode 100644
index 0000000..9cb9ca9
--- /dev/null
+++ b/tests/purs/failing/RowConstructors3.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith KindsDoNotUnify
+module Main where
+
+import Effect.Console (log)
+
+type Foo = { x :: Number }
+type Bar = { | Foo }
+
+main = log "Done"
diff --git a/tests/purs/failing/RowInInstanceNotDetermined0.purs b/tests/purs/failing/RowInInstanceNotDetermined0.purs
new file mode 100644
index 0000000..6e2a9d8
--- /dev/null
+++ b/tests/purs/failing/RowInInstanceNotDetermined0.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith InvalidInstanceHead
+module Main where
+
+import Prelude
+
+-- no fundeps
+class C a b
+instance c :: C Unit {}
+
diff --git a/tests/purs/failing/RowInInstanceNotDetermined1.purs b/tests/purs/failing/RowInInstanceNotDetermined1.purs
new file mode 100644
index 0000000..39083a9
--- /dev/null
+++ b/tests/purs/failing/RowInInstanceNotDetermined1.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith InvalidInstanceHead
+module Main where
+
+import Prelude
+
+-- `c` not mentioned in any fundeps
+class C a b c | a -> b
+instance c :: C Unit Unit {}
+
diff --git a/tests/purs/failing/RowInInstanceNotDetermined2.purs b/tests/purs/failing/RowInInstanceNotDetermined2.purs
new file mode 100644
index 0000000..141e9c5
--- /dev/null
+++ b/tests/purs/failing/RowInInstanceNotDetermined2.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith InvalidInstanceHead
+module Main where
+
+import Prelude
+
+-- `b` isn't determined by anything that `b` doesn't determine
+class C a b | a -> b, b -> a
+instance c :: C Unit {}
+
diff --git a/tests/purs/failing/RowLacks.purs b/tests/purs/failing/RowLacks.purs
new file mode 100644
index 0000000..7805872
--- /dev/null
+++ b/tests/purs/failing/RowLacks.purs
@@ -0,0 +1,18 @@
+-- @shouldFailWith NoInstanceFound
+module Main where
+
+import Effect.Console (log)
+import Prim.Row (class Lacks)
+import Type.Row (RProxy(..))
+
+lacksX
+ :: forall r
+ . Lacks "x" r
+ => RProxy r
+ -> RProxy ()
+lacksX _ = RProxy
+
+test1 :: RProxy ()
+test1 = lacksX (RProxy :: RProxy (x :: Int, y :: Int, z :: String))
+
+main = log "Done"
diff --git a/tests/purs/failing/SkolemEscape.purs b/tests/purs/failing/SkolemEscape.purs
new file mode 100644
index 0000000..c9c63ad
--- /dev/null
+++ b/tests/purs/failing/SkolemEscape.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith EscapedSkolem
+module Main where
+
+import Prelude
+
+foreign import foo :: (forall a. a -> a) -> Number
+
+test = \x -> foo x
diff --git a/tests/purs/failing/SkolemEscape2.purs b/tests/purs/failing/SkolemEscape2.purs
new file mode 100644
index 0000000..1a9b060
--- /dev/null
+++ b/tests/purs/failing/SkolemEscape2.purs
@@ -0,0 +1,11 @@
+-- @shouldFailWith EscapedSkolem
+module Main where
+
+import Prelude
+import Effect
+import Control.Monad.ST as ST
+import Control.Monad.ST.Ref as STRef
+
+test _ = do
+ r <- pure (ST.run (STRef.new 0))
+ pure r
diff --git a/tests/purs/failing/SuggestComposition.purs b/tests/purs/failing/SuggestComposition.purs
new file mode 100644
index 0000000..4fd84b4
--- /dev/null
+++ b/tests/purs/failing/SuggestComposition.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith TypesDoNotUnify
+-- TODO: Ensure the correct suggestion is produced.
+module SuggestComposition where
+
+import Prelude
+
+f = g . g where g = (_ + 1)
diff --git a/tests/purs/failing/Superclasses1.purs b/tests/purs/failing/Superclasses1.purs
new file mode 100644
index 0000000..f6f2b3d
--- /dev/null
+++ b/tests/purs/failing/Superclasses1.purs
@@ -0,0 +1,14 @@
+-- @shouldFailWith NoInstanceFound
+module Main where
+
+import Prelude
+
+class Su a where
+ su :: a -> a
+
+class (Su a) <= Cl a where
+ cl :: a -> a -> a
+
+instance clNumber :: Cl Number where
+ cl n m = n + m
+
diff --git a/tests/purs/failing/Superclasses2.purs b/tests/purs/failing/Superclasses2.purs
new file mode 100644
index 0000000..0c50349
--- /dev/null
+++ b/tests/purs/failing/Superclasses2.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith CycleInTypeSynonym
+-- TODO: Should this have its own error, perhaps CycleInTypeClassDeclaration?
+module CycleInSuperclasses where
+
+import Prelude
+
+class (Foo a) <= Bar a
+
+class (Bar a) <= Foo a
+
+instance barString :: Bar String
+
+instance fooString :: Foo String
diff --git a/tests/purs/failing/Superclasses3.purs b/tests/purs/failing/Superclasses3.purs
new file mode 100644
index 0000000..2a6c225
--- /dev/null
+++ b/tests/purs/failing/Superclasses3.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith UndefinedTypeVariable
+module UnknownSuperclassTypeVar where
+
+import Prelude
+
+class Foo a
+
+class (Foo b) <= Bar a
diff --git a/tests/purs/failing/Superclasses5.purs b/tests/purs/failing/Superclasses5.purs
new file mode 100644
index 0000000..5bbfae6
--- /dev/null
+++ b/tests/purs/failing/Superclasses5.purs
@@ -0,0 +1,26 @@
+-- @shouldFailWith NoInstanceFound
+
+module Main where
+
+import Prelude
+import Effect.Console (logShow)
+
+class Su a where
+ su :: a -> a
+
+class Su (Array a) <= Cl a where
+ cl :: a -> a -> a
+
+instance suNumber :: Su Number where
+ su n = n + 1.0
+
+instance suArray :: Su a => Su (Array a) where
+ su [x] = [su x]
+
+instance clNumber :: Cl Number where
+ cl n m = n + m
+
+test :: forall a. Cl a => a -> Array a
+test x = su [cl x x]
+
+main = logShow $ test 10.0
diff --git a/tests/purs/failing/TooFewClassInstanceArgs.purs b/tests/purs/failing/TooFewClassInstanceArgs.purs
new file mode 100644
index 0000000..2d612c9
--- /dev/null
+++ b/tests/purs/failing/TooFewClassInstanceArgs.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith ClassInstanceArityMismatch
+module Main where
+
+import Prelude
+
+class Foo a b
+
+instance fooString :: Foo String
diff --git a/tests/purs/failing/TopLevelCaseNoArgs.purs b/tests/purs/failing/TopLevelCaseNoArgs.purs
new file mode 100644
index 0000000..fae9238
--- /dev/null
+++ b/tests/purs/failing/TopLevelCaseNoArgs.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith DuplicateValueDeclaration
+module Main where
+
+import Prelude
+
+foo :: Number
+foo = 1
+foo = 2
diff --git a/tests/purs/failing/TransitiveDctorExport.purs b/tests/purs/failing/TransitiveDctorExport.purs
new file mode 100644
index 0000000..1de81eb
--- /dev/null
+++ b/tests/purs/failing/TransitiveDctorExport.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith TransitiveExportError
+module Main (Y(..)) where
+
+type X = Int
+data Y = Y X
diff --git a/tests/purs/failing/TransitiveKindExport.purs b/tests/purs/failing/TransitiveKindExport.purs
new file mode 100644
index 0000000..7aba655
--- /dev/null
+++ b/tests/purs/failing/TransitiveKindExport.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith TransitiveExportError
+module Main (TestProxy(..)) where
+
+foreign import kind Test
+
+data TestProxy (p :: Test) = TestProxy
diff --git a/tests/purs/failing/TransitiveSynonymExport.purs b/tests/purs/failing/TransitiveSynonymExport.purs
new file mode 100644
index 0000000..9778e1f
--- /dev/null
+++ b/tests/purs/failing/TransitiveSynonymExport.purs
@@ -0,0 +1,5 @@
+-- @shouldFailWith TransitiveExportError
+module Main (Y()) where
+
+type X = Int
+type Y = X
diff --git a/tests/purs/failing/TypeClasses2.purs b/tests/purs/failing/TypeClasses2.purs
new file mode 100644
index 0000000..16f6175
--- /dev/null
+++ b/tests/purs/failing/TypeClasses2.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith NoInstanceFound
+module Main where
+
+import Prelude ()
+
+class Show a where
+ show :: a -> String
+
+test = show "testing"
diff --git a/tests/purs/failing/TypeError.purs b/tests/purs/failing/TypeError.purs
new file mode 100644
index 0000000..1c5c980
--- /dev/null
+++ b/tests/purs/failing/TypeError.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith TypesDoNotUnify
+module Main where
+
+import Prelude
+
+test = 1 <> "A"
diff --git a/tests/purs/failing/TypeOperatorAliasNoExport.purs b/tests/purs/failing/TypeOperatorAliasNoExport.purs
new file mode 100644
index 0000000..227479a
--- /dev/null
+++ b/tests/purs/failing/TypeOperatorAliasNoExport.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith TransitiveExportError
+module Test (type (×)) where
+
+data Tuple a b = Tuple a b
+
+infixl 6 type Tuple as ×
diff --git a/tests/purs/failing/TypeSynonyms.purs b/tests/purs/failing/TypeSynonyms.purs
new file mode 100644
index 0000000..6afcde4
--- /dev/null
+++ b/tests/purs/failing/TypeSynonyms.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith CycleInTypeSynonym
+module Main where
+
+import Prelude
+
+type T1 = Array T2
+
+type T2 = T1
diff --git a/tests/purs/failing/TypeSynonyms2.purs b/tests/purs/failing/TypeSynonyms2.purs
new file mode 100644
index 0000000..e129df2
--- /dev/null
+++ b/tests/purs/failing/TypeSynonyms2.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith TypeSynonymInstance
+module Main where
+
+import Prelude
+
+class Foo a where
+ foo :: a -> String
+
+type Bar = String
+
+instance fooBar :: Foo Bar where
+ foo s = s
diff --git a/tests/purs/failing/TypeSynonyms3.purs b/tests/purs/failing/TypeSynonyms3.purs
new file mode 100644
index 0000000..e129df2
--- /dev/null
+++ b/tests/purs/failing/TypeSynonyms3.purs
@@ -0,0 +1,12 @@
+-- @shouldFailWith TypeSynonymInstance
+module Main where
+
+import Prelude
+
+class Foo a where
+ foo :: a -> String
+
+type Bar = String
+
+instance fooBar :: Foo Bar where
+ foo s = s
diff --git a/tests/purs/failing/TypeSynonyms4.purs b/tests/purs/failing/TypeSynonyms4.purs
new file mode 100644
index 0000000..5861ef3
--- /dev/null
+++ b/tests/purs/failing/TypeSynonyms4.purs
@@ -0,0 +1,11 @@
+-- @shouldFailWith PartiallyAppliedSynonym
+module TypeSynonyms4 where
+
+import Prelude
+
+type F x y = x -> y
+
+type G x = F x
+
+f :: G String String -> String
+f k = k "Done"
diff --git a/tests/purs/failing/TypeSynonyms5.purs b/tests/purs/failing/TypeSynonyms5.purs
new file mode 100644
index 0000000..964106b
--- /dev/null
+++ b/tests/purs/failing/TypeSynonyms5.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith CycleInTypeSynonym
+module Main where
+
+import Prelude
+
+type T = T
diff --git a/tests/purs/failing/TypeWildcards1.purs b/tests/purs/failing/TypeWildcards1.purs
new file mode 100644
index 0000000..6a54b8e
--- /dev/null
+++ b/tests/purs/failing/TypeWildcards1.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith ErrorParsingModule
+module TypeWildcards where
+
+import Prelude
+
+type Test = _
+
diff --git a/tests/purs/failing/TypeWildcards2.purs b/tests/purs/failing/TypeWildcards2.purs
new file mode 100644
index 0000000..f09a2dc
--- /dev/null
+++ b/tests/purs/failing/TypeWildcards2.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith ErrorParsingModule
+module TypeWildcards where
+
+import Prelude
+
+data Test = Test _
+
diff --git a/tests/purs/failing/TypeWildcards3.purs b/tests/purs/failing/TypeWildcards3.purs
new file mode 100644
index 0000000..c0463fa
--- /dev/null
+++ b/tests/purs/failing/TypeWildcards3.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith InvalidInstanceHead
+module TypeWildcards where
+
+import Prelude
+
+data Foo a = Foo
+
+instance showFoo :: Show (Foo _) where
+ show Foo = "Foo"
diff --git a/tests/purs/failing/TypedBinders.purs b/tests/purs/failing/TypedBinders.purs
new file mode 100644
index 0000000..f13a759
--- /dev/null
+++ b/tests/purs/failing/TypedBinders.purs
@@ -0,0 +1,10 @@
+-- @shouldFailWith ErrorParsingModule
+module Main where
+
+import Effect.Console (log)
+
+test = (\f :: Int -> Int -> f 10) identity
+
+main = do
+ let t1 = test
+ log "Done"
diff --git a/tests/purs/failing/TypedBinders2.purs b/tests/purs/failing/TypedBinders2.purs
new file mode 100644
index 0000000..7262441
--- /dev/null
+++ b/tests/purs/failing/TypedBinders2.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith TypesDoNotUnify
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+main = do
+ s :: String <- log "Foo"
+ log "Done"
diff --git a/tests/purs/failing/TypedBinders3.purs b/tests/purs/failing/TypedBinders3.purs
new file mode 100644
index 0000000..3edcfd9
--- /dev/null
+++ b/tests/purs/failing/TypedBinders3.purs
@@ -0,0 +1,13 @@
+-- @shouldFailWith TypesDoNotUnify
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test = case 1 of
+ (0 :: String) -> true
+ _ -> false
+
+main = do
+ let t = test
+ log "Done"
diff --git a/tests/purs/failing/TypedHole.purs b/tests/purs/failing/TypedHole.purs
new file mode 100644
index 0000000..9cb6e34
--- /dev/null
+++ b/tests/purs/failing/TypedHole.purs
@@ -0,0 +1,8 @@
+-- @shouldFailWith HoleInferredType
+module Main where
+
+import Prelude
+import Effect (Effect)
+
+main :: Effect Unit
+main = ?ummm
diff --git a/tests/purs/failing/UnderscoreModuleName.purs b/tests/purs/failing/UnderscoreModuleName.purs
new file mode 100644
index 0000000..671e6a3
--- /dev/null
+++ b/tests/purs/failing/UnderscoreModuleName.purs
@@ -0,0 +1,6 @@
+-- @shouldFailWith ErrorParsingModule
+module Bad_Module where
+
+import Effect.Console (log)
+
+main = log "Done"
diff --git a/tests/purs/failing/UnknownType.purs b/tests/purs/failing/UnknownType.purs
new file mode 100644
index 0000000..d77ccb6
--- /dev/null
+++ b/tests/purs/failing/UnknownType.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith UnknownName
+module Main where
+
+import Prelude
+
+test :: Number -> Something
+test = {}
diff --git a/tests/purs/failing/UnusableTypeClassMethod.purs b/tests/purs/failing/UnusableTypeClassMethod.purs
new file mode 100644
index 0000000..058f504
--- /dev/null
+++ b/tests/purs/failing/UnusableTypeClassMethod.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith UnusableDeclaration
+module Main where
+
+class C a b where
+ -- type doesn't contain `a`, which is also required to determine an instance
+ c :: b
+
diff --git a/tests/purs/failing/UnusableTypeClassMethodConflictingIdent.purs b/tests/purs/failing/UnusableTypeClassMethodConflictingIdent.purs
new file mode 100644
index 0000000..08ed602
--- /dev/null
+++ b/tests/purs/failing/UnusableTypeClassMethodConflictingIdent.purs
@@ -0,0 +1,7 @@
+-- @shouldFailWith UnusableDeclaration
+module Main where
+
+class C a where
+ -- type doesn't contain the type class var `a`
+ c :: forall a. a
+
diff --git a/tests/purs/failing/UnusableTypeClassMethodSynonym.purs b/tests/purs/failing/UnusableTypeClassMethodSynonym.purs
new file mode 100644
index 0000000..aae1e33
--- /dev/null
+++ b/tests/purs/failing/UnusableTypeClassMethodSynonym.purs
@@ -0,0 +1,9 @@
+-- @shouldFailWith UnusableDeclaration
+module Main where
+
+type M x = forall a. a
+
+class C a where
+ -- after synonym expansion, the type doesn't actually contain an `a`
+ c :: M a
+
diff --git a/tests/purs/passing/1110.purs b/tests/purs/passing/1110.purs
new file mode 100644
index 0000000..32ecebc
--- /dev/null
+++ b/tests/purs/passing/1110.purs
@@ -0,0 +1,26 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data X a = X
+
+x :: forall a. X a
+x = X
+
+type Y = { x :: X Int }
+
+test :: forall m. Monad m => m Y
+test = pure { x: x }
+
+type Z t = forall x. t x -> (forall a. t a) -> t x
+
+class C t where c :: Z t
+
+instance cA :: C Array where
+ c x _ = x
+
+test2 :: forall m. Monad m => m { ccc :: Z Array }
+test2 = pure { ccc: (c :: Z Array) }
+
+main = log "Done"
diff --git a/tests/purs/passing/1185.purs b/tests/purs/passing/1185.purs
new file mode 100644
index 0000000..c32b7e3
--- /dev/null
+++ b/tests/purs/passing/1185.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Effect.Console (log)
+
+data Person = Person String Boolean
+
+getName :: Person -> String
+getName p = case p of
+ Person name true -> name
+ _ -> "Unknown"
+
+name :: String
+name = getName (Person "John Smith" true)
+
+main = log "Done"
diff --git a/tests/purs/passing/1335.purs b/tests/purs/passing/1335.purs
new file mode 100644
index 0000000..eadb257
--- /dev/null
+++ b/tests/purs/passing/1335.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+x :: forall a. a -> String
+x a = y "Test"
+ where
+ y :: forall a. Show a => a -> String
+ y a = show (a :: a)
+
+main = do
+ log (x 0)
+ log "Done"
diff --git a/tests/purs/passing/1570.purs b/tests/purs/passing/1570.purs
new file mode 100644
index 0000000..1898847
--- /dev/null
+++ b/tests/purs/passing/1570.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Effect.Console (log)
+
+test :: forall a. a -> a
+test = \(x :: a) -> x
+
+main = log "Done"
diff --git a/tests/purs/passing/1664.purs b/tests/purs/passing/1664.purs
new file mode 100644
index 0000000..c488037
--- /dev/null
+++ b/tests/purs/passing/1664.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+data Identity a = Identity a
+
+newtype IdentityEff a = IdentityEff (Effect (Identity a))
+
+test :: forall a. IdentityEff a -> IdentityEff Unit
+test (IdentityEff action) = IdentityEff $ do
+ (Identity x :: Identity _) <- action
+ pure $ Identity unit
+
+main = log "Done"
diff --git a/tests/purs/passing/1697.purs b/tests/purs/passing/1697.purs
new file mode 100644
index 0000000..fee4d77
--- /dev/null
+++ b/tests/purs/passing/1697.purs
@@ -0,0 +1,25 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+_2 :: forall a. a -> a
+_2 a = a
+
+x :: forall m. Monad m => m Unit
+x = do
+ _ <- pure unit
+ pure unit
+
+y :: forall m. Monad m => m Unit
+y = do
+ _ <- pure unit
+ pure unit
+
+wtf :: forall m. Monad m => m Unit
+wtf = do
+ _ <- pure unit
+ let tmp = _2 1
+ pure unit
+
+main = log "Done"
diff --git a/tests/purs/passing/1807.purs b/tests/purs/passing/1807.purs
new file mode 100644
index 0000000..3e9e63f
--- /dev/null
+++ b/tests/purs/passing/1807.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+fn = _.b.c.d
+a = {b:{c:{d:2}}}
+
+d :: Int
+d = fn a + a.b.c.d
+
+main = if fn a + a.b.c.d == 4
+ then log "Done"
+ else log "Fail"
diff --git a/tests/purs/passing/1881.purs b/tests/purs/passing/1881.purs
new file mode 100644
index 0000000..595400f
--- /dev/null
+++ b/tests/purs/passing/1881.purs
@@ -0,0 +1,19 @@
+module Main where
+
+import Effect.Console (log)
+
+foo =
+ 1
+
+bar
+ = 2
+
+baz
+ =
+ 3
+
+qux
+ =
+ 3
+
+main = log "Done"
diff --git a/tests/purs/passing/1991.purs b/tests/purs/passing/1991.purs
new file mode 100644
index 0000000..b98d2ea
--- /dev/null
+++ b/tests/purs/passing/1991.purs
@@ -0,0 +1,22 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+singleton :: forall a. a -> Array a
+singleton x = [x]
+
+empty :: forall a. Array a
+empty = []
+
+foldMap :: forall a m. Semigroup m => (a -> m) -> Array a -> m
+foldMap f [a, b, c, d, e] = f a <> f b <> f c <> f d <> f e
+foldMap f xs = foldMap f xs -- spin, not used
+
+regression :: Array Int
+regression =
+ let as = [1,2,3,4,5]
+ as' = foldMap (\x -> if 1 < x && x < 4 then singleton x else empty) as
+ in as'
+
+main = log "Done"
diff --git a/tests/purs/passing/2018.purs b/tests/purs/passing/2018.purs
new file mode 100644
index 0000000..8ace881
--- /dev/null
+++ b/tests/purs/passing/2018.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import A (foo)
+import B (Foo(..))
+import Effect (Effect)
+import Effect.Console (log)
+
+main :: Effect Unit
+main = do
+ let tmp = foo X
+ log "Done"
diff --git a/tests/purs/passing/2018/A.purs b/tests/purs/passing/2018/A.purs
new file mode 100644
index 0000000..bff4cd0
--- /dev/null
+++ b/tests/purs/passing/2018/A.purs
@@ -0,0 +1,7 @@
+module A where
+
+import B as Main
+
+-- Prior to the 2018 fix this would be detected as a cycle between A and Main.
+foo ∷ Main.Foo → Main.Foo
+foo x = x
diff --git a/tests/purs/passing/2018/B.purs b/tests/purs/passing/2018/B.purs
new file mode 100644
index 0000000..c87647d
--- /dev/null
+++ b/tests/purs/passing/2018/B.purs
@@ -0,0 +1,3 @@
+module B where
+
+data Foo = X | Y
diff --git a/tests/purs/passing/2049.purs b/tests/purs/passing/2049.purs
new file mode 100644
index 0000000..d9307b3
--- /dev/null
+++ b/tests/purs/passing/2049.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data List a = Cons a (List a) | Nil
+
+infixr 6 Cons as :
+
+f :: List { x :: Int, y :: Int } -> Int
+f ( r@{ x } : _) = x + r.y
+f _ = 0
+
+main = log "Done"
diff --git a/tests/purs/passing/2136.purs b/tests/purs/passing/2136.purs
new file mode 100644
index 0000000..9082a90
--- /dev/null
+++ b/tests/purs/passing/2136.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+main =
+ if (negate (bottom :: Int) > top)
+ then log "Fail"
+ else log "Done"
diff --git a/tests/purs/passing/2138.purs b/tests/purs/passing/2138.purs
new file mode 100644
index 0000000..b0cae5e
--- /dev/null
+++ b/tests/purs/passing/2138.purs
@@ -0,0 +1,7 @@
+module Main where
+
+import Effect.Console (log)
+
+import Lib (A(B,C))
+
+main = log "Done"
diff --git a/tests/purs/passing/2138/Lib.purs b/tests/purs/passing/2138/Lib.purs
new file mode 100644
index 0000000..3c433e0
--- /dev/null
+++ b/tests/purs/passing/2138/Lib.purs
@@ -0,0 +1,3 @@
+module Lib (A(..), A) where
+
+data A = B | C
diff --git a/tests/purs/passing/2172.js b/tests/purs/passing/2172.js
new file mode 100644
index 0000000..34d232e
--- /dev/null
+++ b/tests/purs/passing/2172.js
@@ -0,0 +1,5 @@
+exports['a\''] = 0;
+exports["\x62\x27"] = 1;
+// NOTE: I wanted to use "\c'" here, but langauge-javascript doesn't support it...
+exports["c'"] = 2;
+exports["\u0064\u0027"] = 3;
diff --git a/tests/purs/passing/2172.purs b/tests/purs/passing/2172.purs
new file mode 100644
index 0000000..34580cc
--- /dev/null
+++ b/tests/purs/passing/2172.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Effect.Console (log)
+
+foreign import a' :: Number
+foreign import b' :: Number
+foreign import c' :: Number
+foreign import d' :: Number
+
+main = log "Done"
diff --git a/tests/purs/passing/2197-1.purs b/tests/purs/passing/2197-1.purs
new file mode 100644
index 0000000..6b05c68
--- /dev/null
+++ b/tests/purs/passing/2197-1.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Effect.Console
+import Prim as P
+
+type Number = P.Number
+type Test = {}
+
+z :: Number
+z = 0.0
+
+main = log "Done"
diff --git a/tests/purs/passing/2197-2.purs b/tests/purs/passing/2197-2.purs
new file mode 100644
index 0000000..b9122c5
--- /dev/null
+++ b/tests/purs/passing/2197-2.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Effect.Console
+import Prim (Int)
+
+type Number = Int
+
+z :: Number
+z = 0
+
+main = log "Done"
diff --git a/tests/purs/passing/2252.purs b/tests/purs/passing/2252.purs
new file mode 100644
index 0000000..598b379
--- /dev/null
+++ b/tests/purs/passing/2252.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Effect.Console (log)
+
+data T a = T
+
+ti :: T Int
+ti = T
+
+t :: forall a. T a
+t = T
+
+xs = [ti, t, t]
+
+main = log "Done"
diff --git a/tests/purs/passing/2288.purs b/tests/purs/passing/2288.purs
new file mode 100644
index 0000000..cab96bd
--- /dev/null
+++ b/tests/purs/passing/2288.purs
@@ -0,0 +1,19 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Data.Array
+import Data.Array.Partial as P
+import Partial.Unsafe
+
+length :: forall a. Array a -> Int
+length = go 0 where
+ go acc arr =
+ if null arr
+ then acc
+ else go (acc + 1) (unsafePartial P.tail arr)
+
+main = do
+ logShow (length (1 .. 10000))
+ log "Done"
diff --git a/tests/purs/passing/2378.purs b/tests/purs/passing/2378.purs
new file mode 100644
index 0000000..fb42bae
--- /dev/null
+++ b/tests/purs/passing/2378.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Effect.Console (log)
+
+class Foo (a :: Symbol)
+
+instance fooX :: Foo "x"
+
+main = log "Done"
diff --git a/tests/purs/passing/2438.purs b/tests/purs/passing/2438.purs
new file mode 100644
index 0000000..223f2ff
--- /dev/null
+++ b/tests/purs/passing/2438.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Effect.Console (log)
+
+done :: String
+done = {"𝌆": "Done"}."𝌆"
+
+main = log done
diff --git a/tests/purs/passing/2609.purs b/tests/purs/passing/2609.purs
new file mode 100644
index 0000000..132e044
--- /dev/null
+++ b/tests/purs/passing/2609.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Eg (Foo'(Bar'), (:->))
+import Effect (Effect)
+import Effect.Console (log)
+
+bar' :: Foo'
+bar' = 4 :-> 5
+
+main :: Effect Unit
+main = case bar' of Bar' l r -> log "Done"
diff --git a/tests/purs/passing/2609/Eg.purs b/tests/purs/passing/2609/Eg.purs
new file mode 100644
index 0000000..ceb6c36
--- /dev/null
+++ b/tests/purs/passing/2609/Eg.purs
@@ -0,0 +1,6 @@
+module Eg (Foo'(Bar'), (:->)) where
+
+data Foo' = Bar' Int Int
+
+infix 4 Bar' as :->
+
diff --git a/tests/purs/passing/2616.purs b/tests/purs/passing/2616.purs
new file mode 100644
index 0000000..92b6666
--- /dev/null
+++ b/tests/purs/passing/2616.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+newtype F r a = F { x :: a | r }
+
+unF :: forall r a. F r a -> { x :: a | r }
+unF (F x) = x
+
+derive instance functorF :: Functor (F r)
+
+main = log (unF (map identity (F { x: "Done", y: 42 }))).x
diff --git a/tests/purs/passing/2626.purs b/tests/purs/passing/2626.purs
new file mode 100644
index 0000000..5fd0360
--- /dev/null
+++ b/tests/purs/passing/2626.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Effect.Console (log)
+
+f = \(x :: forall a. a -> a) -> x x
+
+test1 = (f \x -> x) 1
+
+g = \(x :: (forall a. a -> a) -> Int) -> x (\y -> y)
+
+test2 = g \f -> if f true then f 0 else f 1
+
+main = log "Done"
diff --git a/tests/purs/passing/2663.purs b/tests/purs/passing/2663.purs
new file mode 100644
index 0000000..fd6ca35
--- /dev/null
+++ b/tests/purs/passing/2663.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Prim.TypeError (class Warn, Text)
+import Effect.Console (log)
+
+foo :: forall t. Warn (Text "Example") => t -> t
+foo x = x
+
+main = when (foo 42 == 42) $ log "Done"
diff --git a/tests/purs/passing/2689.purs b/tests/purs/passing/2689.purs
new file mode 100644
index 0000000..08e6851
--- /dev/null
+++ b/tests/purs/passing/2689.purs
@@ -0,0 +1,36 @@
+module Main where
+
+import Prelude
+import Effect.Console
+import Data.Array.Partial
+import Partial.Unsafe
+
+sumTCObug = go identity where
+ go f 0 = f
+ go f n =
+ let
+ f' a = n + a
+ in
+ go f' 0
+
+sumTCObug' = go identity where
+ go f 0 = f
+ go f n = go (\a -> n + a) 0
+
+count :: forall a. (a -> Boolean) -> Array a -> Int
+count p = count' 0 where
+ count' acc [] = acc
+ count' acc xs =
+ let h = unsafePartial head xs
+ in count' (acc + if p h then 1 else 0) (unsafePartial tail xs)
+
+main = do
+ let x = sumTCObug 7 3
+ y = sumTCObug' 7 3
+ z = count (_ > 0) [-1, 0, 1]
+ logShow x
+ logShow y
+ logShow z
+ if x == 10 && y == 10 && z == 1
+ then log "Done"
+ else log "Fail"
diff --git a/tests/purs/passing/2756.purs b/tests/purs/passing/2756.purs
new file mode 100644
index 0000000..46a930f
--- /dev/null
+++ b/tests/purs/passing/2756.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Effect (Effect)
+import Effect.Console (log)
+import Prelude
+
+pu :: forall i. i -> Effect Unit
+pu _ = pure unit
+
+type C i = { pu :: i -> Effect Unit }
+
+sampleC :: C Unit
+sampleC = { pu: pu }
+
+newtype Identity a = Id a
+
+sampleIdC :: Identity (C Unit)
+sampleIdC = Id { pu : pu }
+
+main = log "Done"
diff --git a/tests/purs/passing/2787.purs b/tests/purs/passing/2787.purs
new file mode 100644
index 0000000..608cfc7
--- /dev/null
+++ b/tests/purs/passing/2787.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+main
+ | between 0 1 2 = log "Fail"
+ | otherwise = log "Done"
diff --git a/tests/purs/passing/2795.purs b/tests/purs/passing/2795.purs
new file mode 100644
index 0000000..110dc02
--- /dev/null
+++ b/tests/purs/passing/2795.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data X = X Int | Y
+
+x :: X -> Int
+x = case _ of
+ Y -> 0
+ X n | 1 <- n -> 1
+ | otherwise -> 2
+
+main = log "Done"
diff --git a/tests/purs/passing/2803.purs b/tests/purs/passing/2803.purs
new file mode 100644
index 0000000..42cbcd7
--- /dev/null
+++ b/tests/purs/passing/2803.purs
@@ -0,0 +1,17 @@
+module Main where
+
+import Prelude ((+), (-), (==))
+import Effect.Console (log)
+
+f :: Int -> Int -> Int
+f = (+)
+
+infixl 6 f as %
+
+g :: Int -> Int -> Int
+g a b = let f = (-) in a % b
+
+main =
+ if g 10 5 == 15
+ then log "Done"
+ else log "Failed"
diff --git a/tests/purs/passing/2806.purs b/tests/purs/passing/2806.purs
new file mode 100644
index 0000000..658a913
--- /dev/null
+++ b/tests/purs/passing/2806.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Stream a = Cons a (Stream a)
+
+step :: forall a. Stream a -> Stream a
+step (Cons _ xs) = xs
+
+head :: forall a. Stream a -> a
+head xs | Cons x _ <- step xs = x
+
+main = log "Done"
diff --git a/tests/purs/passing/2947.purs b/tests/purs/passing/2947.purs
new file mode 100644
index 0000000..0b0b3f2
--- /dev/null
+++ b/tests/purs/passing/2947.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Foo = Foo
+
+instance eqFoo :: Eq Foo where
+ eq _ _ = true
+
+main = log "Done"
diff --git a/tests/purs/passing/2958.purs b/tests/purs/passing/2958.purs
new file mode 100644
index 0000000..b6b0619
--- /dev/null
+++ b/tests/purs/passing/2958.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Effect.Console
+
+data Nil
+data Snoc xs x
+
+infixl 1 type Snoc as :>
+
+type One = Nil :> Int
+type Two = Nil :> Int :> Int
+type Three = Nil :> Int :> Int :> Int
+
+main = log "Done"
diff --git a/tests/purs/passing/2972.purs b/tests/purs/passing/2972.purs
new file mode 100644
index 0000000..d0e97b3
--- /dev/null
+++ b/tests/purs/passing/2972.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Effect.Console (log)
+import Prelude (class Show, show)
+
+type I t = t
+
+newtype Id t = Id t
+
+instance foo :: Show (I t) => Show (Id t) where
+ show (Id t) = "Done"
+
+main = log (show (Id "other"))
diff --git a/tests/purs/passing/3114.purs b/tests/purs/passing/3114.purs
new file mode 100644
index 0000000..5d9d2af
--- /dev/null
+++ b/tests/purs/passing/3114.purs
@@ -0,0 +1,53 @@
+module Main where
+
+import Prelude
+
+import Data.Either
+import Data.Maybe
+import Data.Tuple
+import Effect
+import Effect.Console (log)
+import VendoredVariant
+import Data.Symbol
+
+type TestVariants =
+ ( foo :: FProxy Maybe
+ , bar :: FProxy (Tuple String)
+ )
+
+_foo :: SProxy "foo"
+_foo = SProxy
+
+_bar :: SProxy "bar"
+_bar = SProxy
+
+main :: Effect Unit
+main = do
+ let
+ -- with the type signatures on `a`, this compiles fine.
+ case1 :: VariantF TestVariants Int → String
+ case1 = case_
+ # on _foo (\a → "foo: " <> show (a :: Maybe Int))
+ # on _bar (\a → "bar: " <> show (a :: Tuple String Int))
+
+ -- without the type signature, this would complain about
+ -- Could not match type
+ -- Array
+ -- with type
+ -- Tuple String
+ -- while trying to match the type FProxy Array
+ -- with type FProxy (Tuple String)
+ -- while solving type class constraint
+ -- Prim.RowCons "baz"
+ -- (FProxy t0)
+ -- t1
+ -- ( foo :: FProxy Maybe
+ -- , bar :: FProxy (Tuple String)
+ -- )
+ -- while inferring the type of `on _baz`
+ case2 :: VariantF TestVariants Int → String
+ case2 = case_
+ # on _foo (\a → "foo: " <> show a)
+ # on _bar (\a → "bar: " <> show a)
+
+ log "Done"
diff --git a/tests/purs/passing/3114/VendoredVariant.purs b/tests/purs/passing/3114/VendoredVariant.purs
new file mode 100644
index 0000000..2442e99
--- /dev/null
+++ b/tests/purs/passing/3114/VendoredVariant.purs
@@ -0,0 +1,42 @@
+module VendoredVariant where
+
+import Prelude
+
+import Prim.Row as Row
+
+import Unsafe.Coerce (unsafeCoerce)
+import Partial.Unsafe (unsafeCrashWith)
+import Data.Symbol
+
+data FProxy (k :: Type -> Type) = FProxy
+data VariantF (f :: # Type) a
+
+newtype VariantFRep f a = VariantFRep
+ { type :: String
+ , value :: f a
+ , map :: forall x y. (x -> y) -> f x -> f y
+ }
+
+case_ :: forall a b. VariantF () a -> b
+case_ r = unsafeCrashWith case unsafeCoerce r of
+ VariantFRep v -> "failure on " <> v.type
+
+on
+ :: forall sym f a b r1 r2
+ . Row.Cons sym (FProxy f) r1 r2
+ => IsSymbol sym
+ => SProxy sym
+ -> (f a -> b)
+ -> (VariantF r1 a -> b)
+ -> VariantF r2 a
+ -> b
+on p f g r =
+ case coerceY r of
+ VariantFRep v | v.type == reflectSymbol p -> f v.value
+ _ -> g (coerceR r)
+ where
+ coerceY :: VariantF r2 a -> VariantFRep f a
+ coerceY = unsafeCoerce
+
+ coerceR :: VariantF r2 a -> VariantF r1 a
+ coerceR = unsafeCoerce
diff --git a/tests/purs/passing/3125.purs b/tests/purs/passing/3125.purs
new file mode 100644
index 0000000..152e86d
--- /dev/null
+++ b/tests/purs/passing/3125.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Data.Monoid (class Monoid, mempty)
+import Effect.Console (log, logShow)
+
+data B a = B a a
+
+memptyB :: forall a b. Monoid b => B (a -> b)
+memptyB = B l r where
+ l _ = mempty
+ r _ = mempty
+
+main = do
+ logShow $ case (memptyB :: B (Int -> Array Unit)) of B l r -> l 0 == r 0
+ log "Done"
diff --git a/tests/purs/passing/3187-UnusedNameClash.purs b/tests/purs/passing/3187-UnusedNameClash.purs
new file mode 100644
index 0000000..434a3c9
--- /dev/null
+++ b/tests/purs/passing/3187-UnusedNameClash.purs
@@ -0,0 +1,12 @@
+module Main (main) where
+
+import Prelude ((+))
+import Effect.Console (log)
+
+-- the __unused parameter used to get optimized away
+abuseUnused :: forall a. a -> a
+abuseUnused __unused = __unused
+
+main = do
+ let explode = abuseUnused 0 + abuseUnused 0
+ log "Done"
diff --git a/tests/purs/passing/652.purs b/tests/purs/passing/652.purs
new file mode 100644
index 0000000..c001d02
--- /dev/null
+++ b/tests/purs/passing/652.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Foo a b
+
+class Bar a c
+
+class (Foo a b, Bar a c) <= Baz a b c
+
+instance foo :: Foo (a -> b) a
+
+instance bar :: Bar (a -> b) b
+
+instance baz :: (Eq a) => Baz (a -> b) a b
+
+main = log "Done"
diff --git a/tests/purs/passing/810.purs b/tests/purs/passing/810.purs
new file mode 100644
index 0000000..332723c
--- /dev/null
+++ b/tests/purs/passing/810.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Maybe a = Nothing | Just a
+
+test :: forall a. Maybe a -> Maybe a
+test m = o.x
+ where
+ o = case m of Nothing -> { x : Nothing }
+ Just a -> { x : Just a }
+
+main = log "Done"
diff --git a/tests/purs/passing/862.purs b/tests/purs/passing/862.purs
new file mode 100644
index 0000000..53570ee
--- /dev/null
+++ b/tests/purs/passing/862.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+id' = (\x -> x) <$> \y -> y
+
+main = log (id' "Done")
diff --git a/tests/purs/passing/922.purs b/tests/purs/passing/922.purs
new file mode 100644
index 0000000..3e944b3
--- /dev/null
+++ b/tests/purs/passing/922.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+
+import Effect.Console
+
+class Default a where
+ def :: a
+
+instance defaultString :: Default String where
+ def = "Done"
+
+data I a = I a
+
+instance defaultI :: (Default a) => Default (I a) where
+ def = I def
+
+main = do
+ case def of
+ I s -> log s
diff --git a/tests/purs/passing/Ado.purs b/tests/purs/passing/Ado.purs
new file mode 100644
index 0000000..4bb1c5d
--- /dev/null
+++ b/tests/purs/passing/Ado.purs
@@ -0,0 +1,77 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+import Effect.Ref as Ref
+
+data Maybe a = Nothing | Just a
+
+instance functorMaybe :: Functor Maybe where
+ map f Nothing = Nothing
+ map f (Just x) = Just (f x)
+
+instance applyMaybe :: Apply Maybe where
+ apply (Just f) (Just x) = Just (f x)
+ apply _ _ = Nothing
+
+instance applicativeMaybe :: Applicative Maybe where
+ pure = Just
+
+test1 = \_ -> ado
+ in "abc"
+
+test2 = \_ -> ado
+ x <- Just 1.0
+ y <- Just 2.0
+ in x + y
+
+test3 = \_ -> ado
+ _ <- Just 1.0
+ _ <- Nothing :: Maybe Number
+ in 2.0
+
+test4 mx my = ado
+ x <- mx
+ y <- my
+ in x + y + 1.0
+
+test5 mx my mz = ado
+ x <- mx
+ y <- my
+ let sum = x + y
+ z <- mz
+ in z + sum + 1.0
+
+test6 mx = \_ -> ado
+ let
+ f :: forall a. Maybe a -> a
+ f (Just x) = x
+ in f mx
+
+test8 = \_ -> ado
+ in (ado
+ in 1.0)
+
+test9 = \_ -> (+) <$> Just 1.0 <*> Just 2.0
+
+test10 _ = ado
+ let
+ f x = g x * 3.0
+ g x = f x / 2.0
+ in f 10.0
+
+test11 = \_ -> ado
+ x <- pure 1
+ y <- pure "A"
+ z <- pure []
+ in show (x :: Int) <> y <> show (z :: Array Int)
+
+main = do
+ r <- Ref.new "X"
+ log =<< ado
+ _ <- Ref.write "D" r
+ a <- Ref.read r
+ b <- pure "o"
+ let c = "n"
+ d <- pure "e"
+ in a <> b <> c <> d
diff --git a/tests/purs/passing/AppendInReverse.purs b/tests/purs/passing/AppendInReverse.purs
new file mode 100644
index 0000000..b900657
--- /dev/null
+++ b/tests/purs/passing/AppendInReverse.purs
@@ -0,0 +1,38 @@
+module Main where
+
+import Prelude
+import Data.Symbol (SProxy(..))
+import Prim.Symbol (class Append)
+import Effect.Console (log)
+
+class Balanced (sym :: Symbol)
+
+instance balanced1 :: Balanced ""
+else
+instance balanced2
+ :: ( Append "(" sym1 sym
+ , Append sym2 ")" sym1
+ , Balanced sym2
+ ) => Balanced sym
+
+balanced :: forall sym. Balanced sym => SProxy sym -> String
+balanced _ = "ok"
+
+b0 :: String
+b0 = balanced (SProxy :: SProxy "")
+
+b1 :: String
+b1 = balanced (SProxy :: SProxy "()")
+
+b2 :: String
+b2 = balanced (SProxy :: SProxy "(())")
+
+b3 :: String
+b3 = balanced (SProxy :: SProxy "((()))")
+
+main = do
+ log b0
+ log b1
+ log b2
+ log b3
+ log "Done"
diff --git a/tests/purs/passing/Applicative.purs b/tests/purs/passing/Applicative.purs
new file mode 100644
index 0000000..f8ea7c5
--- /dev/null
+++ b/tests/purs/passing/Applicative.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Effect.Console (log)
+
+class Applicative f where
+ pure :: forall a. a -> f a
+ apply :: forall a b. f (a -> b) -> f a -> f b
+
+data Maybe a = Nothing | Just a
+
+instance applicativeMaybe :: Applicative Maybe where
+ pure = Just
+ apply (Just f) (Just a) = Just (f a)
+ apply _ _ = Nothing
+
+main = log "Done"
diff --git a/tests/purs/passing/ArrayType.purs b/tests/purs/passing/ArrayType.purs
new file mode 100644
index 0000000..b801b93
--- /dev/null
+++ b/tests/purs/passing/ArrayType.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Pointed p where
+ point :: forall a. a -> p a
+
+instance pointedArray :: Pointed Array where
+ point a = [a]
+
+main = log "Done"
diff --git a/tests/purs/passing/Auto.purs b/tests/purs/passing/Auto.purs
new file mode 100644
index 0000000..5a831d9
--- /dev/null
+++ b/tests/purs/passing/Auto.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Auto s i o = Auto { state :: s, step :: s -> i -> o }
+
+type SomeAuto i o = forall r. (forall s. Auto s i o -> r) -> r
+
+exists :: forall s i o. s -> (s -> i -> o) -> SomeAuto i o
+exists = \state step f -> f (Auto { state: state, step: step })
+
+run :: forall i o. SomeAuto i o -> i -> o
+run = \s i -> s (\a -> case a of Auto a -> a.step a.state i)
+
+main = log "Done"
diff --git a/tests/purs/passing/AutoPrelude.purs b/tests/purs/passing/AutoPrelude.purs
new file mode 100644
index 0000000..9dcc474
--- /dev/null
+++ b/tests/purs/passing/AutoPrelude.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+f x = x * 10.0
+g y = y - 10.0
+
+main = do
+ log $ show $ (f <<< g) 100.0
+ log "Done"
diff --git a/tests/purs/passing/AutoPrelude2.purs b/tests/purs/passing/AutoPrelude2.purs
new file mode 100644
index 0000000..03d18fd
--- /dev/null
+++ b/tests/purs/passing/AutoPrelude2.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Prelude as P
+import Effect.Console
+
+f :: forall a. a -> a
+f = P.identity
+
+main = P.($) log ((f P.<<< f) "Done")
diff --git a/tests/purs/passing/BindersInFunctions.purs b/tests/purs/passing/BindersInFunctions.purs
new file mode 100644
index 0000000..d1fda59
--- /dev/null
+++ b/tests/purs/passing/BindersInFunctions.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Partial.Unsafe (unsafePartial)
+import Test.Assert (assert')
+import Effect (Effect)
+import Effect.Console (log)
+
+snd :: forall a. Partial => Array a -> a
+snd = \[_, y] -> y
+
+main :: Effect _
+main = do
+ let ts = unsafePartial (snd [1.0, 2.0])
+ assert' "Incorrect result from 'snd'." (ts == 2.0)
+ log "Done"
diff --git a/tests/purs/passing/BindingGroups.purs b/tests/purs/passing/BindingGroups.purs
new file mode 100644
index 0000000..43d0df6
--- /dev/null
+++ b/tests/purs/passing/BindingGroups.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+foo = bar
+ where bar r = r + 1.0
+
+r = foo 2.0
+
+main = log "Done"
diff --git a/tests/purs/passing/BlockString.purs b/tests/purs/passing/BlockString.purs
new file mode 100644
index 0000000..eeb0a7d
--- /dev/null
+++ b/tests/purs/passing/BlockString.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+foo :: String
+foo = """foo"""
+
+main = log "Done"
diff --git a/tests/purs/passing/CaseInDo.purs b/tests/purs/passing/CaseInDo.purs
new file mode 100644
index 0000000..a4fbd83
--- /dev/null
+++ b/tests/purs/passing/CaseInDo.purs
@@ -0,0 +1,21 @@
+module Main where
+
+import Prelude
+import Partial.Unsafe (unsafeCrashWith)
+import Effect.Console
+import Effect
+
+doIt :: Effect Boolean
+doIt = pure true
+
+set = do
+ log "Testing..."
+ case 0 of
+ 0 -> doIt
+ _ -> pure false
+
+main = do
+ b <- set
+ case b of
+ true -> log "Done"
+ false -> unsafeCrashWith "Failed"
diff --git a/tests/purs/passing/CaseInputWildcard.purs b/tests/purs/passing/CaseInputWildcard.purs
new file mode 100644
index 0000000..d18098f
--- /dev/null
+++ b/tests/purs/passing/CaseInputWildcard.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect (Effect)
+import Effect.Console (log)
+
+data Foo = X | Y
+
+what ∷ Foo → Int → Boolean → Foo
+what x = case _, x, _ of
+ 0, X, true → X
+ 0, Y, true → X
+ _, _, _ → Y
+
+main :: Effect Unit
+main = do
+ let tmp = what Y 0 true
+ log "Done"
diff --git a/tests/purs/passing/CaseMultipleExpressions.purs b/tests/purs/passing/CaseMultipleExpressions.purs
new file mode 100644
index 0000000..535faf1
--- /dev/null
+++ b/tests/purs/passing/CaseMultipleExpressions.purs
@@ -0,0 +1,21 @@
+module Main where
+
+import Prelude
+import Partial.Unsafe (unsafeCrashWith)
+import Effect.Console
+import Effect
+
+doIt :: Effect Boolean
+doIt = pure true
+
+set = do
+ log "Testing..."
+ case 42, 10 of
+ 42, 10 -> doIt
+ _ , _ -> pure false
+
+main = do
+ b <- set
+ case b of
+ true -> log "Done"
+ false -> unsafeCrashWith "Failed"
diff --git a/tests/purs/passing/CaseStatement.purs b/tests/purs/passing/CaseStatement.purs
new file mode 100644
index 0000000..5eb635b
--- /dev/null
+++ b/tests/purs/passing/CaseStatement.purs
@@ -0,0 +1,22 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data A = A | B | C
+
+f a _ A = a
+f _ a B = a
+f _ _ C = "Done"
+
+g a _ A = a
+g _ b B = b
+g _ _ C = C
+
+data M a = N | J a
+
+h f N a = a
+h f a N = a
+h f (J a) (J b) = J (f a b)
+
+main = log $ f "Done" "Failed" A
diff --git a/tests/purs/passing/CheckFunction.purs b/tests/purs/passing/CheckFunction.purs
new file mode 100644
index 0000000..82e4152
--- /dev/null
+++ b/tests/purs/passing/CheckFunction.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test = ((\x -> x+1.0) >>> (\x -> x*2.0)) 4.0
+
+main = log "Done"
diff --git a/tests/purs/passing/CheckSynonymBug.purs b/tests/purs/passing/CheckSynonymBug.purs
new file mode 100644
index 0000000..0a664d0
--- /dev/null
+++ b/tests/purs/passing/CheckSynonymBug.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+length :: forall a. Array a -> Int
+length _ = 0
+
+type Foo a = Array a
+
+foo _ = length ([] :: Foo Number)
+
+main = log "Done"
diff --git a/tests/purs/passing/CheckTypeClass.purs b/tests/purs/passing/CheckTypeClass.purs
new file mode 100644
index 0000000..cf1e009
--- /dev/null
+++ b/tests/purs/passing/CheckTypeClass.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Bar a = Bar
+data Baz
+
+class Foo a where
+ foo :: Bar a -> Baz
+
+foo_ :: forall a. Foo a => a -> Baz
+foo_ x = foo ((mkBar :: forall a. Foo a => a -> Bar a) x)
+
+mkBar :: forall a. a -> Bar a
+mkBar _ = Bar
+
+main = log "Done"
diff --git a/tests/purs/passing/Church.purs b/tests/purs/passing/Church.purs
new file mode 100644
index 0000000..ab01d25
--- /dev/null
+++ b/tests/purs/passing/Church.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Effect.Console (log)
+
+type List a = forall r. r -> (a -> r -> r) -> r
+
+empty :: forall a. List a
+empty = \r f -> r
+
+cons :: forall a. a -> List a -> List a
+cons = \a l r f -> f a (l r f)
+
+append :: forall a. List a -> List a -> List a
+append = \l1 l2 r f -> l2 (l1 r f) f
+
+test = append (cons 1 empty) (cons 2 empty)
+
+main = log "Done"
diff --git a/tests/purs/passing/ClassRefSyntax.purs b/tests/purs/passing/ClassRefSyntax.purs
new file mode 100644
index 0000000..9297db5
--- /dev/null
+++ b/tests/purs/passing/ClassRefSyntax.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Lib (class X, go)
+import Effect.Console (log)
+
+go' :: forall a. X a => a -> a
+go' = go
+
+main = log "Done"
diff --git a/tests/purs/passing/ClassRefSyntax/Lib.purs b/tests/purs/passing/ClassRefSyntax/Lib.purs
new file mode 100644
index 0000000..345491f
--- /dev/null
+++ b/tests/purs/passing/ClassRefSyntax/Lib.purs
@@ -0,0 +1,4 @@
+module Lib (class X, go) where
+
+class X a where
+ go :: a -> a
diff --git a/tests/purs/passing/Collatz.purs b/tests/purs/passing/Collatz.purs
new file mode 100644
index 0000000..df267fc
--- /dev/null
+++ b/tests/purs/passing/Collatz.purs
@@ -0,0 +1,21 @@
+module Main where
+
+import Prelude
+import Effect
+import Control.Monad.ST as ST
+import Control.Monad.ST.Ref as STRef
+import Effect.Console (log, logShow)
+
+collatz :: Int -> Int
+collatz n = ST.run (do
+ r <- STRef.new n
+ count <- STRef.new 0
+ ST.while (map (_ /= 1) (STRef.read r)) do
+ _ <- STRef.modify (_ + 1) count
+ m <- STRef.read r
+ void $ STRef.write (if m `mod` 2 == 0 then m / 2 else 3 * m + 1) r
+ STRef.read count)
+
+main = do
+ logShow $ collatz 1000
+ log "Done"
diff --git a/tests/purs/passing/Comparisons.purs b/tests/purs/passing/Comparisons.purs
new file mode 100644
index 0000000..b2e710f
--- /dev/null
+++ b/tests/purs/passing/Comparisons.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Test.Assert
+
+main = do
+ assert (1.0 < 2.0)
+ assert (2.0 == 2.0)
+ assert (3.0 > 1.0)
+ assert ("a" < "b")
+ assert ("a" == "a")
+ assert ("z" > "a")
+ log "Done"
diff --git a/tests/purs/passing/Conditional.purs b/tests/purs/passing/Conditional.purs
new file mode 100644
index 0000000..7e36c01
--- /dev/null
+++ b/tests/purs/passing/Conditional.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Effect.Console (log)
+
+fns = \f -> if f true then f else \x -> x
+
+not = \x -> if x then false else true
+
+main = log "Done"
diff --git a/tests/purs/passing/Console.purs b/tests/purs/passing/Console.purs
new file mode 100644
index 0000000..6516727
--- /dev/null
+++ b/tests/purs/passing/Console.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+replicateM_ :: forall m a. Monad m => Number -> m a -> m Unit
+replicateM_ 0.0 _ = pure unit
+replicateM_ n act = do
+ _ <- act
+ replicateM_ (n - 1.0) act
+
+main = do
+ replicateM_ 10.0 (log "Hello World!")
+ log "Done"
diff --git a/tests/purs/passing/ConstraintInference.purs b/tests/purs/passing/ConstraintInference.purs
new file mode 100644
index 0000000..1e11d31
--- /dev/null
+++ b/tests/purs/passing/ConstraintInference.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+shout = log <<< (_ <> "!") <<< show
+
+main = do
+ shout "Test"
+ log "Done"
diff --git a/tests/purs/passing/ConstraintParens.purs b/tests/purs/passing/ConstraintParens.purs
new file mode 100644
index 0000000..3600718
--- /dev/null
+++ b/tests/purs/passing/ConstraintParens.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Foo a where
+ foo ∷ a → a
+
+test ∷ ∀ a. (Foo a) ⇒ a → a
+test = foo
+
+main = log "Done"
diff --git a/tests/purs/passing/ConstraintParsingIssue.purs b/tests/purs/passing/ConstraintParsingIssue.purs
new file mode 100644
index 0000000..04ad2cd
--- /dev/null
+++ b/tests/purs/passing/ConstraintParsingIssue.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Effect.Console
+
+class X a
+
+instance x :: X (Array (Array a)) => X (Array a)
+
+main = log "Done"
diff --git a/tests/purs/passing/ContextSimplification.purs b/tests/purs/passing/ContextSimplification.purs
new file mode 100644
index 0000000..e6d3cd6
--- /dev/null
+++ b/tests/purs/passing/ContextSimplification.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+shout = log <<< (_ <> "!") <<< show
+
+-- Here, we should simplify the context so that only one Show
+-- constraint is added.
+usesShowTwice true = shout
+usesShowTwice false = logShow
+
+main = do
+ usesShowTwice true "Test"
+ log "Done"
diff --git a/tests/purs/passing/DataAndType.purs b/tests/purs/passing/DataAndType.purs
new file mode 100644
index 0000000..ce594ef
--- /dev/null
+++ b/tests/purs/passing/DataAndType.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data A = A B
+
+type B = A
+
+main = log "Done"
diff --git a/tests/purs/passing/DataConsClassConsOverlapOk.purs b/tests/purs/passing/DataConsClassConsOverlapOk.purs
new file mode 100644
index 0000000..6e32f62
--- /dev/null
+++ b/tests/purs/passing/DataConsClassConsOverlapOk.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Effect.Console (log)
+import Prim.Row (class Cons)
+
+data Cons = Cons
+
+main = log "Done"
diff --git a/tests/purs/passing/DctorName.purs b/tests/purs/passing/DctorName.purs
new file mode 100644
index 0000000..7a16b72
--- /dev/null
+++ b/tests/purs/passing/DctorName.purs
@@ -0,0 +1,33 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+newtype Bar' = Bar' Int
+
+data Foo' = Foo' Bar'
+
+data Baz'' = Baz'' | Baz'
+
+f ∷ Foo' → Boolean
+f a = case a of Foo' b → true
+
+f' ∷ Boolean
+f' = f $ Foo' $ Bar' 0
+
+g ∷ Baz'' → Int
+g Baz'' = 0
+g Baz' = 1
+
+g' ∷ Int
+g' = g Baz''
+
+h ∷ Bar' → Int
+h (Bar' x)
+ | x <= 10 = x * 2
+ | otherwise = 10
+
+h' ∷ Int
+h' = h $ Bar' 4
+
+main = log "Done"
diff --git a/tests/purs/passing/DctorOperatorAlias.purs b/tests/purs/passing/DctorOperatorAlias.purs
new file mode 100644
index 0000000..67f2dfb
--- /dev/null
+++ b/tests/purs/passing/DctorOperatorAlias.purs
@@ -0,0 +1,34 @@
+module Main where
+
+ import Prelude (Unit, bind, discard, (==))
+ import Effect (Effect)
+ import Effect.Console (log)
+ import Test.Assert (assert')
+ import List (List(..), (:))
+ import List as L
+
+ -- unqualified
+ infixl 6 Cons as !
+
+ -- qualified
+ infixl 6 L.Cons as !!
+
+ get1 ∷ ∀ a. a → List a → a
+ get1 y xs = case xs of
+ _ : x : _ → x
+ _ → y
+
+ get2 ∷ ∀ a. a → List a → a
+ get2 _ (_ : x : _) = x
+ get2 y _ = y
+
+ get3 ∷ ∀ a. a → List a → a
+ get3 _ (_ ! (x ! _)) = x
+ get3 y _ = y
+
+ main ∷ Effect Unit
+ main = do
+ assert' "Incorrect result!" (get1 0 (1 : 2 : 3 : Nil) == 2)
+ assert' "Incorrect result!" (get2 0 (1 ! (2 ! (3 ! Nil))) == 2)
+ assert' "Incorrect result!" (get3 0.0 (1.0 : 2.0 : (3.0 ! Nil)) == 2.0)
+ log "Done"
diff --git a/tests/purs/passing/DctorOperatorAlias/List.purs b/tests/purs/passing/DctorOperatorAlias/List.purs
new file mode 100644
index 0000000..a428343
--- /dev/null
+++ b/tests/purs/passing/DctorOperatorAlias/List.purs
@@ -0,0 +1,5 @@
+module List where
+
+data List a = Cons a (List a) | Nil
+
+infixr 6 Cons as :
diff --git a/tests/purs/passing/DeepArrayBinder.purs b/tests/purs/passing/DeepArrayBinder.purs
new file mode 100644
index 0000000..a5be973
--- /dev/null
+++ b/tests/purs/passing/DeepArrayBinder.purs
@@ -0,0 +1,17 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console (log)
+import Test.Assert
+
+data List a = Cons a (List a) | Nil
+
+match2 :: List Number -> Number
+match2 (Cons x (Cons y xs)) = x * y + match2 xs
+match2 _ = 0.0
+
+main = do
+ let result = match2 (Cons 1.0 (Cons 2.0 (Cons 3.0 (Cons 4.0 (Cons 5.0 (Cons 6.0 (Cons 7.0 (Cons 8.0 (Cons 9.0 Nil)))))))))
+ assert' "Incorrect result!" (result == 100.0)
+ log "Done"
diff --git a/tests/purs/passing/DeepCase.purs b/tests/purs/passing/DeepCase.purs
new file mode 100644
index 0000000..687993f
--- /dev/null
+++ b/tests/purs/passing/DeepCase.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+f x y =
+ let
+ g = case y of
+ 0.0 -> x
+ x -> 1.0 + x * x
+ in g + x + y
+
+main = do
+ logShow $ f 1.0 10.0
+ log "Done"
diff --git a/tests/purs/passing/DeriveNewtype.purs b/tests/purs/passing/DeriveNewtype.purs
new file mode 100644
index 0000000..e76df26
--- /dev/null
+++ b/tests/purs/passing/DeriveNewtype.purs
@@ -0,0 +1,29 @@
+module Main where
+
+import Effect.Console (log)
+
+import Data.Newtype
+
+type MyString = String
+
+newtype Test = Test MyString
+
+derive instance newtypeTest :: Newtype Test _
+
+t :: Test
+t = wrap "hello"
+
+a :: String
+a = unwrap t
+
+newtype First a = First a
+
+derive instance newtypeFirst :: Newtype (First b) _
+
+f :: First Int
+f = wrap 1
+
+i :: Int
+i = unwrap f
+
+main = log "Done"
diff --git a/tests/purs/passing/DeriveWithNestedSynonyms.purs b/tests/purs/passing/DeriveWithNestedSynonyms.purs
new file mode 100644
index 0000000..56a7b45
--- /dev/null
+++ b/tests/purs/passing/DeriveWithNestedSynonyms.purs
@@ -0,0 +1,29 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type L = {}
+data X = X L
+derive instance eqX :: Eq X
+
+type M = {}
+data Y = Y {foo :: M}
+derive instance eqY :: Eq Y
+
+type N = {}
+data Z = Z N
+derive instance eqZ :: Eq Z
+
+type Foo = String
+
+type Bar = { foo :: Foo }
+
+type Baz = { baz :: Bar }
+
+newtype T = T Baz
+
+derive instance eqT :: Eq T
+derive instance ordT :: Ord T
+
+main = log "Done"
diff --git a/tests/purs/passing/Deriving.purs b/tests/purs/passing/Deriving.purs
new file mode 100644
index 0000000..576603d
--- /dev/null
+++ b/tests/purs/passing/Deriving.purs
@@ -0,0 +1,36 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+import Test.Assert
+
+data V
+
+derive instance eqV :: Eq V
+
+derive instance ordV :: Ord V
+
+type MyString = String
+
+data X = X Int | Y MyString
+
+derive instance eqX :: Eq X
+
+derive instance ordX :: Ord X
+
+newtype Z = Z { left :: X, right :: X }
+
+derive instance eqZ :: Eq Z
+
+main = do
+ assert $ X 0 == X 0
+ assert $ X 0 /= X 1
+ assert $ Y "Foo" == Y "Foo"
+ assert $ Y "Foo" /= Y "Bar"
+ assert $ X 0 < X 1
+ assert $ X 0 < Y "Foo"
+ assert $ Y "Bar" < Y "Baz"
+ assert $ z == z
+ log "Done"
+ where
+ z = Z { left: X 0, right: Y "Foo" }
diff --git a/tests/purs/passing/DerivingFunctor.purs b/tests/purs/passing/DerivingFunctor.purs
new file mode 100644
index 0000000..e931483
--- /dev/null
+++ b/tests/purs/passing/DerivingFunctor.purs
@@ -0,0 +1,36 @@
+module Main where
+
+import Prelude
+import Data.Eq (class Eq1)
+import Effect.Console (log)
+import Test.Assert
+
+type MyRecord a = { myField :: a }
+
+data M f a
+ = M0 a (Array a)
+ | M1 Int
+ | M2 (f a)
+ | M3 { foo :: Int, bar :: a, baz :: f a }
+ | M4 (MyRecord a)
+
+derive instance eqM :: (Eq1 f, Eq a) => Eq (M f a)
+derive instance functorM :: Functor f => Functor (M f)
+
+data T a = T (forall t. Show t => t -> a)
+derive instance functorT :: Functor T
+
+type MA = M Array
+
+main = do
+ assert $ map show (M0 0 [1, 2] :: MA Int) == M0 "0" ["1", "2"]
+ assert $ map show (M1 0 :: MA Int) == M1 0
+ assert $ map show (M2 [0, 1] :: MA Int) == M2 ["0", "1"]
+ assert $ map show (M3 {foo: 0, bar: 1, baz: [2, 3]} :: MA Int) == M3 {foo: 0, bar: "1", baz: ["2", "3"]}
+ assert $ map show (M4 { myField: 42 }) == M4 { myField: "42" } :: MA String
+
+ case map show (T \_ -> 42) of
+ T f -> assert $ f "hello" == "42"
+ _ -> assert false
+
+ log "Done"
diff --git a/tests/purs/passing/Do.purs b/tests/purs/passing/Do.purs
new file mode 100644
index 0000000..e8552ac
--- /dev/null
+++ b/tests/purs/passing/Do.purs
@@ -0,0 +1,68 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Maybe a = Nothing | Just a
+
+instance functorMaybe :: Functor Maybe where
+ map f Nothing = Nothing
+ map f (Just x) = Just (f x)
+
+instance applyMaybe :: Apply Maybe where
+ apply (Just f) (Just x) = Just (f x)
+ apply _ _ = Nothing
+
+instance applicativeMaybe :: Applicative Maybe where
+ pure = Just
+
+instance bindMaybe :: Bind Maybe where
+ bind Nothing _ = Nothing
+ bind (Just a) f = f a
+
+instance monadMaybe :: Monad Maybe
+
+test1 = \_ -> do
+ Just "abc"
+
+test2 = \_ -> do
+ x <- Just 1.0
+ y <- Just 2.0
+ Just (x + y)
+
+test3 = \_ -> do
+ _ <- Just 1.0
+ _ <- Nothing :: Maybe Number
+ Just 2.0
+
+test4 mx my = do
+ x <- mx
+ y <- my
+ Just (x + y + 1.0)
+
+test5 mx my mz = do
+ x <- mx
+ y <- my
+ let sum = x + y
+ z <- mz
+ Just (z + sum + 1.0)
+
+test6 mx = \_ -> do
+ let
+ f :: forall a. Maybe a -> a
+ f (Just x) = x
+ Just (f mx)
+
+test8 = \_ -> do
+ Just (do
+ Just 1.0)
+
+test9 = \_ -> (+) <$> Just 1.0 <*> Just 2.0
+
+test10 _ = do
+ let
+ f x = g x * 3.0
+ g x = f x / 2.0
+ Just (f 10.0)
+
+main = log "Done"
diff --git a/tests/purs/passing/Dollar.purs b/tests/purs/passing/Dollar.purs
new file mode 100644
index 0000000..1898835
--- /dev/null
+++ b/tests/purs/passing/Dollar.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Effect.Console (log)
+
+applyFn :: forall a b. (a -> b) -> a -> b
+applyFn f x = f x
+
+infixr 1000 applyFn as $
+
+id x = x
+
+test1 x = id $ id $ id $ id $ x
+
+test2 x = id id $ id x
+
+main = log "Done"
diff --git a/tests/purs/passing/DuplicateProperties.purs b/tests/purs/passing/DuplicateProperties.purs
new file mode 100644
index 0000000..238a9f2
--- /dev/null
+++ b/tests/purs/passing/DuplicateProperties.purs
@@ -0,0 +1,27 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data RProxy (r :: # Type) = RProxy
+
+data Proxy (a :: Type) = Proxy
+
+subtractX :: forall r a. RProxy (x :: a | r) -> RProxy r
+subtractX RProxy = RProxy
+
+extractX :: forall r a. RProxy (x :: a | r) -> Proxy a
+extractX RProxy = Proxy
+
+hasX :: forall r a b. RProxy (x :: a, y :: b | r)
+hasX = RProxy
+
+test1 = subtractX (subtractX hasX)
+
+test2
+ :: forall r a b
+ . RProxy (x :: a, x :: b, x :: Int | r)
+ -> Proxy Int
+test2 x = extractX (subtractX (subtractX x))
+
+main = log "Done"
diff --git a/tests/purs/passing/EffFn.js b/tests/purs/passing/EffFn.js
new file mode 100644
index 0000000..b645b05
--- /dev/null
+++ b/tests/purs/passing/EffFn.js
@@ -0,0 +1 @@
+exports.add3 = function (a,b,c) { return a + b + c; }; \ No newline at end of file
diff --git a/tests/purs/passing/EffFn.purs b/tests/purs/passing/EffFn.purs
new file mode 100644
index 0000000..5cf26d6
--- /dev/null
+++ b/tests/purs/passing/EffFn.purs
@@ -0,0 +1,22 @@
+module Main where
+
+import Prelude
+
+import Effect.Console (log)
+import Effect.Uncurried (EffectFn3, mkEffectFn7, runEffectFn3, runEffectFn7)
+import Test.Assert (assert)
+
+testBothWays = do
+ res <- (runEffectFn7 $ mkEffectFn7 \x1 x2 x3 x4 x5 x6 x7 -> pure 42) 1 2 3 4 5 6 7
+ assert $ res == 42
+
+foreign import add3 :: EffectFn3 String String String String
+
+testRunFn = do
+ str <- runEffectFn3 add3 "a" "b" "c"
+ assert $ str == "abc"
+
+main = do
+ testBothWays
+ testRunFn
+ log "Done"
diff --git a/tests/purs/passing/EmptyDataDecls.purs b/tests/purs/passing/EmptyDataDecls.purs
new file mode 100644
index 0000000..a52c600
--- /dev/null
+++ b/tests/purs/passing/EmptyDataDecls.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Test.Assert
+import Effect.Console (log)
+
+data Z
+data S n
+
+data ArrayBox n a = ArrayBox (Array a)
+
+nil :: forall a. ArrayBox Z a
+nil = ArrayBox []
+
+cons' :: forall a n. a -> ArrayBox n a -> ArrayBox (S n) a
+cons' x (ArrayBox xs) = ArrayBox $ append [x] xs
+
+main = case cons' 1 $ cons' 2 $ cons' 3 nil of
+ ArrayBox [1, 2, 3] -> log "Done"
+ _ -> assert' "Failed" false
diff --git a/tests/purs/passing/EmptyRow.purs b/tests/purs/passing/EmptyRow.purs
new file mode 100644
index 0000000..ebbcca2
--- /dev/null
+++ b/tests/purs/passing/EmptyRow.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Foo r = Foo { | r }
+
+test :: Foo ()
+test = Foo {}
+
+main = log "Done"
diff --git a/tests/purs/passing/EmptyTypeClass.purs b/tests/purs/passing/EmptyTypeClass.purs
new file mode 100644
index 0000000..2bb5cbc
--- /dev/null
+++ b/tests/purs/passing/EmptyTypeClass.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+head :: forall a. Partial => Array a -> a
+head [x] = x
+
+main :: Effect _
+main = log "Done"
diff --git a/tests/purs/passing/EntailsKindedType.purs b/tests/purs/passing/EntailsKindedType.purs
new file mode 100644
index 0000000..00197be
--- /dev/null
+++ b/tests/purs/passing/EntailsKindedType.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+test x = show (x :: _ :: Type)
+
+main = do
+ when (show (unit :: Unit :: Type) == "unit") (log "Done")
+ when (test unit == "unit") (log "Done")
diff --git a/tests/purs/passing/Eq1Deriving.purs b/tests/purs/passing/Eq1Deriving.purs
new file mode 100644
index 0000000..3cb98e3
--- /dev/null
+++ b/tests/purs/passing/Eq1Deriving.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Data.Eq (class Eq1)
+import Effect.Console (log)
+
+data Product a b = Product a b
+
+derive instance eqMu :: (Eq a, Eq b) => Eq (Product a b)
+derive instance eq1Mu :: Eq a => Eq1 (Product a)
+
+main = log "Done"
diff --git a/tests/purs/passing/Eq1InEqDeriving.purs b/tests/purs/passing/Eq1InEqDeriving.purs
new file mode 100644
index 0000000..2a8d731
--- /dev/null
+++ b/tests/purs/passing/Eq1InEqDeriving.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Data.Eq (class Eq1)
+import Effect.Console (log)
+
+newtype Mu f = In (f (Mu f))
+
+derive instance eqMu :: Eq1 f => Eq (Mu f)
+
+main = log "Done"
diff --git a/tests/purs/passing/EqOrd.purs b/tests/purs/passing/EqOrd.purs
new file mode 100644
index 0000000..5b0f2ba
--- /dev/null
+++ b/tests/purs/passing/EqOrd.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+data Pair a b = Pair a b
+
+instance ordPair :: (Ord a, Ord b) => Ord (Pair a b) where
+ compare (Pair a1 b1) (Pair a2 b2) = case compare a1 a2 of
+ EQ -> compare b1 b2
+ r -> r
+
+instance eqPair :: (Eq a, Eq b) => Eq (Pair a b) where
+ eq (Pair a1 b1) (Pair a2 b2) = a1 == a2 && b1 == b2
+
+main = do
+ logShow $ Pair 1.0 2.0 == Pair 1.0 2.0
+ log "Done"
diff --git a/tests/purs/passing/ExplicitImportReExport.purs b/tests/purs/passing/ExplicitImportReExport.purs
new file mode 100644
index 0000000..798d1c8
--- /dev/null
+++ b/tests/purs/passing/ExplicitImportReExport.purs
@@ -0,0 +1,11 @@
+-- from #1244
+module Main where
+
+import Prelude
+import Effect.Console (log)
+import Bar (foo)
+
+baz :: Int
+baz = foo
+
+main = log "Done"
diff --git a/tests/purs/passing/ExplicitImportReExport/Bar.purs b/tests/purs/passing/ExplicitImportReExport/Bar.purs
new file mode 100644
index 0000000..5f8ef12
--- /dev/null
+++ b/tests/purs/passing/ExplicitImportReExport/Bar.purs
@@ -0,0 +1,3 @@
+module Bar (module Foo) where
+
+import Foo
diff --git a/tests/purs/passing/ExplicitImportReExport/Foo.purs b/tests/purs/passing/ExplicitImportReExport/Foo.purs
new file mode 100644
index 0000000..d2c06e9
--- /dev/null
+++ b/tests/purs/passing/ExplicitImportReExport/Foo.purs
@@ -0,0 +1,4 @@
+module Foo where
+
+foo :: Int
+foo = 3
diff --git a/tests/purs/passing/ExplicitOperatorSections.purs b/tests/purs/passing/ExplicitOperatorSections.purs
new file mode 100644
index 0000000..79f4fcf
--- /dev/null
+++ b/tests/purs/passing/ExplicitOperatorSections.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+subtractOne :: Int -> Int
+subtractOne = (_ - 1)
+
+addOne :: Int -> Int
+addOne = (1 + _)
+
+named :: Int -> Int
+named = (_ `sub` 1)
+
+main = log "Done"
diff --git a/tests/purs/passing/ExportExplicit.purs b/tests/purs/passing/ExportExplicit.purs
new file mode 100644
index 0000000..f5c07f9
--- /dev/null
+++ b/tests/purs/passing/ExportExplicit.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import M1
+import Effect.Console (log)
+
+testX = X
+testZ = Z
+testFoo = foo
+
+main = log "Done"
diff --git a/tests/purs/passing/ExportExplicit/M1.purs b/tests/purs/passing/ExportExplicit/M1.purs
new file mode 100644
index 0000000..273f100
--- /dev/null
+++ b/tests/purs/passing/ExportExplicit/M1.purs
@@ -0,0 +1,10 @@
+module M1 (X(X), Z(..), foo) where
+
+data X = X | Y
+data Z = Z
+
+foo :: Int
+foo = 0
+
+bar :: Int
+bar = 1
diff --git a/tests/purs/passing/ExportExplicit2.purs b/tests/purs/passing/ExportExplicit2.purs
new file mode 100644
index 0000000..c1c896a
--- /dev/null
+++ b/tests/purs/passing/ExportExplicit2.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import M1
+import Effect.Console (log)
+
+testBar = bar
+
+main = log "Done"
diff --git a/tests/purs/passing/ExportExplicit2/M1.purs b/tests/purs/passing/ExportExplicit2/M1.purs
new file mode 100644
index 0000000..aa78149
--- /dev/null
+++ b/tests/purs/passing/ExportExplicit2/M1.purs
@@ -0,0 +1,7 @@
+module M1 (bar) where
+
+foo :: Int
+foo = 0
+
+bar :: Int
+bar = foo
diff --git a/tests/purs/passing/ExportedInstanceDeclarations.purs b/tests/purs/passing/ExportedInstanceDeclarations.purs
new file mode 100644
index 0000000..cddf87b
--- /dev/null
+++ b/tests/purs/passing/ExportedInstanceDeclarations.purs
@@ -0,0 +1,45 @@
+-- Tests that instances for non-exported classes / types do not appear in the
+-- result of `exportedDeclarations`.
+module Main
+ ( Const(..)
+ , class Foo
+ , foo
+ , main
+ ) where
+
+import Prelude
+import Effect.Console (log)
+
+data Const a b = Const a
+
+class Foo a where
+ foo :: a
+
+data NonexportedType = NonexportedType
+
+class NonexportedClass a where
+ notExported :: a
+
+-- There are three places that a nonexported type or type class can occur,
+-- leading an instance to count as non-exported:
+-- * The instance types
+-- * Constraints
+-- * The type class itself
+
+-- Case 1: instance types
+instance constFoo :: Foo (Const NonexportedType b) where
+ foo = Const NonexportedType
+else
+-- Case 2: constraints
+instance nonExportedFoo :: (Foo NonexportedType) => Foo (a -> a) where
+ foo = identity
+else
+-- Another instance of case 2:
+instance nonExportedFoo2 :: (NonexportedClass a) => Foo a where
+ foo = notExported
+
+-- Case 3: type class
+instance nonExportedNonexportedType :: NonexportedClass (Const Int a) where
+ notExported = Const 0
+
+main = log "Done"
diff --git a/tests/purs/passing/ExtendedInfixOperators.purs b/tests/purs/passing/ExtendedInfixOperators.purs
new file mode 100644
index 0000000..68ff336
--- /dev/null
+++ b/tests/purs/passing/ExtendedInfixOperators.purs
@@ -0,0 +1,17 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+import Data.Function (on)
+
+comparing :: forall a b. Ord b => (a -> b) -> a -> a -> Ordering
+comparing f = compare `on` f
+
+null [] = true
+null _ = false
+
+test = [1.0, 2.0, 3.0] `comparing null` [4.0, 5.0, 6.0]
+
+main = do
+ logShow test
+ log "Done"
diff --git a/tests/purs/passing/Fib.purs b/tests/purs/passing/Fib.purs
new file mode 100644
index 0000000..71dc31d
--- /dev/null
+++ b/tests/purs/passing/Fib.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+import Control.Monad.ST as ST
+import Control.Monad.ST.Ref as STRef
+
+fib :: Number
+fib = ST.run do
+ n1 <- STRef.new 1.0
+ n2 <- STRef.new 1.0
+ ST.while ((>) 1000.0 <$> STRef.read n1) do
+ n1' <- STRef.read n1
+ n2' <- STRef.read n2
+ _ <- STRef.write (n1' + n2') n2
+ STRef.write n2' n1
+ STRef.read n2
+
+main = do
+ log "Done"
diff --git a/tests/purs/passing/FieldConsPuns.purs b/tests/purs/passing/FieldConsPuns.purs
new file mode 100644
index 0000000..7a9d74d
--- /dev/null
+++ b/tests/purs/passing/FieldConsPuns.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
+
+main = do
+ greet { greeting, name }
+ log "Done"
+ where
+ greeting = "Hello"
+ name = "World"
diff --git a/tests/purs/passing/FieldPuns.purs b/tests/purs/passing/FieldPuns.purs
new file mode 100644
index 0000000..84e78fa
--- /dev/null
+++ b/tests/purs/passing/FieldPuns.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+greet { greeting, name } = log $ greeting <> ", " <> name <> "."
+
+main = do
+ greet { greeting: "Hello", name: "World" }
+ log "Done"
diff --git a/tests/purs/passing/FinalTagless.purs b/tests/purs/passing/FinalTagless.purs
new file mode 100644
index 0000000..b607427
--- /dev/null
+++ b/tests/purs/passing/FinalTagless.purs
@@ -0,0 +1,25 @@
+module Main where
+
+import Prelude hiding (add)
+import Effect.Console (log, logShow)
+
+class E e where
+ num :: Number -> e Number
+ add :: e Number -> e Number -> e Number
+
+type Expr a = forall e. E e => e a
+
+data Id a = Id a
+
+instance exprId :: E Id where
+ num = Id
+ add (Id n) (Id m) = Id (n + m)
+
+runId (Id a) = a
+
+three :: Expr Number
+three = add (num 1.0) (num 2.0)
+
+main = do
+ logShow $ runId three
+ log "Done"
diff --git a/tests/purs/passing/ForeignKind.purs b/tests/purs/passing/ForeignKind.purs
new file mode 100644
index 0000000..c2d4421
--- /dev/null
+++ b/tests/purs/passing/ForeignKind.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import ForeignKinds.Lib (kind Nat, Zero, Succ, N3, NatProxy, class AddNat, addNat, proxy1, proxy2)
+import Effect.Console (log)
+
+proxy1Add2Is3 :: NatProxy N3
+proxy1Add2Is3 = addNat proxy1 proxy2
+
+main = log "Done"
diff --git a/tests/purs/passing/ForeignKind/Lib.purs b/tests/purs/passing/ForeignKind/Lib.purs
new file mode 100644
index 0000000..0ca2c13
--- /dev/null
+++ b/tests/purs/passing/ForeignKind/Lib.purs
@@ -0,0 +1,60 @@
+module ForeignKinds.Lib (kind Nat, Kinded, Zero, Succ, N0, N1, N2, N3, NatProxy(..), class AddNat, addNat, proxy1, proxy2) where
+
+-- declaration
+
+foreign import kind Nat
+
+-- use in foreign data
+
+foreign import data Zero :: Nat
+foreign import data Succ :: Nat -> Nat
+
+-- use in data
+
+data NatProxy (t :: Nat) = NatProxy
+
+-- use in type sig
+
+succProxy :: forall n. NatProxy n -> NatProxy (Succ n)
+succProxy _ = NatProxy
+
+-- use in alias
+
+type Kinded f = f :: Nat
+
+type KindedZero = Kinded Zero
+
+type N0 = Zero
+type N1 = Succ N0
+type N2 = Succ N1
+type N3 = Succ N2
+
+-- use of alias
+
+proxy0 :: NatProxy N0
+proxy0 = NatProxy
+
+proxy1 :: NatProxy N1
+proxy1 = NatProxy
+
+proxy2 :: NatProxy N2
+proxy2 = NatProxy
+
+proxy3 :: NatProxy N3
+proxy3 = NatProxy
+
+-- use in class
+
+class AddNat (l :: Nat) (r :: Nat) (o :: Nat) | l -> r o
+
+instance addNatZero
+ :: AddNat Zero r r
+
+instance addNatSucc
+ :: AddNat l r o
+ => AddNat (Succ l) r (Succ o)
+
+-- use of class
+
+addNat :: forall l r o. AddNat l r o => NatProxy l -> NatProxy r -> NatProxy o
+addNat _ _ = NatProxy
diff --git a/tests/purs/passing/FunWithFunDeps.js b/tests/purs/passing/FunWithFunDeps.js
new file mode 100644
index 0000000..dea73d1
--- /dev/null
+++ b/tests/purs/passing/FunWithFunDeps.js
@@ -0,0 +1,32 @@
+
+//: forall e. FVect Z e
+exports.fnil = [];
+
+//: forall n e. e -> FVect n e -> FVect (S n) e
+exports.fcons = function (hd) {
+ return function (tl) {
+ return [hd].concat(tl);
+ };
+};
+
+exports.fappend = function (dict) {
+ return function (left) {
+ return function (right) {
+ return left.concat(right);
+ };
+ };
+};
+
+exports.fflatten = function (dict) {
+ return function (v) {
+ var accRef = [];
+ for (var indexRef = 0; indexRef < v.length; indexRef += 1) {
+ accRef = accRef.concat(v[indexRef]);
+ }
+ return accRef;
+ };
+};
+
+exports.ftoArray = function (vect) {
+ return vect;
+};
diff --git a/tests/purs/passing/FunWithFunDeps.purs b/tests/purs/passing/FunWithFunDeps.purs
new file mode 100644
index 0000000..9b9a991
--- /dev/null
+++ b/tests/purs/passing/FunWithFunDeps.purs
@@ -0,0 +1,41 @@
+-- Taken from https://github.com/LiamGoodacre/purescript-fun-with-fundeps
+
+module Main where
+
+import Effect.Console (log)
+
+-- Nat : Type
+data Z
+data S n
+
+type S2 n = S (S n)
+type S3 n = S (S2 n)
+type S4 n = S (S3 n)
+type S5 n = S (S4 n)
+type S15 n = S5 (S5 (S5 n))
+
+class NatPlus l r o | l r -> o
+instance natPlusZ :: NatPlus Z r r
+instance natPlusS :: (NatPlus l r o) => NatPlus (S l) r (S o)
+
+class NatMult l r o | l r -> o
+instance natMultZ :: NatMult Z n Z
+instance natMultS :: (NatMult m n r, NatPlus n r s) => NatMult (S m) n s
+
+-- Foreign Vect
+foreign import data FVect :: Type -> Type -> Type
+foreign import fnil :: forall e. FVect Z e
+foreign import fcons :: forall n e. e -> FVect n e -> FVect (S n) e
+foreign import fappend :: forall l r o e. NatPlus l r o => FVect l e -> FVect r e -> FVect o e
+foreign import fflatten :: forall f s t o. NatMult f s o => FVect f (FVect s t) -> FVect o t
+foreign import ftoArray :: forall n e. FVect n e -> Array e
+
+-- should be able to figure these out
+fsingleton x = fcons x fnil
+fexample = fcons 1 (fsingleton 2) `fappend` fsingleton 3 `fappend` fcons 4 (fsingleton 5)
+fexample2 = fexample `fappend` fexample `fappend` fexample
+fexample3 = fsingleton fexample `fappend` fsingleton fexample `fappend` fsingleton fexample
+
+fexample4 = fflatten fexample3
+
+main = log "Done"
diff --git a/tests/purs/passing/FunctionScope.purs b/tests/purs/passing/FunctionScope.purs
new file mode 100644
index 0000000..d859492
--- /dev/null
+++ b/tests/purs/passing/FunctionScope.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Test.Assert
+import Effect.Console (log)
+
+mkValue :: Number -> Number
+mkValue id = id
+
+main = do
+ let value = mkValue 1.0
+ assert $ value == 1.0
+ log "Done"
diff --git a/tests/purs/passing/FunctionalDependencies.purs b/tests/purs/passing/FunctionalDependencies.purs
new file mode 100644
index 0000000..6cc6485
--- /dev/null
+++ b/tests/purs/passing/FunctionalDependencies.purs
@@ -0,0 +1,21 @@
+module Main where
+
+import Effect.Console (log)
+
+data Nil
+data Cons x xs
+
+class Append a b c | a b -> c
+
+instance appendNil :: Append Nil b b
+
+instance appendCons :: Append xs b c => Append (Cons x xs) b (Cons x c)
+
+data Proxy a = Proxy
+
+appendProxy :: forall a b c. Append a b c => Proxy a -> Proxy b -> Proxy c
+appendProxy Proxy Proxy = Proxy
+
+test = appendProxy (Proxy :: Proxy (Cons Int Nil)) (Proxy :: Proxy (Cons String Nil))
+
+main = log "Done"
diff --git a/tests/purs/passing/Functions.purs b/tests/purs/passing/Functions.purs
new file mode 100644
index 0000000..368a69f
--- /dev/null
+++ b/tests/purs/passing/Functions.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test1 = \_ -> 0.0
+
+test2 = \a b -> a + b + 1.0
+
+test3 = \a -> a
+
+main = log "Done"
diff --git a/tests/purs/passing/Functions2.purs b/tests/purs/passing/Functions2.purs
new file mode 100644
index 0000000..1aede05
--- /dev/null
+++ b/tests/purs/passing/Functions2.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Test.Assert
+import Effect.Console (log)
+
+test :: forall a b. a -> b -> a
+test = \const _ -> const
+
+main = do
+ let value = test "Done" {}
+ assert' "Not done" $ value == "Done"
+ log "Done"
diff --git a/tests/purs/passing/Generalization1.purs b/tests/purs/passing/Generalization1.purs
new file mode 100644
index 0000000..0ce76c4
--- /dev/null
+++ b/tests/purs/passing/Generalization1.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (logShow, log)
+
+main = do
+ logShow (sum 1.0 2.0)
+ logShow (sum 1 2)
+ log "Done"
+
+sum x y = x + y
diff --git a/tests/purs/passing/GenericsRep.purs b/tests/purs/passing/GenericsRep.purs
new file mode 100644
index 0000000..a7e9748
--- /dev/null
+++ b/tests/purs/passing/GenericsRep.purs
@@ -0,0 +1,43 @@
+module Main where
+
+import Prelude
+import Effect (Effect)
+import Effect.Console (log, logShow)
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
+
+data X a = X a
+
+derive instance genericX :: Generic (X a) _
+
+instance eqX :: Eq a => Eq (X a) where
+ eq xs ys = genericEq xs ys
+
+data Y a = Y | Z a (Y a)
+
+derive instance genericY :: Generic (Y a) _
+
+instance eqY :: Eq a => Eq (Y a) where
+ eq xs ys = genericEq xs ys
+
+data Z
+
+derive instance genericZ :: Generic Z _
+
+instance eqZ :: Eq Z where
+ eq x y = genericEq x y
+
+type MyString = String
+
+newtype W = W { x :: Int, y :: MyString }
+
+derive instance genericW :: Generic W _
+
+main :: Effect Unit
+main = do
+ logShow (X 0 == X 1)
+ logShow (X 1 == X 1)
+ logShow (Z 1 Y == Z 1 Y)
+ logShow (Z 1 Y == Y)
+ logShow (Y == Y :: Y Z)
+ log "Done"
diff --git a/tests/purs/passing/Guards.purs b/tests/purs/passing/Guards.purs
new file mode 100644
index 0000000..2894d2e
--- /dev/null
+++ b/tests/purs/passing/Guards.purs
@@ -0,0 +1,64 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+collatz = \x -> case x of
+ y | y `mod` 2.0 == 0.0 -> y / 2.0
+ y -> y * 3.0 + 1.0
+
+-- Guards have access to current scope
+collatz2 = \x y -> case x of
+ z | y > 0.0 -> z / 2.0
+ z -> z * 3.0 + 1.0
+
+min :: forall a. Ord a => a -> a -> a
+min n m | n < m = n
+ | otherwise = m
+
+max :: forall a. Ord a => a -> a -> a
+max n m = case unit of
+ _ | m < n -> n
+ | otherwise -> m
+
+testIndentation :: Number -> Number -> Number
+testIndentation x y | x > 0.0
+ = x + y
+ | otherwise
+ = y - x
+
+-- pattern guard example with two clauses
+clunky1 :: Int -> Int -> Int
+clunky1 a b | x <- max a b
+ , x > 5
+ = x
+clunky1 a _ = a
+
+clunky2 :: Int -> Int -> Int
+clunky2 a b | x <- max a b
+ , x > 5
+ = x
+ | otherwise
+ = a + b
+
+-- pattern guards on case epxressions
+clunky_case1 :: Int -> Int -> Int
+clunky_case1 a b =
+ case unit of
+ unit | x <- max a b
+ , x > 5
+ -> x
+ | otherwise -> a + b
+
+-- test indentation
+clunky_case2 :: Int -> Int -> Int
+clunky_case2 a b =
+ case unit of
+ unit
+ | x <- max a b
+ , x > 5
+ -> x
+ | otherwise
+ -> a + b
+
+main = log $ min "Done" "ZZZZ"
diff --git a/tests/purs/passing/HasOwnProperty.purs b/tests/purs/passing/HasOwnProperty.purs
new file mode 100644
index 0000000..f4630f7
--- /dev/null
+++ b/tests/purs/passing/HasOwnProperty.purs
@@ -0,0 +1,5 @@
+module Main where
+
+import Effect.Console (log)
+
+main = log ({hasOwnProperty: "Hi"} {hasOwnProperty = "Done"}).hasOwnProperty
diff --git a/tests/purs/passing/HoistError.purs b/tests/purs/passing/HoistError.purs
new file mode 100644
index 0000000..be8a8a8
--- /dev/null
+++ b/tests/purs/passing/HoistError.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Test.Assert
+
+main = do
+ let x = 0.0
+ assert $ x == 0.0
+ let x = 1.0 + 1.0
+ log "Done"
diff --git a/tests/purs/passing/IfThenElseMaybe.purs b/tests/purs/passing/IfThenElseMaybe.purs
new file mode 100644
index 0000000..320c303
--- /dev/null
+++ b/tests/purs/passing/IfThenElseMaybe.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Maybe a = Nothing | Just a
+
+test1 = if true then Just 10 else Nothing
+
+test2 = if true then Nothing else Just 10
+
+main = log "Done"
diff --git a/tests/purs/passing/IfWildcard.purs b/tests/purs/passing/IfWildcard.purs
new file mode 100644
index 0000000..243d7fb
--- /dev/null
+++ b/tests/purs/passing/IfWildcard.purs
@@ -0,0 +1,19 @@
+module Main where
+
+import Prelude
+import Effect (Effect)
+import Effect.Console (log)
+
+data Foo = X | Y
+
+cond ∷ ∀ a. Boolean → a → a → a
+cond = if _ then _ else _
+
+what ∷ Boolean → Foo
+what = if _ then X else Y
+
+main :: Effect Unit
+main = do
+ let tmp1 = what true
+ tmp2 = cond true 0 1
+ log "Done"
diff --git a/tests/purs/passing/ImplicitEmptyImport.purs b/tests/purs/passing/ImplicitEmptyImport.purs
new file mode 100644
index 0000000..a0b0d39
--- /dev/null
+++ b/tests/purs/passing/ImplicitEmptyImport.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+main = do
+ log "Hello"
+ log "Goodbye"
+ log "Done"
diff --git a/tests/purs/passing/Import.purs b/tests/purs/passing/Import.purs
new file mode 100644
index 0000000..b77cbf7
--- /dev/null
+++ b/tests/purs/passing/Import.purs
@@ -0,0 +1,6 @@
+module Main where
+
+import M2
+import Effect.Console (log)
+
+main = log "Done"
diff --git a/tests/purs/passing/Import/M1.purs b/tests/purs/passing/Import/M1.purs
new file mode 100644
index 0000000..36cdb4b
--- /dev/null
+++ b/tests/purs/passing/Import/M1.purs
@@ -0,0 +1,8 @@
+module M1 where
+
+import Prelude ()
+
+id :: forall a. a -> a
+id = \x -> x
+
+foo = id
diff --git a/tests/purs/passing/Import/M2.purs b/tests/purs/passing/Import/M2.purs
new file mode 100644
index 0000000..7b4883a
--- /dev/null
+++ b/tests/purs/passing/Import/M2.purs
@@ -0,0 +1,6 @@
+module M2 where
+
+import Prelude ()
+import M1
+
+main = \_ -> foo 42
diff --git a/tests/purs/passing/ImportExplicit.purs b/tests/purs/passing/ImportExplicit.purs
new file mode 100644
index 0000000..18d2dc9
--- /dev/null
+++ b/tests/purs/passing/ImportExplicit.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import M1 (X(..))
+import Effect.Console (log)
+
+testX :: X
+testX = X
+testY = Y
+
+main = log "Done"
diff --git a/tests/purs/passing/ImportExplicit/M1.purs b/tests/purs/passing/ImportExplicit/M1.purs
new file mode 100644
index 0000000..cf27f2d
--- /dev/null
+++ b/tests/purs/passing/ImportExplicit/M1.purs
@@ -0,0 +1,4 @@
+module M1 where
+
+data X = X | Y
+data Z = Z
diff --git a/tests/purs/passing/ImportHiding.purs b/tests/purs/passing/ImportHiding.purs
new file mode 100644
index 0000000..2c355ac
--- /dev/null
+++ b/tests/purs/passing/ImportHiding.purs
@@ -0,0 +1,19 @@
+module Main where
+
+import Effect.Console
+import Prelude hiding (
+ show, -- a value
+ class Show, -- a type class
+ Unit(..) -- a constructor
+ )
+
+show = 1.0
+
+class Show a where
+ noshow :: a -> a
+
+data Unit = X | Y
+
+main = do
+ logShow show
+ log "Done"
diff --git a/tests/purs/passing/ImportQualified.purs b/tests/purs/passing/ImportQualified.purs
new file mode 100644
index 0000000..2051584
--- /dev/null
+++ b/tests/purs/passing/ImportQualified.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Prelude
+import Effect
+import M1
+import Effect.Console as C
+
+main = C.log (log "Done")
diff --git a/tests/purs/passing/ImportQualified/M1.purs b/tests/purs/passing/ImportQualified/M1.purs
new file mode 100644
index 0000000..719a1a0
--- /dev/null
+++ b/tests/purs/passing/ImportQualified/M1.purs
@@ -0,0 +1,3 @@
+module M1 where
+
+log x = x
diff --git a/tests/purs/passing/InferRecFunWithConstrainedArgument.purs b/tests/purs/passing/InferRecFunWithConstrainedArgument.purs
new file mode 100644
index 0000000..a06f573
--- /dev/null
+++ b/tests/purs/passing/InferRecFunWithConstrainedArgument.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+test 100 = 100
+test n = test(1 + n)
+
+main = do
+ logShow (test 0)
+ log "Done"
diff --git a/tests/purs/passing/InstanceBeforeClass.purs b/tests/purs/passing/InstanceBeforeClass.purs
new file mode 100644
index 0000000..76279f9
--- /dev/null
+++ b/tests/purs/passing/InstanceBeforeClass.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+instance fooNumber :: Foo Number where
+ foo = 0.0
+
+class Foo a where
+ foo :: a
+
+main = log "Done"
diff --git a/tests/purs/passing/InstanceChain.purs b/tests/purs/passing/InstanceChain.purs
new file mode 100644
index 0000000..7039afb
--- /dev/null
+++ b/tests/purs/passing/InstanceChain.purs
@@ -0,0 +1,71 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Arg i o | i -> o
+
+data Proxy p = Proxy
+
+arg :: forall i o. Arg i o => Proxy i -> Proxy o
+arg _ = Proxy
+
+instance appArg :: Arg i o => Arg (f i) o
+else instance reflArg :: Arg i i
+
+argEg0 :: Proxy Int
+argEg0 = arg (Proxy :: Proxy Int)
+
+argEg1 :: Proxy Int
+argEg1 = arg (Proxy :: Proxy (Array Int))
+
+argEg2 :: Proxy Int
+argEg2 = arg (Proxy :: Proxy (Boolean -> Array Int))
+
+
+class IsEq l r o | l r -> o
+
+foreign import data True :: Type
+foreign import data False :: Type
+
+isEq :: forall l r o. IsEq l r o => Proxy l -> Proxy r -> Proxy o
+isEq _ _ = Proxy
+
+instance reflIsEq :: IsEq a a True
+else instance notIsEq :: IsEq a b False
+
+isEqEg0 :: Proxy True
+isEqEg0 = isEq (Proxy :: Proxy Int) (Proxy :: Proxy Int)
+
+isEqEg1 :: Proxy True
+isEqEg1 = isEq (Proxy :: Proxy (Array Int)) (Proxy :: Proxy (Array Int))
+
+isEqEg2 :: Proxy False
+isEqEg2 = isEq (Proxy :: Proxy (Array Int)) (Proxy :: Proxy (Array Boolean))
+
+
+-- example chain in which we should only commit to `isStringElse` once we've
+-- learnt that the type param is apart from `String`.
+
+class Learn a b | a -> b
+instance learnInst :: Learn a a
+
+class IsString t o | t -> o
+instance isStringString :: IsString String True
+else instance isStringElse :: IsString t False
+
+learnIsString :: forall a t o.
+ IsString t o =>
+ Learn a t =>
+ Proxy a ->
+ Proxy o
+learnIsString _ = Proxy
+
+isStringEg0 :: Proxy True
+isStringEg0 = learnIsString (Proxy :: Proxy String)
+
+isStringEg1 :: Proxy False
+isStringEg1 = learnIsString (Proxy :: Proxy Int)
+
+
+main = log "Done"
diff --git a/tests/purs/passing/InstanceSigs.purs b/tests/purs/passing/InstanceSigs.purs
new file mode 100644
index 0000000..c98f437
--- /dev/null
+++ b/tests/purs/passing/InstanceSigs.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Effect.Console (log)
+
+class Foo a where
+ foo :: a
+
+instance fooNumber :: Foo Number where
+ foo :: Number
+ foo = 0.0
+
+main = log "Done"
diff --git a/tests/purs/passing/InstanceSigsGeneral.purs b/tests/purs/passing/InstanceSigsGeneral.purs
new file mode 100644
index 0000000..3a324a5
--- /dev/null
+++ b/tests/purs/passing/InstanceSigsGeneral.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Effect.Console (log)
+
+class Eq a where
+ eq :: a -> a -> Boolean
+
+instance eqNumber :: Eq Number where
+ eq :: forall x y. x -> y -> Boolean
+ eq _ _ = true
+
+main = log "Done"
diff --git a/tests/purs/passing/IntAndChar.purs b/tests/purs/passing/IntAndChar.purs
new file mode 100644
index 0000000..476764d
--- /dev/null
+++ b/tests/purs/passing/IntAndChar.purs
@@ -0,0 +1,19 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console (log)
+import Test.Assert
+
+f 1 = 1
+f _ = 0
+
+g 'a' = 'a'
+g _ = 'b'
+
+main = do
+ assert $ f 1 == 1
+ assert $ f 0 == 0
+ assert $ g 'a' == 'a'
+ assert $ g 'b' == 'b'
+ log "Done"
diff --git a/tests/purs/passing/JSReserved.purs b/tests/purs/passing/JSReserved.purs
new file mode 100644
index 0000000..bb9e9c2
--- /dev/null
+++ b/tests/purs/passing/JSReserved.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+yield = 0
+member = 1
+
+public = \return -> return
+
+this catch = catch
+
+main = log "Done"
diff --git a/tests/purs/passing/KindedType.purs b/tests/purs/passing/KindedType.purs
new file mode 100644
index 0000000..13b9817
--- /dev/null
+++ b/tests/purs/passing/KindedType.purs
@@ -0,0 +1,34 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type Star2Star f = f :: Type -> Type
+
+type Star t = t :: Type
+
+test1 :: Star2Star Array String
+test1 = ["test"]
+
+f :: Star (String -> String)
+f s = s
+
+test2 = f "test"
+
+data Proxy (f :: Type -> Type) = Proxy
+
+test3 :: Proxy Array
+test3 = Proxy
+
+type Test (f :: Type -> Type) = f String
+
+test4 :: Test Array
+test4 = ["test"]
+
+class Clazz (a :: Type) where
+ def :: a
+
+instance clazzString :: Clazz String where
+ def = "test"
+
+main = log "Done"
diff --git a/tests/purs/passing/LargeSumType.purs b/tests/purs/passing/LargeSumType.purs
new file mode 100644
index 0000000..9d83a73
--- /dev/null
+++ b/tests/purs/passing/LargeSumType.purs
@@ -0,0 +1,35 @@
+module Main where
+
+import Effect.Console (log)
+
+data Large = A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
+
+explode A A = "A"
+explode B B = "B"
+explode C C = "C"
+explode D D = "D"
+explode E E = "E"
+explode F F = "F"
+explode G G = "G"
+explode H H = "H"
+explode I I = "I"
+explode J J = "J"
+explode K K = "K"
+explode L L = "L"
+explode M M = "M"
+explode N N = "N"
+explode O O = "O"
+explode P P = "P"
+explode Q Q = "Q"
+explode R R = "R"
+explode S S = "S"
+explode T T = "T"
+explode U U = "U"
+explode V V = "V"
+explode W W = "W"
+explode X X = "X"
+explode Y Y = "Y"
+explode Z Z = "Z"
+explode _ _ = ""
+
+main = log "Done"
diff --git a/tests/purs/passing/Let.purs b/tests/purs/passing/Let.purs
new file mode 100644
index 0000000..03cd3cf
--- /dev/null
+++ b/tests/purs/passing/Let.purs
@@ -0,0 +1,58 @@
+module Main where
+
+import Prelude
+import Partial.Unsafe (unsafePartial)
+import Effect
+import Effect.Console (log, logShow)
+import Control.Monad.ST
+
+test1 x = let
+ y :: Number
+ y = x + 1.0
+ in y
+
+test2 x y =
+ let x' = x + 1.0 in
+ let y' = y + 1.0 in
+ x' + y'
+
+test3 = let f x y z = x + y + z in
+ f 1.0 2.0 3.0
+
+test4 = let
+ f x [y, z] = x y z
+ in f (+) [1.0, 2.0]
+
+test5 = let
+ f x | x > 0.0 = g (x / 2.0) + 1.0
+ f x = 0.0
+ g x = f (x - 1.0) + 1.0
+ in f 10.0
+
+test7 = let
+ f :: forall a. a -> a
+ f x = x
+ in if f true then f 1.0 else f 2.0
+
+test8 :: Number -> Number
+test8 x = let
+ go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
+ go y = go $ (y + x / y) / 2.0
+ in go x
+
+test10 _ =
+ let
+ f x = g x * 3.0
+ g x = f x / 2.0
+ in f 10.0
+
+main :: Effect _
+main = do
+ logShow (test1 1.0)
+ logShow (test2 1.0 2.0)
+ logShow test3
+ unsafePartial (logShow test4)
+ logShow test5
+ logShow test7
+ logShow (test8 100.0)
+ log "Done"
diff --git a/tests/purs/passing/Let2.purs b/tests/purs/passing/Let2.purs
new file mode 100644
index 0000000..37e96ac
--- /dev/null
+++ b/tests/purs/passing/Let2.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+test =
+ let f :: Number -> Boolean
+ f 0.0 = false
+ f n = g (n - 1.0)
+
+ g :: Number -> Boolean
+ g 0.0 = true
+ g n = f (n - 1.0)
+
+ x = f 1.0
+ in not x
+
+main = do
+ logShow test
+ log "Done"
diff --git a/tests/purs/passing/LetInInstance.purs b/tests/purs/passing/LetInInstance.purs
new file mode 100644
index 0000000..0688893
--- /dev/null
+++ b/tests/purs/passing/LetInInstance.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Foo a where
+ foo :: a -> String
+
+instance fooString :: Foo String where
+ foo = go
+ where
+ go :: String -> String
+ go s = s
+
+main = log "Done"
diff --git a/tests/purs/passing/LetPattern.purs b/tests/purs/passing/LetPattern.purs
new file mode 100644
index 0000000..799e22f
--- /dev/null
+++ b/tests/purs/passing/LetPattern.purs
@@ -0,0 +1,196 @@
+module Main where
+
+import Prelude
+import Partial.Unsafe (unsafePartial)
+import Effect (Effect)
+import Effect.Console (log)
+import Test.Assert (assert')
+
+patternSimple :: Boolean
+patternSimple =
+ let x = 25252
+ in
+ x == 25252
+
+patternDoSimple :: Effect Boolean
+patternDoSimple = do
+ let x = 25252
+ pure $ x == 25252
+
+newtype X = X Int
+
+patternNewtype :: Boolean
+patternNewtype =
+ let X a = X 123
+ in
+ a == 123
+
+patternDoNewtype :: Effect Boolean
+patternDoNewtype = do
+ let X a = X 123
+ pure $ a == 123
+
+data Y = Y Int String Boolean
+
+patternData :: Boolean
+patternData =
+ let Y a b c = Y 456 "hello, world" false
+ in
+ a == 456 && b == "hello, world" && not c
+
+patternDataIgnored :: Boolean
+patternDataIgnored =
+ let Y _ x _ = Y 789 "world, hello" true
+ in
+ x == "world, hello"
+
+patternDoData :: Effect Boolean
+patternDoData = do
+ let Y a b c = Y 456 "hello, world" false
+ pure $ a == 456 && b == "hello, world" && not c
+
+patternDoDataIgnored :: Effect Boolean
+patternDoDataIgnored = do
+ let Y _ x _ = Y 789 "world, hello" true
+ pure $ x == "world, hello"
+
+patternArray :: Boolean
+patternArray = unsafePartial $
+ let [a, b] = [1, 2]
+ in
+ a == 1 && b == 2
+
+patternDoArray :: Effect Boolean
+patternDoArray = unsafePartial do
+ let [a, b] = [1, 2]
+ pure $ a == 1 && b == 2
+
+patternMultiple :: Boolean
+patternMultiple = unsafePartial $
+ let
+ x = 25252
+ X a = X x
+ Y b c d = Y x "hello, world" false
+ Y _ e _ = Y 789 "world, hello" true
+ [f, g] = [1, 2]
+ in
+ x == 25252 && a == 25252 && b == 25252 && c == "hello, world" &&
+ not d && e == "world, hello" && f == 1 && g == 2
+
+patternDoMultiple :: Effect Boolean
+patternDoMultiple = unsafePartial do
+ let
+ x = 25252
+ X a = X x
+ Y b c d = Y x "hello, world" false
+ Y _ e _ = Y 789 "world, hello" true
+ [f, g] = [1, 2]
+ pure $ x == 25252 && a == 25252 && b == 25252 && c == "hello, world" &&
+ not d && e == "world, hello" && f == 1 && g == 2
+
+patternMultipleWithNormal :: Boolean
+patternMultipleWithNormal = unsafePartial $
+ let
+ x = 25252
+ X a = X x
+ y = 2525
+ Y b c d = Y y "hello, world" false
+ in
+ x == 25252 && y == 2525 &&
+ a == 25252 && b == 2525 && c == "hello, world" && not d
+
+patternDoMultipleWithNormal :: Effect Boolean
+patternDoMultipleWithNormal = unsafePartial do
+ let
+ x = 25252
+ X a = X x
+ y = 2525
+ Y b c d = Y y "hello, world" false
+ pure $ x == 25252 && y == 2525 &&
+ a == 25252 && b == 2525 && c == "hello, world" && not d
+
+patternWithParens :: Boolean
+patternWithParens = unsafePartial $
+ let
+ (x) = 25252
+ (X a) = X x
+ (Y b c d) = Y x "hello, world" false
+ (Y _ e _) = Y 789 "world, hello" true
+ ([f, g]) = [1, 2]
+ in
+ x == 25252 && a == 25252 && b == 25252 && c == "hello, world" &&
+ not d && e == "world, hello" && f == 1 && g == 2
+
+patternDoWithParens :: Effect Boolean
+patternDoWithParens = unsafePartial do
+ let
+ (x) = 25252
+ (X a) = X x
+ (Y b c d) = Y x "hello, world" false
+ (Y _ e _) = Y 789 "world, hello" true
+ ([f, g]) = [1, 2]
+ pure $ x == 25252 && a == 25252 && b == 25252 && c == "hello, world" &&
+ not d && e == "world, hello" && f == 1 && g == 2
+
+patternWithNamedBinder :: Boolean
+patternWithNamedBinder = unsafePartial $
+ let
+ a@{x, y} = {x: 10, y: 20}
+ in
+ a.x == 10 && x == 10 && a.y == 20 && y == 20
+
+patternDoWithNamedBinder :: Effect Boolean
+patternDoWithNamedBinder = unsafePartial do
+ let
+ a@{x, y} = {x: 10, y: 20}
+ pure $
+ a.x == 10 && x == 10 && a.y == 20 && y == 20
+
+data List a = Nil | Cons a (List a)
+infixr 6 Cons as :
+
+instance eqList :: Eq a => Eq (List a) where
+ eq xs ys = go xs ys true
+ where
+ go _ _ false = false
+ go Nil Nil acc = acc
+ go (x : xs') (y : ys') acc = go xs' ys' $ acc && (y == x)
+ go _ _ _ = false
+
+patternWithInfixOp :: Boolean
+patternWithInfixOp = unsafePartial $
+ let
+ x : xs = 1 : 2 : 3 : 4 : Nil
+ in
+ x == 1 && xs == 2 : 3 : 4 : Nil
+
+patternDoWithInfixOp :: Effect Boolean
+patternDoWithInfixOp = unsafePartial do
+ let
+ x : xs = 1 : 2 : 3 : 4 : Nil
+ pure $
+ x == 1 && xs == 2 : 3 : 4 : Nil
+
+main :: Effect Unit
+main = do
+ assert' "simple variable pattern" patternSimple
+ assert' "simple variable pattern with do" =<< patternDoSimple
+ assert' "constructor pattern (newtype)" patternNewtype
+ assert' "constructor pattern (newtype) with do" =<< patternDoNewtype
+ assert' "constructor pattern (data)" patternData
+ assert' "constructor pattern with ignorances" patternDataIgnored
+ assert' "constructor pattern (data) with do" =<< patternDoData
+ assert' "constructor pattern with ignorances and do" =<< patternDoDataIgnored
+ assert' "array pattern" patternArray
+ assert' "array pattern with do" =<< patternDoArray
+ assert' "multiple patterns" patternMultiple
+ assert' "multiple patterns with do" =<< patternDoMultiple
+ assert' "multiple patterns with normal let's" patternMultipleWithNormal
+ assert' "multiple patterns with normal let's and do" =<< patternDoMultipleWithNormal
+ assert' "multiple patterns with parens" patternWithParens
+ assert' "multiple patterns with parens and do" =<< patternDoWithParens
+ assert' "multiple patterns with named binder" patternWithNamedBinder
+ assert' "multiple patterns with named binder and do" =<< patternDoWithNamedBinder
+ assert' "pattern with infix operator" patternWithInfixOp
+ assert' "pattern with infix operator and do" =<< patternDoWithInfixOp
+ log "Done"
diff --git a/tests/purs/passing/LiberalTypeSynonyms.purs b/tests/purs/passing/LiberalTypeSynonyms.purs
new file mode 100644
index 0000000..1f6c3d1
--- /dev/null
+++ b/tests/purs/passing/LiberalTypeSynonyms.purs
@@ -0,0 +1,22 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type Reader = (->) String
+
+foo :: Reader String
+foo s = s
+
+type AndFoo r = (foo :: String | r)
+
+getFoo :: forall r. Prim.Record (AndFoo r) -> String
+getFoo o = o.foo
+
+type F r = { | r } -> { | r }
+
+f :: (forall r. F r) -> String
+f g = case g { x: "Hello" } of
+ { x: x } -> x
+
+main = log "Done"
diff --git a/tests/purs/passing/MPTCs.purs b/tests/purs/passing/MPTCs.purs
new file mode 100644
index 0000000..6de6002
--- /dev/null
+++ b/tests/purs/passing/MPTCs.purs
@@ -0,0 +1,21 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class NullaryTypeClass where
+ greeting :: String
+
+instance nullaryTypeClass :: NullaryTypeClass where
+ greeting = "Hello, World!"
+
+class Coerce a b where
+ coerce :: a -> b
+
+instance coerceShow :: Show a => Coerce a String where
+ coerce = show
+else
+instance coerceRefl :: Coerce a a where
+ coerce a = a
+
+main = log "Done"
diff --git a/tests/purs/passing/Match.purs b/tests/purs/passing/Match.purs
new file mode 100644
index 0000000..60a264d
--- /dev/null
+++ b/tests/purs/passing/Match.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Foo a = Foo
+
+foo = \f -> case f of Foo -> "foo"
+
+main = log "Done"
diff --git a/tests/purs/passing/Module.purs b/tests/purs/passing/Module.purs
new file mode 100644
index 0000000..d8f5501
--- /dev/null
+++ b/tests/purs/passing/Module.purs
@@ -0,0 +1,7 @@
+module Main where
+
+import M1
+import M2
+import Effect.Console (log)
+
+main = log "Done"
diff --git a/tests/purs/passing/Module/M1.purs b/tests/purs/passing/Module/M1.purs
new file mode 100644
index 0000000..d276f7a
--- /dev/null
+++ b/tests/purs/passing/Module/M1.purs
@@ -0,0 +1,14 @@
+module M1 where
+
+import Prelude
+
+data Foo = Foo String
+
+foo :: Foo -> String
+foo = \f -> case f of Foo s -> s <> "foo"
+
+bar :: Foo -> String
+bar = foo
+
+incr :: Int -> Int
+incr x = x + 1
diff --git a/tests/purs/passing/Module/M2.purs b/tests/purs/passing/Module/M2.purs
new file mode 100644
index 0000000..b2c8b86
--- /dev/null
+++ b/tests/purs/passing/Module/M2.purs
@@ -0,0 +1,10 @@
+module M2 where
+
+import Prelude
+import M1 as M1
+
+baz :: M1.Foo -> String
+baz = M1.foo
+
+match :: M1.Foo -> String
+match = \f -> case f of M1.Foo s -> s <> "foo"
diff --git a/tests/purs/passing/ModuleDeps.purs b/tests/purs/passing/ModuleDeps.purs
new file mode 100644
index 0000000..79db9e1
--- /dev/null
+++ b/tests/purs/passing/ModuleDeps.purs
@@ -0,0 +1,6 @@
+module Main where
+
+import M1
+import Effect.Console (log)
+
+main = log "Done"
diff --git a/tests/purs/passing/ModuleDeps/M1.purs b/tests/purs/passing/ModuleDeps/M1.purs
new file mode 100644
index 0000000..535aa28
--- /dev/null
+++ b/tests/purs/passing/ModuleDeps/M1.purs
@@ -0,0 +1,5 @@
+module M1 where
+
+import M2 as M2
+
+foo = M2.bar
diff --git a/tests/purs/passing/ModuleDeps/M2.purs b/tests/purs/passing/ModuleDeps/M2.purs
new file mode 100644
index 0000000..017e70e
--- /dev/null
+++ b/tests/purs/passing/ModuleDeps/M2.purs
@@ -0,0 +1,5 @@
+module M2 where
+
+import M3 as M3
+
+bar = M3.baz
diff --git a/tests/purs/passing/ModuleDeps/M3.purs b/tests/purs/passing/ModuleDeps/M3.purs
new file mode 100644
index 0000000..f07167b
--- /dev/null
+++ b/tests/purs/passing/ModuleDeps/M3.purs
@@ -0,0 +1,3 @@
+module M3 where
+
+baz = 1
diff --git a/tests/purs/passing/ModuleExport.purs b/tests/purs/passing/ModuleExport.purs
new file mode 100644
index 0000000..9a04dbe
--- /dev/null
+++ b/tests/purs/passing/ModuleExport.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Effect.Console (log, logShow)
+import A
+
+main = do
+ logShow (show 1.0)
+ log "Done"
diff --git a/tests/purs/passing/ModuleExport/A.purs b/tests/purs/passing/ModuleExport/A.purs
new file mode 100644
index 0000000..4c11122
--- /dev/null
+++ b/tests/purs/passing/ModuleExport/A.purs
@@ -0,0 +1,3 @@
+module A (module Prelude) where
+
+import Prelude
diff --git a/tests/purs/passing/ModuleExportDupes.purs b/tests/purs/passing/ModuleExportDupes.purs
new file mode 100644
index 0000000..4cf1a72
--- /dev/null
+++ b/tests/purs/passing/ModuleExportDupes.purs
@@ -0,0 +1,11 @@
+module Main where
+
+ import Effect.Console
+ import A
+ import B
+ import C
+ import Prelude
+
+ main = do
+ logShow (show 1.0)
+ log "Done"
diff --git a/tests/purs/passing/ModuleExportDupes/A.purs b/tests/purs/passing/ModuleExportDupes/A.purs
new file mode 100644
index 0000000..4c11122
--- /dev/null
+++ b/tests/purs/passing/ModuleExportDupes/A.purs
@@ -0,0 +1,3 @@
+module A (module Prelude) where
+
+import Prelude
diff --git a/tests/purs/passing/ModuleExportDupes/B.purs b/tests/purs/passing/ModuleExportDupes/B.purs
new file mode 100644
index 0000000..c4ed60d
--- /dev/null
+++ b/tests/purs/passing/ModuleExportDupes/B.purs
@@ -0,0 +1,3 @@
+module B (module Prelude) where
+
+import Prelude
diff --git a/tests/purs/passing/ModuleExportDupes/C.purs b/tests/purs/passing/ModuleExportDupes/C.purs
new file mode 100644
index 0000000..b92340f
--- /dev/null
+++ b/tests/purs/passing/ModuleExportDupes/C.purs
@@ -0,0 +1,4 @@
+module C (module Prelude, module A) where
+
+import Prelude
+import A
diff --git a/tests/purs/passing/ModuleExportExcluded.purs b/tests/purs/passing/ModuleExportExcluded.purs
new file mode 100644
index 0000000..99c97fa
--- /dev/null
+++ b/tests/purs/passing/ModuleExportExcluded.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+import A (foo)
+
+otherwise = false
+
+main = do
+ logShow "1.0"
+ log "Done"
diff --git a/tests/purs/passing/ModuleExportExcluded/A.purs b/tests/purs/passing/ModuleExportExcluded/A.purs
new file mode 100644
index 0000000..fe4e91e
--- /dev/null
+++ b/tests/purs/passing/ModuleExportExcluded/A.purs
@@ -0,0 +1,6 @@
+module A (module Prelude, foo) where
+
+import Prelude
+
+foo :: Number -> Number
+foo _ = 0.0
diff --git a/tests/purs/passing/ModuleExportQualified.purs b/tests/purs/passing/ModuleExportQualified.purs
new file mode 100644
index 0000000..5d0e289
--- /dev/null
+++ b/tests/purs/passing/ModuleExportQualified.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+import A as B
+
+main = do
+ logShow (B.show 1.0)
+ log "Done"
diff --git a/tests/purs/passing/ModuleExportQualified/A.purs b/tests/purs/passing/ModuleExportQualified/A.purs
new file mode 100644
index 0000000..4c11122
--- /dev/null
+++ b/tests/purs/passing/ModuleExportQualified/A.purs
@@ -0,0 +1,3 @@
+module A (module Prelude) where
+
+import Prelude
diff --git a/tests/purs/passing/ModuleExportSelf.purs b/tests/purs/passing/ModuleExportSelf.purs
new file mode 100644
index 0000000..edcd9f4
--- /dev/null
+++ b/tests/purs/passing/ModuleExportSelf.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Effect.Console
+import A
+
+bar :: Foo
+bar = true
+
+main = do
+ logShow (show bar)
+ log "Done"
diff --git a/tests/purs/passing/ModuleExportSelf/A.purs b/tests/purs/passing/ModuleExportSelf/A.purs
new file mode 100644
index 0000000..4e8742e
--- /dev/null
+++ b/tests/purs/passing/ModuleExportSelf/A.purs
@@ -0,0 +1,5 @@
+module A (module A, module Prelude) where
+
+import Prelude
+
+type Foo = Boolean
diff --git a/tests/purs/passing/Monad.purs b/tests/purs/passing/Monad.purs
new file mode 100644
index 0000000..8bf3c33
--- /dev/null
+++ b/tests/purs/passing/Monad.purs
@@ -0,0 +1,32 @@
+module Main where
+
+import Effect.Console (log)
+
+type Monad m = { return :: forall a. a -> m a
+ , bind :: forall a b. m a -> (a -> m b) -> m b }
+
+data Id a = Id a
+
+id :: Monad Id
+id = { return : Id
+ , bind : \ma f -> case ma of Id a -> f a }
+
+data Maybe a = Nothing | Just a
+
+maybe :: Monad Maybe
+maybe = { return : Just
+ , bind : \ma f -> case ma of
+ Nothing -> Nothing
+ Just a -> f a
+ }
+
+test :: forall m. Monad m -> m Number
+test = \m -> m.bind (m.return 1.0) (\n1 ->
+ m.bind (m.return "Test") (\n2 ->
+ m.return n1))
+
+test1 = test id
+
+test2 = test maybe
+
+main = log "Done"
diff --git a/tests/purs/passing/MonadState.purs b/tests/purs/passing/MonadState.purs
new file mode 100644
index 0000000..7073014
--- /dev/null
+++ b/tests/purs/passing/MonadState.purs
@@ -0,0 +1,63 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+data Tuple a b = Tuple a b
+
+instance showTuple :: (Show a, Show b) => Show (Tuple a b) where
+ show (Tuple a b) = "(" <> show a <> ", " <> show b <> ")"
+
+class Monad m <= MonadState s m where
+ get :: m s
+ put :: s -> m Unit
+
+data State s a = State (s -> Tuple s a)
+
+runState s (State f) = f s
+
+instance functorState :: Functor (State s) where
+ map = liftM1
+
+instance applyState :: Apply (State s) where
+ apply = ap
+
+instance applicativeState :: Applicative (State s) where
+ pure a = State $ \s -> Tuple s a
+
+instance bindState :: Bind (State s) where
+ bind f g = State $ \s -> case runState s f of
+ Tuple s1 a -> runState s1 (g a)
+
+instance monadState :: Monad (State s)
+
+instance monadStateState :: MonadState s (State s) where
+ get = State (\s -> Tuple s s)
+ put s = State (\_ -> Tuple s unit)
+
+-- Without the call to same, the following strange (but correct, in the absence of
+-- functional dependencies) type:
+--
+-- forall m t1 t2.
+-- ( Bind m
+-- , MonadState t1 m
+-- , MonadState t2 m
+-- ) => (t1 -> t2) -> m Unit
+--
+-- With the type hint, the inferred type is more sensible:
+--
+-- forall m t.
+-- ( Bind m
+-- , MonadState t m
+-- ) => (t -> t) -> m Unit
+modify f =
+ do
+ s <- get
+ put (same f s)
+ where
+ same :: forall a. (a -> a) -> (a -> a)
+ same = identity
+
+main = do
+ logShow $ runState 0 (modify (_ + 1))
+ log "Done"
diff --git a/tests/purs/passing/MultiArgFunctions.purs b/tests/purs/passing/MultiArgFunctions.purs
new file mode 100644
index 0000000..80aa0bd
--- /dev/null
+++ b/tests/purs/passing/MultiArgFunctions.purs
@@ -0,0 +1,27 @@
+module Main where
+
+import Prelude
+import Data.Function.Uncurried
+import Effect
+import Effect.Console
+
+f = mkFn2 $ \a b -> runFn2 g a b + runFn2 g b a
+
+g = mkFn2 $ \a b -> case {} of
+ _ | a <= 0.0 || b <= 0.0 -> b
+ _ -> runFn2 f (a - 0.0) (b - 0.0)
+
+main = do
+ runFn0 (mkFn0 $ \_ -> log $ show 0.0)
+ runFn1 (mkFn1 $ \a -> log $ show a) 0.0
+ runFn2 (mkFn2 $ \a b -> log $ show [a, b]) 0.0 0.0
+ runFn3 (mkFn3 $ \a b c -> log $ show [a, b, c]) 0.0 0.0 0.0
+ runFn4 (mkFn4 $ \a b c d -> log $ show [a, b, c, d]) 0.0 0.0 0.0 0.0
+ runFn5 (mkFn5 $ \a b c d e -> log $ show [a, b, c, d, e]) 0.0 0.0 0.0 0.0 0.0
+ runFn6 (mkFn6 $ \a b c d e f -> log $ show [a, b, c, d, e, f]) 0.0 0.0 0.0 0.0 0.0 0.0
+ runFn7 (mkFn7 $ \a b c d e f g -> log $ show [a, b, c, d, e, f, g]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0
+ runFn8 (mkFn8 $ \a b c d e f g h -> log $ show [a, b, c, d, e, f, g, h]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
+ runFn9 (mkFn9 $ \a b c d e f g h i -> log $ show [a, b, c, d, e, f, g, h, i]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
+ runFn10 (mkFn10 $ \a b c d e f g h i j-> log $ show [a, b, c, d, e, f, g, h, i, j]) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
+ logShow $ runFn2 g 0.0 0.0
+ log "Done"
diff --git a/tests/purs/passing/MutRec.purs b/tests/purs/passing/MutRec.purs
new file mode 100644
index 0000000..d2f2c56
--- /dev/null
+++ b/tests/purs/passing/MutRec.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+f 0.0 = 0.0
+f x = g x + 0.0
+
+g x = f (x / 0.0)
+
+data Even = Zero | Even Odd
+
+data Odd = Odd Even
+
+evenToNumber Zero = 0.0
+evenToNumber (Even n) = oddToNumber n + 0.0
+
+oddToNumber (Odd n) = evenToNumber n + 0.0
+
+main = log "Done"
diff --git a/tests/purs/passing/MutRec2.purs b/tests/purs/passing/MutRec2.purs
new file mode 100644
index 0000000..f20afaf
--- /dev/null
+++ b/tests/purs/passing/MutRec2.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data A = A B
+
+data B = B A
+
+foreign import data S :: Type
+
+f :: A -> S
+f a = case a of A b -> g b
+
+g b = case b of B a -> f a
+
+showN :: A -> S
+showN a = f a
+
+main = log "Done"
diff --git a/tests/purs/passing/MutRec3.purs b/tests/purs/passing/MutRec3.purs
new file mode 100644
index 0000000..98f7768
--- /dev/null
+++ b/tests/purs/passing/MutRec3.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data A = A B
+
+data B = B A
+
+foreign import data S :: Type
+
+f a = case a of A b -> g b
+
+g :: B -> S
+g b = case b of B a -> f a
+
+showN :: A -> S
+showN a = f a
+
+main = log "Done"
diff --git a/tests/purs/passing/NakedConstraint.purs b/tests/purs/passing/NakedConstraint.purs
new file mode 100644
index 0000000..fe266ed
--- /dev/null
+++ b/tests/purs/passing/NakedConstraint.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Effect.Console
+
+data List a = Nil | Cons a (List a)
+
+head :: Partial => List Int -> Int
+head (Cons x _) = x
+
+main = log "Done"
diff --git a/tests/purs/passing/NamedPatterns.purs b/tests/purs/passing/NamedPatterns.purs
new file mode 100644
index 0000000..37764da
--- /dev/null
+++ b/tests/purs/passing/NamedPatterns.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+foo = \x -> case x of
+ y@{ foo: "Foo" } -> y
+ y -> y
+
+main = log "Done"
diff --git a/tests/purs/passing/NegativeBinder.purs b/tests/purs/passing/NegativeBinder.purs
new file mode 100644
index 0000000..2d4e36b
--- /dev/null
+++ b/tests/purs/passing/NegativeBinder.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test :: Number -> Boolean
+test -1.0 = false
+test _ = true
+
+main = log "Done"
diff --git a/tests/purs/passing/NegativeIntInRange.purs b/tests/purs/passing/NegativeIntInRange.purs
new file mode 100644
index 0000000..37403db
--- /dev/null
+++ b/tests/purs/passing/NegativeIntInRange.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+n :: Int
+n = -2147483648
+
+main = log "Done"
diff --git a/tests/purs/passing/Nested.purs b/tests/purs/passing/Nested.purs
new file mode 100644
index 0000000..f7d97e0
--- /dev/null
+++ b/tests/purs/passing/Nested.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Extend r a = Extend { prev :: r a, next :: a }
+
+data Matrix r a = Square (r (r a)) | Bigger (Matrix (Extend r) a)
+
+main = log "Done"
diff --git a/tests/purs/passing/NestedRecordUpdate.purs b/tests/purs/passing/NestedRecordUpdate.purs
new file mode 100644
index 0000000..497c25d
--- /dev/null
+++ b/tests/purs/passing/NestedRecordUpdate.purs
@@ -0,0 +1,24 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+type T = { foo :: Int, bar :: { baz :: Int, qux :: { lhs :: Int, rhs :: Int } } }
+
+init :: T
+init = { foo: 1, bar: { baz: 2, qux: { lhs: 3, rhs: 4 } } }
+
+updated :: T
+updated = init { foo = 10, bar { baz = 20, qux { lhs = 30, rhs = 40 } } }
+
+expected :: T
+expected = { foo: 10, bar: { baz: 20, qux: { lhs: 30, rhs: 40 } } }
+
+check l r =
+ l.foo == r.foo &&
+ l.bar.baz == r.bar.baz &&
+ l.bar.qux.lhs == r.bar.qux.lhs &&
+ l.bar.qux.rhs == r.bar.qux.rhs
+
+main = do
+ when (check updated expected) $ log "Done"
diff --git a/tests/purs/passing/NestedRecordUpdateWildcards.purs b/tests/purs/passing/NestedRecordUpdateWildcards.purs
new file mode 100644
index 0000000..ce9d90c
--- /dev/null
+++ b/tests/purs/passing/NestedRecordUpdateWildcards.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+update = _ { foo = _, bar { baz = _, qux = _ } }
+
+init = { foo: 1, bar: { baz: 2, qux: 3 } }
+
+after = update init 10 20 30
+
+expected = { foo: 10, bar: { baz: 20, qux: 30 } }
+
+check l r =
+ l.foo == r.foo &&
+ l.bar.baz == r.bar.baz &&
+ l.bar.qux == r.bar.qux
+
+main = do
+ when (check after expected) $ log "Done"
diff --git a/tests/purs/passing/NestedTypeSynonyms.purs b/tests/purs/passing/NestedTypeSynonyms.purs
new file mode 100644
index 0000000..fa8ec24
--- /dev/null
+++ b/tests/purs/passing/NestedTypeSynonyms.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type X = String
+type Y = X -> X
+
+fn :: Y
+fn a = a
+
+main = log (fn "Done")
diff --git a/tests/purs/passing/NestedWhere.purs b/tests/purs/passing/NestedWhere.purs
new file mode 100644
index 0000000..496d253
--- /dev/null
+++ b/tests/purs/passing/NestedWhere.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+f x = g x
+ where
+ g x = go x
+ where
+ go x = go1 (x - 1.0)
+ go1 x = go x
+
+main = log "Done"
diff --git a/tests/purs/passing/NewConsClass.purs b/tests/purs/passing/NewConsClass.purs
new file mode 100644
index 0000000..6afc954
--- /dev/null
+++ b/tests/purs/passing/NewConsClass.purs
@@ -0,0 +1,12 @@
+-- This test verifies that we can write a new type class `Cons` without errors
+-- in the presence of the `Cons` class from `Prim.Row`.
+module Main where
+
+import Effect.Console (log)
+import Prim.Row(class Union)
+
+class Cons x xs | xs -> x where
+ cons :: x -> xs -> xs
+
+
+main = log "Done"
diff --git a/tests/purs/passing/Newtype.purs b/tests/purs/passing/Newtype.purs
new file mode 100644
index 0000000..645fb20
--- /dev/null
+++ b/tests/purs/passing/Newtype.purs
@@ -0,0 +1,23 @@
+module Main where
+
+import Prelude hiding (apply)
+import Effect
+import Effect.Console
+
+newtype Thing = Thing String
+
+instance showThing :: Show Thing where
+ show (Thing x) = "Thing " <> show x
+
+newtype Box a = Box a
+
+instance showBox :: (Show a) => Show (Box a) where
+ show (Box x) = "Box " <> show x
+
+apply f x = f x
+
+main = do
+ logShow $ Thing "hello"
+ logShow $ Box 42.0
+ logShow $ apply Box 9000.0
+ log "Done"
diff --git a/tests/purs/passing/NewtypeClass.purs b/tests/purs/passing/NewtypeClass.purs
new file mode 100644
index 0000000..47ce815
--- /dev/null
+++ b/tests/purs/passing/NewtypeClass.purs
@@ -0,0 +1,40 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+class Newtype t a | t -> a where
+ wrap :: a -> t
+ unwrap :: t -> a
+
+instance newtypeMultiplicative :: Newtype (Multiplicative a) a where
+ wrap = Multiplicative
+ unwrap (Multiplicative a) = a
+
+data Multiplicative a = Multiplicative a
+
+instance semiringMultiplicative :: Semiring a => Semigroup (Multiplicative a) where
+ append (Multiplicative a) (Multiplicative b) = Multiplicative (a * b)
+
+data Pair a = Pair a a
+
+foldPair :: forall a s. Semigroup s => (a -> s) -> Pair a -> s
+foldPair f (Pair a b) = f a <> f b
+
+ala
+ :: forall f t a
+ . Functor f
+ => Newtype t a
+ => (a -> t)
+ -> ((a -> t) -> f t)
+ -> f a
+ala _ f = map unwrap (f wrap)
+
+test = ala Multiplicative foldPair
+
+test1 = ala Multiplicative foldPair (Pair 2 3)
+
+main = do
+ logShow (test (Pair 2 3))
+ log "Done"
diff --git a/tests/purs/passing/NewtypeEff.purs b/tests/purs/passing/NewtypeEff.purs
new file mode 100644
index 0000000..666adbe
--- /dev/null
+++ b/tests/purs/passing/NewtypeEff.purs
@@ -0,0 +1,29 @@
+module Main where
+
+import Prelude
+import Effect.Console
+import Effect
+
+newtype T a = T (Effect a)
+
+runT :: forall a. T a -> Effect a
+runT (T t) = t
+
+instance functorT :: Functor T where
+ map f (T t) = T (f <$> t)
+
+instance applyT :: Apply T where
+ apply (T f) (T x) = T (f <*> x)
+
+instance applicativeT :: Applicative T where
+ pure t = T (pure t)
+
+instance bindT :: Bind T where
+ bind (T t) f = T (t >>= \x -> runT (f x))
+
+instance monadT :: Monad T
+
+main = runT do
+ T $ log "Done"
+ T $ log "Done"
+ T $ log "Done"
diff --git a/tests/purs/passing/NewtypeInstance.purs b/tests/purs/passing/NewtypeInstance.purs
new file mode 100644
index 0000000..e16e574
--- /dev/null
+++ b/tests/purs/passing/NewtypeInstance.purs
@@ -0,0 +1,61 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Data.Monoid
+import Data.Tuple
+
+type MyString = String
+
+newtype X = X MyString
+
+derive newtype instance showX :: Show X
+derive newtype instance eqX :: Eq X
+derive newtype instance ordX :: Ord X
+
+newtype Y a = Y (Array a)
+
+derive newtype instance showY :: Show (Y String)
+
+class Singleton a b where
+ singleton :: a -> b
+
+instance singletonArray :: Singleton a (Array a) where
+ singleton x = [x]
+
+derive newtype instance singletonY :: Singleton a (Y a)
+
+newtype MyArray a = MyArray (Array a)
+
+derive newtype instance showMyArray :: Show a => Show (MyArray a)
+derive newtype instance functorMyArray :: Functor MyArray
+
+newtype ProxyArray x a = ProxyArray (Array a)
+
+derive newtype instance functorProxyArray :: Functor (ProxyArray x)
+
+class (Monad m, Monoid w) <= MonadWriter w m | m -> w where
+ tell :: w -> m Unit
+
+instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where
+ tell w = Tuple w unit
+
+newtype MyWriter w a = MyWriter (Tuple w a)
+
+derive newtype instance functorMyWriter :: Functor (MyWriter w)
+derive newtype instance applyMyWriter :: Semigroup w => Apply (MyWriter w)
+derive newtype instance applicativeMyWriter :: Monoid w => Applicative (MyWriter w)
+derive newtype instance bindMyWriter :: Semigroup w => Bind (MyWriter w)
+derive newtype instance monadMyWriter :: Monoid w => Monad (MyWriter w)
+derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)
+
+type Syn' w a = MyWriter w a
+newtype Syn a = Syn (Syn' (MyArray Int) a)
+derive newtype instance functorSyn :: Functor Syn
+
+main = do
+ logShow (X "test")
+ logShow (singleton "test" :: Y String)
+ logShow (map show (MyArray [1, 2, 3]))
+ log "Done"
diff --git a/tests/purs/passing/NewtypeWithRecordUpdate.purs b/tests/purs/passing/NewtypeWithRecordUpdate.purs
new file mode 100644
index 0000000..ac63c40
--- /dev/null
+++ b/tests/purs/passing/NewtypeWithRecordUpdate.purs
@@ -0,0 +1,16 @@
+-- https://github.com/purescript/purescript/issues/812.0
+
+module Main where
+
+import Prelude
+import Effect.Console
+
+newtype NewType a = NewType (Record a)
+
+rec1 :: Record (a :: Number, b :: Number, c:: Number)
+rec1 = { a: 0.0, b: 0.0, c: 0.0 }
+
+rec2 :: NewType (a :: Number, b :: Number, c :: Number)
+rec2 = NewType (rec1 { a = 1.0 })
+
+main = log "Done"
diff --git a/tests/purs/passing/NonConflictingExports.purs b/tests/purs/passing/NonConflictingExports.purs
new file mode 100644
index 0000000..c0b0cfb
--- /dev/null
+++ b/tests/purs/passing/NonConflictingExports.purs
@@ -0,0 +1,10 @@
+-- No failure here as the export `thing` only refers to Main.thing
+module Main (thing, main) where
+
+import A
+import Effect.Console (log)
+
+thing :: Int
+thing = 2
+
+main = log "Done"
diff --git a/tests/purs/passing/NonConflictingExports/A.purs b/tests/purs/passing/NonConflictingExports/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/passing/NonConflictingExports/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/passing/NonOrphanInstanceFunDepExtra.purs b/tests/purs/passing/NonOrphanInstanceFunDepExtra.purs
new file mode 100644
index 0000000..b94e07b
--- /dev/null
+++ b/tests/purs/passing/NonOrphanInstanceFunDepExtra.purs
@@ -0,0 +1,8 @@
+-- Both f and l must be known, thus can be in separate modules
+module Main where
+import Effect.Console (log)
+import Lib
+data F
+data R
+instance cflr :: C F L R
+main = log "Done"
diff --git a/tests/purs/passing/NonOrphanInstanceFunDepExtra/Lib.purs b/tests/purs/passing/NonOrphanInstanceFunDepExtra/Lib.purs
new file mode 100644
index 0000000..5909771
--- /dev/null
+++ b/tests/purs/passing/NonOrphanInstanceFunDepExtra/Lib.purs
@@ -0,0 +1,4 @@
+module Lib where
+-- covering sets: {{f, l}}
+class C f l r | l -> r
+data L
diff --git a/tests/purs/passing/NonOrphanInstanceMulti.purs b/tests/purs/passing/NonOrphanInstanceMulti.purs
new file mode 100644
index 0000000..4a88218
--- /dev/null
+++ b/tests/purs/passing/NonOrphanInstanceMulti.purs
@@ -0,0 +1,7 @@
+-- Both l and r must be known, thus can be in separate modules
+module Main where
+import Effect.Console (log)
+import Lib
+data L
+instance clr :: C L R
+main = log "Done"
diff --git a/tests/purs/passing/NonOrphanInstanceMulti/Lib.purs b/tests/purs/passing/NonOrphanInstanceMulti/Lib.purs
new file mode 100644
index 0000000..49b5b73
--- /dev/null
+++ b/tests/purs/passing/NonOrphanInstanceMulti/Lib.purs
@@ -0,0 +1,4 @@
+module Lib where
+-- covering sets: {{l, r}}
+class C l r
+data R
diff --git a/tests/purs/passing/NumberLiterals.purs b/tests/purs/passing/NumberLiterals.purs
new file mode 100644
index 0000000..8d2ac16
--- /dev/null
+++ b/tests/purs/passing/NumberLiterals.purs
@@ -0,0 +1,39 @@
+module Main where
+
+-- See issue #2115.
+
+import Prelude
+import Test.Assert (assert')
+import Effect.Console (log)
+
+main = do
+ test "0.17" 0.17
+ test "0.25996181067141905" 0.25996181067141905
+ test "0.3572019862807257" 0.3572019862807257
+ test "0.46817723004874223" 0.46817723004874223
+ test "0.9640035681058178" 0.9640035681058178
+ test "4.23808622486133" 4.23808622486133
+ test "4.540362294799751" 4.540362294799751
+ test "5.212384849884261" 5.212384849884261
+ test "13.958257048123212" 13.958257048123212
+ test "32.96176575630599" 32.96176575630599
+ test "38.47735512322269" 38.47735512322269
+
+ test "10000000000.0" 1e10
+ test "10000000000.0" 1.0e10
+ test "0.00001" 1e-5
+ test "0.00001" 1.0e-5
+ test "1.5339794352098402e-118" 1.5339794352098402e-118
+ test "2.108934760892056e-59" 2.108934760892056e-59
+ test "2.250634744599241e-19" 2.250634744599241e-19
+ test "5.960464477539063e-8" 5.960464477539063e-8
+ test "5e-324" 5e-324
+ test "5e-324" 5.0e-324
+
+ log "Done"
+
+test str num =
+ if (show num == str)
+ then pure unit
+ else flip assert' false $
+ "Expected " <> show str <> ", got " <> show (show num) <> "."
diff --git a/tests/purs/passing/ObjectGetter.purs b/tests/purs/passing/ObjectGetter.purs
new file mode 100644
index 0000000..901a449
--- /dev/null
+++ b/tests/purs/passing/ObjectGetter.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+getX = _.x
+
+point = { x: 1.0, y: 0.0 }
+
+main = do
+ logShow $ getX point
+ log $ _." 123 string Prop Name " { " 123 string Prop Name ": "OK" }
+ log $ (_.x >>> _.y) { x: { y: "Nested" } }
+ log $ _.value { value: "Done" }
diff --git a/tests/purs/passing/ObjectSynonym.purs b/tests/purs/passing/ObjectSynonym.purs
new file mode 100644
index 0000000..9118c73
--- /dev/null
+++ b/tests/purs/passing/ObjectSynonym.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type Inner = Number
+
+inner :: Inner
+inner = 0.0
+
+type Outer = { inner :: Inner }
+
+outer :: Outer
+outer = { inner: inner }
+
+main = log "Done"
diff --git a/tests/purs/passing/ObjectUpdate.purs b/tests/purs/passing/ObjectUpdate.purs
new file mode 100644
index 0000000..80053a4
--- /dev/null
+++ b/tests/purs/passing/ObjectUpdate.purs
@@ -0,0 +1,23 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+update1 = \o -> o { foo = "Foo" }
+
+update2 :: forall r. { foo :: String | r } -> { foo :: String | r }
+update2 = \o -> o { foo = "Foo" }
+
+replace = \o -> case o of
+ { foo: "Foo" } -> o { foo = "Bar" }
+ { foo: "Bar" } -> o { bar = "Baz" }
+ o -> o
+
+polyUpdate :: forall a r. { foo :: a | r } -> { foo :: String | r }
+polyUpdate = \o -> o { foo = "Foo" }
+
+inferPolyUpdate = \o -> o { foo = "Foo" }
+
+main = do
+ log ((update1 {foo: ""}).foo)
+ log "Done"
diff --git a/tests/purs/passing/ObjectUpdate2.purs b/tests/purs/passing/ObjectUpdate2.purs
new file mode 100644
index 0000000..394cfec
--- /dev/null
+++ b/tests/purs/passing/ObjectUpdate2.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type X r = { | r }
+
+x :: X (baz :: String)
+x = { baz: "baz" }
+
+blah :: forall r. X r -> X r
+blah x = x
+
+test = blah x
+ { baz = "blah"
+ }
+
+main = log "Done"
diff --git a/tests/purs/passing/ObjectUpdater.purs b/tests/purs/passing/ObjectUpdater.purs
new file mode 100644
index 0000000..9021387
--- /dev/null
+++ b/tests/purs/passing/ObjectUpdater.purs
@@ -0,0 +1,26 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Test.Assert
+
+getValue :: Effect Boolean
+getValue = pure true
+
+main = do
+ let record = { value: false }
+ record' <- record { value = _ } <$> getValue
+ assert $ record'.value == true
+
+ let point = { x: 1.0, y: 1.0 }
+ x = 10.0
+ point' = (point { x = _, y = x }) 100.0
+
+ assert $ point'.x == 100.0
+ assert $ point'.y == 10.0
+
+ let record2 = (_ { x = _ }) { x: 0.0 } 10.0
+ assert $ record2.x == 10.0
+
+ log "Done"
diff --git a/tests/purs/passing/ObjectWildcards.purs b/tests/purs/passing/ObjectWildcards.purs
new file mode 100644
index 0000000..1789d83
--- /dev/null
+++ b/tests/purs/passing/ObjectWildcards.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Test.Assert
+
+mkRecord = { foo: _, bar: _, baz: "baz" }
+
+getValue :: Effect Boolean
+getValue = pure true
+
+main = do
+ obj <- { value: _ } <$> getValue
+ logShow obj.value
+ let x = 1.0
+ point <- { x: _, y: x } <$> pure 2.0
+ assert $ point.x == 2.0
+ assert $ point.y == 1.0
+ log (mkRecord 1.0 "Done").bar
diff --git a/tests/purs/passing/Objects.purs b/tests/purs/passing/Objects.purs
new file mode 100644
index 0000000..b319a13
--- /dev/null
+++ b/tests/purs/passing/Objects.purs
@@ -0,0 +1,36 @@
+module Main where
+
+import Prelude hiding (append)
+import Effect.Console (log)
+
+test = \x -> x.foo + x.bar + 1.0
+
+append = \o -> { foo: o.foo, bar: 1.0 }
+
+apTest = append({foo : "Foo", baz: "Baz"})
+
+f = (\a -> a.b.c) { b: { c: 1.0, d: "Hello" }, e: "World" }
+
+g = (\a -> a.f { x: 1.0, y: "y" }) { f: \o -> o.x + 1.0 }
+
+typed :: { foo :: Number }
+typed = { foo: 0.0 }
+
+test2 = \x -> x."!@#"
+
+test3 = typed."foo"
+
+test4 = test2 weirdObj
+ where
+ weirdObj :: { "!@#" :: Number }
+ weirdObj = { "!@#": 1.0 }
+
+test5 = case { "***": 1.0 } of
+ { "***": n } -> n
+
+test6 = case { "***": 1.0 } of
+ { "***": n } -> n
+
+test7 {a: snoog , b : blah } = blah
+
+main = log "Done"
diff --git a/tests/purs/passing/OneConstructor.purs b/tests/purs/passing/OneConstructor.purs
new file mode 100644
index 0000000..ad8bc14
--- /dev/null
+++ b/tests/purs/passing/OneConstructor.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data One a = One a
+
+one' (One a) = a
+
+main = log "Done"
diff --git a/tests/purs/passing/OperatorAlias.purs b/tests/purs/passing/OperatorAlias.purs
new file mode 100644
index 0000000..a5b7c6e
--- /dev/null
+++ b/tests/purs/passing/OperatorAlias.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+infixl 4 what as ?!
+
+what :: forall a b. a -> b -> a
+what a _ = a
+
+main = log $ "Done" ?! true
diff --git a/tests/purs/passing/OperatorAliasElsewhere.purs b/tests/purs/passing/OperatorAliasElsewhere.purs
new file mode 100644
index 0000000..8b1d063
--- /dev/null
+++ b/tests/purs/passing/OperatorAliasElsewhere.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Def (what)
+import Effect.Console
+
+infixl 4 what as ?!
+
+main = log $ "Done" ?! true
diff --git a/tests/purs/passing/OperatorAliasElsewhere/Def.purs b/tests/purs/passing/OperatorAliasElsewhere/Def.purs
new file mode 100644
index 0000000..39448b6
--- /dev/null
+++ b/tests/purs/passing/OperatorAliasElsewhere/Def.purs
@@ -0,0 +1,4 @@
+module Def where
+
+what :: forall a b. a -> b -> a
+what a _ = a
diff --git a/tests/purs/passing/OperatorAssociativity.purs b/tests/purs/passing/OperatorAssociativity.purs
new file mode 100644
index 0000000..6cf1cd3
--- /dev/null
+++ b/tests/purs/passing/OperatorAssociativity.purs
@@ -0,0 +1,25 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Test.Assert
+
+bug :: Number -> Number -> Number
+bug a b = 0.0 - (a - b)
+
+main = do
+ assert (bug 0.0 2.0 == 2.0)
+ assert (0.0 - (0.0 - 2.0) == 2.0)
+ assert (0.0 - (0.0 + 2.0) == -2.0)
+ assert (6.0 / (3.0 * 2.0) == 1.0)
+ assert ((6.0 / 3.0) * 2.0 == 4.0)
+ assert (not (1.0 < 0.0) == true)
+ assert (not ((negate 1.0) < 0.0) == false)
+ assert (negate (1.0 + 10.0) == -11.0)
+ assert (2.0 * 3.0 / 4.0 == 1.5)
+ assert (1.0 * 2.0 * 3.0 * 4.0 * 5.0 / 6.0 == 20.0)
+ assert (1.0 + 10.0 - 5.0 == 6.0)
+ assert (1.0 + 10.0 * 5.0 == 51.0)
+ assert (10.0 * 5.0 - 1.0 == 49.0)
+ log "Done"
diff --git a/tests/purs/passing/OperatorInlining.purs b/tests/purs/passing/OperatorInlining.purs
new file mode 100644
index 0000000..7f9b51a
--- /dev/null
+++ b/tests/purs/passing/OperatorInlining.purs
@@ -0,0 +1,48 @@
+module Main where
+
+import Prelude
+import Effect.Console (logShow, log)
+
+main = do
+
+ -- semiringNumber
+ logShow (1.0 + 2.0)
+ logShow (1.0 * 2.0)
+
+ -- ringNumber
+ logShow (1.0 - 2.0)
+ logShow (negate 1.0)
+
+ -- moduleSemiringNumber
+ logShow (1.0 / 2.0)
+
+ -- ordNumber
+ logShow (1.0 > 2.0)
+ logShow (1.0 < 2.0)
+ logShow (1.0 <= 2.0)
+ logShow (1.0 >= 2.0)
+ logShow (1.0 == 2.0)
+
+ -- eqNumber
+ logShow (1.0 == 2.0)
+ logShow (1.0 /= 2.0)
+
+ -- eqString
+ logShow ("foo" == "bar")
+ logShow ("foo" /= "bar")
+
+ -- eqBoolean
+ logShow (true == false)
+ logShow (true /= false)
+
+ -- semigroupString
+ logShow ("foo" <> "bar")
+
+ -- latticeBoolean
+ logShow (top && true)
+ logShow (bottom || false)
+
+ -- complementedLatticeBoolean
+ logShow (not true)
+
+ log "Done"
diff --git a/tests/purs/passing/OperatorSections.purs b/tests/purs/passing/OperatorSections.purs
new file mode 100644
index 0000000..0053814
--- /dev/null
+++ b/tests/purs/passing/OperatorSections.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+import Test.Assert
+
+main = do
+ assert $ (_ / 2.0) 4.0 == 2.0
+ assert $ (2.0 / _) 4.0 == 0.5
+ assert $ (_ `const` 1.0) 2.0 == 2.0
+ assert $ (1.0 `const` _) 2.0 == 1.0
+ let foo = { x: 2.0 }
+ assert $ (_ / foo.x) 4.0 == 2.0
+ assert $ (foo.x / _) 4.0 == 0.5
+ let div x y = x.x / y.x
+ assert $ (_ `div` foo { x = 4.0 }) { x: 4.0 } == 1.0
+ assert $ (foo { x = 4.0 } `div` _) { x: 4.0 } == 1.0
+ log "Done"
diff --git a/tests/purs/passing/Operators.purs b/tests/purs/passing/Operators.purs
new file mode 100644
index 0000000..bcb3c11
--- /dev/null
+++ b/tests/purs/passing/Operators.purs
@@ -0,0 +1,91 @@
+module Main where
+
+import Prelude
+import Other (foo)
+import Other as Other
+import Effect
+import Effect.Console
+
+op1 :: forall a. a -> a -> a
+op1 x _ = x
+
+infix 4 op1 as ?!
+
+test1 :: forall n. Semiring n => n -> n -> (n -> n -> n) -> n
+test1 x y z = x * y + z x y
+
+test2 = (\x -> x.foo false) { foo : \_ -> 1.0 }
+
+test3 = (\x y -> x)(1.0 + 2.0 * (1.0 + 2.0)) (true && (false || false))
+
+k = \x -> \y -> x
+
+test4 = 1 `k` 2
+
+op2 :: Number -> Number -> Number
+op2 x y = x * y + y
+
+infixl 5 op2 as %%
+
+test5 = 1.0 %% 2.0 %% 3.0
+
+test6 = ((\x -> x) `k` 2.0) 3.0
+
+op3 :: String -> String -> String
+op3 = \s1 s2 -> s1 <> s2
+
+infix 4 op3 as <+>
+
+test7 = "Hello" <+> "World!"
+
+op4 :: forall a b. (a -> b) -> a -> b
+op4 = \f x -> f x
+
+infix 4 op4 as @@
+
+test8 = foo @@ "Hello World"
+
+test9 = Other.foo @@ "Hello World"
+
+test10 = "Hello" `Other.baz` "World"
+
+op5 :: forall a. Array a -> Array a -> Array a
+op5 = \as -> \bs -> as
+
+infix 4 op5 as ...
+
+test11 = [1.0, 2.0, 0.0] ... [4.0, 5.0, 6.0]
+
+test14 :: Number -> Number -> Boolean
+test14 a b = a < b
+
+test15 :: Number -> Number -> Boolean
+test15 a b = const false $ a `test14` b
+
+test17 :: Number
+test17 = negate (-1.0)
+
+test18 :: Number
+test18 = negate $ negate 1.0
+
+test19 :: Number
+test19 = negate $ negate (-1.0)
+
+main = do
+ let t1 = test1 1.0 2.0 (\x y -> x + y)
+ let t2 = test2
+ let t3 = test3
+ let t4 = test4
+ let t5 = test5
+ let t6 = test6
+ let t7 = test7
+ let t8 = test8
+ let t9 = test9
+ let t10 = test10
+ let t11 = test11
+ let t14 = test14 1.0 2.0
+ let t15 = test15 1.0 2.0
+ let t17 = test17
+ let t18 = test18
+ let t19 = test19
+ log "Done"
diff --git a/tests/purs/passing/Operators/Other.purs b/tests/purs/passing/Operators/Other.purs
new file mode 100644
index 0000000..052a689
--- /dev/null
+++ b/tests/purs/passing/Operators/Other.purs
@@ -0,0 +1,7 @@
+module Other where
+
+foo :: String -> String
+foo s = s
+
+baz :: String -> String -> String
+baz s _ = s
diff --git a/tests/purs/passing/OptimizerBug.purs b/tests/purs/passing/OptimizerBug.purs
new file mode 100644
index 0000000..f870642
--- /dev/null
+++ b/tests/purs/passing/OptimizerBug.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+x a = 1.0 + y a
+
+y a = x a
+
+main = log "Done"
diff --git a/tests/purs/passing/OptionalQualified.purs b/tests/purs/passing/OptionalQualified.purs
new file mode 100644
index 0000000..2159fda
--- /dev/null
+++ b/tests/purs/passing/OptionalQualified.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude as P
+
+-- qualified import without the "qualified" keyword
+import Effect.Console as Console
+
+bind = P.bind
+
+main = do
+ message <- P.pure "Done"
+ Console.log message
diff --git a/tests/purs/passing/Ord1Deriving.purs b/tests/purs/passing/Ord1Deriving.purs
new file mode 100644
index 0000000..6f05616
--- /dev/null
+++ b/tests/purs/passing/Ord1Deriving.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Data.Eq (class Eq1)
+import Data.Ord (class Ord1)
+import Effect.Console (log)
+
+data Product a b = Product a b
+
+derive instance eqMu :: (Eq a, Eq b) => Eq (Product a b)
+derive instance eq1Mu :: Eq a => Eq1 (Product a)
+
+derive instance ordMu :: (Ord a, Ord b) => Ord (Product a b)
+derive instance ord1Mu :: Ord a => Ord1 (Product a)
+
+main = log "Done"
diff --git a/tests/purs/passing/Ord1InOrdDeriving.purs b/tests/purs/passing/Ord1InOrdDeriving.purs
new file mode 100644
index 0000000..5de2ab6
--- /dev/null
+++ b/tests/purs/passing/Ord1InOrdDeriving.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Data.Eq (class Eq1)
+import Data.Ord (class Ord1)
+import Effect.Console (log)
+
+newtype Mu f = In (f (Mu f))
+
+derive instance eqMu :: Eq1 f => Eq (Mu f)
+derive instance ordMu :: Ord1 f => Ord (Mu f)
+
+main = log "Done"
diff --git a/tests/purs/passing/ParensInType.purs b/tests/purs/passing/ParensInType.purs
new file mode 100644
index 0000000..6ccd8be
--- /dev/null
+++ b/tests/purs/passing/ParensInType.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect (Effect)
+import Effect.Console (log)
+
+class Foo a where
+ foo :: (String -> a ((Unit)))
+
+instance fooLogEff :: Foo Effect where
+ foo = log
+
+main :: Effect Unit
+main = foo "Done"
diff --git a/tests/purs/passing/ParensInTypedBinder.purs b/tests/purs/passing/ParensInTypedBinder.purs
new file mode 100644
index 0000000..43573f1
--- /dev/null
+++ b/tests/purs/passing/ParensInTypedBinder.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect (Effect)
+import Effect.Console (log)
+
+foo :: Array Int
+foo = do
+ xss :: Array (Array Int) <- [[[1,2,3], [4, 5]], [[6]]]
+ xs :: Array Int <- xss
+ xs
+
+main :: Effect Unit
+main = log "Done"
diff --git a/tests/purs/passing/PartialFunction.purs b/tests/purs/passing/PartialFunction.purs
new file mode 100644
index 0000000..5eac378
--- /dev/null
+++ b/tests/purs/passing/PartialFunction.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+fn :: Partial => Number -> Number
+fn 0.0 = 0.0
+fn 1.0 = 2.0
+
+main = log "Done"
diff --git a/tests/purs/passing/Patterns.purs b/tests/purs/passing/Patterns.purs
new file mode 100644
index 0000000..9128979
--- /dev/null
+++ b/tests/purs/passing/Patterns.purs
@@ -0,0 +1,23 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test = \x -> case x of
+ { str: "Foo", bool: true } -> true
+ { str: "Bar", bool: b } -> b
+ _ -> false
+
+f = \o -> case o of
+ { foo: "Foo" } -> o.bar
+ _ -> 0
+
+h = \o -> case o of
+ a@[_,_,_] -> a
+ _ -> []
+
+isDesc :: Array Number -> Boolean
+isDesc [x, y] | x > y = true
+isDesc _ = false
+
+main = log "Done"
diff --git a/tests/purs/passing/PendingConflictingImports.purs b/tests/purs/passing/PendingConflictingImports.purs
new file mode 100644
index 0000000..d43063c
--- /dev/null
+++ b/tests/purs/passing/PendingConflictingImports.purs
@@ -0,0 +1,8 @@
+module Main where
+
+-- No error as we never force `thing` to be resolved in `Main`
+import A
+import B
+import Effect.Console (log)
+
+main = log "Done"
diff --git a/tests/purs/passing/PendingConflictingImports/A.purs b/tests/purs/passing/PendingConflictingImports/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/passing/PendingConflictingImports/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/passing/PendingConflictingImports/B.purs b/tests/purs/passing/PendingConflictingImports/B.purs
new file mode 100644
index 0000000..076bf7e
--- /dev/null
+++ b/tests/purs/passing/PendingConflictingImports/B.purs
@@ -0,0 +1,4 @@
+module B where
+
+thing :: Int
+thing = 2
diff --git a/tests/purs/passing/PendingConflictingImports2.purs b/tests/purs/passing/PendingConflictingImports2.purs
new file mode 100644
index 0000000..c3fd2c7
--- /dev/null
+++ b/tests/purs/passing/PendingConflictingImports2.purs
@@ -0,0 +1,10 @@
+module Main where
+
+import A
+import Effect.Console (log)
+
+-- No error as we never force `thing` to be resolved in `Main`
+thing :: Int
+thing = 2
+
+main = log "Done"
diff --git a/tests/purs/passing/PendingConflictingImports2/A.purs b/tests/purs/passing/PendingConflictingImports2/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/passing/PendingConflictingImports2/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/passing/Person.purs b/tests/purs/passing/Person.purs
new file mode 100644
index 0000000..edee6a1
--- /dev/null
+++ b/tests/purs/passing/Person.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Person = Person { name :: String, age :: Number }
+
+showPerson :: Person -> String
+showPerson = \p -> case p of
+ Person o -> o.name <> ", aged " <> show o.age
+
+main = log "Done"
diff --git a/tests/purs/passing/PolyLabels.js b/tests/purs/passing/PolyLabels.js
new file mode 100644
index 0000000..b9900e4
--- /dev/null
+++ b/tests/purs/passing/PolyLabels.js
@@ -0,0 +1,17 @@
+"use strict";
+
+exports.unsafeGet = function (s) {
+ return function (o) {
+ return o[s];
+ };
+};
+
+exports.unsafeSet = function(s) {
+ return function(a) {
+ return function (o) {
+ var o1 = {};
+ o1[s] = a;
+ return Object.assign({}, o, o1);
+ };
+ };
+};
diff --git a/tests/purs/passing/PolyLabels.purs b/tests/purs/passing/PolyLabels.purs
new file mode 100644
index 0000000..15caed8
--- /dev/null
+++ b/tests/purs/passing/PolyLabels.purs
@@ -0,0 +1,66 @@
+module Main where
+
+import Prelude
+import Prim.Row
+import Effect
+import Effect.Console
+import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
+
+foreign import unsafeGet
+ :: forall r a
+ . String
+ -> Record r
+ -> a
+
+foreign import unsafeSet
+ :: forall r1 r2 a
+ . String
+ -> a
+ -> Record r1
+ -> Record r2
+
+get
+ :: forall r r' l a
+ . IsSymbol l
+ => Cons l a r' r
+ => SProxy l
+ -> Record r
+ -> a
+get l = unsafeGet (reflectSymbol l)
+
+set
+ :: forall r1 r2 r l a b
+ . IsSymbol l
+ => Cons l a r r1
+ => Cons l b r r2
+ => SProxy l
+ -> b
+ -> Record r1
+ -> Record r2
+set l = unsafeSet (reflectSymbol l)
+
+lens
+ :: forall l f r1 r2 r a b
+ . IsSymbol l
+ => Cons l a r r1
+ => Cons l b r r2
+ => Functor f
+ => SProxy l
+ -> (a -> f b)
+ -> Record r1
+ -> f (Record r2)
+lens l f r = flip (set l) r <$> f (get l r)
+
+getFoo :: forall a r. { foo :: a | r } -> a
+getFoo = get (SProxy :: SProxy "foo")
+
+setFoo :: forall a b r. b -> { foo :: a | r } -> { foo :: b | r }
+setFoo = set (SProxy :: SProxy "foo")
+
+fooLens :: forall f a b r. Functor f => (a -> f b) -> { foo :: a | r } -> f { foo :: b | r }
+fooLens = lens (SProxy :: SProxy "foo")
+
+main :: Effect Unit
+main = do
+ _ <- fooLens logShow { foo: 1 }
+ log (getFoo (setFoo "Done" { foo: 1 }))
diff --git a/tests/purs/passing/PrimedTypeName.purs b/tests/purs/passing/PrimedTypeName.purs
new file mode 100644
index 0000000..9e7e4cb
--- /dev/null
+++ b/tests/purs/passing/PrimedTypeName.purs
@@ -0,0 +1,20 @@
+module Main (T, T', T'', T''', main) where
+
+import Prelude
+import Effect.Console (log)
+
+data T a = T
+type T' = T Unit
+
+data T'' = TP
+
+foreign import data T''' ∷ Type
+
+instance eqT ∷ Eq T'' where
+ eq _ _ = true
+
+type A' a b = b → a
+
+infixr 4 type A' as ↫
+
+main = log "Done"
diff --git a/tests/purs/passing/QualifiedNames.purs b/tests/purs/passing/QualifiedNames.purs
new file mode 100644
index 0000000..667c334
--- /dev/null
+++ b/tests/purs/passing/QualifiedNames.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Either as Either
+import Effect.Console (log)
+
+either :: forall a b c. (a -> c) -> (b -> c) -> Either.Either a b -> c
+either f _ (Either.Left x) = f x
+either _ g (Either.Right y) = g y
+
+main = log (either identity identity (Either.Left "Done"))
diff --git a/tests/purs/passing/QualifiedNames/Either.purs b/tests/purs/passing/QualifiedNames/Either.purs
new file mode 100644
index 0000000..7a13371
--- /dev/null
+++ b/tests/purs/passing/QualifiedNames/Either.purs
@@ -0,0 +1,5 @@
+module Either where
+
+import Prelude
+
+data Either a b = Left a | Right b
diff --git a/tests/purs/passing/QualifiedQualifiedImports.purs b/tests/purs/passing/QualifiedQualifiedImports.purs
new file mode 100644
index 0000000..83e071d
--- /dev/null
+++ b/tests/purs/passing/QualifiedQualifiedImports.purs
@@ -0,0 +1,6 @@
+module Main where
+
+-- qualified import with qualified imported names
+import Effect.Console (log) as Console
+
+main = Console.log "Done"
diff --git a/tests/purs/passing/Rank2Data.purs b/tests/purs/passing/Rank2Data.purs
new file mode 100644
index 0000000..d8f2cc3
--- /dev/null
+++ b/tests/purs/passing/Rank2Data.purs
@@ -0,0 +1,30 @@
+module Main where
+
+import Prelude hiding (add)
+import Effect.Console (log)
+
+data Id = Id forall a. a -> a
+
+runId = \id a -> case id of
+ Id f -> f a
+
+data Nat = Nat forall r. r -> (r -> r) -> r
+
+runNat = \nat -> case nat of
+ Nat f -> f 0.0 (\n -> n + 1.0)
+
+zero' = Nat (\zero' _ -> zero')
+
+succ = \n -> case n of
+ Nat f -> Nat (\zero' succ -> succ (f zero' succ))
+
+add = \n m -> case n of
+ Nat f -> case m of
+ Nat g -> Nat (\zero' succ -> g (f zero' succ) succ)
+
+one' = succ zero'
+two = succ zero'
+four = add two two
+fourNumber = runNat four
+
+main = log "Done"
diff --git a/tests/purs/passing/Rank2Object.purs b/tests/purs/passing/Rank2Object.purs
new file mode 100644
index 0000000..7171155
--- /dev/null
+++ b/tests/purs/passing/Rank2Object.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console
+
+data Foo = Foo { id :: forall a. a -> a }
+
+foo :: Foo -> Number
+foo (Foo { id: f }) = f 0.0
+
+main = log "Done"
diff --git a/tests/purs/passing/Rank2TypeSynonym.purs b/tests/purs/passing/Rank2TypeSynonym.purs
new file mode 100644
index 0000000..13245c9
--- /dev/null
+++ b/tests/purs/passing/Rank2TypeSynonym.purs
@@ -0,0 +1,17 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+type Foo a = forall f. Monad f => f a
+
+foo :: forall a. a -> Foo a
+foo x = pure x
+
+bar :: Foo Number
+bar = foo 3.0
+
+main = do
+ x <- bar
+ logShow x
+ log "Done"
diff --git a/tests/purs/passing/Rank2Types.purs b/tests/purs/passing/Rank2Types.purs
new file mode 100644
index 0000000..b682f50
--- /dev/null
+++ b/tests/purs/passing/Rank2Types.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test1 :: (forall a. (a -> a)) -> Number
+test1 = \f -> f 0.0
+
+forever :: forall m a b. (forall a b. m a -> (a -> m b) -> m b) -> m a -> m b
+forever = \bind action -> bind action $ \_ -> forever bind action
+
+main = log "Done"
diff --git a/tests/purs/passing/ReExportQualified.purs b/tests/purs/passing/ReExportQualified.purs
new file mode 100644
index 0000000..b7e8e7a
--- /dev/null
+++ b/tests/purs/passing/ReExportQualified.purs
@@ -0,0 +1,7 @@
+module Main where
+
+import Prelude
+import C
+import Effect.Console (log)
+
+main = log (x <> y)
diff --git a/tests/purs/passing/ReExportQualified/A.purs b/tests/purs/passing/ReExportQualified/A.purs
new file mode 100644
index 0000000..ae23128
--- /dev/null
+++ b/tests/purs/passing/ReExportQualified/A.purs
@@ -0,0 +1,3 @@
+module A where
+
+x = "Do"
diff --git a/tests/purs/passing/ReExportQualified/B.purs b/tests/purs/passing/ReExportQualified/B.purs
new file mode 100644
index 0000000..2e14922
--- /dev/null
+++ b/tests/purs/passing/ReExportQualified/B.purs
@@ -0,0 +1,3 @@
+module B where
+
+y = "ne"
diff --git a/tests/purs/passing/ReExportQualified/C.purs b/tests/purs/passing/ReExportQualified/C.purs
new file mode 100644
index 0000000..589f37b
--- /dev/null
+++ b/tests/purs/passing/ReExportQualified/C.purs
@@ -0,0 +1,4 @@
+module C (module A, module M2) where
+
+import A
+import B as M2
diff --git a/tests/purs/passing/RebindableSyntax.purs b/tests/purs/passing/RebindableSyntax.purs
new file mode 100644
index 0000000..11da9a6
--- /dev/null
+++ b/tests/purs/passing/RebindableSyntax.purs
@@ -0,0 +1,43 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+example1 :: String
+example1 = do
+ "Do"
+ " notation"
+ " for"
+ " Semigroup"
+ where
+ discard x f = x <> f unit
+
+applySecond :: forall f a b. Apply f => f a -> f b -> f b
+applySecond fa fb = const identity <$> fa <*> fb
+
+infixl 4 applySecond as *>
+
+newtype Const a b = Const a
+
+runConst :: forall a b. Const a b -> a
+runConst (Const a) = a
+
+instance functorConst :: Functor (Const a) where
+ map _ (Const a) = Const a
+
+instance applyConst :: Semigroup a => Apply (Const a) where
+ apply (Const a1) (Const a2) = Const (a1 <> a2)
+
+example2 :: Const String Unit
+example2 = do
+ Const "Do"
+ Const " notation"
+ Const " for"
+ Const " Apply"
+ where
+ discard x f = x *> f unit
+
+main = do
+ log example1
+ log $ runConst example2
+ log "Done"
diff --git a/tests/purs/passing/Recursion.purs b/tests/purs/passing/Recursion.purs
new file mode 100644
index 0000000..d071149
--- /dev/null
+++ b/tests/purs/passing/Recursion.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+fib = \n -> case n of
+ 0.0 -> 1.0
+ 1.0 -> 1.0
+ n -> fib (n - 1.0) + fib (n - 2.0)
+
+main = log "Done"
diff --git a/tests/purs/passing/RedefinedFixity.purs b/tests/purs/passing/RedefinedFixity.purs
new file mode 100644
index 0000000..8bee75a
--- /dev/null
+++ b/tests/purs/passing/RedefinedFixity.purs
@@ -0,0 +1,6 @@
+module Main where
+
+import M3
+import Effect.Console (log)
+
+main = log "Done"
diff --git a/tests/purs/passing/RedefinedFixity/M1.purs b/tests/purs/passing/RedefinedFixity/M1.purs
new file mode 100644
index 0000000..703e37b
--- /dev/null
+++ b/tests/purs/passing/RedefinedFixity/M1.purs
@@ -0,0 +1,6 @@
+module M1 where
+
+applyFn :: forall a b. (forall c d. c -> d) -> a -> b
+applyFn f a = f a
+
+infixr 1000 applyFn as $
diff --git a/tests/purs/passing/RedefinedFixity/M2.purs b/tests/purs/passing/RedefinedFixity/M2.purs
new file mode 100644
index 0000000..359b514
--- /dev/null
+++ b/tests/purs/passing/RedefinedFixity/M2.purs
@@ -0,0 +1,5 @@
+module M2 where
+
+import Prelude ()
+
+import M1
diff --git a/tests/purs/passing/RedefinedFixity/M3.purs b/tests/purs/passing/RedefinedFixity/M3.purs
new file mode 100644
index 0000000..f7ac462
--- /dev/null
+++ b/tests/purs/passing/RedefinedFixity/M3.purs
@@ -0,0 +1,6 @@
+module M3 where
+
+import Prelude ()
+
+import M1
+import M2
diff --git a/tests/purs/passing/ReservedWords.purs b/tests/purs/passing/ReservedWords.purs
new file mode 100644
index 0000000..84120b6
--- /dev/null
+++ b/tests/purs/passing/ReservedWords.purs
@@ -0,0 +1,19 @@
+-- See https://github.com/purescript/purescript/issues/606
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console (log)
+
+o :: { type :: String }
+o = { type: "o" }
+
+p :: { type :: String }
+p = o { type = "p" }
+
+f :: forall r. { type :: String | r } -> String
+f { type: "p" } = "Done"
+f _ = "Fail"
+
+main :: Effect _
+main = log $ f { type: p.type, foo: "bar" }
diff --git a/tests/purs/passing/ResolvableScopeConflict.purs b/tests/purs/passing/ResolvableScopeConflict.purs
new file mode 100644
index 0000000..42c2a90
--- /dev/null
+++ b/tests/purs/passing/ResolvableScopeConflict.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import A (thing)
+import B
+import Effect.Console (log)
+
+-- Not an error as although we have `thing` in scope from both A and B, it is
+-- imported explicitly from A, giving it a resolvable solution.
+what :: Boolean -> Int
+what true = thing
+what false = zing
+
+main = log "Done"
diff --git a/tests/purs/passing/ResolvableScopeConflict/A.purs b/tests/purs/passing/ResolvableScopeConflict/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/passing/ResolvableScopeConflict/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/passing/ResolvableScopeConflict/B.purs b/tests/purs/passing/ResolvableScopeConflict/B.purs
new file mode 100644
index 0000000..4ad4bb6
--- /dev/null
+++ b/tests/purs/passing/ResolvableScopeConflict/B.purs
@@ -0,0 +1,7 @@
+module B where
+
+thing :: Int
+thing = 2
+
+zing :: Int
+zing = 3
diff --git a/tests/purs/passing/ResolvableScopeConflict2.purs b/tests/purs/passing/ResolvableScopeConflict2.purs
new file mode 100644
index 0000000..2bbe991
--- /dev/null
+++ b/tests/purs/passing/ResolvableScopeConflict2.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import A
+import Effect.Console (log)
+
+thing :: Int
+thing = 1
+
+-- Not an error as although we have `thing` in scope from both Main and A,
+-- as the local declaration takes precedence over the implicit import
+what :: Boolean -> Int
+what true = thing
+what false = zing
+
+main = log "Done"
diff --git a/tests/purs/passing/ResolvableScopeConflict2/A.purs b/tests/purs/passing/ResolvableScopeConflict2/A.purs
new file mode 100644
index 0000000..943011c
--- /dev/null
+++ b/tests/purs/passing/ResolvableScopeConflict2/A.purs
@@ -0,0 +1,7 @@
+module A where
+
+thing :: Int
+thing = 2
+
+zing :: Int
+zing = 3
diff --git a/tests/purs/passing/ResolvableScopeConflict3.purs b/tests/purs/passing/ResolvableScopeConflict3.purs
new file mode 100644
index 0000000..853adcf
--- /dev/null
+++ b/tests/purs/passing/ResolvableScopeConflict3.purs
@@ -0,0 +1,9 @@
+module Main (thing, main, module A) where
+
+import A
+import Effect.Console (log)
+
+thing :: Int
+thing = 2
+
+main = log "Done"
diff --git a/tests/purs/passing/ResolvableScopeConflict3/A.purs b/tests/purs/passing/ResolvableScopeConflict3/A.purs
new file mode 100644
index 0000000..302b032
--- /dev/null
+++ b/tests/purs/passing/ResolvableScopeConflict3/A.purs
@@ -0,0 +1,4 @@
+module A where
+
+thing :: Int
+thing = 1
diff --git a/tests/purs/passing/RowConstructors.purs b/tests/purs/passing/RowConstructors.purs
new file mode 100644
index 0000000..d80457c
--- /dev/null
+++ b/tests/purs/passing/RowConstructors.purs
@@ -0,0 +1,43 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type Foo = (x :: Number | (y :: Number | (z :: Number)))
+type Bar = (x :: Number, y :: Number, z :: Number)
+type Baz = { w :: Number | Bar }
+
+foo :: { | Foo }
+foo = { x: 0.0, y: 0.0, z: 0.0 }
+
+bar :: { | Bar }
+bar = { x: 0.0, y: 0.0, z: 0.0 }
+
+id' :: Record Foo -> Record Bar
+id' = identity
+
+foo' :: { | Foo }
+foo' = id' foo
+
+bar' :: { | Bar }
+bar' = id' bar
+
+baz :: Baz
+baz = { x: 0.0, y: 0.0, z: 0.0, w: 0.0 }
+
+type Quux r = (q :: Number | r)
+type Norf r = (q' :: Number | Quux r)
+
+quux :: { f :: { | Foo } | Quux Bar }
+quux = { f: foo', x: 0.0, y: 0.0, z: 0.0, q: 0.0 }
+
+quux' :: { | Norf Bar }
+quux' = { x: 0.0, y: 0.0, z: 0.0, q: 0.0, q': 0.0 }
+
+wildcard :: { w :: Number | _ } -> Baz
+wildcard { w: w } = { x: w, y: w, z: w, w: w }
+
+wildcard' :: { | Quux _ } -> Number
+wildcard' { q: q } = q
+
+main = log "Done"
diff --git a/tests/purs/passing/RowInInstanceHeadDetermined.purs b/tests/purs/passing/RowInInstanceHeadDetermined.purs
new file mode 100644
index 0000000..036618d
--- /dev/null
+++ b/tests/purs/passing/RowInInstanceHeadDetermined.purs
@@ -0,0 +1,40 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Empty = Empty
+data Cons = Cons
+
+
+-- simple case
+class Simple a b | a -> b where c :: a -> b
+instance simple0 :: Simple Empty {} where c _ = {}
+instance simple1 :: Simple Cons {foo :: Cons} where c cons = {foo: cons}
+
+
+-- simple transitive example
+class Transitive a b c | a -> b, b -> c where d :: a -> c
+instance transitive :: Transitive Empty {} {} where d _ = {}
+
+
+-- transitive example with cycles
+class Cyclic a b c d | a -> b, b -> a
+ , a -> c
+ , c -> d, d -> c
+instance cyclic :: Cyclic Empty Empty {} {}
+
+
+-- Determined cycle
+class DeterminedCycle a b c | a -> b
+ , b -> c, c -> b
+instance determinedCycle :: DeterminedCycle Empty {} {}
+
+
+-- multiple determiners
+class MultipleDeterminers a b c d | a b -> c d
+instance multipleDeterminers :: MultipleDeterminers Empty Empty {} {}
+
+
+main = log "Done"
+
diff --git a/tests/purs/passing/RowLacks.purs b/tests/purs/passing/RowLacks.purs
new file mode 100644
index 0000000..06e7b91
--- /dev/null
+++ b/tests/purs/passing/RowLacks.purs
@@ -0,0 +1,23 @@
+module Main where
+
+import Effect.Console (log)
+import Prim.Row (class Lacks)
+import Type.Row (RProxy(..))
+
+lacksX
+ :: forall r
+ . Lacks "x" r
+ => RProxy r
+ -> RProxy ()
+lacksX _ = RProxy
+
+test1 :: RProxy ()
+test1 = lacksX (RProxy :: RProxy (y :: Int, z :: String))
+
+test2 :: forall r. Lacks "x" r => RProxy r -> RProxy ()
+test2 _ = lacksX (RProxy :: RProxy (y :: Int, z :: String | r))
+
+test3 :: RProxy ()
+test3 = test2 (RProxy :: RProxy (a :: String))
+
+main = log "Done"
diff --git a/tests/purs/passing/RowNub.purs b/tests/purs/passing/RowNub.purs
new file mode 100644
index 0000000..fd9f6ca
--- /dev/null
+++ b/tests/purs/passing/RowNub.purs
@@ -0,0 +1,23 @@
+module Main where
+
+import Effect.Console (log)
+import Prim.Row (class Nub, class Union)
+import Type.Row (RProxy(..))
+
+nubUnion
+ :: forall r1 r2 r3 r4
+ . Union r1 r2 r3
+ => Nub r3 r4
+ => RProxy r1
+ -> RProxy r2
+ -> RProxy r4
+nubUnion _ _ = RProxy
+
+type InL = (x :: Int, y :: String)
+type InR = (x :: String, y :: Int, z :: Boolean)
+type Out = (x :: Int, y :: String, z :: Boolean)
+
+test :: RProxy Out
+test = nubUnion (RProxy :: RProxy InL) (RProxy :: RProxy InR)
+
+main = log "Done"
diff --git a/tests/purs/passing/RowPolyInstanceContext.purs b/tests/purs/passing/RowPolyInstanceContext.purs
new file mode 100644
index 0000000..90f9ce4
--- /dev/null
+++ b/tests/purs/passing/RowPolyInstanceContext.purs
@@ -0,0 +1,23 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class T s m | m -> s where
+ state :: (s -> s) -> m Unit
+
+data S s a = S (s -> { new :: s, ret :: a })
+
+instance st :: T s (S s) where
+ state f = S $ \s -> { new: f s, ret: unit }
+
+test1 :: forall r . S { foo :: String | r } Unit
+test1 = state $ \o -> o { foo = o.foo <> "!" }
+
+test2 :: forall m r . T { foo :: String | r } m => m Unit
+test2 = state $ \o -> o { foo = o.foo <> "!" }
+
+main = do
+ let t1 = test1
+ let t2 = test2
+ log "Done"
diff --git a/tests/purs/passing/RowUnion.js b/tests/purs/passing/RowUnion.js
new file mode 100644
index 0000000..c002b18
--- /dev/null
+++ b/tests/purs/passing/RowUnion.js
@@ -0,0 +1,10 @@
+"use strict";
+
+exports.merge = function (dict) {
+ return function (l) {
+ return function (r) {
+ var o = {};
+ return Object.assign(o, r, l);
+ };
+ };
+};
diff --git a/tests/purs/passing/RowUnion.purs b/tests/purs/passing/RowUnion.purs
new file mode 100644
index 0000000..2b921f2
--- /dev/null
+++ b/tests/purs/passing/RowUnion.purs
@@ -0,0 +1,69 @@
+module Main where
+
+import Prelude
+import Prim.Row
+import Effect
+import Effect.Console
+
+foreign import merge
+ :: forall r1 r2 r3
+ . Union r1 r2 r3
+ => Record r1
+ -> Record r2
+ -> Record r3
+
+test1 = merge { x: 1 } { y: true }
+
+test2 = merge { x: 1 } { x: true }
+
+mergeWithExtras
+ :: forall r1 r2 r3
+ . Union r1 (y :: Boolean | r2) (y :: Boolean | r3)
+ => { x :: Int | r1 }
+ -> { y :: Boolean | r2 }
+ -> { x :: Int, y :: Boolean | r3}
+mergeWithExtras = merge
+
+test3 x = merge { x: 1 } x
+test3' x = merge x { x: 1 }
+
+type Mandatory r = (x :: Int | r)
+type Optional r = (x :: Int, y :: Int, z :: Int | r)
+
+withDefaults
+ :: forall r s
+ . Union r (y :: Int, z :: Int) (y :: Int, z :: Int | s)
+ => Record (Mandatory r)
+ -> Record (Optional s)
+withDefaults p = merge p { y: 1, z: 1 }
+
+withDefaultsClosed
+ :: forall r s
+ . Union r (y :: Int, z :: Int) (y :: Int, z :: Int | s)
+ => Subrow s (y :: Int, z :: Int)
+ => Record (Mandatory r)
+ -> Record (Optional s)
+withDefaultsClosed p = merge p { y: 1, z: 1 }
+
+test4 = withDefaults { x: 1, y: 2 }
+
+-- r is a subrow of s if Union r t s for some t.
+class Subrow (r :: # Type) (s :: # Type)
+instance subrow :: Union r t s => Subrow r s
+
+main :: Effect Unit
+main = do
+ logShow test1.x
+ logShow test1.y
+ logShow (test1.x == 1)
+ logShow (mergeWithExtras { x: 1 } { x: 0, y: true, z: 42.0 }).x
+ logShow (withDefaults { x: 1 }).x
+ logShow (withDefaults { x: 1 }).y
+ logShow (withDefaults { x: 1 }).z
+ logShow (withDefaults { x: 1, y: 2 }).x
+ logShow (withDefaults { x: 1, y: 2 }).y
+ logShow (withDefaults { x: 1, y: 2 }).z
+ logShow (withDefaultsClosed { x: 1, y: 2 }).x
+ logShow (withDefaultsClosed { x: 1, y: 2 }).y
+ logShow (withDefaultsClosed { x: 1, y: 2 }).z
+ log "Done"
diff --git a/tests/purs/passing/RowsInInstanceContext.purs b/tests/purs/passing/RowsInInstanceContext.purs
new file mode 100644
index 0000000..19fa17f
--- /dev/null
+++ b/tests/purs/passing/RowsInInstanceContext.purs
@@ -0,0 +1,25 @@
+module Main where
+
+import Prelude
+import Effect (Effect)
+import Effect.Console (log)
+import Data.Newtype (class Newtype, unwrap)
+
+class TypeEquals a b | a -> b, b -> a where
+ coerce :: a -> b
+ coerceBack :: b -> a
+
+instance refl :: TypeEquals a a where
+ coerce = identity
+ coerceBack = identity
+
+newtype RecordNewtype = RecordNewtype { x :: String }
+
+instance newtypeRecordNewtype ::
+ TypeEquals inner { x :: String }
+ => Newtype RecordNewtype inner where
+ wrap = RecordNewtype <<< coerce
+ unwrap (RecordNewtype rec) = coerceBack rec
+
+main :: Effect Unit
+main = log (unwrap (RecordNewtype { x: "Done" })).x
diff --git a/tests/purs/passing/RunFnInline.purs b/tests/purs/passing/RunFnInline.purs
new file mode 100644
index 0000000..dd73588
--- /dev/null
+++ b/tests/purs/passing/RunFnInline.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+
+import Effect.Console (log)
+
+runFn3 :: forall a b c d. (a -> b -> c -> d) -> a -> b -> c -> d
+runFn3 f a b c = f a b c
+
+main = do
+ log $ runFn3 (\a b c -> c) 1 2 "Done"
diff --git a/tests/purs/passing/RuntimeScopeIssue.purs b/tests/purs/passing/RuntimeScopeIssue.purs
new file mode 100644
index 0000000..447d80f
--- /dev/null
+++ b/tests/purs/passing/RuntimeScopeIssue.purs
@@ -0,0 +1,22 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+class A a where
+ a :: a -> Boolean
+
+class B a where
+ b :: a -> Boolean
+
+instance aNumber :: A Number where
+ a 0.0 = true
+ a n = b (n - 1.0)
+
+instance bNumber :: B Number where
+ b 0.0 = false
+ b n = a (n - 1.0)
+
+main = do
+ logShow $ a 10.0
+ log "Done"
diff --git a/tests/purs/passing/ScopedTypeVariables.purs b/tests/purs/passing/ScopedTypeVariables.purs
new file mode 100644
index 0000000..3f71bbe
--- /dev/null
+++ b/tests/purs/passing/ScopedTypeVariables.purs
@@ -0,0 +1,37 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test1 :: forall a. (a -> a) -> a -> a
+test1 f x = g (g x)
+ where
+ g :: a -> a
+ g y = f (f y)
+
+test2 :: forall a. (a -> a) -> a -> a
+test2 = h
+ where
+ h :: forall b. (b -> b) -> b -> b
+ h f x = g (g x)
+ where
+ g :: b -> b
+ g y = f (f y)
+
+test3 :: Number
+test3 = ((\b -> b :: b) :: forall b. b -> b) 0.0
+
+test4 :: forall a. (a -> a) -> a -> a
+test4 = h
+ where
+ h :: forall b. (b -> b) -> b -> b
+ h f x = g (g x)
+ where
+ g :: b -> b
+ g y = j (f (f y))
+ where
+ j :: forall b. b -> b
+ j x = x
+
+
+main = log "Done"
diff --git a/tests/purs/passing/Sequence.purs b/tests/purs/passing/Sequence.purs
new file mode 100644
index 0000000..b6adc20
--- /dev/null
+++ b/tests/purs/passing/Sequence.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console (log)
+
+data List a = Cons a (List a) | Nil
+
+class Sequence t where
+ sequence :: forall m a. Monad m => t (m a) -> m (t a)
+
+instance sequenceList :: Sequence List where
+ sequence Nil = pure Nil
+ sequence (Cons x xs) = Cons <$> x <*> sequence xs
+
+main = sequence $ Cons (log "Done") Nil
diff --git a/tests/purs/passing/SequenceDesugared.purs b/tests/purs/passing/SequenceDesugared.purs
new file mode 100644
index 0000000..696e016
--- /dev/null
+++ b/tests/purs/passing/SequenceDesugared.purs
@@ -0,0 +1,38 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console (log)
+
+data List a = Cons a (List a) | Nil
+
+data Sequence t = Sequence (forall m a. Monad m => t (m a) -> m (t a))
+
+sequence :: forall t. Sequence t -> (forall m a. Monad m => t (m a) -> m (t a))
+sequence (Sequence s) = s
+
+sequenceListSeq :: forall m a. Monad m => List (m a) -> m (List a)
+sequenceListSeq Nil = pure Nil
+sequenceListSeq (Cons x xs) = Cons <$> x <*> sequenceListSeq xs
+
+sequenceList :: Sequence List
+sequenceList = Sequence (sequenceListSeq)
+
+sequenceList' :: Sequence List
+sequenceList' = Sequence ((\val -> case val of
+ Nil -> pure Nil
+ Cons x xs -> Cons <$> x <*> sequence sequenceList' xs))
+
+sequenceList'' :: Sequence List
+sequenceList'' = Sequence (sequenceListSeq :: forall m a. Monad m => List (m a) -> m (List a))
+
+sequenceList''' :: Sequence List
+sequenceList''' = Sequence ((\val -> case val of
+ Nil -> pure Nil
+ Cons x xs -> Cons <$> x <*> sequence sequenceList''' xs) :: forall m a. Monad m => List (m a) -> m (List a))
+
+main = do
+ void $ sequence sequenceList $ Cons (log "Done") Nil
+ void $ sequence sequenceList' $ Cons (log "Done") Nil
+ void $ sequence sequenceList'' $ Cons (log "Done") Nil
+ void $ sequence sequenceList''' $ Cons (log "Done") Nil
diff --git a/tests/purs/passing/ShadowedModuleName.purs b/tests/purs/passing/ShadowedModuleName.purs
new file mode 100644
index 0000000..bf89d70
--- /dev/null
+++ b/tests/purs/passing/ShadowedModuleName.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Test
+import Effect.Console
+
+data Test = Test
+
+main = log (runZ (Z "Done"))
diff --git a/tests/purs/passing/ShadowedModuleName/Test.purs b/tests/purs/passing/ShadowedModuleName/Test.purs
new file mode 100644
index 0000000..b30eb2d
--- /dev/null
+++ b/tests/purs/passing/ShadowedModuleName/Test.purs
@@ -0,0 +1,6 @@
+module Test where
+
+data Z = Z String
+
+runZ :: Z -> String
+runZ (Z s) = s
diff --git a/tests/purs/passing/ShadowedName.purs b/tests/purs/passing/ShadowedName.purs
new file mode 100644
index 0000000..3639dc8
--- /dev/null
+++ b/tests/purs/passing/ShadowedName.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Prelude
+import Effect.Console
+import Effect.Console (log)
+
+done :: String
+done = let str = "Not yet done" in
+ let str = "Done" in str
+
+main = log done
diff --git a/tests/purs/passing/ShadowedRename.purs b/tests/purs/passing/ShadowedRename.purs
new file mode 100644
index 0000000..26def25
--- /dev/null
+++ b/tests/purs/passing/ShadowedRename.purs
@@ -0,0 +1,14 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+import Test.Assert
+
+foo foo = let foo_1 = \_ -> foo
+ foo_2 = foo_1 unit + 1.0
+ in foo_2
+
+main = do
+ assert $ foo 1.0 == 2.0
+ log "Done"
diff --git a/tests/purs/passing/ShadowedTCO.purs b/tests/purs/passing/ShadowedTCO.purs
new file mode 100644
index 0000000..f8d6612
--- /dev/null
+++ b/tests/purs/passing/ShadowedTCO.purs
@@ -0,0 +1,21 @@
+module Main where
+
+import Prelude hiding (add)
+import Effect.Console (log)
+
+runNat f = f 0.0 (\n -> n + 1.0)
+
+zero' z _ = z
+
+succ f zero' succ = succ (f zero' succ)
+
+add f g zero' succ = g (f zero' succ) succ
+
+one' = succ zero'
+two = succ one'
+four = add two two
+fourNumber = runNat four
+
+main = do
+ log $ show fourNumber
+ log "Done"
diff --git a/tests/purs/passing/ShadowedTCOLet.purs b/tests/purs/passing/ShadowedTCOLet.purs
new file mode 100644
index 0000000..5090d4d
--- /dev/null
+++ b/tests/purs/passing/ShadowedTCOLet.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Partial.Unsafe (unsafePartial)
+import Effect
+import Effect.Console (log)
+
+f x y z =
+ let f 1.0 2.0 3.0 = 1.0
+ in f x z y
+
+main :: Effect _
+main = do
+ log $ show $ unsafePartial f 1.0 3.0 2.0
+ log "Done"
diff --git a/tests/purs/passing/SignedNumericLiterals.purs b/tests/purs/passing/SignedNumericLiterals.purs
new file mode 100644
index 0000000..851e7aa
--- /dev/null
+++ b/tests/purs/passing/SignedNumericLiterals.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+p = 0.5
+q = 1.0
+x = -1.0
+y = -0.5
+z = 0.5
+w = 1.0
+
+f :: Number -> Number
+f x = -x
+
+test1 = 2.0 - 1.0
+
+main = log "Done"
diff --git a/tests/purs/passing/SolvingAppendSymbol.purs b/tests/purs/passing/SolvingAppendSymbol.purs
new file mode 100644
index 0000000..a1656dc
--- /dev/null
+++ b/tests/purs/passing/SolvingAppendSymbol.purs
@@ -0,0 +1,34 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+import Prim.Symbol (class Append)
+import Type.Data.Symbol (SProxy(..), reflectSymbol)
+import Type.Data.Symbol (append) as Symbol
+
+sym :: SProxy ""
+sym = SProxy
+
+symA :: SProxy "A"
+symA = SProxy
+
+symB :: SProxy "B"
+symB = SProxy
+
+egAB :: SProxy "AB"
+egAB = Symbol.append symA symB
+
+egBA :: SProxy "BA"
+egBA = Symbol.append symB symA
+
+egA' :: SProxy "A"
+egA' = Symbol.append sym (Symbol.append symA sym)
+
+main = do
+ let gotAB = reflectSymbol egAB == "AB"
+ gotBA = reflectSymbol egBA == "BA"
+ gotA' = reflectSymbol egA' == "A"
+ when (not gotAB) $ log "Did not get AB"
+ when (not gotBA) $ log "Did not get BA"
+ when (not gotA') $ log "Did not get A"
+ when (gotAB && gotBA && gotA') $ log "Done"
diff --git a/tests/purs/passing/SolvingCompareSymbol.purs b/tests/purs/passing/SolvingCompareSymbol.purs
new file mode 100644
index 0000000..0b18b12
--- /dev/null
+++ b/tests/purs/passing/SolvingCompareSymbol.purs
@@ -0,0 +1,33 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+import Prim.Symbol (class Compare)
+import Prim.Ordering (kind Ordering, LT, EQ, GT)
+import Type.Data.Symbol (SProxy(..))
+import Type.Data.Symbol (compare) as Symbol
+import Type.Data.Ordering (OProxy(..), reflectOrdering)
+
+symA :: SProxy "A"
+symA = SProxy
+
+symB :: SProxy "B"
+symB = SProxy
+
+egLT :: OProxy LT
+egLT = Symbol.compare symA symB
+
+egEQ :: OProxy EQ
+egEQ = Symbol.compare symA symA
+
+egGT :: OProxy GT
+egGT = Symbol.compare symB symA
+
+main = do
+ let gotLT = reflectOrdering egLT == LT
+ gotEQ = reflectOrdering egEQ == EQ
+ gotGT = reflectOrdering egGT == GT
+ when (not gotLT) $ log "Did not get LT"
+ when (not gotEQ) $ log "Did not get EQ"
+ when (not gotGT) $ log "Did not get GT"
+ when (gotLT && gotEQ && gotGT) $ log "Done"
diff --git a/tests/purs/passing/SolvingIsSymbol.purs b/tests/purs/passing/SolvingIsSymbol.purs
new file mode 100644
index 0000000..71f5c18
--- /dev/null
+++ b/tests/purs/passing/SolvingIsSymbol.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+-- Here we import as alias of reflectSymbol without importing Data.Symbol. However,
+-- Data.Symbol should be implicitly imported as we have an instance of IsSymbol solved.
+import SolvingIsSymbol.Lib (literalSymbol, libReflectSymbol)
+
+main = do
+ let lit = libReflectSymbol literalSymbol
+ when (lit == "literal") (log "Done")
diff --git a/tests/purs/passing/SolvingIsSymbol/Lib.purs b/tests/purs/passing/SolvingIsSymbol/Lib.purs
new file mode 100644
index 0000000..18ea3b2
--- /dev/null
+++ b/tests/purs/passing/SolvingIsSymbol/Lib.purs
@@ -0,0 +1,10 @@
+module SolvingIsSymbol.Lib where
+
+import Data.Symbol
+
+literalSymbol :: SProxy "literal"
+literalSymbol = SProxy
+
+libReflectSymbol :: forall s. IsSymbol s => SProxy s -> String
+libReflectSymbol = reflectSymbol
+
diff --git a/tests/purs/passing/Stream.purs b/tests/purs/passing/Stream.purs
new file mode 100644
index 0000000..cd9b86b
--- /dev/null
+++ b/tests/purs/passing/Stream.purs
@@ -0,0 +1,26 @@
+module Main where
+
+import Prelude
+
+import Effect (Effect)
+import Effect.Console (log)
+
+class IsStream el s | s -> el where
+ cons :: el -> (Unit -> s) -> s
+ uncons :: s -> { head :: el, tail :: s }
+
+data Stream a = Stream a (Unit -> Stream a)
+
+instance streamIsStream :: IsStream a (Stream a) where
+ cons x xs = Stream x xs
+ uncons (Stream x f) = { head: x, tail: f unit }
+
+test :: forall el s. IsStream el s => s -> s
+test s = case uncons s of
+ { head, tail } -> cons head \_ -> tail
+
+main :: Effect Unit
+main = do
+ let dones :: Stream String
+ dones = cons "Done" \_ -> dones
+ log (uncons (test dones)).head
diff --git a/tests/purs/passing/StringEdgeCases.purs b/tests/purs/passing/StringEdgeCases.purs
new file mode 100644
index 0000000..b361eb1
--- /dev/null
+++ b/tests/purs/passing/StringEdgeCases.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Records as Records
+import Symbols as Symbols
+
+main = do
+ Records.main
+ Symbols.main
diff --git a/tests/purs/passing/StringEdgeCases/Records.purs b/tests/purs/passing/StringEdgeCases/Records.purs
new file mode 100644
index 0000000..6d0c455
--- /dev/null
+++ b/tests/purs/passing/StringEdgeCases/Records.purs
@@ -0,0 +1,39 @@
+module Records where
+
+import Prelude
+import Effect.Console (log)
+import Test.Assert (assert')
+
+newtype AstralKeys = AstralKeys { "💡" :: Int, "💢" :: Int }
+newtype LoneSurrogateKeys = LoneSurrogateKeys { "\xdf06" :: Int, "\xd834" :: Int }
+
+testLoneSurrogateKeys =
+ let
+ expected = 5
+ actual = (_."\xd801" <<< helper) { "\xd800": 5 }
+ in
+ assert' ("lone surrogate keys: " <> show actual) (expected == actual)
+
+ where
+ helper :: { "\xd800" :: Int } -> { "\xd801" :: Int }
+ helper o =
+ case o."\xd800" of
+ x -> { "\xd801": x }
+
+testAstralKeys =
+ let
+ expected = 5
+ actual = (_."💢" <<< helper) { "💡": 5 }
+ in
+ assert' ("astral keys: " <> show actual) (expected == actual)
+
+ where
+ helper :: { "💡" :: Int } -> { "💢" :: Int }
+ helper o =
+ case o."💡" of
+ x -> { "💢": x }
+
+main = do
+ testLoneSurrogateKeys
+ testAstralKeys
+ log "Done"
diff --git a/tests/purs/passing/StringEdgeCases/Symbols.purs b/tests/purs/passing/StringEdgeCases/Symbols.purs
new file mode 100644
index 0000000..0289a89
--- /dev/null
+++ b/tests/purs/passing/StringEdgeCases/Symbols.purs
@@ -0,0 +1,32 @@
+-- This is similar to StringEscapes except we are performing the same tests
+-- with Symbols (at the type level).
+
+module Symbols where
+
+import Prelude
+import Effect.Console (log)
+import Prim.Symbol (class Append)
+import Type.Data.Symbol (SProxy(..), reflectSymbol)
+import Type.Data.Symbol (append) as Symbol
+import Test.Assert (assert')
+
+highS :: SProxy "\xd834"
+highS = SProxy
+
+lowS :: SProxy "\xdf06"
+lowS = SProxy
+
+loneSurrogates :: Boolean
+loneSurrogates = reflectSymbol (Symbol.append highS lowS) == "\x1d306"
+
+outOfOrderSurrogates :: Boolean
+outOfOrderSurrogates = reflectSymbol (Symbol.append lowS highS) == "\xdf06\xd834"
+
+notReplacing :: Boolean
+notReplacing = reflectSymbol lowS /= "\xfffd"
+
+main = do
+ assert' "lone surrogates may be combined into a surrogate pair" loneSurrogates
+ assert' "lone surrogates may be combined out of order to remain lone surrogates" outOfOrderSurrogates
+ assert' "lone surrogates are not replaced with the Unicode replacement character U+FFFD" notReplacing
+ log "Done"
diff --git a/tests/purs/passing/StringEscapes.purs b/tests/purs/passing/StringEscapes.purs
new file mode 100644
index 0000000..9194ce7
--- /dev/null
+++ b/tests/purs/passing/StringEscapes.purs
@@ -0,0 +1,26 @@
+module Main where
+
+import Prelude ((==), (/=), (<>), discard)
+import Test.Assert (assert, assert')
+import Effect.Console (log)
+
+singleCharacter = "\0\b\t\n\v\f\r\"\\" == "\x0\x8\x9\xA\xB\xC\xD\x22\x5C"
+hex = "\x1D306\x2603\x3C6\xE0\x0" == "𝌆☃φà\0"
+decimal = "\119558\9731\966\224\0" == "𝌆☃φà\0"
+surrogatePair = "\xD834\xDF06" == "\x1D306"
+highSurrogate = "\xD834"
+lowSurrogate = "\xDF06"
+loneSurrogates = (highSurrogate <> lowSurrogate) == "\x1D306"
+outOfOrderSurrogates = (lowSurrogate <> highSurrogate) == "\xDF06\xD834"
+replacement = "\xFFFD"
+notReplacing = replacement /= highSurrogate
+
+main = do
+ assert' "single-character escape sequences" singleCharacter
+ assert' "hex escape sequences" hex
+ assert' "decimal escape sequences" decimal
+ assert' "astral code points are represented as a UTF-16 surrogate pair" surrogatePair
+ assert' "lone surrogates may be combined into a surrogate pair" loneSurrogates
+ assert' "lone surrogates may be combined out of order to remain lone surrogates" outOfOrderSurrogates
+ assert' "lone surrogates are not replaced with the Unicode replacement character U+FFFD" notReplacing
+ log "Done"
diff --git a/tests/purs/passing/Superclasses1.purs b/tests/purs/passing/Superclasses1.purs
new file mode 100644
index 0000000..2f514cf
--- /dev/null
+++ b/tests/purs/passing/Superclasses1.purs
@@ -0,0 +1,23 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+class Su a where
+ su :: a -> a
+
+class (Su a) <= Cl a where
+ cl :: a -> a -> a
+
+instance suNumber :: Su Number where
+ su n = n + 1.0
+
+instance clNumber :: Cl Number where
+ cl n m = n + m
+
+test :: forall a. Cl a => a -> a
+test a = su (cl a a)
+
+main = do
+ logShow $ test 10.0
+ log "Done"
diff --git a/tests/purs/passing/Superclasses3.purs b/tests/purs/passing/Superclasses3.purs
new file mode 100644
index 0000000..ec3da56
--- /dev/null
+++ b/tests/purs/passing/Superclasses3.purs
@@ -0,0 +1,41 @@
+module Main where
+
+import Prelude
+import Effect.Console
+import Effect
+
+class Monad m <= MonadWriter w m where
+ tell :: w -> m Unit
+
+testFunctor :: forall m. Monad m => m Number -> m Number
+testFunctor n = (+) 1.0 <$> n
+
+test :: forall w m. Monad m => MonadWriter w m => w -> m Unit
+test w = do
+ tell w
+ tell w
+ tell w
+
+data MTrace a = MTrace (Effect a)
+
+runMTrace :: forall a. MTrace a -> Effect a
+runMTrace (MTrace a) = a
+
+instance functorMTrace :: Functor MTrace where
+ map = liftM1
+
+instance applyMTrace :: Apply MTrace where
+ apply = ap
+
+instance applicativeMTrace :: Applicative MTrace where
+ pure = MTrace <<< pure
+
+instance bindMTrace :: Bind MTrace where
+ bind m f = MTrace (runMTrace m >>= (runMTrace <<< f))
+
+instance monadMTrace :: Monad MTrace
+
+instance writerMTrace :: MonadWriter String MTrace where
+ tell s = MTrace (log s)
+
+main = runMTrace $ test "Done"
diff --git a/tests/purs/passing/TCO.purs b/tests/purs/passing/TCO.purs
new file mode 100644
index 0000000..d1a1fa9
--- /dev/null
+++ b/tests/purs/passing/TCO.purs
@@ -0,0 +1,28 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+import Control.Monad.Rec.Class
+import Data.Array ((..), span, length)
+
+main = do
+ let f x = x + 1
+ let v = 0
+ logShow (applyN 0 f v)
+ logShow (applyN 1 f v)
+ logShow (applyN 2 f v)
+ logShow (applyN 3 f v)
+ logShow (applyN 4 f v)
+
+ let largeArray = 1..10000
+ logShow (length (span (\_ -> true) largeArray).init)
+
+ logShow (tailRec (\n -> if n < 10000 then Loop (n + 1) else Done 42) 0)
+
+ log "Done"
+
+applyN :: forall a. Int -> (a -> a) -> a -> a
+applyN = go identity
+ where
+ go f n _ | n <= 0 = f
+ go f n g = go (f >>> g) (n - 1) g
diff --git a/tests/purs/passing/TCOCase.purs b/tests/purs/passing/TCOCase.purs
new file mode 100644
index 0000000..b42e299
--- /dev/null
+++ b/tests/purs/passing/TCOCase.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Data = One | More Data
+
+main = log (from (to 10000.0 One))
+ where
+ to 0.0 a = a
+ to n a = to (n - 1.0) (More a)
+ from One = "Done"
+ from (More d) = from d
diff --git a/tests/purs/passing/TailCall.purs b/tests/purs/passing/TailCall.purs
new file mode 100644
index 0000000..2435d2d
--- /dev/null
+++ b/tests/purs/passing/TailCall.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import Prelude
+import Effect.Console (log, logShow)
+
+data L a = C a (L a) | N
+
+test :: Number -> L Number -> Number
+test n N = n
+test n (C x xs) = test (n + x) xs
+
+loop :: forall a. Number -> a
+loop x = loop (x + 1.0)
+
+notATailCall = \x ->
+ (\notATailCall -> notATailCall x) (\x -> x)
+
+main = do
+ logShow (test 0.0 (1.0 `C` (2.0 `C` (3.0 `C` N))))
+ log "Done"
diff --git a/tests/purs/passing/Tick.purs b/tests/purs/passing/Tick.purs
new file mode 100644
index 0000000..58867a5
--- /dev/null
+++ b/tests/purs/passing/Tick.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test' x = x
+
+main = log "Done"
diff --git a/tests/purs/passing/TopLevelCase.purs b/tests/purs/passing/TopLevelCase.purs
new file mode 100644
index 0000000..b740399
--- /dev/null
+++ b/tests/purs/passing/TopLevelCase.purs
@@ -0,0 +1,19 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+gcd :: Number -> Number -> Number
+gcd 0.0 x = x
+gcd x 0.0 = x
+gcd x y | x > y = gcd (x `mod` y) y
+gcd x y = gcd (y `mod` x) x
+
+guardsTest [x] | x > 0.0 = []
+guardsTest xs = xs
+
+data A = A
+
+parseTest A 0.0 = 0.0
+
+main = log "Done"
diff --git a/tests/purs/passing/TransitiveImport.purs b/tests/purs/passing/TransitiveImport.purs
new file mode 100644
index 0000000..62830af
--- /dev/null
+++ b/tests/purs/passing/TransitiveImport.purs
@@ -0,0 +1,9 @@
+module Main where
+
+ import Prelude
+ import Middle
+ import Effect.Console
+
+ main = do
+ logShow (middle unit)
+ log "Done"
diff --git a/tests/purs/passing/TransitiveImport/Middle.purs b/tests/purs/passing/TransitiveImport/Middle.purs
new file mode 100644
index 0000000..c4b5282
--- /dev/null
+++ b/tests/purs/passing/TransitiveImport/Middle.purs
@@ -0,0 +1,5 @@
+module Middle where
+
+import Test (test)
+
+middle = test
diff --git a/tests/purs/passing/TransitiveImport/Test.purs b/tests/purs/passing/TransitiveImport/Test.purs
new file mode 100644
index 0000000..cd06ec2
--- /dev/null
+++ b/tests/purs/passing/TransitiveImport/Test.purs
@@ -0,0 +1,9 @@
+module Test where
+
+import Prelude
+
+class TestCls a where
+ test :: a -> a
+
+instance unitTestCls :: TestCls Unit where
+ test _ = unit
diff --git a/tests/purs/passing/TypeClassMemberOrderChange.purs b/tests/purs/passing/TypeClassMemberOrderChange.purs
new file mode 100644
index 0000000..6b7633c
--- /dev/null
+++ b/tests/purs/passing/TypeClassMemberOrderChange.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Test a where
+ fn :: a -> a -> a
+ val :: a
+
+instance testBoolean :: Test Boolean where
+ val = true
+ fn x y = y
+
+main = do
+ log (show (fn true val))
+ log "Done"
diff --git a/tests/purs/passing/TypeClasses.purs b/tests/purs/passing/TypeClasses.purs
new file mode 100644
index 0000000..b4650d3
--- /dev/null
+++ b/tests/purs/passing/TypeClasses.purs
@@ -0,0 +1,71 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+test1 = \_ -> show "testing"
+
+f :: forall a. Show a => a -> String
+f x = show x
+
+test2 = \_ -> f "testing"
+
+test7 :: forall a. Show a => a -> String
+test7 = show
+
+test8 = \_ -> show $ "testing"
+
+data Data a = Data a
+
+instance showData :: Show a => Show (Data a) where
+ show (Data a) = "Data (" <> show a <> ")"
+
+test3 = \_ -> show (Data "testing")
+
+instance functorData :: Functor Data where
+ map = liftM1
+
+instance applyData :: Apply Data where
+ apply = ap
+
+instance applicativeData :: Applicative Data where
+ pure = Data
+
+instance bindData :: Bind Data where
+ bind (Data a) f = f a
+
+instance monadData :: Monad Data
+
+data Maybe a = Nothing | Just a
+
+instance functorMaybe :: Functor Maybe where
+ map = liftM1
+
+instance applyMaybe :: Apply Maybe where
+ apply = ap
+
+instance applicativeMaybe :: Applicative Maybe where
+ pure = Just
+
+instance bindMaybe :: Bind Maybe where
+ bind Nothing _ = Nothing
+ bind (Just a) f = f a
+
+instance monadMaybe :: Monad Maybe
+
+test4 :: forall a m. Monad m => a -> m Number
+test4 = \_ -> pure 1.0
+
+test5 = \_ -> Just 1.0 >>= \n -> pure (n + 1.0)
+
+ask r = r
+
+runReader r f = f r
+
+test9 _ = runReader 0.0 $ do
+ n <- ask
+ pure $ n + 1.0
+
+main = do
+ log (test7 "Hello")
+ log "Done"
diff --git a/tests/purs/passing/TypeClassesInOrder.purs b/tests/purs/passing/TypeClassesInOrder.purs
new file mode 100644
index 0000000..fe62bcf
--- /dev/null
+++ b/tests/purs/passing/TypeClassesInOrder.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Foo a where
+ foo :: a -> String
+
+instance fooString :: Foo String where
+ foo s = s
+
+main = log $ foo "Done"
diff --git a/tests/purs/passing/TypeClassesWithOverlappingTypeVariables.purs b/tests/purs/passing/TypeClassesWithOverlappingTypeVariables.purs
new file mode 100644
index 0000000..c8019d1
--- /dev/null
+++ b/tests/purs/passing/TypeClassesWithOverlappingTypeVariables.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Either a b = Left a | Right b
+
+instance functorEither :: Functor (Either a) where
+ map _ (Left x) = Left x
+ map f (Right y) = Right (f y)
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeDecl.purs b/tests/purs/passing/TypeDecl.purs
new file mode 100644
index 0000000..64b8b77
--- /dev/null
+++ b/tests/purs/passing/TypeDecl.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+k :: String -> Number -> String
+k x y = x
+
+iterate :: forall a. Number -> (a -> a) -> a -> a
+iterate 0.0 f a = a
+iterate n f a = iterate (n - 1.0) f (f a)
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeOperators.purs b/tests/purs/passing/TypeOperators.purs
new file mode 100644
index 0000000..2c0c4df
--- /dev/null
+++ b/tests/purs/passing/TypeOperators.purs
@@ -0,0 +1,20 @@
+module Main where
+
+import A (type (~>), type (/\), (/\))
+import Effect.Console (log)
+
+natty ∷ ∀ f. f ~> f
+natty x = x
+
+data Compose f g a = Compose (f (g a))
+
+testPrecedence1 ∷ ∀ f g. Compose f g ~> Compose f g
+testPrecedence1 x = x
+
+testPrecedence2 ∷ ∀ f g. f ~> g → f ~> g
+testPrecedence2 nat fx = nat fx
+
+swap ∷ ∀ a b. a /\ b → b /\ a
+swap (a /\ b) = b /\ a
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeOperators/A.purs b/tests/purs/passing/TypeOperators/A.purs
new file mode 100644
index 0000000..1c1fe8b
--- /dev/null
+++ b/tests/purs/passing/TypeOperators/A.purs
@@ -0,0 +1,22 @@
+module A
+( Tuple(..)
+, type (/\)
+, (/\)
+, Natural
+, type (~>)
+) where
+
+data Tuple a b = Tuple a b
+
+infixl 6 Tuple as /\
+infixl 6 type Tuple as /\
+
+type Natural f g = ∀ a. f a → g a
+
+infixr 0 type Natural as ~>
+
+tup ∷ ∀ a b. a → b → b /\ a
+tup a b = b /\ a
+
+tupX ∷ ∀ a b c. a /\ b /\ c → c
+tupX (a /\ b /\ c) = c
diff --git a/tests/purs/passing/TypeSynonymInData.purs b/tests/purs/passing/TypeSynonymInData.purs
new file mode 100644
index 0000000..a003f1f
--- /dev/null
+++ b/tests/purs/passing/TypeSynonymInData.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type A a = Array a
+
+data Foo a = Foo (A a) | Bar
+
+foo (Foo []) = Bar
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeSynonyms.purs b/tests/purs/passing/TypeSynonyms.purs
new file mode 100644
index 0000000..55ddf98
--- /dev/null
+++ b/tests/purs/passing/TypeSynonyms.purs
@@ -0,0 +1,28 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+type Lens a b =
+ { get :: a -> b
+ , set :: a -> b -> a
+ }
+
+composeLenses :: forall a b c. Lens a b -> Lens b c -> Lens a c
+composeLenses = \l1 -> \l2 ->
+ { get: \a -> l2.get (l1.get a)
+ , set: \a c -> l1.set a (l2.set (l1.get a) c)
+ }
+
+type Pair a b = { fst :: a, snd :: b }
+
+fst :: forall a b. Lens (Pair a b) a
+fst =
+ { get: \p -> p.fst
+ , set: \p a -> { fst: a, snd: p.snd }
+ }
+
+test1 :: forall a b c. Lens (Pair (Pair a b) c) a
+test1 = composeLenses fst fst
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeWildcards.purs b/tests/purs/passing/TypeWildcards.purs
new file mode 100644
index 0000000..3fe4cfd
--- /dev/null
+++ b/tests/purs/passing/TypeWildcards.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+testTopLevel :: _ -> _
+testTopLevel n = n + 1.0
+
+test :: forall a. Eq a => (a -> a) -> a -> a
+test f a = go (f a) a
+ where
+ go :: _ -> _ -> _
+ go a1 a2 | a1 == a2 = a1
+ go a1 _ = go (f a1) a1
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeWildcardsRecordExtension.purs b/tests/purs/passing/TypeWildcardsRecordExtension.purs
new file mode 100644
index 0000000..d2400cf
--- /dev/null
+++ b/tests/purs/passing/TypeWildcardsRecordExtension.purs
@@ -0,0 +1,9 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+foo :: forall a. {b :: Number | a} -> {b :: Number | _}
+foo f = f
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeWithoutParens.purs b/tests/purs/passing/TypeWithoutParens.purs
new file mode 100644
index 0000000..aff33f2
--- /dev/null
+++ b/tests/purs/passing/TypeWithoutParens.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Lib (X, Y)
+import Effect.Console (log)
+
+idX :: X -> X
+idX x = x
+
+idY :: Y -> Y
+idY y = y
+
+main = log "Done"
diff --git a/tests/purs/passing/TypeWithoutParens/Lib.purs b/tests/purs/passing/TypeWithoutParens/Lib.purs
new file mode 100644
index 0000000..95b9a09
--- /dev/null
+++ b/tests/purs/passing/TypeWithoutParens/Lib.purs
@@ -0,0 +1,4 @@
+module Lib (X, Y) where
+
+data X = X
+type Y = X
diff --git a/tests/purs/passing/TypedBinders.purs b/tests/purs/passing/TypedBinders.purs
new file mode 100644
index 0000000..f94926e
--- /dev/null
+++ b/tests/purs/passing/TypedBinders.purs
@@ -0,0 +1,68 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Tuple a b = Tuple a b
+
+class MonadState s m where
+ get :: m s
+ put :: s -> m Unit
+
+data State s a = State (s -> Tuple s a)
+
+runState s (State f) = f s
+
+instance functorState :: Functor (State s) where
+ map = liftM1
+
+instance applyState :: Apply (State s) where
+ apply = ap
+
+instance applicativeState :: Applicative (State s) where
+ pure a = State $ \s -> Tuple s a
+
+instance bindState :: Bind (State s) where
+ bind f g = State $ \s -> case runState s f of
+ Tuple s1 a -> runState s1 (g a)
+
+instance monadState :: Monad (State s)
+
+instance monadStateState :: MonadState s (State s) where
+ get = State (\s -> Tuple s s)
+ put s = State (\_ -> Tuple s unit)
+
+modify :: forall m s. Monad m => MonadState s m => (s -> s) -> m Unit
+modify f = do
+ s <- get
+ put (f s)
+
+test :: Tuple String String
+test = runState "" $ do
+ modify $ (<>) "World!"
+ modify $ (<>) "Hello, "
+ str :: String <- get
+ pure str
+
+test2 :: (Int -> Int) -> Int
+test2 = (\(f :: Int -> Int) -> f 10)
+
+test3 :: Int -> Boolean
+test3 n = case n of
+ (0 :: Int) -> true
+ _ -> false
+
+test4 :: Tuple Int Int -> Tuple Int Int
+test4 = (\(Tuple a b :: Tuple Int Int) -> Tuple b a)
+
+type Int1 = Int
+
+test5 :: Int1 -> Int1
+test5 = \(x :: Int1) -> x
+
+main = do
+ let t1 = test
+ t2 = test2 identity
+ t3 = test3 1
+ t4 = test4 (Tuple 1 0)
+ log "Done"
diff --git a/tests/purs/passing/TypedWhere.purs b/tests/purs/passing/TypedWhere.purs
new file mode 100644
index 0000000..dfacebe
--- /dev/null
+++ b/tests/purs/passing/TypedWhere.purs
@@ -0,0 +1,18 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data E a b = L a | R b
+
+data L a = C a (L a) | N
+
+lefts :: forall a b. L (E a b) -> L a
+lefts = go N
+ where
+ go :: forall a b. L a -> L (E a b) -> L a
+ go ls N = ls
+ go ls (C (L a) rest) = go (C a ls) rest
+ go ls (C _ rest) = go ls rest
+
+main = log "Done"
diff --git a/tests/purs/passing/UTF8Sourcefile.purs b/tests/purs/passing/UTF8Sourcefile.purs
new file mode 100644
index 0000000..ecacfd7
--- /dev/null
+++ b/tests/purs/passing/UTF8Sourcefile.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Effect.Console
+
+-- '→' is multibyte sequence \u2192.
+utf8multibyte = "Hello λ→ world!!"
+
+main = log "Done"
diff --git a/tests/purs/passing/UnderscoreIdent.purs b/tests/purs/passing/UnderscoreIdent.purs
new file mode 100644
index 0000000..e09a09c
--- /dev/null
+++ b/tests/purs/passing/UnderscoreIdent.purs
@@ -0,0 +1,13 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+data Data_type = Con_Structor | Con_2 String
+
+type Type_name = Data_type
+
+done (Con_2 s) = s
+done _ = "Failed"
+
+main = log (done (Con_2 "Done"))
diff --git a/tests/purs/passing/UnicodeIdentifier.purs b/tests/purs/passing/UnicodeIdentifier.purs
new file mode 100644
index 0000000..021aa4e
--- /dev/null
+++ b/tests/purs/passing/UnicodeIdentifier.purs
@@ -0,0 +1,7 @@
+module Main where
+
+import Effect.Console (log)
+
+f asgård = asgård
+
+main = log (f "Done")
diff --git a/tests/purs/passing/UnicodeOperators.purs b/tests/purs/passing/UnicodeOperators.purs
new file mode 100644
index 0000000..0c86721
--- /dev/null
+++ b/tests/purs/passing/UnicodeOperators.purs
@@ -0,0 +1,22 @@
+module Main where
+
+import Effect.Console (log)
+
+compose :: forall a b c. (b -> c) -> (a -> b) -> a -> c
+compose f g a = f (g a)
+
+infixr 9 compose as ∘
+
+test1 = (\x -> x) ∘ \y -> y
+
+elem :: forall a b. a -> (a -> Boolean) -> Boolean
+elem x f = f x
+
+infixl 1 elem as ∈
+
+emptySet :: forall a. a -> Boolean
+emptySet _ = true
+
+test2 = 1 ∈ emptySet
+
+main = log "Done"
diff --git a/tests/purs/passing/UnicodeType.purs b/tests/purs/passing/UnicodeType.purs
new file mode 100644
index 0000000..2fd5b8a
--- /dev/null
+++ b/tests/purs/passing/UnicodeType.purs
@@ -0,0 +1,22 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Monad m ⇐ Monad1 m where
+ f1 :: m Int
+
+class Monad m <= Monad2 m where
+ f2 :: m Int
+
+f ∷ ∀ m. Monad m ⇒ Int → m Int
+f n = do
+ n' ← pure n
+ pure n'
+
+f' :: forall m. Monad m => Int -> m Int
+f' n = do
+ n' <- pure n
+ pure n'
+
+main = log "Done"
diff --git a/tests/purs/passing/UnifyInTypeInstanceLookup.purs b/tests/purs/passing/UnifyInTypeInstanceLookup.purs
new file mode 100644
index 0000000..dade5e9
--- /dev/null
+++ b/tests/purs/passing/UnifyInTypeInstanceLookup.purs
@@ -0,0 +1,25 @@
+module Main where
+
+import Effect.Console (log)
+
+data Z = Z
+data S n = S n
+
+data T
+data F
+
+class EQ x y b
+instance eqT :: EQ x x T
+instance eqF :: EQ x y F
+
+test :: forall a b. EQ a b T => a -> b -> a
+test a _ = a
+
+spin :: forall a b. a -> b
+spin a = spin a
+
+-- Expected type:
+-- forall t. (EQ t (S Z) T) => t
+test1 = test (spin 1) (S Z)
+
+main = log "Done"
diff --git a/tests/purs/passing/Unit.purs b/tests/purs/passing/Unit.purs
new file mode 100644
index 0000000..c585f64
--- /dev/null
+++ b/tests/purs/passing/Unit.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Prelude
+import Effect.Console (logShow, log)
+
+main = do
+ logShow (const unit $ "Hello world")
+ log "Done"
diff --git a/tests/purs/passing/UnknownInTypeClassLookup.purs b/tests/purs/passing/UnknownInTypeClassLookup.purs
new file mode 100644
index 0000000..d5d1936
--- /dev/null
+++ b/tests/purs/passing/UnknownInTypeClassLookup.purs
@@ -0,0 +1,15 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class EQ a b
+
+instance eqAA :: EQ a a
+
+test :: forall a b. EQ a b => a -> b -> String
+test _ _ = "Done"
+
+runTest a = test a a
+
+main = log $ runTest 0.0
diff --git a/tests/purs/passing/UnsafeCoerce.purs b/tests/purs/passing/UnsafeCoerce.purs
new file mode 100644
index 0000000..357e90f
--- /dev/null
+++ b/tests/purs/passing/UnsafeCoerce.purs
@@ -0,0 +1,16 @@
+module Main where
+
+import Prelude (Unit)
+import Unsafe.Coerce (unsafeCoerce)
+import Effect (Effect)
+import Effect.Console (log)
+
+x :: Number
+x = unsafeCoerce 1
+
+y :: Number
+y = case unsafeCoerce 1 of
+ z -> unsafeCoerce z
+
+main :: Effect Unit
+main = log "Done"
diff --git a/tests/purs/passing/UntupledConstraints.purs b/tests/purs/passing/UntupledConstraints.purs
new file mode 100644
index 0000000..2724fe6
--- /dev/null
+++ b/tests/purs/passing/UntupledConstraints.purs
@@ -0,0 +1,17 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+class Show a <= Nonsense a where
+ method :: a -> a
+
+data Box a = Box a
+
+instance showBox :: Show a => Show (Box a) where
+ show (Box a) = "Box " <> show a
+
+strangeThing :: forall m. Semigroup (m Unit) => m Unit -> m Unit -> m Unit
+strangeThing x y = x <> y
+
+main = log "Done"
diff --git a/tests/purs/passing/UsableTypeClassMethods.purs b/tests/purs/passing/UsableTypeClassMethods.purs
new file mode 100644
index 0000000..3222f04
--- /dev/null
+++ b/tests/purs/passing/UsableTypeClassMethods.purs
@@ -0,0 +1,35 @@
+-- this is testing that we don't see an `UnusableDeclaration` error for type
+-- class methods that should be valid based on various configurations of fundeps
+module Main where
+
+import Effect.Console (log)
+
+-- no fundeps
+class C0 a b where
+ c0 :: a -> b
+
+-- simple fundep
+class C1 a b | a -> b where
+ c1 :: a
+ c1' :: a -> b
+
+-- transitive
+class C2 a b c | a -> b, b -> c where
+ c2 :: a
+ c2' :: a -> b
+ c2'' :: a -> c
+ c2''' :: a -> b -> c
+
+-- with cycles
+class C3 a b c | a -> b, b -> a, b -> c where
+ c3 :: a
+ c3' :: b
+ c3'' :: a -> c
+ c3''' :: b -> c
+ c3'''' :: a -> b -> c
+
+-- nullary class
+class C4 where
+ c4 :: forall a. a
+
+main = log "Done"
diff --git a/tests/purs/passing/Where.purs b/tests/purs/passing/Where.purs
new file mode 100644
index 0000000..2b379da
--- /dev/null
+++ b/tests/purs/passing/Where.purs
@@ -0,0 +1,49 @@
+module Main where
+
+import Prelude
+import Partial.Unsafe (unsafePartial)
+import Effect
+import Effect.Console (logShow, log)
+
+test1 x = y
+ where
+ y :: Number
+ y = x + 1.0
+
+test2 x y = x' + y'
+ where
+ x' = x + 1.0
+ y' = y + 1.0
+
+test3 = f 1.0 2.0 3.0
+ where f x y z = x + y + z
+
+test4 = f (+) [1.0, 2.0]
+ where f x [y, z] = x y z
+
+test5 = g 10.0
+ where
+ f x | x > 0.0 = g (x / 2.0) + 1.0
+ f x = 0.0
+ g x = f (x - 1.0) + 1.0
+
+test6 = if f true then f 1.0 else f 2.0
+ where f :: forall a. a -> a
+ f x = x
+
+test7 :: Number -> Number
+test7 x = go x
+ where
+ go y | (x - 0.1 < y * y) && (y * y < x + 0.1) = y
+ go y = go $ (y + x / y) / 2.0
+
+main :: Effect _
+main = do
+ logShow (test1 1.0)
+ logShow (test2 1.0 2.0)
+ logShow test3
+ unsafePartial (logShow test4)
+ logShow test5
+ logShow test6
+ logShow (test7 100.0)
+ log "Done"
diff --git a/tests/purs/passing/WildcardInInstance.purs b/tests/purs/passing/WildcardInInstance.purs
new file mode 100644
index 0000000..f619a2c
--- /dev/null
+++ b/tests/purs/passing/WildcardInInstance.purs
@@ -0,0 +1,21 @@
+module Main where
+
+import Prelude
+import Effect
+import Effect.Console
+
+class Monad m <= MonadAsk r m | m -> r where
+ ask :: m r
+
+instance monadAskFun :: MonadAsk r ((->) r) where
+ ask = identity
+
+-- This should generate a warning with the correct inferred type.
+test :: forall m. MonadAsk _ m => m Int
+test = do
+ x <- ask
+ pure (x + 1)
+
+main :: Effect Unit
+main = do
+ log "Done"
diff --git a/tests/purs/passing/WildcardType.purs b/tests/purs/passing/WildcardType.purs
new file mode 100644
index 0000000..893c444
--- /dev/null
+++ b/tests/purs/passing/WildcardType.purs
@@ -0,0 +1,12 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+f1 :: (_ -> _) -> _
+f1 g = g 1
+
+f2 :: _ -> _
+f2 _ = "Done"
+
+main = log $ f1 f2
diff --git a/tests/purs/passing/iota.purs b/tests/purs/passing/iota.purs
new file mode 100644
index 0000000..a24ed80
--- /dev/null
+++ b/tests/purs/passing/iota.purs
@@ -0,0 +1,11 @@
+module Main where
+
+import Effect.Console (log)
+
+s = \x -> \y -> \z -> x z (y z)
+
+k = \x -> \y -> x
+
+iota = \x -> x s k
+
+main = log "Done"
diff --git a/tests/purs/passing/s.purs b/tests/purs/passing/s.purs
new file mode 100644
index 0000000..a9589fd
--- /dev/null
+++ b/tests/purs/passing/s.purs
@@ -0,0 +1,8 @@
+module Main where
+
+import Prelude
+import Effect.Console (log)
+
+s = \x y z -> x z (y z)
+
+main = log "Done"
diff --git a/tests/purs/psci/BasicEval.purs b/tests/purs/psci/BasicEval.purs
new file mode 100644
index 0000000..2722a71
--- /dev/null
+++ b/tests/purs/psci/BasicEval.purs
@@ -0,0 +1,10 @@
+import Prelude
+import Data.Array
+
+-- @shouldEvaluateTo 3628800
+let fac n = foldl mul 1 (1..n) in fac 10
+
+fac n = foldl mul 1 (1..n)
+
+-- @shouldEvaluateTo 3628800
+fac 10
diff --git a/tests/purs/psci/Multiline.purs b/tests/purs/psci/Multiline.purs
new file mode 100644
index 0000000..86f0dcf
--- /dev/null
+++ b/tests/purs/psci/Multiline.purs
@@ -0,0 +1,10 @@
+import Prelude
+import Data.Array
+
+-- @paste
+fac :: Int -> Int
+fac n = foldl mul 1 (1..n)
+-- @paste
+
+-- @shouldEvaluateTo 3628800
+fac 10
diff --git a/tests/purs/warning/2140.purs b/tests/purs/warning/2140.purs
new file mode 100644
index 0000000..3369cba
--- /dev/null
+++ b/tests/purs/warning/2140.purs
@@ -0,0 +1,5 @@
+-- @shouldWarnWith ShadowedTypeVar
+module Main where
+
+class Test a where
+ f :: (forall a. a -> a) -> a -> a
diff --git a/tests/purs/warning/2383.purs b/tests/purs/warning/2383.purs
new file mode 100644
index 0000000..855a4d6
--- /dev/null
+++ b/tests/purs/warning/2383.purs
@@ -0,0 +1,12 @@
+-- | This specifically shouldn't warn about `x` being shadowed in `main`
+-- | See https://github.com/purescript/purescript/issues/2383
+module Main where
+
+import Prelude
+
+import Effect (Effect)
+
+main :: Effect Unit
+main = do
+ x <- let x = pure unit in x
+ pure unit
diff --git a/tests/purs/warning/2411.purs b/tests/purs/warning/2411.purs
new file mode 100644
index 0000000..581c606
--- /dev/null
+++ b/tests/purs/warning/2411.purs
@@ -0,0 +1,15 @@
+-- @shouldWarnWith ShadowedName
+module Main where
+
+import Prelude
+
+import Effect (Effect)
+
+test :: forall m. Monad m => Int -> m Unit
+test x =
+ let x = unit
+ in pure x
+
+main :: Effect Unit
+main = test 42
+
diff --git a/tests/purs/warning/2542.purs b/tests/purs/warning/2542.purs
new file mode 100644
index 0000000..df7a68c
--- /dev/null
+++ b/tests/purs/warning/2542.purs
@@ -0,0 +1,16 @@
+-- @shouldWarnWith MissingTypeDeclaration
+module Main where
+
+import Effect.Console
+
+type T = forall a. Array a
+
+-- | Note: This should not raise a `ShadowedTypeVar` warning as the
+-- | type `a` introduced in `T` should not be in scope
+-- | in the definition of `bar`.
+foo :: T
+foo = bar where
+ bar :: forall a. Array a
+ bar = []
+
+main = log "Done"
diff --git a/tests/purs/warning/CustomWarning.purs b/tests/purs/warning/CustomWarning.purs
new file mode 100644
index 0000000..7d509eb
--- /dev/null
+++ b/tests/purs/warning/CustomWarning.purs
@@ -0,0 +1,11 @@
+-- @shouldWarnWith UserDefinedWarning
+module Main where
+
+import Prim.TypeError
+
+foo :: forall t. Warn (Beside (Text "Custom warning ") (Quote t)) => t -> t
+foo x = x
+
+bar :: Int
+bar = foo 42
+
diff --git a/tests/purs/warning/CustomWarning2.purs b/tests/purs/warning/CustomWarning2.purs
new file mode 100644
index 0000000..488dc4d
--- /dev/null
+++ b/tests/purs/warning/CustomWarning2.purs
@@ -0,0 +1,13 @@
+-- @shouldWarnWith UserDefinedWarning
+module Main where
+
+import Prim.TypeError
+
+foo :: Warn (Text "foo") => Int -> Int
+foo x = x
+
+bar :: Warn (Text "foo") => Int
+bar = foo 42
+
+baz :: Int
+baz = bar
diff --git a/tests/purs/warning/CustomWarning3.purs b/tests/purs/warning/CustomWarning3.purs
new file mode 100644
index 0000000..a43cce6
--- /dev/null
+++ b/tests/purs/warning/CustomWarning3.purs
@@ -0,0 +1,15 @@
+-- @shouldWarnWith UserDefinedWarning
+-- @shouldWarnWith UserDefinedWarning
+module Main where
+
+import Prim.TypeError
+
+foo :: Warn (Text "foo") => Int -> Int
+foo x = x
+
+-- Defer the "foo" warning and warn with "bar" as well
+bar :: Warn (Text "foo") => Warn (Text "bar") => Int
+bar = foo 42
+
+baz :: Int
+baz = bar
diff --git a/tests/purs/warning/DuplicateExportRef.purs b/tests/purs/warning/DuplicateExportRef.purs
new file mode 100644
index 0000000..aa70f7a
--- /dev/null
+++ b/tests/purs/warning/DuplicateExportRef.purs
@@ -0,0 +1,30 @@
+-- @shouldWarnWith DuplicateExportRef
+-- @shouldWarnWith DuplicateExportRef
+-- @shouldWarnWith DuplicateExportRef
+-- @shouldWarnWith DuplicateExportRef
+-- @shouldWarnWith DuplicateExportRef
+-- @shouldWarnWith DuplicateExportRef
+-- @shouldWarnWith DuplicateExportRef
+module Main
+ ( X(X, X), X
+ , fn, fn
+ , (!), (!)
+ , class Y, class Y
+ , Natural, type (~>), type (~>)
+ , module Prelude, module Prelude
+ ) where
+
+import Prelude (Unit)
+
+data X = X
+
+fn :: X -> X -> X
+fn _ _ = X
+
+infix 2 fn as !
+
+class Y a
+
+type Natural f g = forall a. f a -> g a
+
+infixl 1 type Natural as ~>
diff --git a/tests/purs/warning/DuplicateImport.purs b/tests/purs/warning/DuplicateImport.purs
new file mode 100644
index 0000000..f9a179b
--- /dev/null
+++ b/tests/purs/warning/DuplicateImport.purs
@@ -0,0 +1,10 @@
+-- @shouldWarnWith DuplicateImport
+module Main where
+
+import Prelude (Unit, unit, pure)
+import Prelude (Unit, unit, pure)
+
+import Effect (Effect)
+
+main :: Effect Unit
+main = pure unit
diff --git a/tests/purs/warning/DuplicateImportRef.purs b/tests/purs/warning/DuplicateImportRef.purs
new file mode 100644
index 0000000..e082bd4
--- /dev/null
+++ b/tests/purs/warning/DuplicateImportRef.purs
@@ -0,0 +1,18 @@
+-- @shouldWarnWith DuplicateImportRef
+-- @shouldWarnWith DuplicateImportRef
+-- @shouldWarnWith DuplicateImportRef
+-- @shouldWarnWith DuplicateImportRef
+module Main where
+
+import Prelude
+ ( Unit, Unit
+ , unit, unit
+ , class Functor, class Functor
+ , (<>), (<>)
+ )
+
+u :: Unit
+u = unit <> unit
+
+fid :: forall f a. Functor f => f a -> f a
+fid fa = fa
diff --git a/tests/purs/warning/DuplicateSelectiveImport.purs b/tests/purs/warning/DuplicateSelectiveImport.purs
new file mode 100644
index 0000000..ea97e85
--- /dev/null
+++ b/tests/purs/warning/DuplicateSelectiveImport.purs
@@ -0,0 +1,10 @@
+-- @shouldWarnWith DuplicateSelectiveImport
+module Main where
+
+import Prelude (Unit, unit)
+import Prelude (pure)
+
+import Effect (Effect)
+
+main :: Effect Unit
+main = pure unit
diff --git a/tests/purs/warning/HidingImport.purs b/tests/purs/warning/HidingImport.purs
new file mode 100644
index 0000000..aba434b
--- /dev/null
+++ b/tests/purs/warning/HidingImport.purs
@@ -0,0 +1,9 @@
+-- @shouldWarnWith HidingImport
+-- @shouldWarnWith HidingImport
+module Main where
+
+import Prelude hiding (one)
+import Effect hiding (untilE)
+
+main :: Effect Unit
+main = pure unit
diff --git a/tests/purs/warning/ImplicitImport.purs b/tests/purs/warning/ImplicitImport.purs
new file mode 100644
index 0000000..29a2f35
--- /dev/null
+++ b/tests/purs/warning/ImplicitImport.purs
@@ -0,0 +1,9 @@
+-- @shouldWarnWith ImplicitImport
+-- @shouldWarnWith ImplicitImport
+module Main where
+
+import Prelude
+import Effect
+
+main :: Effect Unit
+main = pure unit
diff --git a/tests/purs/warning/ImplicitQualifiedImport.purs b/tests/purs/warning/ImplicitQualifiedImport.purs
new file mode 100644
index 0000000..193e72b
--- /dev/null
+++ b/tests/purs/warning/ImplicitQualifiedImport.purs
@@ -0,0 +1,11 @@
+-- @shouldWarnWith ImplicitQualifiedImport
+-- @shouldWarnWith ImplicitQualifiedImport
+module Main where
+
+import Data.Unit
+
+import Effect as E
+import Effect.Console as E
+
+main :: E.Effect Unit
+main = E.log "test"
diff --git a/tests/purs/warning/ImplicitQualifiedImportReExport.purs b/tests/purs/warning/ImplicitQualifiedImportReExport.purs
new file mode 100644
index 0000000..92889cc
--- /dev/null
+++ b/tests/purs/warning/ImplicitQualifiedImportReExport.purs
@@ -0,0 +1,13 @@
+-- @shouldWarnWith ImplicitQualifiedImportReExport
+-- @shouldWarnWith ImplicitQualifiedImportReExport
+module Main (module X, module Y, main) where
+
+import Prelude
+
+import Effect (Effect)
+import Effect.Console (log)
+import Data.Maybe as X
+import Data.Either as Y
+
+main :: Effect Unit
+main = log "test"
diff --git a/tests/purs/warning/MissingTypeDeclaration.purs b/tests/purs/warning/MissingTypeDeclaration.purs
new file mode 100644
index 0000000..a5b8466
--- /dev/null
+++ b/tests/purs/warning/MissingTypeDeclaration.purs
@@ -0,0 +1,4 @@
+-- @shouldWarnWith MissingTypeDeclaration
+module Main where
+
+x = 0
diff --git a/tests/purs/warning/NewtypeInstance.purs b/tests/purs/warning/NewtypeInstance.purs
new file mode 100644
index 0000000..944ee45
--- /dev/null
+++ b/tests/purs/warning/NewtypeInstance.purs
@@ -0,0 +1,8 @@
+-- @shouldWarnWith MissingNewtypeSuperclassInstance
+module Main where
+
+import Prelude
+
+newtype X = X String
+
+derive newtype instance ordX :: Ord X
diff --git a/tests/purs/warning/NewtypeInstance2.purs b/tests/purs/warning/NewtypeInstance2.purs
new file mode 100644
index 0000000..d148ed0
--- /dev/null
+++ b/tests/purs/warning/NewtypeInstance2.purs
@@ -0,0 +1,15 @@
+-- @shouldWarnWith MissingNewtypeSuperclassInstance
+module Main where
+
+import Prelude
+import Data.Tuple (Tuple(..))
+
+class (Monad m, Monoid w) <= MonadWriter w m | m -> w where
+ tell :: w -> m Unit
+
+instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where
+ tell w = Tuple w unit
+
+newtype MyWriter w a = MyWriter (Tuple w a)
+
+derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)
diff --git a/tests/purs/warning/NewtypeInstance3.purs b/tests/purs/warning/NewtypeInstance3.purs
new file mode 100644
index 0000000..f61a558
--- /dev/null
+++ b/tests/purs/warning/NewtypeInstance3.purs
@@ -0,0 +1,21 @@
+-- @shouldWarnWith MissingNewtypeSuperclassInstance
+module Main where
+
+import Prelude
+import Data.Tuple (Tuple(..))
+
+class (Monad m, Monoid w) <= MonadTell w m | m -> w where
+ tell :: w -> m Unit
+
+class (MonadTell w m) <= MonadWriter w m | m -> w where
+ listen :: forall a. m a -> m (Tuple w a)
+
+instance monadTellTuple :: Monoid w => MonadTell w (Tuple w) where
+ tell w = Tuple w unit
+
+instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where
+ listen (Tuple w a) = Tuple w (Tuple w a)
+
+newtype MyWriter w a = MyWriter (Tuple w a)
+
+derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)
diff --git a/tests/purs/warning/NewtypeInstance4.purs b/tests/purs/warning/NewtypeInstance4.purs
new file mode 100644
index 0000000..878d56e
--- /dev/null
+++ b/tests/purs/warning/NewtypeInstance4.purs
@@ -0,0 +1,23 @@
+-- @shouldWarnWith UnverifiableSuperclassInstance
+module Main where
+
+import Prelude
+import Data.Tuple (Tuple(..))
+
+class Monoid w <= MonadTell w m where
+ tell :: w -> m Unit
+
+class (MonadTell w m) <= MonadWriter w m where
+ listen :: forall a. m a -> m (Tuple w a)
+
+instance monadTellTuple :: Monoid w => MonadTell w (Tuple w) where
+ tell w = Tuple w unit
+
+instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where
+ listen (Tuple w a) = Tuple w (Tuple w a)
+
+newtype MyWriter w a = MyWriter (Tuple w a)
+
+-- No fundep means this is unverifiable
+derive newtype instance monadTellMyWriter :: Monoid w => MonadTell w (MyWriter w)
+derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)
diff --git a/tests/purs/warning/OverlappingPattern.purs b/tests/purs/warning/OverlappingPattern.purs
new file mode 100644
index 0000000..d667eb3
--- /dev/null
+++ b/tests/purs/warning/OverlappingPattern.purs
@@ -0,0 +1,15 @@
+-- @shouldWarnWith OverlappingPattern
+-- @shouldWarnWith OverlappingPattern
+module Main where
+
+data X = A | B
+
+pat1 :: X -> Boolean
+pat1 A = true
+pat1 A = true
+pat1 B = false
+
+pat2 :: X -> Boolean
+pat2 A = true
+pat2 _ = false
+pat2 B = false
diff --git a/tests/purs/warning/ScopeShadowing.purs b/tests/purs/warning/ScopeShadowing.purs
new file mode 100644
index 0000000..380a4ee
--- /dev/null
+++ b/tests/purs/warning/ScopeShadowing.purs
@@ -0,0 +1,13 @@
+-- @shouldWarnWith ScopeShadowing
+module Main where
+
+import Prelude
+
+-- No warning at the definition, only when the name is later resolved
+data Unit = Unit
+
+-- This is only a warning as the `Prelude` import is implicit. If `Unit` was
+-- named explicitly in an import list, then this refernce to `Unit`
+-- would be a `ScopeConflict` error instead.
+test :: Unit
+test = const Unit unit
diff --git a/tests/purs/warning/ScopeShadowing2.purs b/tests/purs/warning/ScopeShadowing2.purs
new file mode 100644
index 0000000..d9c3598
--- /dev/null
+++ b/tests/purs/warning/ScopeShadowing2.purs
@@ -0,0 +1,10 @@
+-- @shouldWarnWith ScopeShadowing
+module Main
+ ( append
+ , module Data.Semigroup
+ ) where
+
+import Data.Semigroup
+
+append :: forall a. a -> a -> a
+append x _ = x
diff --git a/tests/purs/warning/ShadowedBinderPatternGuard.purs b/tests/purs/warning/ShadowedBinderPatternGuard.purs
new file mode 100644
index 0000000..f4bb85d
--- /dev/null
+++ b/tests/purs/warning/ShadowedBinderPatternGuard.purs
@@ -0,0 +1,7 @@
+-- @shouldWarnWith ShadowedName
+module Main where
+
+f :: Int -> Int
+f n | i <- true -- this i is shadowed
+ , i <- 1234
+ = i \ No newline at end of file
diff --git a/tests/purs/warning/ShadowedNameParens.purs b/tests/purs/warning/ShadowedNameParens.purs
new file mode 100644
index 0000000..9241f68
--- /dev/null
+++ b/tests/purs/warning/ShadowedNameParens.purs
@@ -0,0 +1,5 @@
+-- @shouldWarnWith ShadowedName
+module Main where
+
+f :: Int -> Int -> Int
+f n = \(n) -> 1
diff --git a/tests/purs/warning/ShadowedTypeVar.purs b/tests/purs/warning/ShadowedTypeVar.purs
new file mode 100644
index 0000000..89813e7
--- /dev/null
+++ b/tests/purs/warning/ShadowedTypeVar.purs
@@ -0,0 +1,5 @@
+-- @shouldWarnWith ShadowedTypeVar
+module Main where
+
+f :: forall a. (forall a. a -> a) -> a -> a
+f g x = g x
diff --git a/tests/purs/warning/UnnecessaryFFIModule.js b/tests/purs/warning/UnnecessaryFFIModule.js
new file mode 100644
index 0000000..346c8e9
--- /dev/null
+++ b/tests/purs/warning/UnnecessaryFFIModule.js
@@ -0,0 +1 @@
+exports.out = null;
diff --git a/tests/purs/warning/UnnecessaryFFIModule.purs b/tests/purs/warning/UnnecessaryFFIModule.purs
new file mode 100644
index 0000000..947aef9
--- /dev/null
+++ b/tests/purs/warning/UnnecessaryFFIModule.purs
@@ -0,0 +1,5 @@
+-- @shouldWarnWith UnnecessaryFFIModule
+module Main where
+
+t :: Boolean
+t = true
diff --git a/tests/purs/warning/UnusedDctorExplicitImport.purs b/tests/purs/warning/UnusedDctorExplicitImport.purs
new file mode 100644
index 0000000..35040ef
--- /dev/null
+++ b/tests/purs/warning/UnusedDctorExplicitImport.purs
@@ -0,0 +1,8 @@
+-- @shouldWarnWith UnusedDctorExplicitImport
+module Main where
+
+import Data.Ordering (Ordering(EQ, LT))
+
+f :: Ordering -> Ordering
+f EQ = EQ
+f x = x
diff --git a/tests/purs/warning/UnusedDctorImportAll.purs b/tests/purs/warning/UnusedDctorImportAll.purs
new file mode 100644
index 0000000..807302f
--- /dev/null
+++ b/tests/purs/warning/UnusedDctorImportAll.purs
@@ -0,0 +1,7 @@
+-- @shouldWarnWith UnusedDctorImport
+module Main where
+
+import Data.Ordering (Ordering(..))
+
+f :: Ordering -> Ordering
+f x = x
diff --git a/tests/purs/warning/UnusedDctorImportExplicit.purs b/tests/purs/warning/UnusedDctorImportExplicit.purs
new file mode 100644
index 0000000..11dc2d6
--- /dev/null
+++ b/tests/purs/warning/UnusedDctorImportExplicit.purs
@@ -0,0 +1,7 @@
+-- @shouldWarnWith UnusedDctorImport
+module Main where
+
+import Data.Ordering (Ordering(EQ))
+
+f :: Ordering -> Ordering
+f x = x
diff --git a/tests/purs/warning/UnusedExplicitImport.purs b/tests/purs/warning/UnusedExplicitImport.purs
new file mode 100644
index 0000000..d456c7a
--- /dev/null
+++ b/tests/purs/warning/UnusedExplicitImport.purs
@@ -0,0 +1,8 @@
+-- @shouldWarnWith UnusedExplicitImport
+module Main where
+
+import Prelude (Unit, unit, pure, bind)
+import Effect (Effect)
+
+main :: Effect Unit
+main = pure unit
diff --git a/tests/purs/warning/UnusedExplicitImportTypeOp.purs b/tests/purs/warning/UnusedExplicitImportTypeOp.purs
new file mode 100644
index 0000000..a7151ae
--- /dev/null
+++ b/tests/purs/warning/UnusedExplicitImportTypeOp.purs
@@ -0,0 +1,9 @@
+-- @shouldWarnWith UnusedExplicitImport
+module Main where
+
+import Prelude (Unit, unit, pure)
+import Effect (Effect)
+import Lib (type (~>), natId)
+
+main :: Effect Unit
+main = natId (pure unit)
diff --git a/tests/purs/warning/UnusedExplicitImportTypeOp/Lib.purs b/tests/purs/warning/UnusedExplicitImportTypeOp/Lib.purs
new file mode 100644
index 0000000..7a2d523
--- /dev/null
+++ b/tests/purs/warning/UnusedExplicitImportTypeOp/Lib.purs
@@ -0,0 +1,8 @@
+module Lib where
+
+type Nat f g = ∀ x. f x → g x
+
+infixr 4 type Nat as ~>
+
+natId ∷ ∀ f. f ~> f
+natId x = x
diff --git a/tests/purs/warning/UnusedExplicitImportValOp.purs b/tests/purs/warning/UnusedExplicitImportValOp.purs
new file mode 100644
index 0000000..920efe9
--- /dev/null
+++ b/tests/purs/warning/UnusedExplicitImportValOp.purs
@@ -0,0 +1,8 @@
+-- @shouldWarnWith UnusedExplicitImport
+module Main where
+
+import Prelude (Unit, unit, pure, (+))
+import Effect (Effect)
+
+main :: Effect Unit
+main = pure unit
diff --git a/tests/purs/warning/UnusedFFIImplementations.js b/tests/purs/warning/UnusedFFIImplementations.js
new file mode 100644
index 0000000..d50f2e6
--- /dev/null
+++ b/tests/purs/warning/UnusedFFIImplementations.js
@@ -0,0 +1,2 @@
+exports.yes = true;
+exports.no = false;
diff --git a/tests/purs/warning/UnusedFFIImplementations.purs b/tests/purs/warning/UnusedFFIImplementations.purs
new file mode 100644
index 0000000..6e263bf
--- /dev/null
+++ b/tests/purs/warning/UnusedFFIImplementations.purs
@@ -0,0 +1,4 @@
+-- @shouldWarnWith UnusedFFIImplementations
+module Main where
+
+foreign import yes :: Boolean
diff --git a/tests/purs/warning/UnusedImport.purs b/tests/purs/warning/UnusedImport.purs
new file mode 100644
index 0000000..1ecd4a3
--- /dev/null
+++ b/tests/purs/warning/UnusedImport.purs
@@ -0,0 +1,14 @@
+-- @shouldWarnWith UnusedImport
+-- @shouldWarnWith UnusedImport
+-- @shouldWarnWith UnusedImport
+module Main where
+
+import Data.Unit (Unit, unit)
+
+-- All of the below are unused
+import Effect
+import Effect.Console as Console
+import Test.Assert ()
+
+main :: Unit
+main = unit
diff --git a/tests/purs/warning/UnusedTypeVar.purs b/tests/purs/warning/UnusedTypeVar.purs
new file mode 100644
index 0000000..03a6410
--- /dev/null
+++ b/tests/purs/warning/UnusedTypeVar.purs
@@ -0,0 +1,5 @@
+-- @shouldWarnWith UnusedTypeVar
+module Main where
+
+f :: forall a b. a -> a
+f x = x
diff --git a/tests/purs/warning/WildcardInferredType.purs b/tests/purs/warning/WildcardInferredType.purs
new file mode 100644
index 0000000..3662384
--- /dev/null
+++ b/tests/purs/warning/WildcardInferredType.purs
@@ -0,0 +1,23 @@
+-- @shouldWarnWith WildcardInferredType
+-- @shouldWarnWith WildcardInferredType
+-- @shouldWarnWith WildcardInferredType
+-- @shouldWarnWith WildcardInferredType
+module Main where
+
+x :: Int
+x = 0 :: _
+
+y :: _
+y = 0
+
+z :: Int
+z =
+ let n :: _
+ n = 0
+ in n
+
+w :: Int
+w = n
+ where
+ n :: _
+ n = 0
diff --git a/tests/support/bower.json b/tests/support/bower.json
index 0973f7a..b44fb23 100644
--- a/tests/support/bower.json
+++ b/tests/support/bower.json
@@ -1,42 +1,77 @@
{
"name": "purescript-test-suite-support",
"dependencies": {
- "purescript-arrays": "4.1.2",
- "purescript-assert": "3.0.0",
- "purescript-bifunctors": "3.0.0",
- "purescript-console": "3.0.0",
- "purescript-control": "3.3.0",
- "purescript-distributive": "3.0.0",
- "purescript-eff": "3.1.0",
- "purescript-either": "3.1.0",
- "purescript-foldable-traversable": "3.4.0",
- "purescript-functions": "3.0.0",
- "purescript-gen": "1.1.0",
- "purescript-generics": "4.0.0",
- "purescript-generics-rep": "5.1.0",
- "purescript-globals": "3.0.0",
- "purescript-identity": "3.1.0",
- "purescript-integers": "3.1.0",
- "purescript-invariant": "3.0.0",
- "purescript-lazy": "3.0.0",
- "purescript-lists": "4.9.0",
- "purescript-math": "2.1.0",
- "purescript-maybe": "3.0.0",
- "purescript-monoid": "3.1.0",
- "purescript-newtype": "2.0.0",
- "purescript-nonempty": "4.0.0",
- "purescript-partial": "1.2.1",
- "purescript-prelude": "3.1.0",
- "purescript-proxy": "2.1.0",
- "purescript-psci-support": "3.0.0",
- "purescript-st": "3.0.0",
- "purescript-strings": "3.3.0",
- "purescript-symbols": "3.0.0",
- "purescript-tailrec": "3.3.0",
- "purescript-tuples": "4.1.0",
- "purescript-type-equality": "2.1.0",
- "purescript-typelevel-prelude": "2.3.0",
- "purescript-unfoldable": "3.0.0",
- "purescript-unsafe-coerce": "3.0.0"
+ "purescript-arrays": "purescript/purescript-arrays#compiler/0.12",
+ "purescript-assert": "purescript/purescript-assert#compiler/0.12",
+ "purescript-bifunctors": "purescript/purescript-bifunctors#compiler/0.12",
+ "purescript-console": "purescript/purescript-console#compiler/0.12",
+ "purescript-control": "purescript/purescript-control#compiler/0.12",
+ "purescript-distributive": "purescript/purescript-distributive#compiler/0.12",
+ "purescript-effect": "purescript/purescript-effect#compiler/0.12",
+ "purescript-either": "purescript/purescript-either#compiler/0.12",
+ "purescript-foldable-traversable": "purescript/purescript-foldable-traversable#compiler/0.12",
+ "purescript-functions": "purescript/purescript-functions#compiler/0.12",
+ "purescript-gen": "purescript/purescript-gen#compiler/0.12",
+ "purescript-generics-rep": "purescript/purescript-generics-rep#compiler/0.12",
+ "purescript-globals": "purescript/purescript-globals#compiler/0.12",
+ "purescript-identity": "purescript/purescript-identity#compiler/0.12",
+ "purescript-integers": "purescript/purescript-integers#compiler/0.12",
+ "purescript-invariant": "purescript/purescript-invariant#compiler/0.12",
+ "purescript-lazy": "purescript/purescript-lazy#compiler/0.12",
+ "purescript-lists": "purescript/purescript-lists#compiler/0.12",
+ "purescript-math": "purescript/purescript-math#compiler/0.12",
+ "purescript-maybe": "purescript/purescript-maybe#compiler/0.12",
+ "purescript-newtype": "purescript/purescript-newtype#compiler/0.12",
+ "purescript-nonempty": "purescript/purescript-nonempty#compiler/0.12",
+ "purescript-partial": "purescript/purescript-partial#compiler/0.12",
+ "purescript-prelude": "purescript/purescript-prelude#compiler/0.12",
+ "purescript-proxy": "purescript/purescript-proxy#compiler/0.12",
+ "purescript-psci-support": "purescript/purescript-psci-support#compiler/0.12",
+ "purescript-refs": "purescript/purescript-refs#compiler/0.12",
+ "purescript-st": "purescript/purescript-st#compiler/0.12",
+ "purescript-strings": "purescript/purescript-strings#compiler/0.12",
+ "purescript-tailrec": "purescript/purescript-tailrec#compiler/0.12",
+ "purescript-tuples": "purescript/purescript-tuples#compiler/0.12",
+ "purescript-type-equality": "purescript/purescript-type-equality#compiler/0.12",
+ "purescript-typelevel-prelude": "purescript/purescript-typelevel-prelude#compiler/0.12",
+ "purescript-unfoldable": "purescript/purescript-unfoldable#compiler/0.12",
+ "purescript-unsafe-coerce": "purescript/purescript-unsafe-coerce#compiler/0.12"
+ },
+ "resolutions": {
+ "purescript-arrays": "compiler/0.12",
+ "purescript-assert": "compiler/0.12",
+ "purescript-bifunctors": "compiler/0.12",
+ "purescript-console": "compiler/0.12",
+ "purescript-control": "compiler/0.12",
+ "purescript-distributive": "compiler/0.12",
+ "purescript-effect": "compiler/0.12",
+ "purescript-either": "compiler/0.12",
+ "purescript-foldable-traversable": "compiler/0.12",
+ "purescript-functions": "compiler/0.12",
+ "purescript-gen": "compiler/0.12",
+ "purescript-generics-rep": "compiler/0.12",
+ "purescript-globals": "compiler/0.12",
+ "purescript-identity": "compiler/0.12",
+ "purescript-integers": "compiler/0.12",
+ "purescript-invariant": "compiler/0.12",
+ "purescript-lazy": "compiler/0.12",
+ "purescript-lists": "compiler/0.12",
+ "purescript-math": "compiler/0.12",
+ "purescript-maybe": "compiler/0.12",
+ "purescript-newtype": "compiler/0.12",
+ "purescript-nonempty": "compiler/0.12",
+ "purescript-partial": "compiler/0.12",
+ "purescript-prelude": "compiler/0.12",
+ "purescript-proxy": "compiler/0.12",
+ "purescript-psci-support": "compiler/0.12",
+ "purescript-refs": "compiler/0.12",
+ "purescript-st": "compiler/0.12",
+ "purescript-strings": "compiler/0.12",
+ "purescript-tailrec": "compiler/0.12",
+ "purescript-tuples": "compiler/0.12",
+ "purescript-type-equality": "compiler/0.12",
+ "purescript-typelevel-prelude": "compiler/0.12",
+ "purescript-unfoldable": "compiler/0.12",
+ "purescript-unsafe-coerce": "compiler/0.12"
}
}
diff --git a/tests/support/package-lock.json b/tests/support/package-lock.json
new file mode 100644
index 0000000..4e3a140
--- /dev/null
+++ b/tests/support/package-lock.json
@@ -0,0 +1,171 @@
+{
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "bower": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.2.tgz",
+ "integrity": "sha1-rfU1KcjUrwLvJPuNU0HBQZ0z4vc="
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.11"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ }
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "requires": {
+ "glob": "7.1.2"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.11"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ }
+ }
+ }
+ }
+}
diff --git a/tests/support/pscide/src/FindUsage.purs b/tests/support/pscide/src/FindUsage.purs
new file mode 100644
index 0000000..b8a6ab0
--- /dev/null
+++ b/tests/support/pscide/src/FindUsage.purs
@@ -0,0 +1,12 @@
+module FindUsage where
+
+import FindUsage.Definition (usageId, ($%), Usage(..))
+import FindUsage.Reexport (toBeReexported)
+
+usagePatternMatch ∷ Usage → Usage
+usagePatternMatch x = case x of
+ Used _ → x
+ _ $% _ → x
+
+usageFn ∷ ∀ a. a → a
+usageFn = usageId toBeReexported
diff --git a/tests/support/pscide/src/FindUsage/Definition.purs b/tests/support/pscide/src/FindUsage/Definition.purs
new file mode 100644
index 0000000..f94b605
--- /dev/null
+++ b/tests/support/pscide/src/FindUsage/Definition.purs
@@ -0,0 +1,13 @@
+module FindUsage.Definition (Usage(..), ($%), usageId, toBeReexported) where
+
+data Usage
+ = Used Int
+ | Usage Int Int
+
+infixl 2 Usage as $%
+
+usageId ∷ ∀ a. a → a
+usageId x = x
+
+toBeReexported ∷ ∀ a. a → a
+toBeReexported = usageId
diff --git a/tests/support/pscide/src/FindUsage/Recursive.purs b/tests/support/pscide/src/FindUsage/Recursive.purs
new file mode 100644
index 0000000..e32ba99
--- /dev/null
+++ b/tests/support/pscide/src/FindUsage/Recursive.purs
@@ -0,0 +1,8 @@
+module FindUsage.Recursive where
+
+data Nat = Suc Nat | Z
+
+recursiveUsage :: Nat -> Int
+recursiveUsage = case _ of
+ Suc x -> recursiveUsage x
+ Z -> 0
diff --git a/tests/support/pscide/src/FindUsage/RecursiveShadowed.purs b/tests/support/pscide/src/FindUsage/RecursiveShadowed.purs
new file mode 100644
index 0000000..3fc0d63
--- /dev/null
+++ b/tests/support/pscide/src/FindUsage/RecursiveShadowed.purs
@@ -0,0 +1,10 @@
+module FindUsage.RecursiveShadowed where
+
+data Nat = Suc Nat | Z
+
+recursiveUsage :: Nat -> Int
+recursiveUsage = case _ of
+ Suc x ->
+ let recursiveUsage = 3
+ in recursiveUsage
+ Z -> 0
diff --git a/tests/support/pscide/src/FindUsage/Reexport.purs b/tests/support/pscide/src/FindUsage/Reexport.purs
new file mode 100644
index 0000000..7a55c39
--- /dev/null
+++ b/tests/support/pscide/src/FindUsage/Reexport.purs
@@ -0,0 +1,3 @@
+module FindUsage.Reexport (module X) where
+
+import FindUsage.Definition (toBeReexported) as X
diff --git a/tests/support/setup-win.cmd b/tests/support/setup-win.cmd
index 2b40898..2b40898 100644..100755
--- a/tests/support/setup-win.cmd
+++ b/tests/support/setup-win.cmd