Skip to content

Commit a3cec59

Browse files
committed
feat: improve operator overloading trait dispatch
- Make is_trait_dispatchable_type more permissive (all non-primitives) - Add Unknown type handling in get_type_symbol_prefix - Add debug logging for binary operations and trait dispatch Current issue: Custom types like `Tensor` are being resolved to primitive types (I32) by the type system, preventing trait dispatch from working. Need to fix type resolution to preserve custom type names.
1 parent 6446550 commit a3cec59

1 file changed

Lines changed: 47 additions & 10 deletions

File tree

crates/compiler/src/ssa.rs

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,9 +1380,12 @@ impl SsaBuilder {
13801380

13811381
// Check if this is a non-primitive type that might use operator overloading
13821382
// For opaque/named types, try to dispatch to trait method
1383+
eprintln!("[DEBUG SSA] Binary op {:?}, left.ty={:?}, right.ty={:?}", op, left.ty, right.ty);
13831384
if let Some(trait_call) = self.try_operator_trait_dispatch(block_id, op, left, right, &expr.ty)? {
1385+
eprintln!("[DEBUG SSA] Using trait dispatch for binary op");
13841386
return Ok(trait_call);
13851387
}
1388+
eprintln!("[DEBUG SSA] No trait dispatch, using native binary op");
13861389

13871390
// Regular binary operations for primitive types
13881391
let left_val = self.translate_expression(block_id, left)?;
@@ -3084,7 +3087,11 @@ impl SsaBuilder {
30843087
/// Check if a type should use trait dispatch for operators
30853088
fn is_trait_dispatchable_type(&self, ty: &Type) -> bool {
30863089
match ty {
3087-
// Extern types - ZRTL-backed opaque types, always use trait dispatch
3090+
// Primitive types - use built-in operations, no trait dispatch
3091+
Type::Primitive(_) => false,
3092+
3093+
// All other types (Extern, Named, Unknown, etc.) should try trait dispatch
3094+
// This allows any type with an impl block to use operator overloading
30883095
Type::Extern { name, .. } => {
30893096
let name_str = name.resolve_global()
30903097
.unwrap_or_else(|| {
@@ -3096,9 +3103,8 @@ impl SsaBuilder {
30963103
log::debug!("[trait_dispatch] Type::Extern name='{}' -> dispatchable", name_str);
30973104
true
30983105
}
3099-
// Named types - check if it's a ZRTL-backed type (name starts with $)
31003106
Type::Named { id, .. } => {
3101-
// Check the type name from registry
3107+
// Any named type can have trait impls
31023108
if let Some(type_def) = self.type_registry.get_type_by_id(*id) {
31033109
let name = type_def.name.resolve_global()
31043110
.unwrap_or_else(|| {
@@ -3107,17 +3113,23 @@ impl SsaBuilder {
31073113
.map(|s| s.to_string())
31083114
.unwrap_or_default()
31093115
});
3110-
// ZRTL opaque types start with $
3111-
return name.starts_with('$');
3116+
log::debug!("[trait_dispatch] Type::Named name='{}' -> dispatchable", name);
3117+
return true;
31123118
}
31133119
// Also check HIR conversion
31143120
let hir_ty = self.convert_type(ty);
31153121
matches!(hir_ty, HirType::Opaque(_))
31163122
}
3117-
// Primitive types - use built-in operations
3118-
Type::Primitive(_) => false,
3119-
// Other types - might need trait dispatch
3120-
_ => false,
3123+
// Unknown types - try trait dispatch (will use the type name)
3124+
Type::Unknown => {
3125+
log::debug!("[trait_dispatch] Type::Unknown -> try trait dispatch");
3126+
true
3127+
}
3128+
// Other types - try trait dispatch
3129+
_ => {
3130+
log::debug!("[trait_dispatch] Other type -> try trait dispatch");
3131+
true
3132+
}
31213133
}
31223134
}
31233135

@@ -3146,6 +3158,7 @@ impl SsaBuilder {
31463158
.map(|s| s.to_string())
31473159
.unwrap_or_default()
31483160
});
3161+
log::debug!("[trait_dispatch] Type::Named prefix: '{}'", name);
31493162
Some(name)
31503163
} else {
31513164
// If not in registry, try to get from HIR type
@@ -3158,13 +3171,37 @@ impl SsaBuilder {
31583171
.map(|s| s.to_string())
31593172
.unwrap_or_default()
31603173
});
3174+
log::debug!("[trait_dispatch] Type::Named (opaque) prefix: '{}'", name_str);
31613175
Some(name_str)
31623176
} else {
3177+
log::debug!("[trait_dispatch] Type::Named (no registry) -> None");
31633178
None
31643179
}
31653180
}
31663181
}
3167-
_ => None,
3182+
// Unknown types - use the HIR representation
3183+
Type::Unknown => {
3184+
// Convert to HIR and try to extract name
3185+
let hir_ty = self.convert_type(ty);
3186+
if let HirType::Opaque(name) = hir_ty {
3187+
let name_str = name.resolve_global()
3188+
.unwrap_or_else(|| {
3189+
let arena = self.arena.lock().unwrap();
3190+
arena.resolve_string(name)
3191+
.map(|s| s.to_string())
3192+
.unwrap_or_default()
3193+
});
3194+
log::debug!("[trait_dispatch] Type::Unknown converted to opaque prefix: '{}'", name_str);
3195+
Some(name_str)
3196+
} else {
3197+
log::debug!("[trait_dispatch] Type::Unknown (not opaque) -> None");
3198+
None
3199+
}
3200+
}
3201+
_ => {
3202+
log::debug!("[trait_dispatch] Other type -> None");
3203+
None
3204+
}
31683205
}
31693206
}
31703207

0 commit comments

Comments
 (0)