@@ -139,14 +139,39 @@ resolveAttributeExprTypeVars (AttributeAndTypeNameExpr _ tCons _) aType tConsMap
139139
140140-- check that type vars on the right also appear on the left
141141-- check that the data constructor names are unique
142−validateTypeConstructorDef :: TypeConstructorDef -> [DataConstructorDef] -> [RelationalError]
143−validateTypeConstructorDef tConsDef dConsList = execWriter $ do
142+validateTypeConstructorDef :: TypeConstructorDef -> [DataConstructorDef] -> TypeConstructorMapping -> Either RelationalError ()
143+validateTypeConstructorDef tConsDef dConsList tConsMap = do
144144 let duplicateDConsNames = dupes (L.sort (map DCD.name dConsList))
145− mapM_ tell [map DataConstructorNameInUseError duplicateDConsNames]
145+ when (length duplicateDConsNames > 0) (Left (someErrors (map DataConstructorNameInUseError duplicateDConsNames)))
146146 let leftSideVars = S.fromList (TCD.typeVars tConsDef)
147147 rightSideVars = S.unions (map DCD.typeVars dConsList)
148148 varsDiff = S.difference leftSideVars rightSideVars
149− mapM_ tell [map DataConstructorUsesUndeclaredTypeVariable (S.toList varsDiff)]
149+ when (S.size varsDiff > 0) (Left (someErrors (map DataConstructorUsesUndeclaredTypeVariable (S.toList varsDiff))))
150+ mapM_ (\dConsDef -> validateDataConstructorDef dConsDef tConsDef tConsMap) dConsList
151+
152+--check that the data constructor names are not in use (recursively)
153+validateDataConstructorDef :: DataConstructorDef -> TypeConstructorDef -> TypeConstructorMapping -> Either RelationalError ()
154+validateDataConstructorDef (DataConstructorDef dConsName dConsDefArgs) tConsDef tConsMap = do
155+ case findDataConstructor dConsName tConsMap of
156+ Just _ -> Left (DataConstructorNameInUseError dConsName)
157+ Nothing -> do
158+ mapM_ (\arg -> validateDataConstructorDefArg arg tConsDef tConsMap) dConsDefArgs
159+
160+
161+validateDataConstructorDefArg :: DataConstructorDefArg -> TypeConstructorDef -> TypeConstructorMapping -> Either RelationalError ()
162+validateDataConstructorDefArg (DataConstructorDefTypeConstructorArg (PrimitiveTypeConstructor _ _)) _ _ = Right ()
163+validateDataConstructorDefArg (DataConstructorDefTypeConstructorArg (TypeVariable _)) _ _ = Right ()
164+validateDataConstructorDefArg (DataConstructorDefTypeConstructorArg tCons) tConsDef tConsMap = case findTypeConstructor (TC.name tCons) tConsMap of
165+ Nothing -> do
166+ when (TC.name tCons /= TCD.name tConsDef) (Left (NoSuchTypeConstructorName (TC.name tCons))) --allows for recursively-defined types
167+ pure ()
168+ Just (ADTypeConstructorDef _ tConsArgs, _) -> do --validate that the argument count matches- type matching can occur later
169+ let existingCount = length tConsArgs
170+ newCount = length (TC.arguments tCons)
171+ when (newCount /= existingCount) (Left (ConstructedAtomArgumentCountMismatchError existingCount newCount))
172+ pure ()
173+ Just (PrimitiveTypeConstructorDef _ _, _) -> pure ()
174+validateDataConstructorDefArg (DataConstructorDefTypeVarNameArg _) _ _ = Right ()
150175
151176atomTypeForTypeConstructor :: TypeConstructor -> TypeConstructorMapping -> TypeVarMap -> Either RelationalError AtomType
152177atomTypeForTypeConstructor = atomTypeForTypeConstructorValidate False