pull/13332/head
			
			
				weekly.2022.05
			
		
		
							parent
							
								
									46a096b95d
								
							
						
					
					
						commit
						b34860e39b
					
				|  | @ -1428,7 +1428,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name | |||
| 		if typ == 0 { | ||||
| 			return none | ||||
| 		} | ||||
| 		return typ.derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 		if typ.has_flag(.generic) { | ||||
| 			return typ.derive_add_muls(generic_type).set_flag(.generic) | ||||
| 		} else { | ||||
| 			return typ.derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 		} | ||||
| 	} | ||||
| 	match mut sym.info { | ||||
| 		Array { | ||||
|  | @ -1443,7 +1447,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name | |||
| 			} | ||||
| 			if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) { | ||||
| 				idx := t.find_or_register_array_with_dims(typ, dims) | ||||
| 				return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				if typ.has_flag(.generic) { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) | ||||
| 				} else { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		ArrayFixed { | ||||
|  | @ -1451,7 +1459,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name | |||
| 				concrete_types) | ||||
| 			{ | ||||
| 				idx := t.find_or_register_array_fixed(typ, sym.info.size, None{}) | ||||
| 				return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				if typ.has_flag(.generic) { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) | ||||
| 				} else { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		Chan { | ||||
|  | @ -1459,16 +1471,24 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name | |||
| 				concrete_types) | ||||
| 			{ | ||||
| 				idx := t.find_or_register_chan(typ, typ.nr_muls() > 0) | ||||
| 				return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				if typ.has_flag(.generic) { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) | ||||
| 				} else { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		FnType { | ||||
| 			mut func := sym.info.func | ||||
| 			mut has_generic := false | ||||
| 			if func.return_type.has_flag(.generic) { | ||||
| 				if typ := t.resolve_generic_to_concrete(func.return_type, generic_names, | ||||
| 					concrete_types) | ||||
| 				{ | ||||
| 					func.return_type = typ | ||||
| 					if typ.has_flag(.generic) { | ||||
| 						has_generic = true | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			func.params = func.params.clone() | ||||
|  | @ -1478,12 +1498,19 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name | |||
| 						concrete_types) | ||||
| 					{ | ||||
| 						param.typ = typ | ||||
| 						if typ.has_flag(.generic) { | ||||
| 							has_generic = true | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			func.name = '' | ||||
| 			idx := t.find_or_register_fn_type('', func, true, false) | ||||
| 			return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 			if has_generic { | ||||
| 				return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) | ||||
| 			} else { | ||||
| 				return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 			} | ||||
| 		} | ||||
| 		MultiReturn { | ||||
| 			mut types := []Type{} | ||||
|  | @ -1498,7 +1525,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name | |||
| 			} | ||||
| 			if type_changed { | ||||
| 				idx := t.find_or_register_multi_return(types) | ||||
| 				return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				if types.any(it.has_flag(.generic)) { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) | ||||
| 				} else { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		Map { | ||||
|  | @ -1519,7 +1550,11 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name | |||
| 			} | ||||
| 			if type_changed { | ||||
| 				idx := t.find_or_register_map(unwrapped_key_type, unwrapped_value_type) | ||||
| 				return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				if unwrapped_key_type.has_flag(.generic) || unwrapped_value_type.has_flag(.generic) { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).set_flag(.generic) | ||||
| 				} else { | ||||
| 					return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		Struct, Interface, SumType { | ||||
|  |  | |||
|  | @ -963,6 +963,13 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) | |||
| 	} | ||||
| 	if func.generic_names.len > 0 { | ||||
| 		if has_generic { | ||||
| 			if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names, | ||||
| 				node.concrete_types) | ||||
| 			{ | ||||
| 				if typ.has_flag(.generic) { | ||||
| 					node.return_type = typ | ||||
| 				} | ||||
| 			} | ||||
| 			return node.return_type | ||||
| 		} else if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names, | ||||
| 			concrete_types) | ||||
|  |  | |||
|  | @ -0,0 +1,26 @@ | |||
| fn test_generics_with_complex_nested_generics_type() { | ||||
| 	mut buf := []byte{} | ||||
| 	initial<string, u64>(buf) | ||||
| } | ||||
| 
 | ||||
| fn initial<K, V>(buf []byte) map[K]V { | ||||
| 	mut ret := map[K]V{} | ||||
| 	for _ in 0 .. 3 { | ||||
| 		k := get<K>(buf) | ||||
| 		v := get<V>(buf) | ||||
| 		ret[k] = v | ||||
| 	} | ||||
| 	println(ret) | ||||
| 	assert '$ret' == "{'get': 22}" | ||||
| 	return ret | ||||
| } | ||||
| 
 | ||||
| fn get<T>(buf []byte) T { | ||||
| 	$if T is string { | ||||
| 		return buf.bytestr() + 'get' | ||||
| 	} $else $if T is u64 { | ||||
| 		return u64(22) | ||||
| 	} $else { | ||||
| 		panic('oops!') | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue