74 lines
2.4 KiB
Markdown
74 lines
2.4 KiB
Markdown
# Diagnostics and Fallback
|
|
|
|
エラーは runtime value ではなく diagnostic として扱う。
|
|
処理系はエラー内容に基づく汎用的な実行時分岐を提供しない。
|
|
|
|
## Diagnostic
|
|
|
|
```text
|
|
Diagnostic {
|
|
kind: DiagnosticKind
|
|
span: Span
|
|
message: String
|
|
labels: Vec<DiagnosticLabel>
|
|
}
|
|
|
|
DiagnosticLabel {
|
|
span: Span
|
|
message: String
|
|
}
|
|
```
|
|
|
|
`span` は primary location を示す。
|
|
`labels` は同じ error に関係する追加 location を示す。
|
|
合成や materialize の失敗では、衝突した constraint、value、default、または処理中 field path を label に含める。
|
|
|
|
代表的な diagnostic kind:
|
|
|
|
- syntax error
|
|
- unresolved identifier
|
|
- type mismatch
|
|
- constraint violation
|
|
- composition conflict
|
|
- default conflict
|
|
- cycle dependency
|
|
- import failure
|
|
- match failure
|
|
- materialization failure
|
|
|
|
## エラーは値ではない
|
|
|
|
評価失敗は `RuntimeValue` ではなく `Diagnostic` を返す。
|
|
そのため、通常の式はエラー内容に基づいて分岐できない。
|
|
|
|
```text
|
|
Result<RuntimeValue, Diagnostic>
|
|
```
|
|
|
|
これにより、制約違反、未定義識別子、循環依存、import 失敗などが通常値として流れることを避ける。
|
|
|
|
## 合成と materialize の diagnostic
|
|
|
|
合成や materialize の失敗は、以下を示す。
|
|
|
|
1. どの段階で失敗したか: composition、patch、materialization
|
|
2. どの field path を処理中だったか
|
|
3. どの constraint、value、default が衝突したか
|
|
4. なぜ合成または materialize できないか
|
|
|
|
例えば default が constraint を満たさない場合は、constraint の位置と default value の位置の両方を label として持つ。
|
|
object field の合成で concrete value が衝突する場合は、左辺 field と右辺 field の位置を label として持つ。
|
|
|
|
## `try / catch` は core に入れない
|
|
|
|
汎用 `try / catch` は core に入れない。
|
|
エラーを制御フローとして扱うと、どの失敗を捕捉できるか、捕捉後の thunk state をどう扱うか、制約違反を握りつぶしてよいか、といった仕様が重くなる。
|
|
|
|
fallback は有限で明示的な仕組みに限定する。
|
|
|
|
- `default`: 未指定値の fallback。
|
|
- `match`: 有限 pattern に基づく分岐。
|
|
|
|
Decodal は `unknown` / `any` を持たないため、field 不在や未解決 identifier を fallback 可能な通常値として扱わない。
|
|
それらは diagnostic として報告する。
|