Commit 1ca40c20 authored by's avatar
Browse files

Fix the GHC.Base.inline builtin rule

The BuiltIn rule for GHC.Base.inline wasn't working for two reasons:
 a) inlineIdName wasn't in basicKnownKeyNames
 b) The rule function wasn't taking into account the type argument

Thanks to Brian Alliet for spotting this bug. 
parent 63f8bf01
......@@ -188,7 +188,7 @@ basicKnownKeyNames
wordTyConName, word8TyConName, word16TyConName, word32TyConName, word64TyConName,
-- Others
otherwiseIdName, inlineIdName,
plusIntegerName, timesIntegerName,
eqStringName, assertName, breakpointName, breakpointCondName,
breakpointAutoName, opaqueTyConName, unknownTyConName,
......@@ -451,9 +451,12 @@ dataToTagRule other = Nothing
builtinRules :: [CoreRule]
-- Rules for non-primops that can't be expressed using a RULE pragma
= [ BuiltinRule FSLIT("AppendLitString") unpackCStringFoldrName 4 match_append_lit,
BuiltinRule FSLIT("EqString") eqStringName 2 match_eq_string,
BuiltinRule FSLIT("Inline") inlineIdName 1 match_inline
= [ BuiltinRule { ru_name = FSLIT("AppendLitString"), ru_fn = unpackCStringFoldrName,
ru_nargs = 4, ru_try = match_append_lit },
BuiltinRule { ru_name = FSLIT("EqString"), ru_fn = eqStringName,
ru_nargs = 2, ru_try = match_eq_string },
BuiltinRule { ru_name = FSLIT("Inline"), ru_fn = inlineIdName,
ru_nargs = 2, ru_try = match_inline }
......@@ -494,9 +497,18 @@ match_eq_string other = Nothing
-- The rule is this:
-- inline (f a b c) = <f's unfolding> a b c
-- inline f_ty (f a b c) = <f's unfolding> a b c
-- (if f has an unfolding)
match_inline (e:_)
-- It's important to allow the argument to 'inline' to have args itself
-- (a) because its more forgiving to allow the programmer to write
-- inline f a b c
-- or inline (f a b c)
-- (b) because a polymorphic f wll get a type argument that the
-- programmer can't avoid
-- Also, don't forget about 'inline's type argument!
match_inline (Type _ : e : _)
| (Var f, args1) <- collectArgs e,
Just unf <- maybeUnfoldingTemplate (idUnfolding f)
= Just (mkApps unf args1)
......@@ -195,10 +195,27 @@ pprRuleBase rules = vcat [ pprRules (tidyRules emptyTidyEnv rs)
%* *
Note [Extra args in rule matching]
If we find a matching rule, we return (Just (rule, rhs)),
but the rule firing has only consumed as many of the input args
as the ruleArity says. It's up to the caller to keep track
of any left-over args. E.g. if you call
lookupRule ... f [e1, e2, e3]
and it returns Just (r, rhs), where r has ruleArity 2
then the real rewrite is
f e1 e2 e3 ==> rhs e3
You might think it'd be cleaner for lookupRule to deal with the
leftover arguments, by applying 'rhs' to them, but the main call
in the Simplifier works better as it is. Reason: the 'args' passed
to lookupRule are the result of a lazy substitution
lookupRule :: (Activation -> Bool) -> InScopeSet
-> RuleBase -- Imported rules
-> Id -> [CoreExpr] -> Maybe (CoreRule, CoreExpr)
-- See Note [Extra argsin rule matching]
lookupRule is_active in_scope rule_base fn args
= matchRules is_active in_scope fn args rules
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment