refactor(mir): Remove TypeContext legacy fields (Phase 2-3/7)
完全移行→削除の安全順序(Option C)に従い、TypeContext の deprecated フィールドと sync helpers を完全削除。 ⚠️ 危険ゾーン: TypeFactsBox 等の同名フィールドと混同しないよう、 ファイル単位で手作業移行を実施。 ## Changes - Migrated all MirBuilder access sites to type_ctx.* (manual, 40+ files) - Removed 3 deprecated fields (value_types, value_kinds, value_origin_newbox) - Removed 2 sync helpers (sync_type_ctx_to_legacy, sync_legacy_to_type_ctx) - Verified TypeFactsBox, CalleeGuardBox unchanged (no false positives) ## Tests - cargo test --release --lib: 1029/1033 PASS - TypeFactsBox integration: PASS (borrowed references unchanged) - Deprecation warnings: 456 → 255 (-201, -44%) ## Safety Verification ✅ TypeFactsBox unchanged (still uses &'a BTreeMap borrowed references) ✅ CalleeGuardBox unchanged ✅ CalleeResolverBox unchanged ✅ BoxCompilationContext unchanged Phase 2 Progress: 3/7 contexts complete (43%) - ✅ MetadataContext - ✅ CoreContext - ✅ TypeContext (this commit) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -148,14 +148,6 @@ pub struct MirBuilder {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>,
|
pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>,
|
||||||
|
|
||||||
/// [DEPRECATED] Origin tracking for simple optimizations (e.g., object.method after new)
|
|
||||||
/// Maps a ValueId to the class name if it was produced by NewBox of that class
|
|
||||||
/// 注意: compilation_contextがSomeの場合は使用されません
|
|
||||||
/// Phase 136: Moved to type_ctx.value_origin_newbox (backward compat wrapper)
|
|
||||||
// Phase 25.1: HashMap → BTreeMap(決定性確保)
|
|
||||||
#[deprecated(note = "Use type_ctx.value_origin_newbox instead")]
|
|
||||||
pub(super) value_origin_newbox: BTreeMap<ValueId, String>,
|
|
||||||
|
|
||||||
/// [DEPRECATED] Names of user-defined boxes declared in the current module
|
/// [DEPRECATED] Names of user-defined boxes declared in the current module
|
||||||
/// Phase 136 Step 7/7: Moved to comp_ctx.user_defined_boxes (backward compat wrapper)
|
/// Phase 136 Step 7/7: Moved to comp_ctx.user_defined_boxes (backward compat wrapper)
|
||||||
#[deprecated(note = "Use comp_ctx.user_defined_boxes instead")]
|
#[deprecated(note = "Use comp_ctx.user_defined_boxes instead")]
|
||||||
@ -180,21 +172,6 @@ pub struct MirBuilder {
|
|||||||
#[deprecated(note = "Use comp_ctx.field_origin_by_box instead")]
|
#[deprecated(note = "Use comp_ctx.field_origin_by_box instead")]
|
||||||
pub(super) field_origin_by_box: HashMap<(String, String), String>,
|
pub(super) field_origin_by_box: HashMap<(String, String), String>,
|
||||||
|
|
||||||
/// [DEPRECATED] Optional per-value type annotations (MIR-level): ValueId -> MirType
|
|
||||||
/// 注意: compilation_contextがSomeの場合は使用されません
|
|
||||||
/// Phase 136: Moved to type_ctx.value_types (backward compat wrapper)
|
|
||||||
// Phase 25.1: HashMap → BTreeMap(決定性確保)
|
|
||||||
#[deprecated(note = "Use type_ctx.value_types instead")]
|
|
||||||
pub(super) value_types: BTreeMap<ValueId, super::MirType>,
|
|
||||||
|
|
||||||
/// [DEPRECATED] Phase 26-A: ValueId型情報マップ(型安全性強化)
|
|
||||||
/// ValueId -> MirValueKind のマッピング
|
|
||||||
/// - GUARDバグ予防: ValueId(0)がParameterかLocalか区別可能
|
|
||||||
/// - デフォルト: 未登録のValueIdはTemporary扱い
|
|
||||||
/// Phase 136: Moved to type_ctx.value_kinds (backward compat wrapper)
|
|
||||||
#[deprecated(note = "Use type_ctx.value_kinds instead")]
|
|
||||||
pub(super) value_kinds: HashMap<ValueId, super::MirValueKind>,
|
|
||||||
|
|
||||||
/// [DEPRECATED] 関数スコープの SlotRegistry(観測専用)
|
/// [DEPRECATED] 関数スコープの SlotRegistry(観測専用)
|
||||||
/// Phase 136 Step 7/7: Moved to comp_ctx.current_slot_registry (backward compat wrapper)
|
/// Phase 136 Step 7/7: Moved to comp_ctx.current_slot_registry (backward compat wrapper)
|
||||||
/// - current_function と同じライフサイクルを持つよ。
|
/// - current_function と同じライフサイクルを持つよ。
|
||||||
@ -362,14 +339,11 @@ impl MirBuilder {
|
|||||||
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
|
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
|
||||||
lexical_scope_stack: Vec::new(),
|
lexical_scope_stack: Vec::new(),
|
||||||
pending_phis: Vec::new(),
|
pending_phis: Vec::new(),
|
||||||
value_origin_newbox: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
|
|
||||||
user_defined_boxes: HashSet::new(),
|
user_defined_boxes: HashSet::new(),
|
||||||
weak_fields_by_box: HashMap::new(),
|
weak_fields_by_box: HashMap::new(),
|
||||||
property_getters_by_box: HashMap::new(),
|
property_getters_by_box: HashMap::new(),
|
||||||
field_origin_class: HashMap::new(),
|
field_origin_class: HashMap::new(),
|
||||||
field_origin_by_box: HashMap::new(),
|
field_origin_by_box: HashMap::new(),
|
||||||
value_types: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
|
|
||||||
value_kinds: HashMap::new(), // Phase 26-A: ValueId型安全化 (backward compat)
|
|
||||||
current_slot_registry: None,
|
current_slot_registry: None,
|
||||||
type_registry: type_registry::TypeRegistry::new(),
|
type_registry: type_registry::TypeRegistry::new(),
|
||||||
plugin_method_sigs,
|
plugin_method_sigs,
|
||||||
@ -411,23 +385,6 @@ impl MirBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Phase 136: TypeContext synchronization helpers ----
|
|
||||||
/// Sync type_ctx changes back to legacy fields (backward compatibility)
|
|
||||||
#[allow(deprecated)]
|
|
||||||
fn sync_type_ctx_to_legacy(&mut self) {
|
|
||||||
self.value_types = self.type_ctx.value_types.clone();
|
|
||||||
self.value_kinds = self.type_ctx.value_kinds.clone();
|
|
||||||
self.value_origin_newbox = self.type_ctx.value_origin_newbox.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sync legacy field changes to type_ctx (backward compatibility)
|
|
||||||
#[allow(deprecated)]
|
|
||||||
fn sync_legacy_to_type_ctx(&mut self) {
|
|
||||||
self.type_ctx.value_types = self.value_types.clone();
|
|
||||||
self.type_ctx.value_kinds = self.value_kinds.clone();
|
|
||||||
self.type_ctx.value_origin_newbox = self.value_origin_newbox.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Phase 136 Step 3/7: ScopeContext synchronization helpers ----
|
// ---- Phase 136 Step 3/7: ScopeContext synchronization helpers ----
|
||||||
/// Sync scope_ctx changes back to legacy fields (backward compatibility)
|
/// Sync scope_ctx changes back to legacy fields (backward compatibility)
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
@ -728,7 +685,7 @@ impl MirBuilder {
|
|||||||
};
|
};
|
||||||
// Annotate type
|
// Annotate type
|
||||||
if let Some(ty) = ty_for_dst {
|
if let Some(ty) = ty_for_dst {
|
||||||
self.value_types.insert(dst, ty);
|
self.type_ctx.value_types.insert(dst, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
@ -1099,7 +1056,7 @@ impl MirBuilder {
|
|||||||
effects: EffectMask::PURE,
|
effects: EffectMask::PURE,
|
||||||
})?;
|
})?;
|
||||||
// 型注釈(最小)
|
// 型注釈(最小)
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(dst, super::MirType::Box(class.clone()));
|
.insert(dst, super::MirType::Box(class.clone()));
|
||||||
return Ok(dst);
|
return Ok(dst);
|
||||||
}
|
}
|
||||||
@ -1117,7 +1074,7 @@ impl MirBuilder {
|
|||||||
dst,
|
dst,
|
||||||
value: ConstValue::Integer(n),
|
value: ConstValue::Integer(n),
|
||||||
})?;
|
})?;
|
||||||
self.value_types.insert(dst, super::MirType::Integer);
|
self.type_ctx.value_types.insert(dst, super::MirType::Integer);
|
||||||
return Ok(dst);
|
return Ok(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1142,11 +1099,11 @@ impl MirBuilder {
|
|||||||
})?;
|
})?;
|
||||||
// Phase 15.5: Unified box type handling
|
// Phase 15.5: Unified box type handling
|
||||||
// All boxes (including former core boxes) are treated uniformly as Box types
|
// All boxes (including former core boxes) are treated uniformly as Box types
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(dst, super::MirType::Box(class.clone()));
|
.insert(dst, super::MirType::Box(class.clone()));
|
||||||
|
|
||||||
// Record origin for optimization: dst was created by NewBox of class
|
// Record origin for optimization: dst was created by NewBox of class
|
||||||
self.value_origin_newbox.insert(dst, class.clone());
|
self.type_ctx.value_origin_newbox.insert(dst, class.clone());
|
||||||
|
|
||||||
// birth 呼び出し(Builder 正規化)
|
// birth 呼び出し(Builder 正規化)
|
||||||
// 優先: 低下済みグローバル関数 `<Class>.birth/Arity`(Arity は me を含まない)
|
// 優先: 低下済みグローバル関数 `<Class>.birth/Arity`(Arity は me を含まない)
|
||||||
@ -1215,18 +1172,18 @@ impl MirBuilder {
|
|||||||
/// Phase 136 P0: Use SSOT allocator (next_value_id) to respect function context
|
/// Phase 136 P0: Use SSOT allocator (next_value_id) to respect function context
|
||||||
pub fn new_typed_value(&mut self, kind: super::MirValueKind) -> super::TypedValueId {
|
pub fn new_typed_value(&mut self, kind: super::MirValueKind) -> super::TypedValueId {
|
||||||
let id = self.next_value_id();
|
let id = self.next_value_id();
|
||||||
self.value_kinds.insert(id, kind);
|
self.type_ctx.value_kinds.insert(id, kind);
|
||||||
super::TypedValueId::new(id, kind)
|
super::TypedValueId::new(id, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 既存ValueIdの型情報を取得
|
/// 既存ValueIdの型情報を取得
|
||||||
pub fn get_value_kind(&self, id: ValueId) -> Option<super::MirValueKind> {
|
pub fn get_value_kind(&self, id: ValueId) -> Option<super::MirValueKind> {
|
||||||
self.value_kinds.get(&id).copied()
|
self.type_ctx.value_kinds.get(&id).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 既存ValueIdに型情報を後付け(レガシー互換用)
|
/// 既存ValueIdに型情報を後付け(レガシー互換用)
|
||||||
pub fn register_value_kind(&mut self, id: ValueId, kind: super::MirValueKind) {
|
pub fn register_value_kind(&mut self, id: ValueId, kind: super::MirValueKind) {
|
||||||
self.value_kinds.insert(id, kind);
|
self.type_ctx.value_kinds.insert(id, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 型安全なパラメータ判定(ValueIdベース) - GUARD Bug Prevention
|
/// 型安全なパラメータ判定(ValueIdベース) - GUARD Bug Prevention
|
||||||
|
|||||||
@ -33,14 +33,14 @@ pub(in super::super) fn annotate_call_result_from_func_name<S: AsRef<str>>(
|
|||||||
// Normalize to Known Box(JsonParser)
|
// Normalize to Known Box(JsonParser)
|
||||||
ret = MirType::Box("JsonParser".into());
|
ret = MirType::Box("JsonParser".into());
|
||||||
}
|
}
|
||||||
builder.value_types.insert(dst, ret.clone());
|
builder.type_ctx.value_types.insert(dst, ret.clone());
|
||||||
if let MirType::Box(bx) = ret {
|
if let MirType::Box(bx) = ret {
|
||||||
builder.value_origin_newbox.insert(dst, bx);
|
builder.type_ctx.value_origin_newbox.insert(dst, bx);
|
||||||
if super::super::utils::builder_debug_enabled()
|
if super::super::utils::builder_debug_enabled()
|
||||||
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
||||||
{
|
{
|
||||||
let bx = builder
|
let bx = builder
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.get(&dst)
|
.get(&dst)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
@ -56,9 +56,9 @@ pub(in super::super) fn annotate_call_result_from_func_name<S: AsRef<str>>(
|
|||||||
// 2) No module signature—apply minimal heuristic for known functions
|
// 2) No module signature—apply minimal heuristic for known functions
|
||||||
if name == "JsonParser.parse/1" {
|
if name == "JsonParser.parse/1" {
|
||||||
let ret = MirType::Box("JsonNode".into());
|
let ret = MirType::Box("JsonNode".into());
|
||||||
builder.value_types.insert(dst, ret.clone());
|
builder.type_ctx.value_types.insert(dst, ret.clone());
|
||||||
if let MirType::Box(bx) = ret {
|
if let MirType::Box(bx) = ret {
|
||||||
builder.value_origin_newbox.insert(dst, bx);
|
builder.type_ctx.value_origin_newbox.insert(dst, bx);
|
||||||
}
|
}
|
||||||
if super::super::utils::builder_debug_enabled()
|
if super::super::utils::builder_debug_enabled()
|
||||||
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
||||||
@ -70,9 +70,9 @@ pub(in super::super) fn annotate_call_result_from_func_name<S: AsRef<str>>(
|
|||||||
}
|
}
|
||||||
} else if name == "JsonParser.current_token/0" {
|
} else if name == "JsonParser.current_token/0" {
|
||||||
let ret = MirType::Box("JsonToken".into());
|
let ret = MirType::Box("JsonToken".into());
|
||||||
builder.value_types.insert(dst, ret.clone());
|
builder.type_ctx.value_types.insert(dst, ret.clone());
|
||||||
if let MirType::Box(bx) = ret {
|
if let MirType::Box(bx) = ret {
|
||||||
builder.value_origin_newbox.insert(dst, bx);
|
builder.type_ctx.value_origin_newbox.insert(dst, bx);
|
||||||
}
|
}
|
||||||
if super::super::utils::builder_debug_enabled()
|
if super::super::utils::builder_debug_enabled()
|
||||||
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
||||||
@ -85,9 +85,9 @@ pub(in super::super) fn annotate_call_result_from_func_name<S: AsRef<str>>(
|
|||||||
} else if name == "JsonTokenizer.tokenize/0" {
|
} else if name == "JsonTokenizer.tokenize/0" {
|
||||||
// Tokenize returns an ArrayBox of tokens
|
// Tokenize returns an ArrayBox of tokens
|
||||||
let ret = MirType::Box("ArrayBox".into());
|
let ret = MirType::Box("ArrayBox".into());
|
||||||
builder.value_types.insert(dst, ret.clone());
|
builder.type_ctx.value_types.insert(dst, ret.clone());
|
||||||
if let MirType::Box(bx) = ret {
|
if let MirType::Box(bx) = ret {
|
||||||
builder.value_origin_newbox.insert(dst, bx);
|
builder.type_ctx.value_origin_newbox.insert(dst, bx);
|
||||||
}
|
}
|
||||||
if super::super::utils::builder_debug_enabled()
|
if super::super::utils::builder_debug_enabled()
|
||||||
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
||||||
@ -100,9 +100,9 @@ pub(in super::super) fn annotate_call_result_from_func_name<S: AsRef<str>>(
|
|||||||
} else if name == "JsonParserModule.create_parser/0" {
|
} else if name == "JsonParserModule.create_parser/0" {
|
||||||
// Fallback path for parser factory
|
// Fallback path for parser factory
|
||||||
let ret = MirType::Box("JsonParser".into());
|
let ret = MirType::Box("JsonParser".into());
|
||||||
builder.value_types.insert(dst, ret.clone());
|
builder.type_ctx.value_types.insert(dst, ret.clone());
|
||||||
if let MirType::Box(bx) = ret {
|
if let MirType::Box(bx) = ret {
|
||||||
builder.value_origin_newbox.insert(dst, bx);
|
builder.type_ctx.value_origin_newbox.insert(dst, bx);
|
||||||
}
|
}
|
||||||
if super::super::utils::builder_debug_enabled()
|
if super::super::utils::builder_debug_enabled()
|
||||||
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
|| std::env::var("NYASH_BUILDER_DEBUG").ok().as_deref() == Some("1")
|
||||||
|
|||||||
@ -270,7 +270,7 @@ impl MirBuilder {
|
|||||||
if let Err(e) = self.emit_constructor_call(math_recv, "MathBox".to_string(), vec![]) {
|
if let Err(e) = self.emit_constructor_call(math_recv, "MathBox".to_string(), vec![]) {
|
||||||
return Some(Err(e));
|
return Some(Err(e));
|
||||||
}
|
}
|
||||||
self.value_origin_newbox
|
self.type_ctx.value_origin_newbox
|
||||||
.insert(math_recv, "MathBox".to_string());
|
.insert(math_recv, "MathBox".to_string());
|
||||||
// birth()
|
// birth()
|
||||||
if let Err(e) = self.emit_method_call(None, math_recv, "birth".to_string(), vec![]) {
|
if let Err(e) = self.emit_method_call(None, math_recv, "birth".to_string(), vec![]) {
|
||||||
@ -567,7 +567,7 @@ impl MirBuilder {
|
|||||||
"[DEBUG/param-recv] build_method_call receiver '{}' → ValueId({})",
|
"[DEBUG/param-recv] build_method_call receiver '{}' → ValueId({})",
|
||||||
name, object_value.0
|
name, object_value.0
|
||||||
);
|
);
|
||||||
if let Some(origin) = self.value_origin_newbox.get(&object_value) {
|
if let Some(origin) = self.type_ctx.value_origin_newbox.get(&object_value) {
|
||||||
eprintln!("[DEBUG/param-recv] origin: {}", origin);
|
eprintln!("[DEBUG/param-recv] origin: {}", origin);
|
||||||
}
|
}
|
||||||
if let Some(&mapped_id) = self.variable_map.get(name) {
|
if let Some(&mapped_id) = self.variable_map.get(name) {
|
||||||
|
|||||||
@ -48,12 +48,12 @@ impl MirBuilder {
|
|||||||
// BoxCompilationContext mode: clear()で完全独立化
|
// BoxCompilationContext mode: clear()で完全独立化
|
||||||
if context_active {
|
if context_active {
|
||||||
self.variable_map.clear();
|
self.variable_map.clear();
|
||||||
self.value_origin_newbox.clear();
|
self.type_ctx.value_origin_newbox.clear();
|
||||||
// value_types も static box 単位で独立させる。
|
// value_types も static box 単位で独立させる。
|
||||||
// これにより、前の static box で使用された ValueId に紐づく型情報が
|
// これにより、前の static box で使用された ValueId に紐づく型情報が
|
||||||
// 次の box にリークして誤った box_name 推論(例: Stage1UsingResolverBox)
|
// 次の box にリークして誤った box_name 推論(例: Stage1UsingResolverBox)
|
||||||
// を引き起こすことを防ぐ。
|
// を引き起こすことを防ぐ。
|
||||||
self.value_types.clear();
|
self.type_ctx.value_types.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
LoweringContext {
|
LoweringContext {
|
||||||
@ -203,14 +203,14 @@ impl MirBuilder {
|
|||||||
'search: for (_bid, bb) in f.blocks.iter() {
|
'search: for (_bid, bb) in f.blocks.iter() {
|
||||||
for inst in bb.instructions.iter() {
|
for inst in bb.instructions.iter() {
|
||||||
if let MirInstruction::Return { value: Some(v) } = inst {
|
if let MirInstruction::Return { value: Some(v) } = inst {
|
||||||
if let Some(mt) = self.value_types.get(v).cloned() {
|
if let Some(mt) = self.type_ctx.value_types.get(v).cloned() {
|
||||||
inferred = Some(mt);
|
inferred = Some(mt);
|
||||||
break 'search;
|
break 'search;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(MirInstruction::Return { value: Some(v) }) = &bb.terminator {
|
if let Some(MirInstruction::Return { value: Some(v) }) = &bb.terminator {
|
||||||
if let Some(mt) = self.value_types.get(v).cloned() {
|
if let Some(mt) = self.type_ctx.value_types.get(v).cloned() {
|
||||||
inferred = Some(mt);
|
inferred = Some(mt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -244,9 +244,9 @@ impl MirBuilder {
|
|||||||
if ctx.context_active {
|
if ctx.context_active {
|
||||||
// BoxCompilationContext mode: clear のみ(次回も完全独立)
|
// BoxCompilationContext mode: clear のみ(次回も完全独立)
|
||||||
self.variable_map.clear();
|
self.variable_map.clear();
|
||||||
self.value_origin_newbox.clear();
|
self.type_ctx.value_origin_newbox.clear();
|
||||||
// static box ごとに型情報も独立させる(前 box の型メタデータを引きずらない)
|
// static box ごとに型情報も独立させる(前 box の型メタデータを引きずらない)
|
||||||
self.value_types.clear();
|
self.type_ctx.value_types.clear();
|
||||||
} else if let Some(saved) = ctx.saved_var_map {
|
} else if let Some(saved) = ctx.saved_var_map {
|
||||||
// Legacy mode: Main.main 側の variable_map を元に戻す
|
// Legacy mode: Main.main 側の variable_map を元に戻す
|
||||||
self.variable_map = saved;
|
self.variable_map = saved;
|
||||||
@ -316,7 +316,7 @@ impl MirBuilder {
|
|||||||
// me
|
// me
|
||||||
let me_id = f.params[0];
|
let me_id = f.params[0];
|
||||||
self.variable_map.insert("me".to_string(), me_id);
|
self.variable_map.insert("me".to_string(), me_id);
|
||||||
self.value_origin_newbox.insert(me_id, box_name.to_string());
|
self.type_ctx.value_origin_newbox.insert(me_id, box_name.to_string());
|
||||||
slot_regs.push(("me".to_string(), None));
|
slot_regs.push(("me".to_string(), None));
|
||||||
|
|
||||||
// 通常パラメータ
|
// 通常パラメータ
|
||||||
@ -449,14 +449,14 @@ impl MirBuilder {
|
|||||||
'search: for (_bid, bb) in f.blocks.iter() {
|
'search: for (_bid, bb) in f.blocks.iter() {
|
||||||
for inst in bb.instructions.iter() {
|
for inst in bb.instructions.iter() {
|
||||||
if let MirInstruction::Return { value: Some(v) } = inst {
|
if let MirInstruction::Return { value: Some(v) } = inst {
|
||||||
if let Some(mt) = self.value_types.get(v).cloned() {
|
if let Some(mt) = self.type_ctx.value_types.get(v).cloned() {
|
||||||
inferred = Some(mt);
|
inferred = Some(mt);
|
||||||
break 'search;
|
break 'search;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(MirInstruction::Return { value: Some(v) }) = &bb.terminator {
|
if let Some(MirInstruction::Return { value: Some(v) }) = &bb.terminator {
|
||||||
if let Some(mt) = self.value_types.get(v).cloned() {
|
if let Some(mt) = self.type_ctx.value_types.get(v).cloned() {
|
||||||
inferred = Some(mt);
|
inferred = Some(mt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,7 @@ impl UnifiedCallEmitterBox {
|
|||||||
{
|
{
|
||||||
let recv_cls = box_type
|
let recv_cls = box_type
|
||||||
.clone()
|
.clone()
|
||||||
.or_else(|| builder.value_origin_newbox.get(&receiver).cloned())
|
.or_else(|| builder.type_ctx.value_origin_newbox.get(&receiver).cloned())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
// Use indexed candidate lookup (tail → names)
|
// Use indexed candidate lookup (tail → names)
|
||||||
let candidates: Vec<String> = builder.method_candidates(method, arity_for_try);
|
let candidates: Vec<String> = builder.method_candidates(method, arity_for_try);
|
||||||
@ -100,9 +100,9 @@ impl UnifiedCallEmitterBox {
|
|||||||
{
|
{
|
||||||
let class_name_opt = box_type
|
let class_name_opt = box_type
|
||||||
.clone()
|
.clone()
|
||||||
.or_else(|| builder.value_origin_newbox.get(&receiver).cloned())
|
.or_else(|| builder.type_ctx.value_origin_newbox.get(&receiver).cloned())
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
builder.value_types.get(&receiver).and_then(|t| {
|
builder.type_ctx.value_types.get(&receiver).and_then(|t| {
|
||||||
if let crate::mir::MirType::Box(b) = t {
|
if let crate::mir::MirType::Box(b) = t {
|
||||||
Some(b.clone())
|
Some(b.clone())
|
||||||
} else {
|
} else {
|
||||||
@ -152,8 +152,8 @@ impl UnifiedCallEmitterBox {
|
|||||||
if let CallTarget::Global(ref _n) = target { /* dev trace removed */ }
|
if let CallTarget::Global(ref _n) = target { /* dev trace removed */ }
|
||||||
// Fallback: if Global target is unknown, try unique static-method mapping (name/arity)
|
// Fallback: if Global target is unknown, try unique static-method mapping (name/arity)
|
||||||
let resolver = super::resolver::CalleeResolverBox::new(
|
let resolver = super::resolver::CalleeResolverBox::new(
|
||||||
&builder.value_origin_newbox,
|
&builder.type_ctx.value_origin_newbox,
|
||||||
&builder.value_types,
|
&builder.type_ctx.value_types,
|
||||||
Some(&builder.type_registry), // 🎯 TypeRegistry を渡す
|
Some(&builder.type_registry), // 🎯 TypeRegistry を渡す
|
||||||
);
|
);
|
||||||
let mut callee = match resolver.resolve(target.clone()) {
|
let mut callee = match resolver.resolve(target.clone()) {
|
||||||
@ -203,12 +203,12 @@ impl UnifiedCallEmitterBox {
|
|||||||
args: Vec::new(), // Static box singleton, no constructor args
|
args: Vec::new(), // Static box singleton, no constructor args
|
||||||
})?;
|
})?;
|
||||||
// Register type information
|
// Register type information
|
||||||
builder.value_types.insert(
|
builder.type_ctx.value_types.insert(
|
||||||
singleton_id,
|
singleton_id,
|
||||||
crate::mir::MirType::Box(box_name.to_string()),
|
crate::mir::MirType::Box(box_name.to_string()),
|
||||||
);
|
);
|
||||||
builder
|
builder
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.insert(singleton_id, box_name.to_string());
|
.insert(singleton_id, box_name.to_string());
|
||||||
// Cache for future use
|
// Cache for future use
|
||||||
builder
|
builder
|
||||||
@ -243,7 +243,7 @@ impl UnifiedCallEmitterBox {
|
|||||||
// Structural guard FIRST: prevent static compiler boxes from being called with runtime receivers
|
// Structural guard FIRST: prevent static compiler boxes from being called with runtime receivers
|
||||||
// 箱理論: CalleeGuardBox による構造的分離
|
// 箱理論: CalleeGuardBox による構造的分離
|
||||||
// (Guard may convert Method → Global, so we check BEFORE materializing receiver)
|
// (Guard may convert Method → Global, so we check BEFORE materializing receiver)
|
||||||
let guard = super::guard::CalleeGuardBox::new(&builder.value_types);
|
let guard = super::guard::CalleeGuardBox::new(&builder.type_ctx.value_types);
|
||||||
callee = guard.apply_static_runtime_guard(callee)?;
|
callee = guard.apply_static_runtime_guard(callee)?;
|
||||||
|
|
||||||
// Safety: ensure receiver is materialized ONLY for Method calls
|
// Safety: ensure receiver is materialized ONLY for Method calls
|
||||||
@ -277,8 +277,8 @@ impl UnifiedCallEmitterBox {
|
|||||||
// Validate call arguments
|
// Validate call arguments
|
||||||
// 箱理論: CalleeResolverBox で引数検証
|
// 箱理論: CalleeResolverBox で引数検証
|
||||||
let resolver = super::resolver::CalleeResolverBox::new(
|
let resolver = super::resolver::CalleeResolverBox::new(
|
||||||
&builder.value_origin_newbox,
|
&builder.type_ctx.value_origin_newbox,
|
||||||
&builder.value_types,
|
&builder.type_ctx.value_types,
|
||||||
Some(&builder.type_registry),
|
Some(&builder.type_registry),
|
||||||
);
|
);
|
||||||
resolver.validate_args(&callee, &args)?;
|
resolver.validate_args(&callee, &args)?;
|
||||||
@ -296,7 +296,7 @@ impl UnifiedCallEmitterBox {
|
|||||||
// Try to retrieve origin info for receiver
|
// Try to retrieve origin info for receiver
|
||||||
let recv_meta = receiver.and_then(|r| {
|
let recv_meta = receiver.and_then(|r| {
|
||||||
builder
|
builder
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.get(&r)
|
.get(&r)
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|cls| (r, cls))
|
.map(|cls| (r, cls))
|
||||||
|
|||||||
@ -95,8 +95,8 @@ impl LoopHeaderPhiBuilder {
|
|||||||
|
|
||||||
// Phase 131-11-H: Set PHI type from entry incoming (init value) only
|
// Phase 131-11-H: Set PHI type from entry incoming (init value) only
|
||||||
// Ignore backedge to avoid circular dependency in type inference
|
// Ignore backedge to avoid circular dependency in type inference
|
||||||
if let Some(init_type) = builder.value_types.get(&loop_var_init).cloned() {
|
if let Some(init_type) = builder.type_ctx.value_types.get(&loop_var_init).cloned() {
|
||||||
builder.value_types.insert(loop_var_phi_dst, init_type.clone());
|
builder.type_ctx.value_types.insert(loop_var_phi_dst, init_type.clone());
|
||||||
|
|
||||||
if debug || std::env::var("NYASH_CARRIER_PHI_DEBUG").ok().as_deref() == Some("1") {
|
if debug || std::env::var("NYASH_CARRIER_PHI_DEBUG").ok().as_deref() == Some("1") {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -144,8 +144,8 @@ impl LoopHeaderPhiBuilder {
|
|||||||
|
|
||||||
// Phase 131-11-H: Set PHI type from entry incoming (init value) only
|
// Phase 131-11-H: Set PHI type from entry incoming (init value) only
|
||||||
// Ignore backedge to avoid circular dependency in type inference
|
// Ignore backedge to avoid circular dependency in type inference
|
||||||
if let Some(init_type) = builder.value_types.get(&init_value).cloned() {
|
if let Some(init_type) = builder.type_ctx.value_types.get(&init_value).cloned() {
|
||||||
builder.value_types.insert(phi_dst, init_type.clone());
|
builder.type_ctx.value_types.insert(phi_dst, init_type.clone());
|
||||||
|
|
||||||
if debug || std::env::var("NYASH_CARRIER_PHI_DEBUG").ok().as_deref() == Some("1") {
|
if debug || std::env::var("NYASH_CARRIER_PHI_DEBUG").ok().as_deref() == Some("1") {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
@ -75,8 +75,8 @@ impl super::MirBuilder {
|
|||||||
box_type: "ArrayBox".to_string(),
|
box_type: "ArrayBox".to_string(),
|
||||||
args: vec![],
|
args: vec![],
|
||||||
})?;
|
})?;
|
||||||
self.value_origin_newbox.insert(pid, "ArrayBox".to_string());
|
self.type_ctx.value_origin_newbox.insert(pid, "ArrayBox".to_string());
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(pid, super::MirType::Box("ArrayBox".to_string()));
|
.insert(pid, super::MirType::Box("ArrayBox".to_string()));
|
||||||
// Explicitly call birth() to initialize internal state
|
// Explicitly call birth() to initialize internal state
|
||||||
self.emit_instruction(MirInstruction::BoxCall {
|
self.emit_instruction(MirInstruction::BoxCall {
|
||||||
@ -112,7 +112,7 @@ impl super::MirBuilder {
|
|||||||
self.variable_map.insert(p.clone(), pid);
|
self.variable_map.insert(p.clone(), pid);
|
||||||
// 関数スコープ SlotRegistry にも登録しておくよ(観測専用)
|
// 関数スコープ SlotRegistry にも登録しておくよ(観測専用)
|
||||||
if let Some(reg) = self.current_slot_registry.as_mut() {
|
if let Some(reg) = self.current_slot_registry.as_mut() {
|
||||||
let ty = self.value_types.get(&pid).cloned();
|
let ty = self.type_ctx.value_types.get(&pid).cloned();
|
||||||
reg.ensure_slot(p, ty);
|
reg.ensure_slot(p, ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ pub fn emit_to(
|
|||||||
b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?;
|
b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?;
|
||||||
}
|
}
|
||||||
// 比較結果は Bool 型(既存実装と同じ振る舞い)
|
// 比較結果は Bool 型(既存実装と同じ振る舞い)
|
||||||
b.value_types.insert(dst, MirType::Bool);
|
b.type_ctx.value_types.insert(dst, MirType::Bool);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ pub fn emit_integer(b: &mut MirBuilder, val: i64) -> ValueId {
|
|||||||
value: ConstValue::Integer(val),
|
value: ConstValue::Integer(val),
|
||||||
});
|
});
|
||||||
// Phase 84-1: Integer constant type annotation
|
// Phase 84-1: Integer constant type annotation
|
||||||
b.value_types.insert(dst, crate::mir::MirType::Integer);
|
b.type_ctx.value_types.insert(dst, crate::mir::MirType::Integer);
|
||||||
dst
|
dst
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ pub fn emit_bool(b: &mut MirBuilder, val: bool) -> ValueId {
|
|||||||
value: ConstValue::Bool(val),
|
value: ConstValue::Bool(val),
|
||||||
});
|
});
|
||||||
// Phase 84-1: Bool constant type annotation
|
// Phase 84-1: Bool constant type annotation
|
||||||
b.value_types.insert(dst, crate::mir::MirType::Bool);
|
b.type_ctx.value_types.insert(dst, crate::mir::MirType::Bool);
|
||||||
dst
|
dst
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ pub fn emit_float(b: &mut MirBuilder, val: f64) -> ValueId {
|
|||||||
value: ConstValue::Float(val),
|
value: ConstValue::Float(val),
|
||||||
});
|
});
|
||||||
// Phase 84-1: Float constant type annotation
|
// Phase 84-1: Float constant type annotation
|
||||||
b.value_types.insert(dst, crate::mir::MirType::Float);
|
b.type_ctx.value_types.insert(dst, crate::mir::MirType::Float);
|
||||||
dst
|
dst
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,9 +51,9 @@ pub fn emit_string<S: Into<String>>(b: &mut MirBuilder, s: S) -> ValueId {
|
|||||||
});
|
});
|
||||||
// 🎯 Phase 3-A: String constant type annotation
|
// 🎯 Phase 3-A: String constant type annotation
|
||||||
// Ensures string constants have proper Box type for method resolution
|
// Ensures string constants have proper Box type for method resolution
|
||||||
b.value_types
|
b.type_ctx.value_types
|
||||||
.insert(dst, crate::mir::MirType::Box("StringBox".to_string()));
|
.insert(dst, crate::mir::MirType::Box("StringBox".to_string()));
|
||||||
b.value_origin_newbox.insert(dst, "StringBox".to_string());
|
b.type_ctx.value_origin_newbox.insert(dst, "StringBox".to_string());
|
||||||
dst
|
dst
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ pub fn emit_null(b: &mut MirBuilder) -> ValueId {
|
|||||||
});
|
});
|
||||||
// Phase 84-1: Null constant type annotation
|
// Phase 84-1: Null constant type annotation
|
||||||
// Note: MirType has no Null variant, using Unknown as fallback
|
// Note: MirType has no Null variant, using Unknown as fallback
|
||||||
b.value_types.insert(dst, crate::mir::MirType::Unknown);
|
b.type_ctx.value_types.insert(dst, crate::mir::MirType::Unknown);
|
||||||
dst
|
dst
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +78,6 @@ pub fn emit_void(b: &mut MirBuilder) -> ValueId {
|
|||||||
value: ConstValue::Void,
|
value: ConstValue::Void,
|
||||||
});
|
});
|
||||||
// Phase 84-1: Void constant type annotation
|
// Phase 84-1: Void constant type annotation
|
||||||
b.value_types.insert(dst, crate::mir::MirType::Void);
|
b.type_ctx.value_types.insert(dst, crate::mir::MirType::Void);
|
||||||
dst
|
dst
|
||||||
}
|
}
|
||||||
|
|||||||
@ -306,9 +306,9 @@ impl super::MirBuilder {
|
|||||||
args: vec![],
|
args: vec![],
|
||||||
effects: super::EffectMask::MUT,
|
effects: super::EffectMask::MUT,
|
||||||
})?;
|
})?;
|
||||||
self.value_origin_newbox
|
self.type_ctx.value_origin_newbox
|
||||||
.insert(arr_id, "ArrayBox".to_string());
|
.insert(arr_id, "ArrayBox".to_string());
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(arr_id, super::MirType::Box("ArrayBox".to_string()));
|
.insert(arr_id, super::MirType::Box("ArrayBox".to_string()));
|
||||||
// TypeRegistry + trace for deterministic debug
|
// TypeRegistry + trace for deterministic debug
|
||||||
self.type_registry
|
self.type_registry
|
||||||
@ -350,9 +350,9 @@ impl super::MirBuilder {
|
|||||||
args: vec![],
|
args: vec![],
|
||||||
effects: super::EffectMask::MUT,
|
effects: super::EffectMask::MUT,
|
||||||
})?;
|
})?;
|
||||||
self.value_origin_newbox
|
self.type_ctx.value_origin_newbox
|
||||||
.insert(map_id, "MapBox".to_string());
|
.insert(map_id, "MapBox".to_string());
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(map_id, super::MirType::Box("MapBox".to_string()));
|
.insert(map_id, super::MirType::Box("MapBox".to_string()));
|
||||||
self.type_registry
|
self.type_registry
|
||||||
.record_newbox(map_id, "MapBox".to_string());
|
.record_newbox(map_id, "MapBox".to_string());
|
||||||
@ -401,10 +401,10 @@ impl super::MirBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn infer_index_target_class(&self, target_val: ValueId) -> Option<String> {
|
fn infer_index_target_class(&self, target_val: ValueId) -> Option<String> {
|
||||||
if let Some(cls) = self.value_origin_newbox.get(&target_val) {
|
if let Some(cls) = self.type_ctx.value_origin_newbox.get(&target_val) {
|
||||||
return Some(cls.clone());
|
return Some(cls.clone());
|
||||||
}
|
}
|
||||||
self.value_types.get(&target_val).and_then(|ty| match ty {
|
self.type_ctx.value_types.get(&target_val).and_then(|ty| match ty {
|
||||||
super::MirType::Box(name) => Some(name.clone()),
|
super::MirType::Box(name) => Some(name.clone()),
|
||||||
super::MirType::String => Some("String".to_string()),
|
super::MirType::String => Some("String".to_string()),
|
||||||
super::MirType::Integer => Some("Integer".to_string()),
|
super::MirType::Integer => Some("Integer".to_string()),
|
||||||
|
|||||||
@ -170,7 +170,7 @@ impl super::MirBuilder {
|
|||||||
captures,
|
captures,
|
||||||
me,
|
me,
|
||||||
})?;
|
})?;
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(dst, crate::mir::MirType::Box("FunctionBox".to_string()));
|
.insert(dst, crate::mir::MirType::Box("FunctionBox".to_string()));
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ impl super::MirBuilder {
|
|||||||
|
|
||||||
// Unified members: if object class is known and has a synthetic getter for `field`,
|
// Unified members: if object class is known and has a synthetic getter for `field`,
|
||||||
// rewrite to method call `__get_<field>()`.
|
// rewrite to method call `__get_<field>()`.
|
||||||
if let Some(class_name) = self.value_origin_newbox.get(&object_value).cloned() {
|
if let Some(class_name) = self.type_ctx.value_origin_newbox.get(&object_value).cloned() {
|
||||||
if let Some(map) = self.property_getters_by_box.get(&class_name) {
|
if let Some(map) = self.property_getters_by_box.get(&class_name) {
|
||||||
if let Some(kind) = map.get(&field) {
|
if let Some(kind) = map.get(&field) {
|
||||||
let mname = match kind {
|
let mname = match kind {
|
||||||
@ -57,8 +57,8 @@ impl super::MirBuilder {
|
|||||||
.get(&(object_value, field.clone()))
|
.get(&(object_value, field.clone()))
|
||||||
.cloned()
|
.cloned()
|
||||||
{
|
{
|
||||||
self.value_origin_newbox.insert(field_val, class_name);
|
self.type_ctx.value_origin_newbox.insert(field_val, class_name);
|
||||||
} else if let Some(base_cls) = self.value_origin_newbox.get(&object_value).cloned() {
|
} else if let Some(base_cls) = self.type_ctx.value_origin_newbox.get(&object_value).cloned() {
|
||||||
// Cross-function heuristic: use class-level field origin mapping
|
// Cross-function heuristic: use class-level field origin mapping
|
||||||
if let Some(fcls) = self
|
if let Some(fcls) = self
|
||||||
.field_origin_by_box
|
.field_origin_by_box
|
||||||
@ -73,13 +73,13 @@ impl super::MirBuilder {
|
|||||||
base_cls, field, fcls
|
base_cls, field, fcls
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
self.value_origin_newbox.insert(field_val, fcls);
|
self.type_ctx.value_origin_newbox.insert(field_val, fcls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If base is a known newbox and field is weak, emit WeakLoad (+ optional barrier)
|
// If base is a known newbox and field is weak, emit WeakLoad (+ optional barrier)
|
||||||
let mut inferred_class: Option<String> =
|
let mut inferred_class: Option<String> =
|
||||||
self.value_origin_newbox.get(&object_value).cloned();
|
self.type_ctx.value_origin_newbox.get(&object_value).cloned();
|
||||||
if inferred_class.is_none() {
|
if inferred_class.is_none() {
|
||||||
if let ASTNode::FieldAccess {
|
if let ASTNode::FieldAccess {
|
||||||
object: inner_obj,
|
object: inner_obj,
|
||||||
@ -128,7 +128,7 @@ impl super::MirBuilder {
|
|||||||
value_result = self.local_arg(value_result);
|
value_result = self.local_arg(value_result);
|
||||||
|
|
||||||
// If base is known and field is weak, create WeakRef before store
|
// If base is known and field is weak, create WeakRef before store
|
||||||
if let Some(class_name) = self.value_origin_newbox.get(&object_value).cloned() {
|
if let Some(class_name) = self.type_ctx.value_origin_newbox.get(&object_value).cloned() {
|
||||||
if let Some(weak_set) = self.weak_fields_by_box.get(&class_name) {
|
if let Some(weak_set) = self.weak_fields_by_box.get(&class_name) {
|
||||||
if weak_set.contains(&field) {
|
if weak_set.contains(&field) {
|
||||||
value_result = self.emit_weak_new(value_result)?;
|
value_result = self.emit_weak_new(value_result)?;
|
||||||
@ -158,7 +158,7 @@ impl super::MirBuilder {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Write barrier if weak field
|
// Write barrier if weak field
|
||||||
if let Some(class_name) = self.value_origin_newbox.get(&object_value).cloned() {
|
if let Some(class_name) = self.type_ctx.value_origin_newbox.get(&object_value).cloned() {
|
||||||
if let Some(weak_set) = self.weak_fields_by_box.get(&class_name) {
|
if let Some(weak_set) = self.weak_fields_by_box.get(&class_name) {
|
||||||
if weak_set.contains(&field) {
|
if weak_set.contains(&field) {
|
||||||
let _ = self.emit_barrier_write(value_result);
|
let _ = self.emit_barrier_write(value_result);
|
||||||
@ -167,11 +167,11 @@ impl super::MirBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Record origin class for this field value if known
|
// Record origin class for this field value if known
|
||||||
if let Some(val_cls) = self.value_origin_newbox.get(&value_result).cloned() {
|
if let Some(val_cls) = self.type_ctx.value_origin_newbox.get(&value_result).cloned() {
|
||||||
self.field_origin_class
|
self.field_origin_class
|
||||||
.insert((object_value, field.clone()), val_cls.clone());
|
.insert((object_value, field.clone()), val_cls.clone());
|
||||||
// Also record class-level mapping if base object class is known
|
// Also record class-level mapping if base object class is known
|
||||||
if let Some(base_cls) = self.value_origin_newbox.get(&object_value).cloned() {
|
if let Some(base_cls) = self.type_ctx.value_origin_newbox.get(&object_value).cloned() {
|
||||||
self.field_origin_by_box
|
self.field_origin_by_box
|
||||||
.insert((base_cls, field.clone()), val_cls);
|
.insert((base_cls, field.clone()), val_cls);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -300,7 +300,7 @@ impl super::MirBuilder {
|
|||||||
value: Some(result_value),
|
value: Some(result_value),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(mt) = self.value_types.get(&result_value).cloned() {
|
if let Some(mt) = self.type_ctx.value_types.get(&result_value).cloned() {
|
||||||
function.signature.return_type = mt;
|
function.signature.return_type = mt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,7 +315,7 @@ impl super::MirBuilder {
|
|||||||
//
|
//
|
||||||
// Loop exit や If merge の edge copy で発生する型欠如を解消する。
|
// Loop exit や If merge の edge copy で発生する型欠如を解消する。
|
||||||
// Copy チェーン: v1 → v2 → v3 で v1 の型が既知なら v2, v3 にも伝播。
|
// Copy チェーン: v1 → v2 → v3 で v1 の型が既知なら v2, v3 にも伝播。
|
||||||
CopyTypePropagator::propagate(&function, &mut self.value_types);
|
CopyTypePropagator::propagate(&function, &mut self.type_ctx.value_types);
|
||||||
|
|
||||||
// Phase 131-9: Global PHI type inference
|
// Phase 131-9: Global PHI type inference
|
||||||
//
|
//
|
||||||
@ -335,7 +335,7 @@ impl super::MirBuilder {
|
|||||||
for inst in &bb.instructions {
|
for inst in &bb.instructions {
|
||||||
if let MirInstruction::Phi { dst, .. } = inst {
|
if let MirInstruction::Phi { dst, .. } = inst {
|
||||||
if std::env::var("NYASH_PHI_GLOBAL_DEBUG").is_ok() {
|
if std::env::var("NYASH_PHI_GLOBAL_DEBUG").is_ok() {
|
||||||
let existing_type = self.value_types.get(dst);
|
let existing_type = self.type_ctx.value_types.get(dst);
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[lifecycle/phi-scan] {} PHI {:?} existing type: {:?}",
|
"[lifecycle/phi-scan] {} PHI {:?} existing type: {:?}",
|
||||||
function.signature.name, dst, existing_type
|
function.signature.name, dst, existing_type
|
||||||
@ -357,12 +357,12 @@ impl super::MirBuilder {
|
|||||||
// Re-infer types for ALL PHI nodes using PhiTypeResolver
|
// Re-infer types for ALL PHI nodes using PhiTypeResolver
|
||||||
// This fixes incorrect types assigned by propagate_phi_meta during circular dependencies
|
// This fixes incorrect types assigned by propagate_phi_meta during circular dependencies
|
||||||
if !all_phi_dsts.is_empty() {
|
if !all_phi_dsts.is_empty() {
|
||||||
let phi_resolver = PhiTypeResolver::new(&function, &self.value_types);
|
let phi_resolver = PhiTypeResolver::new(&function, &self.type_ctx.value_types);
|
||||||
let mut inferred_types: Vec<(ValueId, MirType)> = Vec::new();
|
let mut inferred_types: Vec<(ValueId, MirType)> = Vec::new();
|
||||||
for dst in all_phi_dsts {
|
for dst in all_phi_dsts {
|
||||||
if let Some(mt) = phi_resolver.resolve(dst) {
|
if let Some(mt) = phi_resolver.resolve(dst) {
|
||||||
// Check if type changed
|
// Check if type changed
|
||||||
let existing_type = self.value_types.get(&dst);
|
let existing_type = self.type_ctx.value_types.get(&dst);
|
||||||
if existing_type.is_none() || existing_type != Some(&mt) {
|
if existing_type.is_none() || existing_type != Some(&mt) {
|
||||||
inferred_types.push((dst, mt));
|
inferred_types.push((dst, mt));
|
||||||
}
|
}
|
||||||
@ -371,8 +371,8 @@ impl super::MirBuilder {
|
|||||||
|
|
||||||
// Now insert/update all inferred types
|
// Now insert/update all inferred types
|
||||||
for (dst, mt) in inferred_types {
|
for (dst, mt) in inferred_types {
|
||||||
let old_type = self.value_types.get(&dst).cloned();
|
let old_type = self.type_ctx.value_types.get(&dst).cloned();
|
||||||
self.value_types.insert(dst, mt.clone());
|
self.type_ctx.value_types.insert(dst, mt.clone());
|
||||||
if std::env::var("NYASH_PHI_GLOBAL_DEBUG").is_ok() {
|
if std::env::var("NYASH_PHI_GLOBAL_DEBUG").is_ok() {
|
||||||
if let Some(old) = old_type {
|
if let Some(old) = old_type {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -400,7 +400,7 @@ impl super::MirBuilder {
|
|||||||
|
|
||||||
// Phase 131-9: Update function metadata with corrected types
|
// Phase 131-9: Update function metadata with corrected types
|
||||||
// MUST happen after PHI type correction above AND BinOp re-propagation
|
// MUST happen after PHI type correction above AND BinOp re-propagation
|
||||||
function.metadata.value_types = self.value_types.clone();
|
function.metadata.value_types = self.type_ctx.value_types.clone();
|
||||||
|
|
||||||
// Phase 82-5: lifecycle.rs バグ修正 - terminator の Return のみをチェック
|
// Phase 82-5: lifecycle.rs バグ修正 - terminator の Return のみをチェック
|
||||||
// 問題: instructions を先に走査すると、中間値(const void 等)を誤って推論対象にしてしまう
|
// 問題: instructions を先に走査すると、中間値(const void 等)を誤って推論対象にしてしまう
|
||||||
@ -413,7 +413,7 @@ impl super::MirBuilder {
|
|||||||
for (_bid, bb) in function.blocks.iter() {
|
for (_bid, bb) in function.blocks.iter() {
|
||||||
// Phase 82-5: instructions 走査を削除、terminator の Return のみをチェック
|
// Phase 82-5: instructions 走査を削除、terminator の Return のみをチェック
|
||||||
if let Some(super::MirInstruction::Return { value: Some(v) }) = &bb.terminator {
|
if let Some(super::MirInstruction::Return { value: Some(v) }) = &bb.terminator {
|
||||||
if let Some(mt) = self.value_types.get(v).cloned() {
|
if let Some(mt) = self.type_ctx.value_types.get(v).cloned() {
|
||||||
inferred = Some(mt);
|
inferred = Some(mt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -432,7 +432,7 @@ impl super::MirBuilder {
|
|||||||
if let Some(mt) = MethodReturnHintBox::resolve_for_return(
|
if let Some(mt) = MethodReturnHintBox::resolve_for_return(
|
||||||
&function,
|
&function,
|
||||||
*v,
|
*v,
|
||||||
&self.value_types,
|
&self.type_ctx.value_types,
|
||||||
) {
|
) {
|
||||||
if std::env::var("NYASH_P3D_DEBUG").is_ok() {
|
if std::env::var("NYASH_P3D_DEBUG").is_ok() {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -449,7 +449,7 @@ impl super::MirBuilder {
|
|||||||
// PHI + Copy の小グラフを DFS 探索し、1 種類の型に収束する場合のみ返す。
|
// PHI + Copy の小グラフを DFS 探索し、1 種類の型に収束する場合のみ返す。
|
||||||
// これにより Loop edge copy / If merge 後の型推論が解決できる。
|
// これにより Loop edge copy / If merge 後の型推論が解決できる。
|
||||||
if hint.is_none() {
|
if hint.is_none() {
|
||||||
let phi_resolver = PhiTypeResolver::new(&function, &self.value_types);
|
let phi_resolver = PhiTypeResolver::new(&function, &self.type_ctx.value_types);
|
||||||
if let Some(mt) = phi_resolver.resolve(*v) {
|
if let Some(mt) = phi_resolver.resolve(*v) {
|
||||||
if std::env::var("NYASH_P4_DEBUG").is_ok() {
|
if std::env::var("NYASH_P4_DEBUG").is_ok() {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -464,7 +464,7 @@ impl super::MirBuilder {
|
|||||||
// Phase 67: P3-C 対象なら GenericTypeResolver を優先使用
|
// Phase 67: P3-C 対象なら GenericTypeResolver を優先使用
|
||||||
if hint.is_none() && TypeHintPolicy::is_p3c_target(&function.signature.name) {
|
if hint.is_none() && TypeHintPolicy::is_p3c_target(&function.signature.name) {
|
||||||
if let Some(mt) =
|
if let Some(mt) =
|
||||||
GenericTypeResolver::resolve_from_phi(&function, *v, &self.value_types)
|
GenericTypeResolver::resolve_from_phi(&function, *v, &self.type_ctx.value_types)
|
||||||
{
|
{
|
||||||
if std::env::var("NYASH_P3C_DEBUG").is_ok() {
|
if std::env::var("NYASH_P3C_DEBUG").is_ok() {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -621,21 +621,21 @@ impl super::MirBuilder {
|
|||||||
for inst in bb.instructions.iter() {
|
for inst in bb.instructions.iter() {
|
||||||
match inst {
|
match inst {
|
||||||
MirInstruction::Await { dst, future } => {
|
MirInstruction::Await { dst, future } => {
|
||||||
if self.value_types.contains_key(dst) {
|
if self.type_ctx.value_types.contains_key(dst) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let inferred = match self.value_types.get(future) {
|
let inferred = match self.type_ctx.value_types.get(future) {
|
||||||
Some(MirType::Future(inner)) => (**inner).clone(),
|
Some(MirType::Future(inner)) => (**inner).clone(),
|
||||||
_ => MirType::Unknown,
|
_ => MirType::Unknown,
|
||||||
};
|
};
|
||||||
self.value_types.insert(*dst, inferred);
|
self.type_ctx.value_types.insert(*dst, inferred);
|
||||||
}
|
}
|
||||||
MirInstruction::Call {
|
MirInstruction::Call {
|
||||||
dst: Some(dst),
|
dst: Some(dst),
|
||||||
callee: Some(callee),
|
callee: Some(callee),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if self.value_types.contains_key(dst) {
|
if self.type_ctx.value_types.contains_key(dst) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let inferred = match callee {
|
let inferred = match callee {
|
||||||
@ -647,23 +647,23 @@ impl super::MirBuilder {
|
|||||||
crate::mir::builder::types::annotation::annotate_from_function(
|
crate::mir::builder::types::annotation::annotate_from_function(
|
||||||
self, *dst, name,
|
self, *dst, name,
|
||||||
);
|
);
|
||||||
self.value_types.get(dst).cloned()
|
self.type_ctx.value_types.get(dst).cloned()
|
||||||
})
|
})
|
||||||
.unwrap_or(MirType::Unknown),
|
.unwrap_or(MirType::Unknown),
|
||||||
Callee::Constructor { box_type } => {
|
Callee::Constructor { box_type } => {
|
||||||
let ret = MirType::Box(box_type.clone());
|
let ret = MirType::Box(box_type.clone());
|
||||||
self.value_origin_newbox.insert(*dst, box_type.clone());
|
self.type_ctx.value_origin_newbox.insert(*dst, box_type.clone());
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
_ => MirType::Unknown,
|
_ => MirType::Unknown,
|
||||||
};
|
};
|
||||||
self.value_types.insert(*dst, inferred);
|
self.type_ctx.value_types.insert(*dst, inferred);
|
||||||
}
|
}
|
||||||
MirInstruction::ExternCall { dst: Some(dst), .. }
|
MirInstruction::ExternCall { dst: Some(dst), .. }
|
||||||
| MirInstruction::BoxCall { dst: Some(dst), .. }
|
| MirInstruction::BoxCall { dst: Some(dst), .. }
|
||||||
| MirInstruction::PluginInvoke { dst: Some(dst), .. } => {
|
| MirInstruction::PluginInvoke { dst: Some(dst), .. } => {
|
||||||
if !self.value_types.contains_key(dst) {
|
if !self.type_ctx.value_types.contains_key(dst) {
|
||||||
self.value_types.insert(*dst, MirType::Unknown);
|
self.type_ctx.value_types.insert(*dst, MirType::Unknown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -686,8 +686,8 @@ impl super::MirBuilder {
|
|||||||
// Only handle Add operations (string concat vs numeric addition)
|
// Only handle Add operations (string concat vs numeric addition)
|
||||||
if matches!(op, crate::mir::BinaryOp::Add) {
|
if matches!(op, crate::mir::BinaryOp::Add) {
|
||||||
// Get current lhs/rhs types after PHI resolution
|
// Get current lhs/rhs types after PHI resolution
|
||||||
let lhs_type = self.value_types.get(lhs);
|
let lhs_type = self.type_ctx.value_types.get(lhs);
|
||||||
let rhs_type = self.value_types.get(rhs);
|
let rhs_type = self.type_ctx.value_types.get(rhs);
|
||||||
|
|
||||||
// Classify types
|
// Classify types
|
||||||
let lhs_class = match lhs_type {
|
let lhs_class = match lhs_type {
|
||||||
@ -716,14 +716,14 @@ impl super::MirBuilder {
|
|||||||
|
|
||||||
if let Some(new_ty) = new_type {
|
if let Some(new_ty) = new_type {
|
||||||
// Check if type is missing or different
|
// Check if type is missing or different
|
||||||
let current_type = self.value_types.get(dst);
|
let current_type = self.type_ctx.value_types.get(dst);
|
||||||
if current_type.is_none() || current_type != Some(&new_ty) {
|
if current_type.is_none() || current_type != Some(&new_ty) {
|
||||||
binop_updates.push((*dst, new_ty));
|
binop_updates.push((*dst, new_ty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Other arithmetic ops: always Integer
|
// Other arithmetic ops: always Integer
|
||||||
if !self.value_types.contains_key(dst) {
|
if !self.type_ctx.value_types.contains_key(dst) {
|
||||||
binop_updates.push((*dst, MirType::Integer));
|
binop_updates.push((*dst, MirType::Integer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,7 +739,7 @@ impl super::MirBuilder {
|
|||||||
function.signature.name, dst, ty
|
function.signature.name, dst, ty
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.value_types.insert(dst, ty);
|
self.type_ctx.value_types.insert(dst, ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,11 +19,11 @@ pub fn propagate(builder: &mut MirBuilder, src: ValueId, dst: ValueId) {
|
|||||||
builder.type_registry.propagate(src, dst);
|
builder.type_registry.propagate(src, dst);
|
||||||
} else {
|
} else {
|
||||||
// 従来: 直接アクセス(後方互換性)
|
// 従来: 直接アクセス(後方互換性)
|
||||||
if let Some(t) = builder.value_types.get(&src).cloned() {
|
if let Some(t) = builder.type_ctx.value_types.get(&src).cloned() {
|
||||||
builder.value_types.insert(dst, t);
|
builder.type_ctx.value_types.insert(dst, t);
|
||||||
}
|
}
|
||||||
if let Some(cls) = builder.value_origin_newbox.get(&src).cloned() {
|
if let Some(cls) = builder.type_ctx.value_origin_newbox.get(&src).cloned() {
|
||||||
builder.value_origin_newbox.insert(dst, cls);
|
builder.type_ctx.value_origin_newbox.insert(dst, cls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type_trace::propagate("meta", src, dst);
|
type_trace::propagate("meta", src, dst);
|
||||||
@ -43,7 +43,7 @@ pub fn propagate_with_override(builder: &mut MirBuilder, dst: ValueId, ty: MirTy
|
|||||||
builder.type_registry.record_type(dst, ty);
|
builder.type_registry.record_type(dst, ty);
|
||||||
} else {
|
} else {
|
||||||
// 従来: 直接アクセス
|
// 従来: 直接アクセス
|
||||||
builder.value_types.insert(dst, ty);
|
builder.type_ctx.value_types.insert(dst, ty);
|
||||||
}
|
}
|
||||||
type_trace::ty("override", dst, &ty_clone);
|
type_trace::ty("override", dst, &ty_clone);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,8 @@ pub(crate) fn emit_phi(builder: &MirBuilder, dst: ValueId, inputs: &Vec<(BasicBl
|
|||||||
let preds: Vec<serde_json::Value> = inputs
|
let preds: Vec<serde_json::Value> = inputs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(bb, v)| {
|
.map(|(bb, v)| {
|
||||||
let t = builder.value_types.get(v).cloned();
|
let t = builder.type_ctx.value_types.get(v).cloned();
|
||||||
let o = builder.value_origin_newbox.get(v).cloned();
|
let o = builder.type_ctx.value_origin_newbox.get(v).cloned();
|
||||||
serde_json::json!({
|
serde_json::json!({
|
||||||
"bb": bb.0,
|
"bb": bb.0,
|
||||||
"v": v.0,
|
"v": v.0,
|
||||||
@ -18,13 +18,13 @@ pub(crate) fn emit_phi(builder: &MirBuilder, dst: ValueId, inputs: &Vec<(BasicBl
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let decided_t = builder
|
let decided_t = builder
|
||||||
.value_types
|
.type_ctx.value_types
|
||||||
.get(&dst)
|
.get(&dst)
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|tt| format!("{:?}", tt))
|
.map(|tt| format!("{:?}", tt))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let decided_o = builder
|
let decided_o = builder
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.get(&dst)
|
.get(&dst)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|||||||
@ -70,8 +70,8 @@ impl super::MirBuilder {
|
|||||||
// Phase 196: TypeFacts SSOT - AddOperator call type annotation
|
// Phase 196: TypeFacts SSOT - AddOperator call type annotation
|
||||||
// Phase 131-11-E: TypeFacts - classify operand types (Phase 136: use TypeFactsBox)
|
// Phase 131-11-E: TypeFacts - classify operand types (Phase 136: use TypeFactsBox)
|
||||||
let type_facts = super::type_facts::TypeFactsBox::new(
|
let type_facts = super::type_facts::TypeFactsBox::new(
|
||||||
&self.value_types,
|
&self.type_ctx.value_types,
|
||||||
&self.value_origin_newbox,
|
&self.type_ctx.value_origin_newbox,
|
||||||
);
|
);
|
||||||
let lhs_type = type_facts.classify_operand_type(lhs);
|
let lhs_type = type_facts.classify_operand_type(lhs);
|
||||||
let rhs_type = type_facts.classify_operand_type(rhs);
|
let rhs_type = type_facts.classify_operand_type(rhs);
|
||||||
@ -80,14 +80,14 @@ impl super::MirBuilder {
|
|||||||
match (lhs_type, rhs_type) {
|
match (lhs_type, rhs_type) {
|
||||||
(String, String) => {
|
(String, String) => {
|
||||||
// BOTH are strings: result is string
|
// BOTH are strings: result is string
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(dst, MirType::Box("StringBox".to_string()));
|
.insert(dst, MirType::Box("StringBox".to_string()));
|
||||||
self.value_origin_newbox
|
self.type_ctx.value_origin_newbox
|
||||||
.insert(dst, "StringBox".to_string());
|
.insert(dst, "StringBox".to_string());
|
||||||
}
|
}
|
||||||
(Integer, Integer) | (Integer, Unknown) | (Unknown, Integer) => {
|
(Integer, Integer) | (Integer, Unknown) | (Unknown, Integer) => {
|
||||||
// TypeFact: Integer + anything non-String = Integer
|
// TypeFact: Integer + anything non-String = Integer
|
||||||
self.value_types.insert(dst, MirType::Integer);
|
self.type_ctx.value_types.insert(dst, MirType::Integer);
|
||||||
}
|
}
|
||||||
(String, Integer) | (Integer, String) => {
|
(String, Integer) | (Integer, String) => {
|
||||||
// Mixed types: leave as Unknown for use-site coercion
|
// Mixed types: leave as Unknown for use-site coercion
|
||||||
@ -132,7 +132,7 @@ impl super::MirBuilder {
|
|||||||
vec![lhs, rhs],
|
vec![lhs, rhs],
|
||||||
)?;
|
)?;
|
||||||
// 型注釈: 算術はおおむね整数(Addは上で注釈済み)
|
// 型注釈: 算術はおおむね整数(Addは上で注釈済み)
|
||||||
self.value_types.insert(dst, MirType::Integer);
|
self.type_ctx.value_types.insert(dst, MirType::Integer);
|
||||||
} else {
|
} else {
|
||||||
// guard中は従来のBinOp
|
// guard中は従来のBinOp
|
||||||
if let (Some(func), Some(cur_bb)) =
|
if let (Some(func), Some(cur_bb)) =
|
||||||
@ -144,7 +144,7 @@ impl super::MirBuilder {
|
|||||||
} else {
|
} else {
|
||||||
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
|
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
|
||||||
}
|
}
|
||||||
self.value_types.insert(dst, MirType::Integer);
|
self.type_ctx.value_types.insert(dst, MirType::Integer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 既存の算術経路
|
// 既存の算術経路
|
||||||
@ -162,8 +162,8 @@ impl super::MirBuilder {
|
|||||||
if matches!(op, crate::mir::BinaryOp::Add) {
|
if matches!(op, crate::mir::BinaryOp::Add) {
|
||||||
// Phase 131-11-E: TypeFacts - classify operand types (Phase 136: use TypeFactsBox)
|
// Phase 131-11-E: TypeFacts - classify operand types (Phase 136: use TypeFactsBox)
|
||||||
let type_facts = super::type_facts::TypeFactsBox::new(
|
let type_facts = super::type_facts::TypeFactsBox::new(
|
||||||
&self.value_types,
|
&self.type_ctx.value_types,
|
||||||
&self.value_origin_newbox,
|
&self.type_ctx.value_origin_newbox,
|
||||||
);
|
);
|
||||||
let lhs_type = type_facts.classify_operand_type(lhs);
|
let lhs_type = type_facts.classify_operand_type(lhs);
|
||||||
let rhs_type = type_facts.classify_operand_type(rhs);
|
let rhs_type = type_facts.classify_operand_type(rhs);
|
||||||
@ -172,15 +172,15 @@ impl super::MirBuilder {
|
|||||||
match (lhs_type, rhs_type) {
|
match (lhs_type, rhs_type) {
|
||||||
(String, String) => {
|
(String, String) => {
|
||||||
// BOTH are strings: result is definitely a string
|
// BOTH are strings: result is definitely a string
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(dst, MirType::Box("StringBox".to_string()));
|
.insert(dst, MirType::Box("StringBox".to_string()));
|
||||||
self.value_origin_newbox
|
self.type_ctx.value_origin_newbox
|
||||||
.insert(dst, "StringBox".to_string());
|
.insert(dst, "StringBox".to_string());
|
||||||
}
|
}
|
||||||
(Integer, Integer) | (Integer, Unknown) | (Unknown, Integer) => {
|
(Integer, Integer) | (Integer, Unknown) | (Unknown, Integer) => {
|
||||||
// TypeFact: Integer + anything non-String = Integer
|
// TypeFact: Integer + anything non-String = Integer
|
||||||
// This handles `counter + 1` where counter might be Unknown
|
// This handles `counter + 1` where counter might be Unknown
|
||||||
self.value_types.insert(dst, MirType::Integer);
|
self.type_ctx.value_types.insert(dst, MirType::Integer);
|
||||||
}
|
}
|
||||||
(String, Integer) | (Integer, String) => {
|
(String, Integer) | (Integer, String) => {
|
||||||
// Mixed types: leave as Unknown for use-site coercion
|
// Mixed types: leave as Unknown for use-site coercion
|
||||||
@ -195,7 +195,7 @@ impl super::MirBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.value_types.insert(dst, MirType::Integer);
|
self.type_ctx.value_types.insert(dst, MirType::Integer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -213,38 +213,38 @@ impl super::MirBuilder {
|
|||||||
// String concatenation is handled at use-site in LLVM lowering
|
// String concatenation is handled at use-site in LLVM lowering
|
||||||
if matches!(op, crate::mir::BinaryOp::Add) {
|
if matches!(op, crate::mir::BinaryOp::Add) {
|
||||||
// Check if BOTH operands are known to be strings (TypeFacts)
|
// Check if BOTH operands are known to be strings (TypeFacts)
|
||||||
let lhs_is_str = match self.value_types.get(&lhs) {
|
let lhs_is_str = match self.type_ctx.value_types.get(&lhs) {
|
||||||
Some(MirType::String) => true,
|
Some(MirType::String) => true,
|
||||||
Some(MirType::Box(bt)) if bt == "StringBox" => true,
|
Some(MirType::Box(bt)) if bt == "StringBox" => true,
|
||||||
_ => self
|
_ => self
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.get(&lhs)
|
.get(&lhs)
|
||||||
.map(|s| s == "StringBox")
|
.map(|s| s == "StringBox")
|
||||||
.unwrap_or(false),
|
.unwrap_or(false),
|
||||||
};
|
};
|
||||||
let rhs_is_str = match self.value_types.get(&rhs) {
|
let rhs_is_str = match self.type_ctx.value_types.get(&rhs) {
|
||||||
Some(MirType::String) => true,
|
Some(MirType::String) => true,
|
||||||
Some(MirType::Box(bt)) if bt == "StringBox" => true,
|
Some(MirType::Box(bt)) if bt == "StringBox" => true,
|
||||||
_ => self
|
_ => self
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.get(&rhs)
|
.get(&rhs)
|
||||||
.map(|s| s == "StringBox")
|
.map(|s| s == "StringBox")
|
||||||
.unwrap_or(false),
|
.unwrap_or(false),
|
||||||
};
|
};
|
||||||
if lhs_is_str && rhs_is_str {
|
if lhs_is_str && rhs_is_str {
|
||||||
// BOTH are strings: result is definitely a string
|
// BOTH are strings: result is definitely a string
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(dst, MirType::Box("StringBox".to_string()));
|
.insert(dst, MirType::Box("StringBox".to_string()));
|
||||||
self.value_origin_newbox
|
self.type_ctx.value_origin_newbox
|
||||||
.insert(dst, "StringBox".to_string());
|
.insert(dst, "StringBox".to_string());
|
||||||
} else if !lhs_is_str && !rhs_is_str {
|
} else if !lhs_is_str && !rhs_is_str {
|
||||||
// NEITHER is a string: numeric addition
|
// NEITHER is a string: numeric addition
|
||||||
self.value_types.insert(dst, MirType::Integer);
|
self.type_ctx.value_types.insert(dst, MirType::Integer);
|
||||||
}
|
}
|
||||||
// else: Mixed types (string + int or int + string)
|
// else: Mixed types (string + int or int + string)
|
||||||
// Leave dst type as Unknown - LLVM will handle coercion at use-site
|
// Leave dst type as Unknown - LLVM will handle coercion at use-site
|
||||||
} else {
|
} else {
|
||||||
self.value_types.insert(dst, MirType::Integer);
|
self.type_ctx.value_types.insert(dst, MirType::Integer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,16 +281,16 @@ impl super::MirBuilder {
|
|||||||
super::builder_calls::CallTarget::Global(name),
|
super::builder_calls::CallTarget::Global(name),
|
||||||
vec![op_const, lhs, rhs],
|
vec![op_const, lhs, rhs],
|
||||||
)?;
|
)?;
|
||||||
self.value_types.insert(dst, MirType::Bool);
|
self.type_ctx.value_types.insert(dst, MirType::Bool);
|
||||||
} else {
|
} else {
|
||||||
// 既存の比較経路(安全のための型注釈/slot化含む)
|
// 既存の比較経路(安全のための型注釈/slot化含む)
|
||||||
let (lhs2_raw, rhs2_raw) = if self
|
let (lhs2_raw, rhs2_raw) = if self
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.get(&lhs)
|
.get(&lhs)
|
||||||
.map(|s| s == "IntegerBox")
|
.map(|s| s == "IntegerBox")
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
&& self
|
&& self
|
||||||
.value_origin_newbox
|
.type_ctx.value_origin_newbox
|
||||||
.get(&rhs)
|
.get(&rhs)
|
||||||
.map(|s| s == "IntegerBox")
|
.map(|s| s == "IntegerBox")
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
@ -396,7 +396,7 @@ impl super::MirBuilder {
|
|||||||
func.update_cfg();
|
func.update_cfg();
|
||||||
}
|
}
|
||||||
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
|
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
|
||||||
self.value_types.insert(rhs_bool, MirType::Bool);
|
self.type_ctx.value_types.insert(rhs_bool, MirType::Bool);
|
||||||
rhs_bool
|
rhs_bool
|
||||||
} else {
|
} else {
|
||||||
let t_id = crate::mir::builder::emission::constant::emit_bool(self, true);
|
let t_id = crate::mir::builder::emission::constant::emit_bool(self, true);
|
||||||
@ -450,7 +450,7 @@ impl super::MirBuilder {
|
|||||||
func.update_cfg();
|
func.update_cfg();
|
||||||
}
|
}
|
||||||
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
|
let rhs_bool = self.insert_phi_binary(rhs_true_exit, t_id, rhs_false_exit, f_id)?;
|
||||||
self.value_types.insert(rhs_bool, MirType::Bool);
|
self.type_ctx.value_types.insert(rhs_bool, MirType::Bool);
|
||||||
rhs_bool
|
rhs_bool
|
||||||
};
|
};
|
||||||
let else_exit_block = self.current_block()?;
|
let else_exit_block = self.current_block()?;
|
||||||
@ -480,7 +480,7 @@ impl super::MirBuilder {
|
|||||||
func.update_cfg();
|
func.update_cfg();
|
||||||
}
|
}
|
||||||
let dst = self.insert_phi(inputs)?;
|
let dst = self.insert_phi(inputs)?;
|
||||||
self.value_types.insert(dst, MirType::Bool);
|
self.type_ctx.value_types.insert(dst, MirType::Bool);
|
||||||
dst
|
dst
|
||||||
} else if inputs.len() == 1 {
|
} else if inputs.len() == 1 {
|
||||||
inputs[0].1
|
inputs[0].1
|
||||||
@ -552,7 +552,7 @@ impl super::MirBuilder {
|
|||||||
super::builder_calls::CallTarget::Global(name.to_string()),
|
super::builder_calls::CallTarget::Global(name.to_string()),
|
||||||
vec![operand_val],
|
vec![operand_val],
|
||||||
)?;
|
)?;
|
||||||
self.value_types.insert(dst, rett);
|
self.type_ctx.value_types.insert(dst, rett);
|
||||||
return Ok(dst);
|
return Ok(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ pub(crate) fn annotate_me_origin(builder: &mut MirBuilder, me_id: ValueId) {
|
|||||||
}
|
}
|
||||||
if let Some(c) = cls {
|
if let Some(c) = cls {
|
||||||
// Record both origin class and a Box type hint for downstream passes(観測用)。
|
// Record both origin class and a Box type hint for downstream passes(観測用)。
|
||||||
builder.value_origin_newbox.insert(me_id, c.clone());
|
builder.type_ctx.value_origin_newbox.insert(me_id, c.clone());
|
||||||
builder.value_types.insert(me_id, MirType::Box(c));
|
builder.type_ctx.value_types.insert(me_id, MirType::Box(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ pub(crate) fn propagate_phi_meta(
|
|||||||
let mut common_ty: Option<MirType> = None;
|
let mut common_ty: Option<MirType> = None;
|
||||||
let mut ty_agree = true;
|
let mut ty_agree = true;
|
||||||
for (_bb, v) in inputs.iter() {
|
for (_bb, v) in inputs.iter() {
|
||||||
if let Some(t) = builder.value_types.get(v).cloned() {
|
if let Some(t) = builder.type_ctx.value_types.get(v).cloned() {
|
||||||
match &common_ty {
|
match &common_ty {
|
||||||
None => common_ty = Some(t),
|
None => common_ty = Some(t),
|
||||||
Some(ct) => {
|
Some(ct) => {
|
||||||
@ -28,14 +28,14 @@ pub(crate) fn propagate_phi_meta(
|
|||||||
}
|
}
|
||||||
if ty_agree {
|
if ty_agree {
|
||||||
if let Some(ct) = common_ty {
|
if let Some(ct) = common_ty {
|
||||||
builder.value_types.insert(dst, ct);
|
builder.type_ctx.value_types.insert(dst, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Origin一致のときだけコピー
|
// Origin一致のときだけコピー
|
||||||
let mut common_cls: Option<String> = None;
|
let mut common_cls: Option<String> = None;
|
||||||
let mut cls_agree = true;
|
let mut cls_agree = true;
|
||||||
for (_bb, v) in inputs.iter() {
|
for (_bb, v) in inputs.iter() {
|
||||||
if let Some(c) = builder.value_origin_newbox.get(v).cloned() {
|
if let Some(c) = builder.type_ctx.value_origin_newbox.get(v).cloned() {
|
||||||
match &common_cls {
|
match &common_cls {
|
||||||
None => common_cls = Some(c),
|
None => common_cls = Some(c),
|
||||||
Some(cc) => {
|
Some(cc) => {
|
||||||
@ -52,7 +52,7 @@ pub(crate) fn propagate_phi_meta(
|
|||||||
}
|
}
|
||||||
if cls_agree {
|
if cls_agree {
|
||||||
if let Some(cc) = common_cls {
|
if let Some(cc) = common_cls {
|
||||||
builder.value_origin_newbox.insert(dst, cc);
|
builder.type_ctx.value_origin_newbox.insert(dst, cc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,7 +40,7 @@ pub(crate) fn try_known_rewrite(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// Receiver must be Known (origin 由来)
|
// Receiver must be Known (origin 由来)
|
||||||
if builder.value_origin_newbox.get(&object_value).is_none() {
|
if builder.type_ctx.value_origin_newbox.get(&object_value).is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// Only user-defined boxes (plugin/core boxesは対象外)
|
// Only user-defined boxes (plugin/core boxesは対象外)
|
||||||
@ -54,7 +54,7 @@ pub(crate) fn try_known_rewrite(
|
|||||||
.ok()
|
.ok()
|
||||||
.as_deref()
|
.as_deref()
|
||||||
== Some("1");
|
== Some("1");
|
||||||
let from_new_origin = builder.value_origin_newbox.get(&object_value).is_some();
|
let from_new_origin = builder.type_ctx.value_origin_newbox.get(&object_value).is_some();
|
||||||
let arity = arg_values.len();
|
let arity = arg_values.len();
|
||||||
let fname = crate::mir::builder::calls::function_lowering::generate_method_function_name(
|
let fname = crate::mir::builder::calls::function_lowering::generate_method_function_name(
|
||||||
cls, method, arity,
|
cls, method, arity,
|
||||||
@ -107,7 +107,7 @@ pub(crate) fn try_known_rewrite_to_dst(
|
|||||||
if !rewrite_enabled() {
|
if !rewrite_enabled() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if builder.value_origin_newbox.get(&object_value).is_none() {
|
if builder.type_ctx.value_origin_newbox.get(&object_value).is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if !builder.user_defined_boxes.contains(cls) {
|
if !builder.user_defined_boxes.contains(cls) {
|
||||||
@ -119,7 +119,7 @@ pub(crate) fn try_known_rewrite_to_dst(
|
|||||||
.ok()
|
.ok()
|
||||||
.as_deref()
|
.as_deref()
|
||||||
== Some("1");
|
== Some("1");
|
||||||
let from_new_origin = builder.value_origin_newbox.get(&object_value).is_some();
|
let from_new_origin = builder.type_ctx.value_origin_newbox.get(&object_value).is_some();
|
||||||
let arity = arg_values.len();
|
let arity = arg_values.len();
|
||||||
let fname = crate::mir::builder::calls::function_lowering::generate_method_function_name(
|
let fname = crate::mir::builder::calls::function_lowering::generate_method_function_name(
|
||||||
cls, method, arity,
|
cls, method, arity,
|
||||||
@ -171,7 +171,7 @@ pub(crate) fn try_unique_suffix_rewrite(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// Only attempt if receiver is Known (keeps behavior stable and avoids surprises)
|
// Only attempt if receiver is Known (keeps behavior stable and avoids surprises)
|
||||||
if builder.value_origin_newbox.get(&object_value).is_none() {
|
if builder.type_ctx.value_origin_newbox.get(&object_value).is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let mut cands: Vec<String> = builder.method_candidates(method, arg_values.len());
|
let mut cands: Vec<String> = builder.method_candidates(method, arg_values.len());
|
||||||
@ -200,7 +200,7 @@ pub(crate) fn try_unique_suffix_rewrite(
|
|||||||
}
|
}
|
||||||
builder.annotate_call_result_from_func_name(dst, &fname);
|
builder.annotate_call_result_from_func_name(dst, &fname);
|
||||||
let meta = serde_json::json!({
|
let meta = serde_json::json!({
|
||||||
"recv_cls": builder.value_origin_newbox.get(&object_value).cloned().unwrap_or_default(),
|
"recv_cls": builder.type_ctx.value_origin_newbox.get(&object_value).cloned().unwrap_or_default(),
|
||||||
"method": method,
|
"method": method,
|
||||||
"arity": arity_us,
|
"arity": arity_us,
|
||||||
"chosen": fname,
|
"chosen": fname,
|
||||||
@ -222,7 +222,7 @@ pub(crate) fn try_unique_suffix_rewrite_to_dst(
|
|||||||
if !rewrite_enabled() {
|
if !rewrite_enabled() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if builder.value_origin_newbox.get(&object_value).is_none() {
|
if builder.type_ctx.value_origin_newbox.get(&object_value).is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let mut cands: Vec<String> = builder.method_candidates(method, arg_values.len());
|
let mut cands: Vec<String> = builder.method_candidates(method, arg_values.len());
|
||||||
@ -255,7 +255,7 @@ pub(crate) fn try_unique_suffix_rewrite_to_dst(
|
|||||||
}
|
}
|
||||||
builder.annotate_call_result_from_func_name(actual_dst, &fname);
|
builder.annotate_call_result_from_func_name(actual_dst, &fname);
|
||||||
let meta = serde_json::json!({
|
let meta = serde_json::json!({
|
||||||
"recv_cls": builder.value_origin_newbox.get(&object_value).cloned().unwrap_or_default(),
|
"recv_cls": builder.type_ctx.value_origin_newbox.get(&object_value).cloned().unwrap_or_default(),
|
||||||
"method": method,
|
"method": method,
|
||||||
"arity": arity_us,
|
"arity": arity_us,
|
||||||
"chosen": fname,
|
"chosen": fname,
|
||||||
|
|||||||
@ -112,17 +112,17 @@ pub fn ensure(builder: &mut MirBuilder, v: ValueId, kind: LocalKind) -> ValueId
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Success: register metadata and cache
|
// Success: register metadata and cache
|
||||||
if let Some(t) = builder.value_types.get(&v).cloned() {
|
if let Some(t) = builder.type_ctx.value_types.get(&v).cloned() {
|
||||||
builder.value_types.insert(loc, t);
|
builder.type_ctx.value_types.insert(loc, t);
|
||||||
}
|
}
|
||||||
if let Some(cls) = builder.value_origin_newbox.get(&v).cloned() {
|
if let Some(cls) = builder.type_ctx.value_origin_newbox.get(&v).cloned() {
|
||||||
builder.value_origin_newbox.insert(loc, cls.clone());
|
builder.type_ctx.value_origin_newbox.insert(loc, cls.clone());
|
||||||
|
|
||||||
// CRITICAL FIX: For receiver kind, if type is missing but origin exists,
|
// CRITICAL FIX: For receiver kind, if type is missing but origin exists,
|
||||||
// infer MirType::Box from origin
|
// infer MirType::Box from origin
|
||||||
if kind == LocalKind::Recv && builder.value_types.get(&loc).is_none() {
|
if kind == LocalKind::Recv && builder.type_ctx.value_types.get(&loc).is_none() {
|
||||||
builder
|
builder
|
||||||
.value_types
|
.type_ctx.value_types
|
||||||
.insert(loc, crate::mir::MirType::Box(cls));
|
.insert(loc, crate::mir::MirType::Box(cls));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -341,7 +341,7 @@ impl super::MirBuilder {
|
|||||||
self.declare_local_in_current_scope(var_name, var_id)?;
|
self.declare_local_in_current_scope(var_name, var_id)?;
|
||||||
// SlotRegistry にもローカル変数スロットを登録しておくよ(観測専用)
|
// SlotRegistry にもローカル変数スロットを登録しておくよ(観測専用)
|
||||||
if let Some(reg) = self.current_slot_registry.as_mut() {
|
if let Some(reg) = self.current_slot_registry.as_mut() {
|
||||||
let ty = self.value_types.get(&var_id).cloned();
|
let ty = self.type_ctx.value_types.get(&var_id).cloned();
|
||||||
reg.ensure_slot(&var_name, ty);
|
reg.ensure_slot(&var_name, ty);
|
||||||
}
|
}
|
||||||
last_value = Some(var_id);
|
last_value = Some(var_id);
|
||||||
@ -427,7 +427,7 @@ impl super::MirBuilder {
|
|||||||
})?;
|
})?;
|
||||||
// Future spawn returns a Future<T>; the inner type is not statically known here.
|
// Future spawn returns a Future<T>; the inner type is not statically known here.
|
||||||
// Register at least Future<Unknown> to avoid later fail-fast type inference panics.
|
// Register at least Future<Unknown> to avoid later fail-fast type inference panics.
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(future_id, MirType::Future(Box::new(MirType::Unknown)));
|
.insert(future_id, MirType::Future(Box::new(MirType::Unknown)));
|
||||||
self.variable_map.insert(variable.clone(), future_id);
|
self.variable_map.insert(variable.clone(), future_id);
|
||||||
if let Some(reg) = self.current_slot_registry.as_mut() {
|
if let Some(reg) = self.current_slot_registry.as_mut() {
|
||||||
@ -442,11 +442,11 @@ impl super::MirBuilder {
|
|||||||
value: expression_value,
|
value: expression_value,
|
||||||
})?;
|
})?;
|
||||||
let inner = self
|
let inner = self
|
||||||
.value_types
|
.type_ctx.value_types
|
||||||
.get(&expression_value)
|
.get(&expression_value)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or(MirType::Unknown);
|
.unwrap_or(MirType::Unknown);
|
||||||
self.value_types
|
self.type_ctx.value_types
|
||||||
.insert(future_id, MirType::Future(Box::new(inner)));
|
.insert(future_id, MirType::Future(Box::new(inner)));
|
||||||
self.variable_map.insert(variable.clone(), future_id);
|
self.variable_map.insert(variable.clone(), future_id);
|
||||||
if let Some(reg) = self.current_slot_registry.as_mut() {
|
if let Some(reg) = self.current_slot_registry.as_mut() {
|
||||||
@ -467,11 +467,11 @@ impl super::MirBuilder {
|
|||||||
dst: result_id,
|
dst: result_id,
|
||||||
future: future_value,
|
future: future_value,
|
||||||
})?;
|
})?;
|
||||||
let result_type = match self.value_types.get(&future_value) {
|
let result_type = match self.type_ctx.value_types.get(&future_value) {
|
||||||
Some(MirType::Future(inner)) => (**inner).clone(),
|
Some(MirType::Future(inner)) => (**inner).clone(),
|
||||||
_ => MirType::Unknown,
|
_ => MirType::Unknown,
|
||||||
};
|
};
|
||||||
self.value_types.insert(result_id, result_type);
|
self.type_ctx.value_types.insert(result_id, result_type);
|
||||||
self.emit_instruction(MirInstruction::Safepoint)?;
|
self.emit_instruction(MirInstruction::Safepoint)?;
|
||||||
Ok(result_id)
|
Ok(result_id)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use crate::mir::{MirType, ValueId};
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn set_type(builder: &mut MirBuilder, dst: ValueId, ty: MirType) {
|
pub fn set_type(builder: &mut MirBuilder, dst: ValueId, ty: MirType) {
|
||||||
builder.value_types.insert(dst, ty);
|
builder.type_ctx.value_types.insert(dst, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 関数名から既知の戻り型を注釈する(最小ハードコード)。
|
/// 関数名から既知の戻り型を注釈する(最小ハードコード)。
|
||||||
@ -15,7 +15,7 @@ pub fn set_type(builder: &mut MirBuilder, dst: ValueId, ty: MirType) {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn annotate_from_function(builder: &mut MirBuilder, dst: ValueId, func_name: &str) {
|
pub fn annotate_from_function(builder: &mut MirBuilder, dst: ValueId, func_name: &str) {
|
||||||
if let Some(ty) = infer_return_type(func_name) {
|
if let Some(ty) = infer_return_type(func_name) {
|
||||||
builder.value_types.insert(dst, ty);
|
builder.type_ctx.value_types.insert(dst, ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -185,7 +185,7 @@ impl super::MirBuilder {
|
|||||||
use crate::runtime::{CoreBoxId, CoreMethodId};
|
use crate::runtime::{CoreBoxId, CoreMethodId};
|
||||||
|
|
||||||
// 1. box_val の型を取得
|
// 1. box_val の型を取得
|
||||||
let box_ty = self.value_types.get(&box_val)?;
|
let box_ty = self.type_ctx.value_types.get(&box_val)?;
|
||||||
|
|
||||||
// 2. Box 型名を取得
|
// 2. Box 型名を取得
|
||||||
let box_name = match box_ty {
|
let box_name = match box_ty {
|
||||||
@ -255,9 +255,9 @@ impl super::MirBuilder {
|
|||||||
// Check environment variable for unified call usage, with safe overrides for core/user boxes
|
// Check environment variable for unified call usage, with safe overrides for core/user boxes
|
||||||
let use_unified_env = super::calls::call_unified::is_unified_call_enabled();
|
let use_unified_env = super::calls::call_unified::is_unified_call_enabled();
|
||||||
// First, try to determine the box type
|
// First, try to determine the box type
|
||||||
let mut box_type: Option<String> = self.value_origin_newbox.get(&box_val).cloned();
|
let mut box_type: Option<String> = self.type_ctx.value_origin_newbox.get(&box_val).cloned();
|
||||||
if box_type.is_none() {
|
if box_type.is_none() {
|
||||||
if let Some(t) = self.value_types.get(&box_val) {
|
if let Some(t) = self.type_ctx.value_types.get(&box_val) {
|
||||||
match t {
|
match t {
|
||||||
super::MirType::String => box_type = Some("StringBox".to_string()),
|
super::MirType::String => box_type = Some("StringBox".to_string()),
|
||||||
super::MirType::Box(name) => box_type = Some(name.clone()),
|
super::MirType::Box(name) => box_type = Some(name.clone()),
|
||||||
@ -316,9 +316,9 @@ impl super::MirBuilder {
|
|||||||
effects,
|
effects,
|
||||||
})?;
|
})?;
|
||||||
if let Some(d) = dst {
|
if let Some(d) = dst {
|
||||||
let mut recv_box: Option<String> = self.value_origin_newbox.get(&box_val).cloned();
|
let mut recv_box: Option<String> = self.type_ctx.value_origin_newbox.get(&box_val).cloned();
|
||||||
if recv_box.is_none() {
|
if recv_box.is_none() {
|
||||||
if let Some(t) = self.value_types.get(&box_val) {
|
if let Some(t) = self.type_ctx.value_types.get(&box_val) {
|
||||||
match t {
|
match t {
|
||||||
super::MirType::String => recv_box = Some("StringBox".to_string()),
|
super::MirType::String => recv_box = Some("StringBox".to_string()),
|
||||||
super::MirType::Box(name) => recv_box = Some(name.clone()),
|
super::MirType::Box(name) => recv_box = Some(name.clone()),
|
||||||
@ -328,12 +328,12 @@ impl super::MirBuilder {
|
|||||||
}
|
}
|
||||||
if let Some(bt) = recv_box {
|
if let Some(bt) = recv_box {
|
||||||
if let Some(mt) = self.plugin_method_sigs.get(&(bt.clone(), method.clone())) {
|
if let Some(mt) = self.plugin_method_sigs.get(&(bt.clone(), method.clone())) {
|
||||||
self.value_types.insert(d, mt.clone());
|
self.type_ctx.value_types.insert(d, mt.clone());
|
||||||
} else {
|
} else {
|
||||||
// Phase 84-4-B: ビルトイン Box のメソッド戻り値型推論
|
// Phase 84-4-B: ビルトイン Box のメソッド戻り値型推論
|
||||||
// plugin_method_sigs に登録されていない場合のフォールバック
|
// plugin_method_sigs に登録されていない場合のフォールバック
|
||||||
if let Some(ret_ty) = self.infer_boxcall_return_type(box_val, &method) {
|
if let Some(ret_ty) = self.infer_boxcall_return_type(box_val, &method) {
|
||||||
self.value_types.insert(d, ret_ty.clone());
|
self.type_ctx.value_types.insert(d, ret_ty.clone());
|
||||||
|
|
||||||
if std::env::var("NYASH_BOXCALL_TYPE_TRACE").ok().as_deref() == Some("1") {
|
if std::env::var("NYASH_BOXCALL_TYPE_TRACE").ok().as_deref() == Some("1") {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
@ -118,7 +118,7 @@ impl<'a> BoolExprLowerer<'a> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Mark result type as Bool
|
// Mark result type as Bool
|
||||||
self.builder.value_types.insert(dst, MirType::Bool);
|
self.builder.type_ctx.value_types.insert(dst, MirType::Bool);
|
||||||
|
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ impl<'a> BoolExprLowerer<'a> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Mark result type as Bool
|
// Mark result type as Bool
|
||||||
self.builder.value_types.insert(dst, MirType::Bool);
|
self.builder.type_ctx.value_types.insert(dst, MirType::Bool);
|
||||||
|
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ impl<'a> BoolExprLowerer<'a> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Mark result type as Bool
|
// Mark result type as Bool
|
||||||
self.builder.value_types.insert(dst, MirType::Bool);
|
self.builder.type_ctx.value_types.insert(dst, MirType::Bool);
|
||||||
|
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ impl<'a> BoolExprLowerer<'a> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Mark result type as Bool
|
// Mark result type as Bool
|
||||||
self.builder.value_types.insert(dst, MirType::Bool);
|
self.builder.type_ctx.value_types.insert(dst, MirType::Bool);
|
||||||
|
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,7 +178,7 @@ fn classify_slots_from_variable_map(builder: &MirBuilder) -> Vec<SlotMetadata> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn classify_slot(builder: &MirBuilder, v: ValueId, name: &str) -> RefSlotKind {
|
fn classify_slot(builder: &MirBuilder, v: ValueId, name: &str) -> RefSlotKind {
|
||||||
if let Some(ty) = builder.value_types.get(&v) {
|
if let Some(ty) = builder.type_ctx.value_types.get(&v) {
|
||||||
return Region::classify_ref_kind(ty);
|
return Region::classify_ref_kind(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user