Previously, we blindly assume Ruby strings are UTF-8 and turn them
into Rust Strings (which *are* assumed to be UTF-8). This is clearly
unsafe so this commit adds some checks to cofirm that and generate
type errors appropiately.
Using the object (calling Rust methods from Ruby) after consuming
would raise a RuntimeError.
Also fixes some parser bugs that previously allowed invalid syntax
through in the arguments position.
The main use case for symbols is to use them as a HashMap key. However,
this introduces a GC problem – we cannot store Ruby values in the heap
without properly marking/registering them, otherwise they might get
GC'ed by Ruby unexpectedly. (In fact, this is already a problem if you
have a `Vec<VALUE>`.)
I tried to avoid introducing additional problems by pinning down any
symbols that goes thought the coercion protocol. This is probably
overly aggressive, as it would cause any dynamic symbols (e.g.
`String#to_sym`) to become un-GC-able. We can revisit this once we
have a more general-purpose system to encode pinning semantics in
the type system.
- Make `Checked` an associated type. This allows `from_ruby` to carry
over additional information (useful for `Option` etc)
- Move `ToRust` into `FromRuby` to ensure both get implemented together
This switches the `to_ruby` trait method to return a `Result`, which
allows the coercion to fail.
The most obvious use case for this is to implement coercion for the
`Result` type in Rust (included in this PR), but there could be other
reasons why a coercion might fail. For example, if we were to implement
a coercion between a Rust and Ruby regular expression, the coercion
could fail if the Rust regular expression uses some Rust-specific
features that are not supported by the Ruby regular expression
implementation.
The previous code was relying on the accidental fact that only a single
impl of PartialEq<usize> existed. serde_json defines another impl of
PartialEq<usize>, which causes the constraint to be insufficient, which
results in a compile error when serde_json is added to a project with
Helix.
This commit forces the VALUE into a usize eagerly, avoiding this
inference issue.
Fixes#93
h/t @alyssais
Thanks to @nikomatsakis for helping me figure out the root cause.
Asserting unwind safe is supposed to mean that we poison mutable object
involved in the panic (to prevent objects that were involved in panics
from triggering errors over and over again) and we should do that in the
future.