Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,252
    • Issues 4,252
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 398
    • Merge Requests 398
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #11698

Closed
Open
Opened Mar 10, 2016 by Simon Peyton Jones@simonpjDeveloper

GHC's tct_closed flag is not being set correctly

The Note [Bindings with closed types] in TcEnv describes when a binding is "closed", which in turn affects generalisation. (See the Note for details.)

But the implementation doesn't follow the Note. Instead it uses this function in TcEnv:

isClosedLetBndr :: Id -> TopLevelFlag
-- See Note [Bindings with closed types] in TcRnTypes
-- Note that we decided if a let-bound variable is closed by
-- looking at its type, which is slightly more liberal, and a whole
-- lot easier to implement, than looking at its free variables
isClosedLetBndr id
  | isEmptyVarSet (tyCoVarsOfType (idType id)) = TopLevel
  | otherwise                                  = NotTopLevel

It may be easier but it's also wrong. Consider

f x = ( let g y = x+y in ...
      , x::Int)

Is g closed (which affects how definitions in ... are generalised)? Well if we typecheck the second element of the tuple first, we may "know" that x::Int by the time we are inferring a type for g, conclude that g has no free type variables, and say that it is closed.

But if we do the x::Int part second, so while type checking the let we think that x::alpha, then we'll say that g is open.

This looks nasty. I think we should do it the way the Note says.

Thanks to Facundo for pointing this out. Not urgent, but plainly wrong.

Trac metadata
Trac field Value
Version 7.10.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC facundominguez@gmail.com
Operating system
Architecture
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: ghc/ghc#11698