Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,868
    • Issues 4,868
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 456
    • Merge requests 456
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #18677
Closed
Open
Created Sep 11, 2020 by Simon Peyton Jones@simonpjDeveloper

Rewrite rule can trigger Lint

Consider this program (produced by Michael Sperber)

{-# LANGUAGE MagicHash #-}
module ConCatRules where

import GHC.Prim
import GHC.Int

unboxI :: Int -> Int#
unboxI (I# i#) = i#

plus :: Int -> Int -> Int
plus x y = plus x y
{-# NOINLINE plus #-}

{-# RULES
"reboxa" forall u# v# . (+#) u# v# = unboxI (plus (I# u#) (I# v#))
#-}

foo = I# (10# +# 1#)

Compile with -O and you get

*** Core Lint errors : in result of Simplifier ***
Bar.hs:25:1: warning:
    This argument does not satisfy the let/app invariant:
      case plus (I# 10#) (I# 1#) of { I# i#_aBa -> i#_aBa }
    In the RHS of foo :: Int
    Substitution: [TCvSubst
                     In scope: InScope {}
                     Type env: []
                     Co env: []]

There is a good reason for this. The RULE rewrites

  • an expression that is okForSpeculation (namely 10# +# 1#)
  • into an expression that is not okForSpeculation (namely case plus (I# 10#) (I# 1#) of { I# i#_aBa -> i#_aBa })

The former is allowed as an argument of I# (as it appears in foo); but the latter is not, by the let/app invariant.

GHC never itself rewrites an expression that is okForSpeculation into one that isn't. But this RULE does. And that triggers Lint.

Is this a bug in GHC, or a bug in the RULE?

We could make the simplifier test for this situation, without much difficulty, but doing so would impose a small extra overhead on every compilation.

Edited Sep 11, 2020 by Simon Peyton Jones
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking