Skip to content

[#423] Make `fromIntegral` safe

Alyona Antonova requested to merge alyoanton9/#423-make-fromIntegral-safe into master

Description

fromIntegral is a dangerous function. This MR aims at making its usages safer. It replaces fromIntegral with several new converters:

  1. Statically safe fromIntegral = intCast from Prelude. Being used for such a and b types that a is subtype of b: IsIntSubType a b ~ 'True. E.g. Int64 -> Integer
  2. Statically safe fromIntegralMaybe = intCastMaybe from Prelude. Being used for any a and b that have Integral and Bits instances.
  3. Statically safe fromIntegralToRealFrac from Prelude. Being used to cast integral number to fractional one. E.g. Int64-> Float.
  4. Runtime-safe fromIntegralOverflowing = Universum.fromIntegral from Prelude. Being used for conversions where overflow is intended. Needed to semantically distinguish usages, where overflow is intended, from those that have to fail on overflow. E.g. Int8 -> Word8 with intended bits reinterpretation from lossy Integer -> Int.
  5. Unsafe fromIntegralNoOverflow from Unsafe. Being used for integral conversions where overflow/underflow is not expected. Returns Right value if conversion does not produce overflow/underflow and Left msg with corresponding error message otherwise.
  6. Unsafe fromIntegral from Unsafe. Being used for integral conversions checking for overflow/underflow like fromIntegralNoOverflow, but raising an exception with error in case of overflow/underflow.

Additionally, type annotations are applied for all Unsafe.fromIntegral usages (except for obvious ones) to increase readability. Also, some changes are added to Morley.Tezos.Core module, in particular 2 similar functions mkMutez and mkMutez' are merged in a single mkMutez and unsafeMkMutez is replaced with toMutez where possible. Finally, fromInteger is redefined in Prelude to fail on overflow/underflow.

Related issue(s)

Resolves #423 (closed)

Checklist for your Merge Request

Related changes (conditional)

  • Tests (see short guidelines)

    • If I added new functionality, I added tests covering it.
    • If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again.
  • Documentation

    • I checked whether I should update the docs and did so if necessary:
    • I updated changelog files of all affected packages released to Hackage if my changes are externally visible.

Stylistic guide (mandatory)

Edited by Alyona Antonova

Merge request reports