Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
4,264
Issues
4,264
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
406
Merge Requests
406
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
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Glasgow Haskell Compiler
GHC
Commits
ee07421f
Commit
ee07421f
authored
Nov 29, 2019
by
Simon Peyton Jones
Committed by
Marge Bot
Dec 06, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Work in progress on coercionLKind, coercionRKind
This is a preliminary patch for
#17515
parent
9897e8c8
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
122 additions
and
75 deletions
+122
-75
compiler/types/Coercion.hs
compiler/types/Coercion.hs
+122
-75
No files found.
compiler/types/Coercion.hs
View file @
ee07421f
...
@@ -473,6 +473,10 @@ splitForAllCo_co_maybe _ = Nothing
...
@@ -473,6 +473,10 @@ splitForAllCo_co_maybe _ = Nothing
-------------------------------------------------------
-------------------------------------------------------
-- and some coercion kind stuff
-- and some coercion kind stuff
coVarLType
,
coVarRType
::
HasDebugCallStack
=>
CoVar
->
Type
coVarLType
cv
|
(
_
,
_
,
ty1
,
_
,
_
)
<-
coVarKindsTypesRole
cv
=
ty1
coVarRType
cv
|
(
_
,
_
,
_
,
ty2
,
_
)
<-
coVarKindsTypesRole
cv
=
ty2
coVarTypes
::
HasDebugCallStack
=>
CoVar
->
Pair
Type
coVarTypes
::
HasDebugCallStack
=>
CoVar
->
Pair
Type
coVarTypes
cv
coVarTypes
cv
|
(
_
,
_
,
ty1
,
ty2
,
_
)
<-
coVarKindsTypesRole
cv
|
(
_
,
_
,
ty1
,
ty2
,
_
)
<-
coVarKindsTypesRole
cv
...
@@ -481,13 +485,10 @@ coVarTypes cv
...
@@ -481,13 +485,10 @@ coVarTypes cv
coVarKindsTypesRole
::
HasDebugCallStack
=>
CoVar
->
(
Kind
,
Kind
,
Type
,
Type
,
Role
)
coVarKindsTypesRole
::
HasDebugCallStack
=>
CoVar
->
(
Kind
,
Kind
,
Type
,
Type
,
Role
)
coVarKindsTypesRole
cv
coVarKindsTypesRole
cv
|
Just
(
tc
,
[
k1
,
k2
,
ty1
,
ty2
])
<-
splitTyConApp_maybe
(
varType
cv
)
|
Just
(
tc
,
[
k1
,
k2
,
ty1
,
ty2
])
<-
splitTyConApp_maybe
(
varType
cv
)
=
let
role
=
(
k1
,
k2
,
ty1
,
ty2
,
eqTyConRole
tc
)
|
tc
`
hasKey
`
eqPrimTyConKey
=
Nominal
|
otherwise
|
tc
`
hasKey
`
eqReprPrimTyConKey
=
Representational
=
pprPanic
"coVarKindsTypesRole, non coercion variable"
|
otherwise
=
panic
"coVarKindsTypesRole"
(
ppr
cv
$$
ppr
(
varType
cv
))
in
(
k1
,
k2
,
ty1
,
ty2
,
role
)
|
otherwise
=
pprPanic
"coVarKindsTypesRole, non coercion variable"
(
ppr
cv
$$
ppr
(
varType
cv
))
coVarKind
::
CoVar
->
Type
coVarKind
::
CoVar
->
Type
coVarKind
cv
coVarKind
cv
...
@@ -496,17 +497,19 @@ coVarKind cv
...
@@ -496,17 +497,19 @@ coVarKind cv
coVarRole
::
CoVar
->
Role
coVarRole
::
CoVar
->
Role
coVarRole
cv
coVarRole
cv
=
eqTyConRole
(
case
tyConAppTyCon_maybe
(
varType
cv
)
of
Just
tc0
->
tc0
Nothing
->
pprPanic
"coVarRole: not tyconapp"
(
ppr
cv
))
eqTyConRole
::
TyCon
->
Role
-- Given (~#) or (~R#) return the Nominal or Representational respectively
eqTyConRole
tc
|
tc
`
hasKey
`
eqPrimTyConKey
|
tc
`
hasKey
`
eqPrimTyConKey
=
Nominal
=
Nominal
|
tc
`
hasKey
`
eqReprPrimTyConKey
|
tc
`
hasKey
`
eqReprPrimTyConKey
=
Representational
=
Representational
|
otherwise
|
otherwise
=
pprPanic
"coVarRole: unknown tycon"
(
ppr
cv
<+>
dcolon
<+>
ppr
(
varType
cv
))
=
pprPanic
"eqTyConRole: unknown tycon"
(
ppr
tc
)
where
tc
=
case
tyConAppTyCon_maybe
(
varType
cv
)
of
Just
tc0
->
tc0
Nothing
->
pprPanic
"coVarRole: not tyconapp"
(
ppr
cv
)
-- | Given a coercion @co1 :: (a :: TYPE r1) ~ (b :: TYPE r2)@,
-- | Given a coercion @co1 :: (a :: TYPE r1) ~ (b :: TYPE r2)@,
-- produce a coercion @rep_co :: r1 ~ r2@.
-- produce a coercion @rep_co :: r1 ~ r2@.
...
@@ -2158,6 +2161,14 @@ seqCos (co:cos) = seqCo co `seq` seqCos cos
...
@@ -2158,6 +2161,14 @@ seqCos (co:cos) = seqCo co `seq` seqCos cos
%************************************************************************
%************************************************************************
-}
-}
-- | Apply 'coercionKind' to multiple 'Coercion's
coercionKinds
::
[
Coercion
]
->
Pair
[
Type
]
coercionKinds
tys
=
sequenceA
$
map
coercionKind
tys
-- | Get a coercion's kind and role.
coercionKindRole
::
Coercion
->
(
Pair
Type
,
Role
)
coercionKindRole
co
=
(
coercionKind
co
,
coercionRole
co
)
coercionType
::
Coercion
->
Type
coercionType
::
Coercion
->
Type
coercionType
co
=
case
coercionKindRole
co
of
coercionType
co
=
case
coercionKindRole
co
of
(
Pair
ty1
ty2
,
r
)
->
mkCoercionType
r
ty1
ty2
(
Pair
ty1
ty2
,
r
)
->
mkCoercionType
r
ty1
ty2
...
@@ -2170,84 +2181,128 @@ coercionType co = case coercionKindRole co of
...
@@ -2170,84 +2181,128 @@ coercionType co = case coercionKindRole co of
-- i.e. the kind of @c@ relates @t1@ and @t2@, then @coercionKind c = Pair t1 t2@.
-- i.e. the kind of @c@ relates @t1@ and @t2@, then @coercionKind c = Pair t1 t2@.
coercionKind
::
Coercion
->
Pair
Type
coercionKind
::
Coercion
->
Pair
Type
coercionKind
co
=
coercionKind
co
=
Pair
(
coercionLKind
co
)
(
coercionRKind
co
)
go
co
coercionLKind
::
Coercion
->
Type
coercionLKind
co
=
go
co
where
where
go
(
Refl
ty
)
=
Pair
ty
ty
go
(
Refl
ty
)
=
ty
go
(
GRefl
_
ty
MRefl
)
=
Pair
ty
ty
go
(
GRefl
_
ty
_
)
=
ty
go
(
GRefl
_
ty
(
MCo
co1
))
=
Pair
ty
(
mkCastTy
ty
co1
)
go
(
TyConAppCo
_
tc
cos
)
=
mkTyConApp
tc
(
map
go
cos
)
go
(
TyConAppCo
_
tc
cos
)
=
mkTyConApp
tc
<$>
(
sequenceA
$
map
go
cos
)
go
(
AppCo
co1
co2
)
=
mkAppTy
(
go
co1
)
(
go
co2
)
go
(
AppCo
co1
co2
)
=
mkAppTy
<$>
go
co1
<*>
go
co2
go
(
ForAllCo
tv1
_
co1
)
=
mkTyCoInvForAllTy
tv1
(
go
co1
)
go
(
FunCo
_
co1
co2
)
=
mkVisFunTy
(
go
co1
)
(
go
co2
)
go
(
CoVarCo
cv
)
=
coVarLType
cv
go
(
HoleCo
h
)
=
coVarLType
(
coHoleCoVar
h
)
go
(
UnivCo
_
_
ty1
_
)
=
ty1
go
(
SymCo
co
)
=
coercionRKind
co
go
(
TransCo
co1
_
)
=
go
co1
go
(
LRCo
lr
co
)
=
pickLR
lr
(
splitAppTy
(
go
co
))
go
(
InstCo
aco
arg
)
=
go_app
aco
[
go
arg
]
go
(
KindCo
co
)
=
typeKind
(
go
co
)
go
(
SubCo
co
)
=
go
co
go
(
NthCo
_
d
co
)
=
go_nth
d
(
go
co
)
go
(
AxiomInstCo
ax
ind
cos
)
=
go_ax_inst
ax
ind
(
map
go
cos
)
go
(
AxiomRuleCo
ax
cos
)
=
pFst
$
expectJust
"coercionKind"
$
coaxrProves
ax
$
map
coercionKind
cos
go_ax_inst
ax
ind
tys
|
CoAxBranch
{
cab_tvs
=
tvs
,
cab_cvs
=
cvs
,
cab_lhs
=
lhs
}
<-
coAxiomNthBranch
ax
ind
,
let
(
tys1
,
cotys1
)
=
splitAtList
tvs
tys
cos1
=
map
stripCoercionTy
cotys1
=
ASSERT
(
tys
`
equalLength
`
(
tvs
++
cvs
)
)
-- Invariant of AxiomInstCo: cos should
-- exactly saturate the axiom branch
substTyWith
tvs
tys1
$
substTyWithCoVars
cvs
cos1
$
mkTyConApp
(
coAxiomTyCon
ax
)
lhs
go_app
::
Coercion
->
[
Type
]
->
Type
-- Collect up all the arguments and apply all at once
-- See Note [Nested InstCos]
go_app
(
InstCo
co
arg
)
args
=
go_app
co
(
go
arg
:
args
)
go_app
co
args
=
piResultTys
(
go
co
)
args
go_nth
::
Int
->
Type
->
Type
go_nth
d
ty
|
Just
args
<-
tyConAppArgs_maybe
ty
=
ASSERT
(
args
`
lengthExceeds
`
d
)
args
`
getNth
`
d
|
d
==
0
,
Just
(
tv
,
_
)
<-
splitForAllTy_maybe
ty
=
tyVarKind
tv
|
otherwise
=
pprPanic
"coercionLKind:nth"
(
ppr
d
<+>
ppr
ty
)
coercionRKind
::
Coercion
->
Type
coercionRKind
co
=
go
co
where
go
(
Refl
ty
)
=
ty
go
(
GRefl
_
ty
MRefl
)
=
ty
go
(
GRefl
_
ty
(
MCo
co1
))
=
mkCastTy
ty
co1
go
(
TyConAppCo
_
tc
cos
)
=
mkTyConApp
tc
(
map
go
cos
)
go
(
AppCo
co1
co2
)
=
mkAppTy
(
go
co1
)
(
go
co2
)
go
(
CoVarCo
cv
)
=
coVarRType
cv
go
(
HoleCo
h
)
=
coVarRType
(
coHoleCoVar
h
)
go
(
FunCo
_
co1
co2
)
=
mkVisFunTy
(
go
co1
)
(
go
co2
)
go
(
UnivCo
_
_
_
ty2
)
=
ty2
go
(
SymCo
co
)
=
coercionLKind
co
go
(
TransCo
_
co2
)
=
go
co2
go
(
LRCo
lr
co
)
=
pickLR
lr
(
splitAppTy
(
go
co
))
go
(
InstCo
aco
arg
)
=
go_app
aco
[
go
arg
]
go
(
KindCo
co
)
=
typeKind
(
go
co
)
go
(
SubCo
co
)
=
go
co
go
(
NthCo
_
d
co
)
=
go_nth
d
(
go
co
)
go
(
AxiomInstCo
ax
ind
cos
)
=
go_ax_inst
ax
ind
(
map
go
cos
)
go
(
AxiomRuleCo
ax
cos
)
=
pSnd
$
expectJust
"coercionKind"
$
coaxrProves
ax
$
map
coercionKind
cos
go
co
@
(
ForAllCo
tv1
k_co
co1
)
-- works for both tyvar and covar
go
co
@
(
ForAllCo
tv1
k_co
co1
)
-- works for both tyvar and covar
|
isGReflCo
k_co
=
mkTyCoInvForAllTy
tv1
<$>
go
co1
|
isGReflCo
k_co
=
mkTyCoInvForAllTy
tv1
(
go
co1
)
-- kind_co always has kind @Type@, thus @isGReflCo@
-- kind_co always has kind @Type@, thus @isGReflCo@
|
otherwise
=
go_forall
empty_subst
co
|
otherwise
=
go_forall
empty_subst
co
where
where
empty_subst
=
mkEmptyTCvSubst
(
mkInScopeSet
$
tyCoVarsOfCo
co
)
empty_subst
=
mkEmptyTCvSubst
(
mkInScopeSet
$
tyCoVarsOfCo
co
)
go
(
FunCo
_
co1
co2
)
=
mkVisFunTy
<$>
go
co1
<*>
go
co2
go
(
CoVarCo
cv
)
=
coVarTypes
cv
go_ax_inst
ax
ind
tys
go
(
HoleCo
h
)
=
coVarTypes
(
coHoleCoVar
h
)
go
(
AxiomInstCo
ax
ind
cos
)
|
CoAxBranch
{
cab_tvs
=
tvs
,
cab_cvs
=
cvs
|
CoAxBranch
{
cab_tvs
=
tvs
,
cab_cvs
=
cvs
,
cab_lhs
=
lhs
,
cab_rhs
=
rhs
}
<-
coAxiomNthBranch
ax
ind
,
cab_rhs
=
rhs
}
<-
coAxiomNthBranch
ax
ind
,
let
Pair
tycos1
tycos2
=
sequenceA
(
map
go
cos
)
,
let
(
tys2
,
cotys2
)
=
splitAtList
tvs
tys
(
tys1
,
cotys1
)
=
splitAtList
tvs
tycos1
(
tys2
,
cotys2
)
=
splitAtList
tvs
tycos2
cos1
=
map
stripCoercionTy
cotys1
cos2
=
map
stripCoercionTy
cotys2
cos2
=
map
stripCoercionTy
cotys2
=
ASSERT
(
co
s
`
equalLength
`
(
tvs
++
cvs
)
)
=
ASSERT
(
ty
s
`
equalLength
`
(
tvs
++
cvs
)
)
-- Invariant of AxiomInstCo: cos should
-- Invariant of AxiomInstCo: cos should
-- exactly saturate the axiom branch
-- exactly saturate the axiom branch
Pair
(
substTyWith
tvs
tys1
$
substTyWith
tvs
tys2
$
substTyWithCoVars
cvs
cos1
$
substTyWithCoVars
cvs
cos2
rhs
mkTyConApp
(
coAxiomTyCon
ax
)
lhs
)
(
substTyWith
tvs
tys2
$
substTyWithCoVars
cvs
cos2
rhs
)
go
(
UnivCo
_
_
ty1
ty2
)
=
Pair
ty1
ty2
go
(
SymCo
co
)
=
swap
$
go
co
go
(
TransCo
co1
co2
)
=
Pair
(
pFst
$
go
co1
)
(
pSnd
$
go
co2
)
go
g
@
(
NthCo
_
d
co
)
|
Just
argss
<-
traverse
tyConAppArgs_maybe
tys
=
ASSERT
(
and
$
(`
lengthExceeds
`
d
)
<$>
argss
)
(`
getNth
`
d
)
<$>
argss
|
d
==
0
,
Just
splits
<-
traverse
splitForAllTy_maybe
tys
=
(
tyVarKind
.
fst
)
<$>
splits
|
otherwise
go_app
::
Coercion
->
[
Type
]
->
Type
=
pprPanic
"coercionKind"
(
ppr
g
)
where
tys
=
go
co
go
(
LRCo
lr
co
)
=
(
pickLR
lr
.
splitAppTy
)
<$>
go
co
go
(
InstCo
aco
arg
)
=
go_app
aco
[
arg
]
go
(
KindCo
co
)
=
typeKind
<$>
go
co
go
(
SubCo
co
)
=
go
co
go
(
AxiomRuleCo
ax
cos
)
=
expectJust
"coercionKind"
$
coaxrProves
ax
(
map
go
cos
)
go_app
::
Coercion
->
[
Coercion
]
->
Pair
Type
-- Collect up all the arguments and apply all at once
-- Collect up all the arguments and apply all at once
-- See Note [Nested InstCos]
-- See Note [Nested InstCos]
go_app
(
InstCo
co
arg
)
args
=
go_app
co
(
arg
:
args
)
go_app
(
InstCo
co
arg
)
args
=
go_app
co
(
go
arg
:
args
)
go_app
co
args
=
piResultTys
<$>
go
co
<*>
(
sequenceA
$
map
go
args
)
go_app
co
args
=
piResultTys
(
go
co
)
args
go_forall
subst
(
ForAllCo
tv1
k_co
co
)
go_forall
subst
(
ForAllCo
tv1
k_co
co
)
-- See Note [Nested ForAllCos]
-- See Note [Nested ForAllCos]
|
isTyVar
tv1
|
isTyVar
tv1
=
mkInvForAllTy
<$>
Pair
tv1
tv2
<*>
go_forall
subst'
co
=
mkInvForAllTy
tv2
(
go_forall
subst'
co
)
where
where
Pair
_
k2
=
go
k_co
k2
=
coercionRKind
k_co
tv2
=
setTyVarKind
tv1
(
substTy
subst
k2
)
tv2
=
setTyVarKind
tv1
(
substTy
subst
k2
)
subst'
|
isGReflCo
k_co
=
extendTCvInScope
subst
tv1
subst'
|
isGReflCo
k_co
=
extendTCvInScope
subst
tv1
-- kind_co always has kind @Type@, thus @isGReflCo@
-- kind_co always has kind @Type@, thus @isGReflCo@
|
otherwise
=
extendTvSubst
(
extendTCvInScope
subst
tv2
)
tv1
$
|
otherwise
=
extendTvSubst
(
extendTCvInScope
subst
tv2
)
tv1
$
TyVarTy
tv2
`
mkCastTy
`
mkSymCo
k_co
TyVarTy
tv2
`
mkCastTy
`
mkSymCo
k_co
go_forall
subst
(
ForAllCo
cv1
k_co
co
)
go_forall
subst
(
ForAllCo
cv1
k_co
co
)
|
isCoVar
cv1
|
isCoVar
cv1
=
mkTyCoInvForAllTy
<$>
Pair
cv1
cv2
<*>
go_forall
subst'
co
=
mkTyCoInvForAllTy
cv2
(
go_forall
subst'
co
)
where
where
Pair
_
k2
=
go
k_co
k2
=
coercionRKind
k_co
r
=
coVarRole
cv1
r
=
coVarRole
cv1
eta1
=
mkNthCo
r
2
(
downgradeRole
r
Nominal
k_co
)
eta1
=
mkNthCo
r
2
(
downgradeRole
r
Nominal
k_co
)
eta2
=
mkNthCo
r
3
(
downgradeRole
r
Nominal
k_co
)
eta2
=
mkNthCo
r
3
(
downgradeRole
r
Nominal
k_co
)
...
@@ -2269,7 +2324,7 @@ coercionKind co =
...
@@ -2269,7 +2324,7 @@ coercionKind co =
go_forall
subst
other_co
go_forall
subst
other_co
-- when other_co is not a ForAllCo
-- when other_co is not a ForAllCo
=
substTy
subst
`
pLiftSnd
`
go
other_co
=
substTy
subst
(
go
other_co
)
{-
{-
...
@@ -2288,14 +2343,6 @@ change reduces /total/ compile time by a factor of more than ten.
...
@@ -2288,14 +2343,6 @@ change reduces /total/ compile time by a factor of more than ten.
-}
-}
-- | Apply 'coercionKind' to multiple 'Coercion's
coercionKinds
::
[
Coercion
]
->
Pair
[
Type
]
coercionKinds
tys
=
sequenceA
$
map
coercionKind
tys
-- | Get a coercion's kind and role.
coercionKindRole
::
Coercion
->
(
Pair
Type
,
Role
)
coercionKindRole
co
=
(
coercionKind
co
,
coercionRole
co
)
-- | Retrieve the role from a coercion.
-- | Retrieve the role from a coercion.
coercionRole
::
Coercion
->
Role
coercionRole
::
Coercion
->
Role
coercionRole
=
go
coercionRole
=
go
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment