This commit is contained in:
Felipe Pena 2025-09-12 12:46:47 +00:00 committed by GitHub
commit e525827aca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 9 deletions

View file

@ -1730,11 +1730,16 @@ pub fn (mut t Table) convert_generic_type(generic_type Type, generic_names []str
if typ == 0 { if typ == 0 {
return none return none
} }
mut rtyp := typ.derive_add_muls(generic_type)
if typ.has_flag(.generic) { if typ.has_flag(.generic) {
return typ.derive_add_muls(generic_type).set_flag(.generic) rtyp = rtyp.set_flag(.generic)
} else { } else {
return typ.derive_add_muls(generic_type).clear_flag(.generic) rtyp = rtyp.clear_flag(.generic)
} }
if typ.has_flag(.option) {
rtyp = rtyp.set_flag(.option)
}
return rtyp
} }
match mut sym.info { match mut sym.info {
Array { Array {

View file

@ -2796,19 +2796,23 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
} else if arg.expr is ast.ComptimeSelector && arg_typ.has_flag(.option) } else if arg.expr is ast.ComptimeSelector && arg_typ.has_flag(.option)
&& !expected_type.has_flag(.option) { && !expected_type.has_flag(.option) {
// allow to pass val.$(filed.name) where T is expected, doing automatic unwrap in this case // allow to pass val.$(filed.name) where T is expected, doing automatic unwrap in this case
styp := g.base_type(arg_typ) // styp := g.base_type(arg_typ)
g.write('*(${styp}*)') // g.write('*(${styp}*)')
g.expr_with_cast(arg.expr, arg_typ, expected_type) g.expr_with_opt(arg.expr, arg_typ, expected_type.set_flag(.option))
g.write('.data') // g.write('.data')
return return
} else if arg.expr is ast.Ident && arg_sym.info is ast.Struct && arg_sym.info.is_anon } else if arg.expr is ast.Ident && arg_sym.info is ast.Struct && arg_sym.info.is_anon
&& !expected_type.has_flag(.generic) { && !expected_type.has_flag(.generic) {
// make anon struct struct compatible with another anon struct declaration // make anon struct struct compatible with another anon struct declaration
g.write('*(${g.cc_type(expected_type, false)}*)&') // g.write('*(${g.cc_type(expected_type, false)}*)&')
} }
// check if the argument must be dereferenced or not // check if the argument must be dereferenced or not
g.arg_no_auto_deref = is_smartcast && !arg_is_ptr && !exp_is_ptr && arg.should_be_ptr g.arg_no_auto_deref = is_smartcast && !arg_is_ptr && !exp_is_ptr && arg.should_be_ptr
if arg_typ.has_flag(.option) {
g.expr_with_opt(arg.expr, arg_typ, expected_type.set_flag(.option))
} else {
g.expr_with_cast(arg.expr, arg_typ, expected_type) g.expr_with_cast(arg.expr, arg_typ, expected_type)
}
g.arg_no_auto_deref = false g.arg_no_auto_deref = false
g.inside_smartcast = old_inside_smartcast g.inside_smartcast = old_inside_smartcast
if needs_closing { if needs_closing {

View file

@ -355,6 +355,30 @@ pub fn (mut t TypeResolver) resolve_args(cur_fn &ast.FnDecl, func &ast.Fn, mut n
} else { } else {
comptime_args[k] = ctyp comptime_args[k] = ctyp
} }
} else if mut call_arg.expr is ast.PostfixExpr && call_arg.expr.expr is ast.ComptimeSelector {
comptime_args[k] = t.info.comptime_for_field_type.clear_flag(.option)
arg_sym := t.table.final_sym(call_arg.typ)
param_sym := t.table.sym(param_typ)
if arg_sym.kind == .array && param_sym.kind == .array {
comptime_sym := t.table.sym(comptime_args[k])
comptime_args[k] = t.get_generic_array_element_type(comptime_sym.info as ast.Array)
} else if arg_sym.info is ast.Map && param_sym.info is ast.Map {
comptime_sym := t.table.sym(comptime_args[k])
if comptime_sym.info is ast.Map {
if param_sym.info.key_type.has_flag(.generic) {
comptime_args[k] = comptime_sym.info.key_type
if param_sym.info.value_type.has_flag(.generic) {
k++
comptime_args[k] = comptime_sym.info.value_type
}
} else if param_sym.info.value_type.has_flag(.generic) {
comptime_args[k] = comptime_sym.info.value_type
}
}
}
if param_typ.nr_muls() > 0 && comptime_args[k].nr_muls() > 0 {
comptime_args[k] = comptime_args[k].set_nr_muls(0)
}
} }
} }
return comptime_args return comptime_args

View file

@ -444,7 +444,7 @@ fn (mut encoder Encoder) encode_struct[T](val T) {
if val.$(field.name) == none { if val.$(field.name) == none {
unsafe { encoder.output.push_many(null_string.str, null_string.len) } unsafe { encoder.output.push_many(null_string.str, null_string.len) }
} else { } else {
encoder.encode_value(val.$(field.name)) encoder.encode_value(val.$(field.name) ?)
} }
} $else $if field.indirections == 1 { } $else $if field.indirections == 1 {
encoder.encode_value(*val.$(field.name)) encoder.encode_value(*val.$(field.name))