Skip to content

Clear the -Wall warnings in test/ and hoist -Wall to the top level - #72

Open
kogai wants to merge 1 commit into
claude/tests-actually-use-fixturesfrom
claude/test-warnings
Open

kogai wants to merge 1 commit into
claude/tests-actually-use-fixturesfrom
claude/test-warnings

Conversation

@kogai

@kogai kogai commented Sep 14, 2026

Copy link
Copy Markdown
Owner

#66 のレビューと #71 のレビューで約束した、警告整理の PR です。base は #71

#66 でテストスイートに -Wall を足しましたが、そこで出た警告は放置していました。これを片付けます。

1. 未使用 import(6 ファイル・19 項目)

Data.Text (Text, pack, unpack)Text.XML (def, parseText, readFile)Model (Kind (Tag), dropDuplicate, model, models) は、一度も使われないままファイル間でコピーされていましたTestCode.hsData.Map as MXsd as XTestMixed.hsModel as MdSpec.hsTest (..) も同様です。

ファイル 削除
Spec.hs Test (..)
TestUtils.hs Data.Textpack/unpackModel 全体、Test.HUnit 全体
TestCode.hs Data.Map as MData.Text 全体、Text.XML 全体、Xsd as XTestList
TestMixed.hs Data.Text 全体、Model as MdText.XML 全体、TestList
TestModel.hs Data.Text 全体、Text.XML 全体、TestList
TestParser.hs Data.Text 全体、Model 全体、TestList

あわせて import Util を、各ファイルが実際に使う名前だけに絞りました(TestCodeuniqTestMixedTestModelunwrap)。これは警告の対象ではありませんが、上の削除と同じ性質の掃除です。

判定は静的に行いました。文字列リテラルとコメントを除去したうえで、各 import 項目の名前が本体に単語境界付きで現れるかを機械的に確認しています(この手当ては必要でした。たとえば TestParser.hsdropDuplicateassertEqual "dropDuplicate" ... というアサーションのラベル文字列としてしか現れず、単純な grep では「使用中」に見えます)。Util については、Util の export 12 件それぞれについて 3 ファイルを確認しました。

2. 型シグネチャの欠落(7 件)

  • tests :: [Test]TestCode / TestModel / TestParserTestMixed には既にありました)
  • expected1 .. expected4 :: TypeTestModel
  • expected :: ElementInlineTestParser

型は Xsd.Schema のフィールド定義から確定します(schemaTypes :: Map QName TypeschemaElements :: Map QName ElementInline)。どちらも既存の import XsdXsd.Types を再 export しているのでスコープ内にあり、import の追加はありません

3. -Wall を hpack のトップレベルに引き上げ

ghc-options:
  - -Wall
  - -Wcompat

-Wall を 3 つのスタンザそれぞれの ghc-options から外し、トップレベルに 1 つ置きました。#66 で直したバグの原因そのものが、この「スタンザごとに書く」構造でした — フラグを 3 回書く必要があり、1 回書き忘れていた。トップレベルの 1 エントリなら書き忘れようがありません。

-Wcompat も足しています。GHC の将来の破壊的変更を、実際に壊れる前にここで拾うためです。-Werror は付けていないので、ビルドが落ちることはありません。

4. #71 のレビュー指摘(スタイル)

#71 で触れた 2 ケースを、TestModel.hs の他 7 ケースが使っている let key = ... の形に揃えました。

let key = makeTargetQName "NonEmptyString"
    actual = (typeToText . unwrap . M.lookup key . schemaTypes) scm

確認したこと / していないこと

  • package.yamlyaml.safe_load でパースを確認しました(Un-fold the executable's ghc-options and warn on the test suite too #66 で壊した再発防止)
  • onix.cabal手で編集しています。この環境に hpack がありません。ヘッダの hash は hpack 自身のアルゴリズム(生成ヘッダを除いたファイル全体の sha256)で再計算し、この式が編集前の hash を再現することを先に確認してから使いました。したがって hpack はこのファイルを「手で書き換えられた」とは見なさず、次回実行時に普通に上書き再生成します
  • スタンザに展開した ghc-options の並びは -Wall -Wcompat -threaded -rtsopts -with-rtsopts=-N としました。hpack はトップレベルの値をセクションの値の前に置く、という理解に基づく再現です。順序に意味はない(どちらでもコンパイル結果は同じ)ので実害はありませんが、もし hpack の実際の出力と並びが違えば、次に hpack を走らせたときに差分が出ます
  • ビルドは未検証です(GHC / stack がこの環境にありません)。未使用 import の削除は、消しすぎればコンパイルエラーとして確実に落ちます。この PR の CI が唯一の検証手段です

🤖 Generated with Claude Code

https://claude.ai/code/session_01P8rZakwAiz1jpViUX34x1Z


Generated by Claude Code

#66 turned -Wall on for the test suite but left the warnings it found in
place. This clears them.

Unused imports (19 items across 6 files). Data.Text, Text.XML and the
Model import list were copied from file to file without ever being used;
TestCode's Data.Map and Xsd-as-X likewise. Three whole-module Util
imports are narrowed to the single name each file actually uses.

Missing top-level signatures (7). tests :: [Test] in three modules,
expected1..4 :: Type in TestModel, expected :: ElementInline in
TestParser. Both types come from Xsd.Types via the existing Xsd
re-export, so no import was added for them.

-Wall moves from the three per-stanza ghc-options lists to hpack's
top-level ghc-options. That is what let the test suite go without it in
the first place: the flag had to be repeated once per stanza, and one
was missed. A single top-level entry cannot be missed. -Wcompat comes
along so that GHC's upcoming breaking changes show up here before they
land.

The two cases touched in #71 are rewritten in the `let key = ...` form
the other seven cases in TestModel use, as the reviewer asked.

onix.cabal is hand-edited: this environment has no hpack. The header
hash is recomputed with hpack's own algorithm (sha256 over the file
with the generated-by header removed), so hpack will accept the file
rather than treating it as manually modified.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P8rZakwAiz1jpViUX34x1Z

kogai commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

CI が通りました(run 34800231638、Test haskell codes / Test e2e ともに success)。キャッシュミスでフルコンパイルになったため、ビルドログに全警告が出ています。本文で「未検証」と書いた点を、そのログで実測した結果に差し替えます。

実測: このリポジトリ自身のコードに残る警告は -Wx-partial の 26 件のみ

ログ全体の警告 117 件を分類しました。

警告 件数 出どころ
-Wtype-equality-requires-operators 43 依存パッケージ(conduit 1.3.6.1)
-Wunused-imports 30 依存パッケージ(xml-conduit 1.9.1.4)
-Wincomplete-uni-patterns 18 依存パッケージ(conduit-extra 1.3.7)
-Wx-partial 26 このリポジトリ(内訳は下記)

前 3 つはいずれも /tmp/stack-*/ 以下、つまり stack がソースからビルドした依存パッケージのものです。こちらの ghc-options は効きません。

src/test/app/ に、未使用 import の警告も型シグネチャ欠落の警告も 1 件も残っていません。 この PR の主張どおりです。

-Wcompat がこのリポジトリに追加した警告: 0 件

-Wcompat 由来の -Wtype-equality-requires-operators-Wincomplete-uni-patterns は、すべて依存パッケージ側でした。自前のコードには 1 件も出ていません。ノイズを増やさずに将来の破壊的変更への網だけ張れた形です。

残る -Wx-partial 26 件(この PR の対象外)

ファイル 件数
src/Code.hs 8
test/TestModel.hs 8
test/TestCode.hs 7
src/Model.hs 2
test/TestParser.hs 1

すべて head の使用です(head . map snd . M.toList . schemaTypes など)。

これはこの PR が増やしたものではありません。 -Wx-partial は GHC 9.8 で -Wdefault に入った警告なので、#65 で GHC 9.8.4 に上げた時点から出ていました。-Wall の引き上げとも -Wcompat とも無関係です。

src/ の 10 件はスキーマのパース結果に対する head なので、空リストで落ちる条件が実際にありうるかを個別に見る必要があります。この PR の単位(未使用 import と型シグネチャの掃除)とは別物なので、ここでは触っていません。 必要なら別 PR で扱います。


Generated by Claude Code

kogai commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

レビュー

結論: コード変更自体には指摘なし、マージ可。 onix.cabal の手編集は hash・並び順ともに正しいことを実測で確認しました。ただし、あとから投稿された「CI 実測」コメントに事実と異なる記述が 2 点あるので、そこだけ必須指摘とします。


検証して問題がなかった点(根拠つき)

1. onix.cabal のヘッダ hash — 正しい

hpack 本体 (src/Hpack.hs) の定義:

calculateHash (CabalFile cabalVersion _ _ body _) = sha256 (unlines $ cabalVersion ++ body)

つまり「生成ヘッダ 6 行(3〜8 行目)を除いた全体」の sha256 です。Python で再計算しました。

ファイル 記載 hash 再計算
base (266fcbde…) 266fcbde15564c65aa539a9de93481d85c7dfb8cc735f00132fafc247db05cd9 一致
PR (1e36df2a…) 1e36df2a46c362165a25b450dc435b8ada105cb0d0a304a8fed95cd867ac3e74 一致

(行 1-2 + 行 9 以降を \n で連結、末尾改行あり = unlines と同値。unlines 相当の他の候補 4 通りも試して、この 1 通りだけが base の hash を再現しました。)

これは実害の防止に効いています。mkStatus は hash 不一致を ExistingCabalFileWasModifiedManually として扱い、hpack CLI は exitFailure します。hash が合っているので次回 hpack 実行時は普通に扱われます。

2. ghc-options の並び — 正しい

hpack のマージ規則を sol/hpack のソースで確認しました(0.33.0 と main の両方で同一):

-- Hpack/Config.hs
toSect = toSection packageName_ executableNames . first ((mempty <$ globalOptions) <>)
-- CommonOptions の Semigroup:
commonOptionsGhcOptions = commonOptionsGhcOptions a <> commonOptionsGhcOptions b   -- a = global, b = section

first が適用されるのは global 側なので global <> section、つまりグローバルが先です。-Wall -Wcompat -threaded -rtsopts -with-rtsopts=-N という並びで正しく、次に hpack を走らせても差分は出ません。

(ちなみに commonOptionsDependencies だけは b <> a と逆順で、hpack のマージ順はフィールドごとに違います。ghc-options は global が先で確定です。)

副次的な利点として、global が先に来るので、将来あるスタンザだけ警告を落としたくなったときに stanza 側の -Wno-… が後勝ちで効きます。この順序のほうが都合が良いです。

3. -Wx-partial-Wdefault 相当という主張 — 正しい

compiler/GHC/Driver/Flags.hs (ghc-9.8):

warningGroupIncludesExtendedWarnings W_default = True
warningGroupIncludesExtendedWarnings W_compat  = False

head/tail の警告は base の WARNING in "x-partial" プラグマによる extended warning で、-Wdefault に含まれます。「#65 で GHC 9.8.4 に上げた時点から出ていた」「この PR とは無関係」は正しいです。

4. PR 本文の削除テーブル、Util の export 12 件、「他 7 ケースが let key 形式」 — いずれも diff / ソースと突き合わせて一致しました。


必須

A. コメントの「-Wcompat 由来」が誤り。両方とも -Wcompat に入っていません。

-Wcompat 由来の -Wtype-equality-requires-operators-Wincomplete-uni-patterns は、すべて依存パッケージ側でした。

GHC 9.8 の実際の定義(compiler/GHC/Driver/Flags.hs):

minusWcompatOpts =
  [ Opt_WarnSemigroup, Opt_WarnNonCanonicalMonoidInstances
  , Opt_WarnNonCanonicalMonadInstances, Opt_WarnCompatUnqualifiedImports
  , Opt_WarnTypeEqualityOutOfScope, Opt_WarnImplicitRhsQuantification ]
  • -Wtype-equality-requires-operatorsstandardWarnings(= -Wdefault)。最初から有効。
  • -Wincomplete-uni-patternsminusWallOpts(= -Wall)。

そもそもこの 3 パッケージは /tmp/stack-*/ 配下、つまり stack がソースからビルドした依存パッケージで、こちらの ghc-options は一切効きません(これはコメント自身も書いているとおり)。したがって「-Wcompat 由来のものは全部依存側だった」という論法は成立しません。

結論(「-Wcompat がこのリポジトリに追加した警告 0 件」)自体は正しいのですが、その根拠として挙げた証拠が誤りです。正しくは「-Wcompat が実質追加するのは -Wsemigroup / -Wcompat-unqualified-imports / -Wtype-equality-out-of-scope / -Wimplicit-rhs-quantification の 4 つ(残り 2 つは既に -Wdefault)で、いずれもこのリポジトリでは 0 件だった」です。コメントの修正をお願いします。

B. コメントの「すべて head の使用です」が誤り。src/Model.hstail です。また 26 件は「ログ行数」であって「箇所数」ではありません。

CI ログ(run 34800231638 / job 103841279053)を実際に読んで数え直しました。

src/Model.hs:150:48: warning: [GHC-63394] [-Wx-partial]
    In the use of 'tail'

head ではなく tail です。GHC のメッセージも tail 用の「Replace it with drop 1」版になっています。

もう一点、src/ の件数が 2 倍になっています。make teststack test --trace --fast、かつ stack.yamllibrary-profiling: true / executable-profiling: true があるため、library が vanilla と profiling で 2 回コンパイルされます。ログ上でも [1 of 9] Compiling Paths_onix[9 of 9] Compiling Lib が 03:04:49 と 03:04:51 の 2 回出ています。

ファイル ログ行数 実際の箇所数 内訳
src/Code.hs 8 4 108:60, 129:58, 178:62, 200:38(すべて head
src/Model.hs 2 1 150:48(tail
test/TestModel.hs 8 8 99, 134, 140, 146, 159, 165, 216, 232
test/TestCode.hs 7 7 23, 40, 57, 75(2 箇所), 83, 100
test/TestParser.hs 1 1 95:25
26 21

「src/ の 10 件」は実際には 5 箇所head 4 + tail 1)です。ここも修正をお願いします。


推奨

C. -Wx-partial を別 PR に回した判断は妥当。ただし「個別に見る必要がある」の結論は出せるので、issue を立てて結論ごと残してください。

スコープ分離の判断自体には賛成です(この PR は import と型シグネチャの掃除であって、部分関数の除去は別物)。ただし 5 箇所を実際に読んだ結果、緊急度ははっきり分かれます。

落ちない 3 箇所(警告は偽陽性)

  • src/Code.hs:108if not (null docs_) then head docs_ else ""すでにガードされています
  • src/Code.hs:200 — 直前に constraintToCode (X.Enumeration v []) = … の等式があるので、この等式に来る時点で docs は非空です。
  • src/Model.hs:150ifindIndex … accJust i を返した値なので i < length acc、よって (xs, ys) = splitAt i accys は非空。構造上落ちません。GHC の言うとおり drop 1 に置き換えれば全関数化でき、意味は変わりません。

実際に落ちうる 2 箇所

  • src/Code.hs:129 / src/Code.hs:178 — どちらも X.Enumeration v docs を無ガードで head docs_ しています。<xs:enumeration><xs:documentation> が無ければ docs = [] で落ちます。そして同じファイルの constraintToCodeX.Enumeration v [] を明示的に別等式で処理している、つまり「documentation の無い enumeration は実在する」ことをこのコードベース自身が認めています。偶然まだ踏んでいないだけで、スキーマ次第で確実に踏みます。

さらに、この 2 行は同時に last docs_ も呼んでいますlastx-partial カテゴリに入っていないので警告が出ませんが、空リストで落ちるのは head と同じです。26 件という数字は部分関数の実際の面積を過小評価しています。「head を潰す PR」を作るときに last を取りこぼさないでください。

→ 「src/head/tail を全関数化する」issue を立てて、上の分類(偽陽性 3 / 実害 2 / last も対象)まで書き残しておくのが良いと思います。別 PR に回すこと自体には異論ありません。

D. import を絞る方針が一貫していません。とくに import Xsd を全体のまま残したのは、この PR の目的と噛み合っていません。

PR 後の状態:

ファイル 絞った import 絞っていない import
TestCode Test.HUnit, Util (uniq), Xsd (getSchema) Code
TestUtils Data.Text (Text), Xsd (…)
TestMixed Test.HUnit, Util (unwrap) Mixed, Xsd
TestModel Test.HUnit, Util (unwrap), TestUtils (…) Model, Xsd
TestParser Test.HUnit, TestUtils (…) Xsd

XsdTestCodeTestUtils では絞られていて、TestMixed / TestModel / TestParser では全体のままです。同じモジュールの扱いがファイルによって割れています。

これが単なる美観の話でない理由は、-Wunused-imports は import リストがある場合にのみ個別の名前を報告するからです。実際、この CI ログの依存パッケージ側の警告がその形です:

The import of '<$>, Applicative' from module 'Control.Applicative' is redundant

逆に import Xsd のような全体 import は、中の 40 個のうち 3 個しか使っていなくても永久に無警告です。この PR が消した Data.Text (Text, pack, unpack) のコピペ drift が検出できたのは、まさに import リストが書いてあったからです。Xsd を全体 import のまま残すと、同じ drift が Xsd 経由で再発したときに誰も気付けません。

一方で、全体 import のままにする現実的な理由があるのも分かります。PR 本文が書いているとおり expected1..4 :: Type / expected :: ElementInline がスコープ内にあるのは import XsdXsd.Types を再 export しているからで、絞るなら Type, ElementInline の各フィールド、TypeSimple, AtomicType, ListType, ComplexType, Documentation, QName, Namespace, getSchema, schemaTypes, schemaElements … と相当長いリストになります。

どちらでも構いませんが、「今回はここまで」を明示してください。具体的には次のどちらか:

  • Xsd も含めて全部絞る(別 PR でも可)
  • 絞らない方針を PR 本文か ADR に一行残す(例:「Xsd は型構築子を多用するため全体 import を許容する。代わりに Util など少数の名前しか使わないモジュールは必ず絞る」)

ついでに TestModel.hsimport Modelimport qualified Model as Md を両方持っています。ModelXsd をどちらも非修飾で全体 import しているので、将来どちらかに同名の export が増えると衝突します。ここは Md に寄せるのが安全です。

E. onix.cabal の手編集そのものを次から不要にしてください。

今回は hash も並びも正しかったので実害ゼロですが、「hpack が無い環境で cabal を手で書き、hash を手で再計算する」という手順は、レビュアー側でソースを読んで検算しないと正しさが確認できません(今回私がやったのがまさにそれです)。CI に 1 ステップ足せばこのクラスの問題ごと消えます。

- name: Check onix.cabal is in sync with package.yaml
  run: |
    stack build --dry-run          # stack が同梱 hpack で onix.cabal を再生成する
    git diff --exit-code onix.cabal

あるいは onix.cabal.gitignore に入れて生成物として扱う手もあります(Bazel も使っている構成なので、そちらと相性が悪ければ前者で)。


任意

F. -Wcompat を足す判断は妥当です。 -Werror が無いのでビルドが落ちることはなく、依存パッケージには波及せず(ghc-options は自パッケージのスタンザにしか付きません)、自前コードは 0 件。ノイズなしで網だけ張れています。

一点だけ付け加えると、-Wcompat の中身は GHC のバージョンで変わるので、GHC を上げたときに突然増えることがあります。-Werror を入れていない現状では無害ですが、将来 -Werror を検討するときはこの点を思い出してください。

また -Wcompat に含まれる -Wcompat-unqualified-imports は、D で書いた「import を絞る」方針と相性が良いです(import Data.List のような裸の import を捕まえます)。現状 src/Util.hsimport Data.List (intercalate) なので警告は出ません。

G. -Wall のトップレベル引き上げの波及 — 望ましい方向です。

toPackage_ を読むと、global options は toSect 経由で library / internal-libraries / executables / tests / benchmarks のすべてに適用されます。つまり将来 benchmarks: を足したら自動的に -Wall -Wcompat が付きます。#66 のバグ(3 箇所書くうち 1 箇所書き忘れ)が構造的に再発しなくなるので、これが狙いどおりです。

もし将来あるスタンザだけ警告を緩めたくなっても、2 で確認したとおり global が先・stanza が後の順で並ぶので、stanza 側に -Wno-… を書けば後勝ちで効きます。逃げ道も塞がっていません。

H. cabal ヘッダの hpack バージョンと CI の乖離。 ヘッダは hpack version 0.33.0 ですが、CI は stack-version: "latest" なので同梱 hpack はかなり新しいはずです。ただし mkStatushasSameContent(ヘッダを除いた本文の比較)が真なら OutputUnchanged何も書かないので、本文が一致している限り 0.33.0 の行はそのまま残ります。逆に言うと、0.33.0 と現行 hpack でレンダリング結果が 1 バイトでも違えば、この PR とは無関係に次回 diff が出ます。そこは私も実際に hpack を走らせて確認できていないので、E の CI チェックを入れるとここも同時に片付きます。

I. PR 本文の「19 項目」。 数え方次第で 19 にも 20 にもなります(TestUtils.hsData.Text (Text, pack, unpack)pack/unpack の 2 項目と数えるか、変更した import 1 行と数えるか)。テーブル自体は diff と完全に一致しているので、先頭の数字は「6 ファイル」だけにするか、数え方を一言添えるほうが安全です。

J. PR 本文の「確認したこと / していないこと」の扱い。 本文で「ビルドは未検証」と正直に書き、CI が通ってからコメントで実測に差し替えた流れ自体は良いです。その差し替えコメントの中身に A・B の誤りがあるのが惜しいので、そこだけ直せば記録として完成します。

K. 本 PR 無関係のログノイズ。 stack test --trace+RTS -xc により、全テスト成功後に *** Exception (reporting due to +RTS -xc): (THUNK_STATIC), stack trace: Main.main が出ています(テストは 33 件すべて成功)。既存の挙動ですが、将来ログを読む人が混乱するので、どこかで潰すか Makefile にコメントを残しておくと親切です。


まとめ

diff は良い変更です。A と B(コメントの修正)だけ対応してもらえればマージで問題ありません。 C・D・E は別 PR / issue で構いません。


Generated by Claude Code

kogai commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

レビューありがとうございます。必須の 2 件はどちらもそのとおりで、私の「CI 実測」コメントの誤りです。 自分でも裏を取ったうえで訂正します。

必須 A: 「-Wcompat 由来」という帰属が誤り

GHC 9.8 の compiler/GHC/Driver/Flags.hsghc-9.8 ブランチ)を確認しました。

警告 実際の所属
-Wtype-equality-requires-operators -WdefaultstandardWarnings
-Wincomplete-uni-patterns -WallminusWallOpts
-Wtype-equality-out-of-scope -WcompatminusWcompatOpts

ご指摘のとおり、前 2 つは -Wcompat に入っていません。-Wcompat に入っているのは名前の似た -Wtype-equality-out-of-scope の方で、私はこの 2 つを取り違えていました。

さらに言うと、私の書き方はもっと根本的に筋が通っていませんでした。あの 91 件は依存パッケージ(conduit / conduit-extra / xml-conduit)のビルドで出たもので、このリポジトリの ghc-options は依存パッケージには適用されません。したがってあれらは、-Wcompat が何を足すか/足さないかについてそもそも何の証拠にもなりません

結論(-Wcompat が自前コードに足した警告は 0 件)自体は変わりませんが、根拠は別物です。正しい根拠は単に「src/test/app/ に出た警告が -Wx-partial 以外に 1 件も無い」ということだけです。

必須 B: 「26 件」「すべて head」がどちらも不正確

再集計しました。

ログ行数 実際の箇所数
src/Code.hs 8 4
src/Model.hs 2 1
test/TestCode.hs 7 7
test/TestModel.hs 8 8
test/TestParser.hs 1 1
合計 26 21

src/ が倍になっている理由もご指摘のとおりでした。stack.yamllibrary-profiling: true / executable-profiling: true があり、ログで [8 of 9] Compiling Code2 回出ています(vanilla と profiling の 2 way)。私は「ログ行数」を「箇所数」として報告していました。src/ の 10 件」は実際には 5 箇所です。

src/Model.hs:150head でないことも確認しました。

in xs ++ [x {optional = True}] ++ tail ys

tail です。「すべて head の使用です」は誤りでした。

推奨 C: -Wx-partial の 5 箇所の切り分け

読みました。ご指摘の分類に同意します。

箇所 判定
Code.hs:108 if not (null docs_) then head docs_ else "" ガード済み・偽陽性
Code.hs:200 直前に Enumeration v [] の等式あり 偽陽性
Model.hs:150 findIndex + splitAtys は非空 偽陽性
Code.hs:129 head docs_ 無ガード 落ちうる
Code.hs:178 head docs_ 無ガード 落ちうる

同じファイルの constraintToCodeEnumeration v [] を明示的に処理している、というのが「空の docs が実在する」証拠だという読みは鋭いです。同じ行の last docs_ が同罪(-Wx-partiallast を報告しない)という点も含めて、フォローアップの課題として登録しました。 偽陽性 3 件と実害 2 件を混ぜずに扱います。

推奨 D: import 絞り込みの不統一

事実は認めます。方針を明記します。

小さい面のモジュールは絞る、ドメイン語彙のモジュールは絞らない。 Util(export 12 件、各ファイルが使うのは 1 つ)や Test.HUnit は絞る価値がありますが、XsdXsd.Types を再 export していて、TestModel.hs / TestParser.hs が使うのは QName / Namespace / Type / TypeSimple / TypeComplex / AtomicType / ListType / SimpleRestriction / ComplexType / Enumeration / Documentation / ElementInline / Occurs / MaxOccurs / … と 30 件近くになります。これを列挙した import リストは、drift を検出できる代わりに、それ自体が drift します。

ただし「全体 import を残すと Xsd 経由の drift は検出不能」というご指摘は、そのトレードオフを正確に言い当てています。方針として明記する方を採り、AGENTS.md のテスト規約に一文足す形でフォローアップします。

推奨 E: onix.cabal の手編集をやめる CI チェック

stack build --dry-run + git diff --exit-code onix.cabal は、まさに今回私が hash を手計算するはめになった状況を構造的に防ぎます。採用しますが、この PR の単位(警告の掃除)とは別物なので、フォローアップに回します。

hash と ghc-options の並びの検証について

hpack の calculateHashtoSect(global が先)をソースで裏を取ったうえで「必須指摘にはならなかった」と書いていただいたのは、こちらが一番不安だった箇所なので助かりました。stack-version: latest と cabal ヘッダの hpack 0.33.0 の乖離(任意指摘)も、E のチェックが入れば自然に顕在化します。


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants