@@ -376,16 +376,18 @@ entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filt
377 checkOverlaps :: [DictionaryValue] -> Check Expr
377 checkOverlaps :: [DictionaryValue] -> Check Expr
378 checkOverlaps dicts =
378 checkOverlaps dicts =
379− case sortedNubBy dictTrace (chooseSimplestDictionaries dicts) of
379+ case [ (d1, d2) | d1 <- dicts, d2 <- dicts, d1 `overlapping` d2 ] of
380− [] -> throwError . strMsg $ "No instance found for " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys)
381− [_] -> return $ dictionaryValueToValue $ head dicts
382− (d1 : d2 : _) -> throwError . strMsg $ unlines
380+ (d1, d2) : _ -> throwError . strMsg $ unlines
383 [ "Overlapping instances found for " ++ show className ++ " " ++ unwords (map prettyPrintType tys) ++ "."
381 [ "Overlapping instances found for " ++ show className ++ " " ++ unwords (map prettyPrintType tys) ++ "."
384 , "For example:"
382 , "For example:"
385 , prettyPrintDictionaryValue d1
383 , prettyPrintDictionaryValue d1
387 , prettyPrintDictionaryValue d2
385 , prettyPrintDictionaryValue d2
387+ _ -> case chooseSimplestDictionaries dicts of
388+ [] -> throwError . strMsg $
389+ "No instance found for " ++ show className ++ " " ++ unwords (map prettyPrintTypeAtom tys)
390+ d : _ -> return $ dictionaryValueToValue d
389 -- Choose the simplest DictionaryValues from a list of candidates
391 -- Choose the simplest DictionaryValues from a list of candidates
390 -- The reason for this function is as follows:
392 -- The reason for this function is as follows:
391 -- When considering overlapping instances, we don't want to consider the same dictionary
393 -- When considering overlapping instances, we don't want to consider the same dictionary
@@ -402,13 +404,19 @@ entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filt
402 isSimpleDictionaryValue (DependentDictionaryValue _ ds) = all isSimpleDictionaryValue ds
404 isSimpleDictionaryValue (DependentDictionaryValue _ ds) = all isSimpleDictionaryValue ds
403 isSimpleDictionaryValue _ = True
405 isSimpleDictionaryValue _ = True
405− -- Get the "trace" of a DictionaryValue - that is, remove all SubclassDictionaryValue
407+ -- Check if two dictionaries are overlapping
406− -- data constructors
408+ --
409+ -- Dictionaries which are subclass dictionaries cannot overlap, since otherwise the overlap would have
410+ -- been caught when constructing superclass dictionaries.
408− dictTrace :: DictionaryValue -> DictionaryValue
412+ overlapping :: DictionaryValue -> DictionaryValue -> Bool
409− dictTrace (DependentDictionaryValue fnName dicts) = DependentDictionaryValue fnName $ map dictTrace dicts
413+ overlapping (LocalDictionaryValue nm1) (LocalDictionaryValue nm2) | nm1 == nm2 = False
414+ overlapping (GlobalDictionaryValue nm1) (GlobalDictionaryValue nm2) | nm1 == nm2 = False
415+ overlapping (DependentDictionaryValue nm1 ds1) (DependentDictionaryValue nm2 ds2)
416+ | nm1 == nm2 = any id $ zipWith overlapping ds1 ds2
410− dictTrace (SubclassDictionaryValue dict _ _) = dictTrace dict
417+ overlapping (SubclassDictionaryValue _ _ _) _ = False
411− dictTrace other = other
418+ overlapping _ (SubclassDictionaryValue _ _ _) = False
419+ overlapping _ _ = True
413 -- Render a DictionaryValue fit for human consumption in error messages
421 -- Render a DictionaryValue fit for human consumption in error messages