From: simonpj@microsoft.com Date: Fri, 15 Oct 2010 13:18:14 +0000 (+0000) Subject: Give user-defined rules precedence over built-in rules X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=b3bc4006fef38476d2e66d99879d5adc71d5aa6a Give user-defined rules precedence over built-in rules This fixes Trac #4397. See comments with 'isMoreSpecific'. --- diff --git a/compiler/specialise/Rules.lhs b/compiler/specialise/Rules.lhs index ce9f64a..8ff1edc 100644 --- a/compiler/specialise/Rules.lhs +++ b/compiler/specialise/Rules.lhs @@ -382,8 +382,18 @@ findBest target (rule1,ans1) ((rule2,ans2):prs) (fn,args) = target isMoreSpecific :: CoreRule -> CoreRule -> Bool -isMoreSpecific (BuiltinRule {}) _ = True -isMoreSpecific _ (BuiltinRule {}) = False +-- This tests if one rule is more specific than another +-- We take the view that a BuiltinRule is less specific than +-- anything else, because we want user-define rules to "win" +-- In particular, class ops have a built-in rule, but we +-- any user-specific rules to win +-- eg (Trac #4397) +-- truncate :: (RealFrac a, Integral b) => a -> b +-- {-# RULES "truncate/Double->Int" truncate = double2Int #-} +-- double2Int :: Double -> Int +-- We want the specific RULE to beat the built-in class-op rule +isMoreSpecific (BuiltinRule {}) _ = False +isMoreSpecific (Rule {}) (BuiltinRule {}) = True isMoreSpecific (Rule { ru_bndrs = bndrs1, ru_args = args1 }) (Rule { ru_bndrs = bndrs2, ru_args = args2 }) = isJust (matchN id_unfolding_fun in_scope bndrs2 args2 args1)