Commit c9e8f801 authored by Facundo Domínguez's avatar Facundo Domínguez

Set tct_closed to TopLevel for closed bindings.

Summary:
Till now tct_closed determined whether the type of a binding is closed.
With this patch tct_closed indicates whether the binding is closed.

Test Plan: ./validate

Reviewers: simonpj, austin, bgamari

Reviewed By: simonpj

Subscribers: mboes, thomie, simonpj

Differential Revision: https://phabricator.haskell.org/D2016

GHC Trac Issues: #11698
parent 0f58d348
This diff is collapsed.
......@@ -28,7 +28,7 @@ module TcEnv(
tcExtendLetEnv, tcExtendLetEnvIds,
tcExtendIdEnv, tcExtendIdEnv1, tcExtendIdEnv2,
tcExtendIdBndrs, tcExtendLocalTypeEnv,
isClosedLetBndr,
isTypeClosedLetBndr,
tcLookup, tcLookupLocated, tcLookupLocalIds,
tcLookupId, tcLookupTyVar,
......@@ -409,29 +409,40 @@ getScopedTyVarBinds
= do { lcl_env <- getLclEnv
; return [(name, tv) | ATyVar name tv <- nameEnvElts (tcl_env lcl_env)] }
isClosedLetBndr :: Id -> TopLevelFlag
isTypeClosedLetBndr :: 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
isTypeClosedLetBndr id
| isEmptyVarSet (tyCoVarsOfType (idType id)) = TopLevel
| otherwise = NotTopLevel
tcExtendLetEnv :: TopLevelFlag -> [TcId] -> TcM a -> TcM a
tcExtendLetEnv :: TopLevelFlag -> TopLevelFlag -> [TcId] -> TcM a -> TcM a
-- Used for both top-level value bindings and and nested let/where-bindings
-- Adds to the TcIdBinderStack too
tcExtendLetEnv top_lvl ids thing_inside
tcExtendLetEnv top_lvl closed_group ids thing_inside
= tcExtendIdBndrs [TcIdBndr id top_lvl | id <- ids] $
tcExtendLetEnvIds top_lvl [(idName id, id) | id <- ids] thing_inside
tcExtendLetEnvIds' top_lvl closed_group [(idName id, id) | id <- ids]
thing_inside
tcExtendLetEnvIds :: TopLevelFlag -> [(Name,TcId)] -> TcM a -> TcM a
-- Used for both top-level value bindings and and nested let/where-bindings
-- Does not extend the TcIdBinderStack
tcExtendLetEnvIds top_lvl pairs thing_inside
= tc_extend_local_env top_lvl [ (name, ATcId { tct_id = id
, tct_closed = isClosedLetBndr id })
| (name,id) <- pairs ] $
tcExtendLetEnvIds top_lvl
= tcExtendLetEnvIds' top_lvl TopLevel
tcExtendLetEnvIds' :: TopLevelFlag -> TopLevelFlag -> [(Name,TcId)] -> TcM a
-> TcM a
-- Used for both top-level value bindings and and nested let/where-bindings
-- Does not extend the TcIdBinderStack
tcExtendLetEnvIds' top_lvl closed_group pairs thing_inside
= tc_extend_local_env top_lvl
[ (name, ATcId { tct_id = id
, tct_closed = case closed_group of
TopLevel -> isTypeClosedLetBndr id
_ -> closed_group })
| (name,id) <- pairs ] $
thing_inside
tcExtendIdEnv :: [TcId] -> TcM a -> TcM a
......
......@@ -757,7 +757,7 @@ tcInstDecls2 tycl_decls inst_decls
; let dm_ids = collectHsBindsBinders dm_binds
-- Add the default method Ids (again)
-- See Note [Default methods and instances]
; inst_binds_s <- tcExtendLetEnv TopLevel dm_ids $
; inst_binds_s <- tcExtendLetEnv TopLevel TopLevel dm_ids $
mapM tcInstDecl2 inst_decls
-- Done
......
......@@ -1629,7 +1629,7 @@ runTcInteractive hsc_env thing_inside
-- See Note [Initialising the type environment for GHCi]
is_closed thing
| AnId id <- thing
, NotTopLevel <- isClosedLetBndr id
, NotTopLevel <- isTypeClosedLetBndr id
= Left (idName id, ATcId { tct_id = id, tct_closed = NotTopLevel })
| otherwise
= Right thing
......
......@@ -962,10 +962,14 @@ environment that makes things tricky for OutsideIn generalisation.
Definition:
A variable is "closed", and has tct_closed set to TopLevel,
iff
a) all its free variables are imported, or are let-bound with closed types
a) all its free variables are imported, or are let-bound and closed
b) generalisation is not restricted by the monomorphism restriction
Invariant: a closed variable has no free type variables in its type.
Why? Assume (induction hypothesis) that closed variables have closed
types, and that we have a new binding f = e, satisfying (a) and (b).
Then since monomorphism restriction does not apply, and there are no
free type variables, we can fully generalise, so its type will be closed.
Under OutsideIn we are free to generalise a closed let-binding.
This is an extension compared to the JFP paper on OutsideIn, which
......
{-# LANGUAGE MonoLocalBinds #-}
module T11698 where
f x = (k 'v', k True)
where
h = const True x
k z = const h (k z) -- k type should not be generalized because h is closed.
T11698.hs:4:17: error:
• Couldn't match expected type ‘Char’ with actual type ‘Bool’
• In the first argument of ‘k’, namely ‘True’
In the expression: k True
In the expression: (k 'v', k True)
......@@ -412,3 +412,4 @@ test('T11313', normal, compile_fail, [''])
test('T11723', normal, compile_fail, [''])
test('T11724', normal, compile_fail, [''])
test('BadUnboxedTuple', normal, compile_fail, [''])
test('T11698', normal, compile_fail, [''])
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