Dereferencing static pointer arising from polymorphic function works when it probably shouldn't
I was investigating the treatment of type variables in the static pointers extension to work out how they dealt with free type variables and I realised that despite some care taken to emit a
Typeable constraint the definition of closed does not extend to type variables. This means you can dereference a static pointer at a different instantiation of a type without any ill effects.
Starting from the expression
foo = static id
Firstly note that
id is not a closed term because
the inferred type is
foo = static id :: Typeable a => StaticPtr (a -> a)
a is floated outside of the
static bracket and hence the
id @a is not closed.
Then I instantiate
a with a type such as
foo @Bool :: StaticPtr (Bool -> Bool). So
foo @Bool is a
StaticPtr which contains a function
Bool -> Bool.
However, if I lookup
foo at a different type then my program doesn't segfault.
-- But now we look it up as `Int -> Int` foo4 :: IO (Maybe (StaticPtr (Int -> Int))) foo4 = unsafeLookupStaticPtr (staticKey (foo @Bool)) -- And it works fine.. foo5 :: IO Int foo5 = do Just sp <- foo4 return $ (deRefStaticPtr sp) 5
This seems dubious to me. Bad things should happen if the type of
StaticPtr which you try to coerce to is a different type to the static form itself. At least a segfault would be appropriate here.
It is also very ad-hoc how it is claimed that only closed terms are allowed to appear in
static forms but this definition of closed does not extend to type variables. The manual is also silent on this and even about the purpose of the
Typeable constraint to begin with.