Conversation
#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
|
CI が通りました(run 34800231638、Test haskell codes / Test e2e ともに success)。キャッシュミスでフルコンパイルになったため、ビルドログに全警告が出ています。本文で「未検証」と書いた点を、そのログで実測した結果に差し替えます。 実測: このリポジトリ自身のコードに残る警告は
|
| 警告 | 件数 | 出どころ |
|---|---|---|
-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
レビュー結論: コード変更自体には指摘なし、マージ可。 検証して問題がなかった点(根拠つき)1. hpack 本体 ( calculateHash (CabalFile cabalVersion _ _ body _) = sha256 (unlines $ cabalVersion ++ body)つまり「生成ヘッダ 6 行(3〜8 行目)を除いた全体」の sha256 です。Python で再計算しました。
(行 1-2 + 行 9 以降を これは実害の防止に効いています。 2. hpack のマージ規則を -- Hpack/Config.hs
toSect = toSection packageName_ executableNames . first ((mempty <$ globalOptions) <>)
-- CommonOptions の Semigroup:
commonOptionsGhcOptions = commonOptionsGhcOptions a <> commonOptionsGhcOptions b -- a = global, b = section
(ちなみに 副次的な利点として、global が先に来るので、将来あるスタンザだけ警告を落としたくなったときに stanza 側の 3.
warningGroupIncludesExtendedWarnings W_default = True
warningGroupIncludesExtendedWarnings W_compat = False
4. PR 本文の削除テーブル、 必須A. コメントの「
GHC 9.8 の実際の定義( minusWcompatOpts =
[ Opt_WarnSemigroup, Opt_WarnNonCanonicalMonoidInstances
, Opt_WarnNonCanonicalMonadInstances, Opt_WarnCompatUnqualifiedImports
, Opt_WarnTypeEqualityOutOfScope, Opt_WarnImplicitRhsQuantification ]
そもそもこの 3 パッケージは 結論(「 B. コメントの「すべて CI ログ(run 34800231638 / job 103841279053)を実際に読んで数え直しました。
もう一点、
「src/ の 10 件」は実際には 5 箇所( 推奨C. スコープ分離の判断自体には賛成です(この PR は import と型シグネチャの掃除であって、部分関数の除去は別物)。ただし 5 箇所を実際に読んだ結果、緊急度ははっきり分かれます。 落ちない 3 箇所(警告は偽陽性)
実際に落ちうる 2 箇所
さらに、この 2 行は同時に → 「 D. import を絞る方針が一貫していません。とくに PR 後の状態:
これが単なる美観の話でない理由は、 逆に 一方で、全体 import のままにする現実的な理由があるのも分かります。PR 本文が書いているとおり どちらでも構いませんが、「今回はここまで」を明示してください。具体的には次のどちらか:
ついでに E. 今回は 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あるいは 任意F. 一点だけ付け加えると、 また G.
もし将来あるスタンザだけ警告を緩めたくなっても、2 で確認したとおり global が先・stanza が後の順で並ぶので、stanza 側に H. cabal ヘッダの hpack バージョンと CI の乖離。 ヘッダは I. PR 本文の「19 項目」。 数え方次第で 19 にも 20 にもなります( J. PR 本文の「確認したこと / していないこと」の扱い。 本文で「ビルドは未検証」と正直に書き、CI が通ってからコメントで実測に差し替えた流れ自体は良いです。その差し替えコメントの中身に A・B の誤りがあるのが惜しいので、そこだけ直せば記録として完成します。 K. 本 PR 無関係のログノイズ。 まとめdiff は良い変更です。A と B(コメントの修正)だけ対応してもらえればマージで問題ありません。 C・D・E は別 PR / issue で構いません。 Generated by Claude Code |
|
レビューありがとうございます。必須の 2 件はどちらもそのとおりで、私の「CI 実測」コメントの誤りです。 自分でも裏を取ったうえで訂正します。 必須 A: 「
|
| 警告 | 実際の所属 |
|---|---|
-Wtype-equality-requires-operators |
-Wdefault(standardWarnings) |
-Wincomplete-uni-patterns |
-Wall(minusWallOpts) |
-Wtype-equality-out-of-scope |
-Wcompat(minusWcompatOpts) |
ご指摘のとおり、前 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.yaml に library-profiling: true / executable-profiling: true があり、ログで [8 of 9] Compiling Code が 2 回出ています(vanilla と profiling の 2 way)。私は「ログ行数」を「箇所数」として報告していました。「src/ の 10 件」は実際には 5 箇所です。
src/Model.hs:150 が head でないことも確認しました。
in xs ++ [x {optional = True}] ++ tail ystail です。「すべて 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 + splitAt で ys は非空 |
偽陽性 |
Code.hs:129 |
head docs_ 無ガード |
落ちうる |
Code.hs:178 |
head docs_ 無ガード |
落ちうる |
同じファイルの constraintToCode が Enumeration v [] を明示的に処理している、というのが「空の docs が実在する」証拠だという読みは鋭いです。同じ行の last docs_ が同罪(-Wx-partial は last を報告しない)という点も含めて、フォローアップの課題として登録しました。 偽陽性 3 件と実害 2 件を混ぜずに扱います。
推奨 D: import 絞り込みの不統一
事実は認めます。方針を明記します。
小さい面のモジュールは絞る、ドメイン語彙のモジュールは絞らない。 Util(export 12 件、各ファイルが使うのは 1 つ)や Test.HUnit は絞る価値がありますが、Xsd は Xsd.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 の calculateHash と toSect(global が先)をソースで裏を取ったうえで「必須指摘にはならなかった」と書いていただいたのは、こちらが一番不安だった箇所なので助かりました。stack-version: latest と cabal ヘッダの hpack 0.33.0 の乖離(任意指摘)も、E のチェックが入れば自然に顕在化します。
Generated by Claude Code
#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.hsのData.Map as MとXsd as X、TestMixed.hsのModel as Md、Spec.hsのTest (..)も同様です。Spec.hsTest (..)TestUtils.hsData.Textのpack/unpack、Model全体、Test.HUnit全体TestCode.hsData.Map as M、Data.Text全体、Text.XML全体、Xsd as X、TestListTestMixed.hsData.Text全体、Model as Md、Text.XML全体、TestListTestModel.hsData.Text全体、Text.XML全体、TestListTestParser.hsData.Text全体、Model全体、TestListあわせて
import Utilを、各ファイルが実際に使う名前だけに絞りました(TestCodeはuniq、TestMixedとTestModelはunwrap)。これは警告の対象ではありませんが、上の削除と同じ性質の掃除です。判定は静的に行いました。文字列リテラルとコメントを除去したうえで、各 import 項目の名前が本体に単語境界付きで現れるかを機械的に確認しています(この手当ては必要でした。たとえば
TestParser.hsのdropDuplicateはassertEqual "dropDuplicate" ...というアサーションのラベル文字列としてしか現れず、単純な grep では「使用中」に見えます)。Utilについては、Utilの export 12 件それぞれについて 3 ファイルを確認しました。2. 型シグネチャの欠落(7 件)
tests :: [Test]—TestCode/TestModel/TestParser(TestMixedには既にありました)expected1..expected4 :: Type—TestModelexpected :: ElementInline—TestParser型は
Xsd.Schemaのフィールド定義から確定します(schemaTypes :: Map QName Type、schemaElements :: Map QName ElementInline)。どちらも既存のimport XsdがXsd.Typesを再 export しているのでスコープ内にあり、import の追加はありません。3.
-Wallを hpack のトップレベルに引き上げ-Wallを 3 つのスタンザそれぞれのghc-optionsから外し、トップレベルに 1 つ置きました。#66 で直したバグの原因そのものが、この「スタンザごとに書く」構造でした — フラグを 3 回書く必要があり、1 回書き忘れていた。トップレベルの 1 エントリなら書き忘れようがありません。-Wcompatも足しています。GHC の将来の破壊的変更を、実際に壊れる前にここで拾うためです。-Werrorは付けていないので、ビルドが落ちることはありません。4. #71 のレビュー指摘(スタイル)
#71 で触れた 2 ケースを、
TestModel.hsの他 7 ケースが使っているlet key = ...の形に揃えました。確認したこと / していないこと
package.yamlはyaml.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 を走らせたときに差分が出ます🤖 Generated with Claude Code
https://claude.ai/code/session_01P8rZakwAiz1jpViUX34x1Z
Generated by Claude Code