@@ -251,7 +251,8 @@ data Phase = CompileTime | RunTime
251-- Work Right to Left
251-- Work Right to Left
253simpleCase :: Bool -> SC -> Bool ->
253simpleCase :: Bool -> SC -> Bool ->
254− Phase -> FC -> [Int] -> [Type] ->
254+ Phase -> FC -> [Int] ->
255+ [(Type, Bool)] -> -- ^ (Argument type, whether it's canonical)
255 [([Name], Term, Term)] ->
256 [([Name], Term, Term)] ->
256 ErasureInfo ->
257 ErasureInfo ->
257 TC CaseDef
258 TC CaseDef
@@ -273,7 +274,7 @@ simpleCase tc defcase reflect phase fc inacc argtys cs erInfo
273 OK pats ->
274 OK pats ->
274 let numargs = length (fst (head pats))
275 let numargs = length (fst (head pats))
275 ns = take numargs args
276 ns = take numargs args
276− (ns', ps') = order [(n, i `elem` inacc) | (i,n) <- zip [0..] ns] pats
277+ (ns', ps') = order phase [(n, i `elem` inacc) | (i,n) <- zip [0..] ns] pats (map snd argtys)
277 (tree, st) = runCaseBuilder erInfo
278 (tree, st) = runCaseBuilder erInfo
278 (match ns' ps' defcase)
279 (match ns' ps' defcase)
279 ([], numargs, [])
280 ([], numargs, [])
@@ -431,28 +432,38 @@ partition xs = error $ "Partition " ++ show xs
432-- The first argument means [(Name, IsInaccessible)].
433-- The first argument means [(Name, IsInaccessible)].
434−order :: [(Name, Bool)] -> [Clause] -> ([Name], [Clause])
435+order :: Phase -> [(Name, Bool)] -> [Clause] -> [Bool] -> ([Name], [Clause])
436+-- do nothing at compile time: FIXME (EB): Put this in after checking
437+-- implications for Franck's reflection work... see issue 3233
438+-- order CompileTime ns cs _ = (map fst ns, cs)
435−order [] cs = ([], cs)
439+order _ [] cs cans = ([], cs)
436−order ns' [] = (map fst ns', [])
440+order _ ns' [] cans = (map fst ns', [])
441+order phase ns' cs cans
437−order ns' cs = let patnames = transpose (map (zip ns') (map fst cs))
442+ = let patnames = transpose (map (zip ns') (map (zip cans) (map fst cs)))
438− -- only sort the arguments where there is no clash in
443+ -- only sort the arguments where there is no clash in
444+ -- constructor tags between families, the argument type is canonical,
439− -- constructor tags between families, and no constructor/constant
445+ -- and no constructor/constant
440− -- clash, because otherwise we can't reliable make the
446+ -- clash, because otherwise we can't reliable make the
441− -- case distinction on evaluation
447+ -- case distinction on evaluation
442− (patnames_ord, patnames_rest)
448+ (patnames_ord, patnames_rest)
443− = Data.List.partition (noClash . map snd) patnames
449+ = Data.List.partition (noClash . map snd) patnames
444− -- note: sortBy . reverse is not nonsense because sortBy is stable
450+ patnames_ord' = case phase of
451+ CompileTime -> patnames_ord
452+ -- reversing tends to make better case trees
453+ -- and helps erasure
454+ RunTime -> reverse patnames_ord
445− pats' = transpose (sortBy moreDistinct (reverse patnames_ord)
455+ pats' = transpose (sortBy moreDistinct patnames_ord'
446− ++ patnames_rest) in
456+ ++ patnames_rest) in
447− (getNOrder pats', zipWith rebuild pats' cs)
457+ (getNOrder pats', zipWith rebuild pats' cs)
449 getNOrder [] = error $ "Failed order on " ++ show (map fst ns', cs)
459 getNOrder [] = error $ "Failed order on " ++ show (map fst ns', cs)
450 getNOrder (c : _) = map (fst . fst) c
460 getNOrder (c : _) = map (fst . fst) c
452− rebuild patnames clause = (map snd patnames, snd clause)
462+ rebuild patnames clause = (map (snd . snd) patnames, snd clause)
454 noClash [] = True
464 noClash [] = True
455− noClash (p : ps) = not (any (clashPat p) ps) && noClash ps
465+ noClash ((can, p) : ps) = can && not (any (clashPat p) (map snd ps))
457 clashPat (PCon _ _ _ _) (PConst _) = True
468 clashPat (PCon _ _ _ _) (PConst _) = True
458 clashPat (PConst _) (PCon _ _ _ _) = True
469 clashPat (PConst _) (PCon _ _ _ _) = True
@@ -462,12 +473,13 @@ order ns' cs = let patnames = transpose (map (zip ns') (map fst cs))
462 clashPat _ _ = False
473 clashPat _ _ = False
464 -- this compares (+isInaccessible, -numberOfCases)
475 -- this compares (+isInaccessible, -numberOfCases)
465− moreDistinct xs ys = compare (snd . fst . head $ xs, numNames [] (map snd ys))
477+ = compare (snd . fst . head $ xs, numNames [] (map snd ys))
466− (snd . fst . head $ ys, numNames [] (map snd xs))
478+ (snd . fst . head $ ys, numNames [] (map snd xs))
468− numNames xs (PCon _ n _ _ : ps)
480+ numNames xs ((_, PCon _ n _ _) : ps)
469 | not (Left n `elem` xs) = numNames (Left n : xs) ps
481 | not (Left n `elem` xs) = numNames (Left n : xs) ps
470− numNames xs (PConst c : ps)
482+ numNames xs ((_, PConst c) : ps)
471 | not (Right c `elem` xs) = numNames (Right c : xs) ps
483 | not (Right c `elem` xs) = numNames (Right c : xs) ps
472 numNames xs (_ : ps) = numNames xs ps
484 numNames xs (_ : ps) = numNames xs ps
473 numNames xs [] = length xs
485 numNames xs [] = length xs