docs: ドキュメント配置ルール(SSOT)確立

## 追加内容
- CLAUDE.md にドキュメント配置ルール(SSOT)セクション追加
- DOCS_LAYOUT.md (SSOT): 置き場所ルール定義
- phases/README.md: Phase ドキュメント説明
- design/README.md: 設計図ドキュメント説明
- investigations/README.md: 調査ログ説明

## ルール概要
1. **Phase 文書** → phases/phase-<N>/
2. **設計図** → design/
3. **調査ログ** → investigations/ (結論を 10-Now/20-Decisions に反映)

## 導線
- CLAUDE.md で概要説明
- DOCS_LAYOUT.md で詳細定義(SSOT)
- 各フォルダ README で参照方法

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-14 18:27:24 +09:00
parent e4678585d5
commit 4b87b6cc88
12 changed files with 289 additions and 22 deletions

View File

@ -138,18 +138,25 @@ def lower_binop(
# except Exception:
# pass
# tagged string handles?(どちらかが string-ish のとき)
# Phase 196: TypeFacts SSOT - Only check for actual string types (not use-site demands)
# Check if BOTH operands are known to be strings from their definition
any_tagged = False
try:
if resolver is not None:
if hasattr(resolver, 'is_stringish'):
any_tagged = resolver.is_stringish(lhs) or resolver.is_stringish(rhs)
# literal strings are tracked separately
if not any_tagged and hasattr(resolver, 'string_literals'):
# Only check string_literals (TypeFacts), NOT is_stringish (TypeDemands)
if hasattr(resolver, 'string_literals'):
any_tagged = (lhs in resolver.string_literals) or (rhs in resolver.string_literals)
# Check if resolver has explicit type information (MirType::String or StringBox)
if not any_tagged and hasattr(resolver, 'value_types'):
lhs_ty = resolver.value_types.get(lhs)
rhs_ty = resolver.value_types.get(rhs)
lhs_str = lhs_ty and (lhs_ty.get('kind') == 'string' or
(lhs_ty.get('kind') == 'handle' and lhs_ty.get('box_type') == 'StringBox'))
rhs_str = rhs_ty and (rhs_ty.get('kind') == 'string' or
(rhs_ty.get('kind') == 'handle' and rhs_ty.get('box_type') == 'StringBox'))
any_tagged = lhs_str or rhs_str
except Exception:
pass
# Phase 131-6: Removed force_string from this check
is_str = is_ptr_side or any_tagged
# Phase 131-6 DEBUG
@ -184,12 +191,25 @@ def lower_binop(
return val
return ir.Constant(i64, 0)
# Decide route: handle+handle when both sides are string-ish; otherwise pointer+int route.
# Phase 196: TypeFacts SSOT - Use handle+handle only when BOTH are strings
lhs_tag = False; rhs_tag = False
try:
if resolver is not None and hasattr(resolver, 'is_stringish'):
lhs_tag = resolver.is_stringish(lhs)
rhs_tag = resolver.is_stringish(rhs)
if resolver is not None:
# Check string_literals (actual string constants)
if hasattr(resolver, 'string_literals'):
lhs_tag = lhs in resolver.string_literals
rhs_tag = rhs in resolver.string_literals
# Check value_types for String/StringBox types
if not lhs_tag and hasattr(resolver, 'value_types'):
lhs_ty = resolver.value_types.get(lhs)
if lhs_ty and (lhs_ty.get('kind') == 'string' or
(lhs_ty.get('kind') == 'handle' and lhs_ty.get('box_type') == 'StringBox')):
lhs_tag = True
if not rhs_tag and hasattr(resolver, 'value_types'):
rhs_ty = resolver.value_types.get(rhs)
if rhs_ty and (rhs_ty.get('kind') == 'string' or
(rhs_ty.get('kind') == 'handle' and rhs_ty.get('box_type') == 'StringBox')):
rhs_tag = True
except Exception:
pass
if lhs_tag and rhs_tag: