【问题标题】:Resolving "code is unreachable" in sorbet解决冰糕中的“代码无法访问”
【发布时间】:2022-01-18 02:29:59
【问题描述】:

我维护 pdf-reader ruby​​ gem,并且正在尝试通过 sorbet 进行静态类型检查。

我有一个particular source file,目前是typed: false,我想将其更改为typed: true。当我这样做时,冰糕抱怨这种状态机形状的方法:

    def process_data(data)
      parser = build_parser(data)
      mode = :none
      instructions = []

      while token = parser.parse_token(CMAP_KEYWORDS)
        if token == "beginbfchar"
          mode = :char
        elsif token == "endbfchar"
          process_bfchar_instructions(instructions)
          instructions = []
          mode = :none
        elsif token == "beginbfrange"
          mode = :range
        elsif token == "endbfrange"
          process_bfrange_instructions(instructions)
          instructions = []
          mode = :none
        elsif mode == :char || mode == :range
          instructions << token
        end
      end
    end

我收到此错误:

$ srb  tc
./lib/pdf/reader/cmap.rb:74: This code is unreachable https://srb.help/7006
    74 |        elsif mode == :char || mode == :range
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ./lib/pdf/reader/cmap.rb:74: This condition was always falsy (T::Boolean)
    74 |        elsif mode == :char || mode == :range
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Got T::Boolean originating from:
    ./lib/pdf/reader/cmap.rb:74:
    74 |        elsif mode == :char || mode == :range
                      ^^^^^^^^^^^^^

./lib/pdf/reader/cmap.rb:75: This code is unreachable https://srb.help/7006
    75 |          instructions << token
                  ^^^^^^^^^^^^^^^^^^^^^
    ./lib/pdf/reader/cmap.rb:74: This condition was always falsy (T::Boolean)
    74 |        elsif mode == :char || mode == :range
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Got T::Boolean originating from:
    ./lib/pdf/reader/cmap.rb:74:
    74 |        elsif mode == :char || mode == :range

我相当有信心 sorbet 认为无法在生产环境中执行的代码。如果是这种情况,此类将无法工作。

大概有一些关于这个代码结构或类型注释的东西让 sorbet 相信mode 永远不会等于:char:range。到目前为止,我还无法解决它。我错过了什么?

【问题讨论】:

  • 您最初设置了 mode = :none,因此 sorbet 可能会得出结论,它不能等于 :char,因为它没有考虑到 while 循环。

标签: ruby sorbet


【解决方案1】:

看起来它与this bug 有关。我暂时将mode 标记为不安全。

mode = T.unsafe(:none)

你可以在sorbet.run上玩代码

【讨论】:

  • 嗯,很有趣。我尝试将带有|| 的条件拆分为两个elsif 分支,但我仍然收到错误消息。不过,请查看 GitHub 上的其他未解决问题,this one looks like it might be relevant。不幸的是,我不能使用解决方法,因为我不希望 sorbet 成为 gem 的运行时依赖项
猜你喜欢
  • 2019-11-10
  • 2019-11-02
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
相关资源
最近更新 更多