Ticket #1995 (closed bug: fixed)

Opened 5 years ago

Last modified 4 years ago

Unsoundness in the RTTI scheme when newtypes are involved

Reported by: mnislaih Owned by: mnislaih
Priority: normal Milestone: 6.10 branch
Component: GHCi Version: 6.8.2
Keywords: Cc: mnislaih@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Difficulty: Project (more than a week)
Test Case: print029, print030, print031 Blocked By:
Blocking: Related Tickets:

Description

To be filled with further details soon

Change History

Changed 5 years ago by mnislaih

This means that the debugger can assign incorrect types to the variables in a breakpoint.

An example. If we have a polymorphic function with a type variable of kind (* -> *) in its signature in some argument, and in a function call that parameter happens to be instantiated with a newtype of a certain shape, RTTI can panic or even worse, recover a false type. Concretely,

newtype MkT2 a = MkT2 [Maybe a]
...
fmapInt :: Functor f => (Int->b) -> f Int -> f b
fmapInt f x = fmap f x

MkT2 a is isomorphic to [Maybe a], but MkT2 itself has no correspondent isomorphic type! The RTTI mechanism makes an assumption that every newtype is isomorphic to some type, but that is true in all cases only if the type constructor is fully applied. If not, it doesn't need to be true.

This is what RTTI will currently do. Suppose a function If fmapInt is called with a MkT2 value, the RTTI scheme, in absence of the newtype evidence, will either

1) see the (:) constructor, conclude that t = [] and since now the type of x is monomorphic, and stop there if there is no need to reconstruct the term too. It has computed a false type.

2) if there is the need to reconstruct the term, see the (:) constructor and the Just constructor below it, and conjecture that the type of x is [Maybe Int]. So far so good, but then when it tries to satisfy the constraint that x::t Int it panics with "Can't unify".

3) even if the term is reconstructed as in 2), it is possible to compute a wrong type if the closure with the Just constructor is unevaluated.

Changed 5 years ago by mnislaih

(replace t with f in the types in items 1)-3) above)

Changed 5 years ago by mnislaih

  • testcase set to print029, print030, print031

Changed 5 years ago by simonmar

  • architecture changed from Unknown to Unknown/Multiple

Changed 5 years ago by simonmar

  • os changed from Unknown to Unknown/Multiple

Changed 5 years ago by mnislaih

  • status changed from new to closed
  • resolution set to fixed

Fixed up to some point by the patch below.

Thu Sep 18 05:21:33 PDT 2008  pepe
 * Fix a couple of issues with :print

It is still possible to make :print compute unsound types, e.g. with recursive newtypes like:

newtype In f = In (f (In f))

I don't think this can be fixed completely without resorting to a separate compilation mode for :print, where newtypes are replaced by strict one-constructor datatypes.

Changed 5 years ago by igloo

This was merged into the 6.10 branch too.

Changed 4 years ago by simonmar

  • difficulty changed from Project (> 1 week) to Project (more than a week)
Note: See TracTickets for help on using tickets.