New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
soundness bug with polymorphic variants #6787
Comments
Comment author: @lpw25 I've got it down to the following case:
|
Comment author: @garrigue Interestingly, the bug does not occur with -principal. |
Comment author: hnrgrgr By using |
Comment author: @garrigue Fixed in trunk and 4.02 at revisions 15851 and 15852. Some code added to allow the propagation of type information to patterns was breaking the invariant that two different polymorphic variant types should not share the same row variable. |
Comment author: @lpw25 In case anyone comes across this elsewhere, one of the ways this bug can manifest itself is as code which takes the wrong branch on a match with polymorphic variants in it. For example: module Monad : sig
type 'a t
val return : 'a -> 'a t
val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t
val run : 'a t -> 'a
end = struct
type 'a t = 'a
let return x = x
let ( >>= ) m k = k m
let run m = m
end
open Monad
let foo x =
match x with
| `Error -> return `Error
| `Ok y ->
match y with
| `Left | `Right -> return (`Ok y)
let bar x =
foo x
>>= function
| `Error -> return 1
| `Ok `Left -> return 2
| `Ok `Right -> return 3
let () =
Printf.printf "%d\n" (run (bar (`Ok `Right))) will print 2 instead of 3 as the wrong branch is taken in |
Original bug ID: 6787
Reporter: mkoconnor
Assigned to: @garrigue
Status: closed (set by @xavierleroy on 2016-12-07T10:49:24Z)
Resolution: fixed
Priority: normal
Severity: major
Version: 4.02.1
Fixed in version: 4.02.2+dev / +rc1
Category: typing
Monitored by: @Drup jpdeplaix @gasche @yallop @hcarty
Bug description
The code below (also attached) gives a function which interprets an int as a string and produces a segfault when run. I think this code is roughly minimal (e.g., I think the [revapply] function is necessary).
let revapply x f = f x
module Contravariant : sig
type -'a t
val create : unit -> [< `Foo] t
end = struct
type 'a t = unit
let create () = ()
end
module M : sig
val int_to_string : [
Bar of int ] -> string end = struct let int_to_string x = let x = revapply x (fun (
Bar int) -> (Bar int), Contravariant.create ()) in revapply x (fun ((
Bar int), _) -> (int : string))end
let () = Printf.printf "%s" (M.int_to_string (`Bar 0))
Steps to reproduce
Compile trial.ml with ocamlc or ocamlopt.opt and run.
File attachments
The text was updated successfully, but these errors were encountered: