cgen: fix struct type dependency sorting, when struct field types, are aliases to struct types from other modules (#13779)
							parent
							
								
									71edaa071a
								
							
						
					
					
						commit
						caa0e25939
					
				|  | @ -4524,17 +4524,17 @@ fn (mut g Gen) write_builtin_types() { | ||||||
| // Sort the types, make sure types that are referenced by other types
 | // Sort the types, make sure types that are referenced by other types
 | ||||||
| // are added before them.
 | // are added before them.
 | ||||||
| fn (mut g Gen) write_sorted_types() { | fn (mut g Gen) write_sorted_types() { | ||||||
|  | 	g.type_definitions.writeln('// #start sorted_symbols') | ||||||
|  | 	defer { | ||||||
|  | 		g.type_definitions.writeln('// #end sorted_symbols') | ||||||
|  | 	} | ||||||
| 	mut symbols := []&ast.TypeSymbol{cap: g.table.type_symbols.len} // structs that need to be sorted
 | 	mut symbols := []&ast.TypeSymbol{cap: g.table.type_symbols.len} // structs that need to be sorted
 | ||||||
| 	for sym in g.table.type_symbols { | 	for sym in g.table.type_symbols { | ||||||
| 		if sym.name !in c.builtins { | 		if sym.name !in c.builtins { | ||||||
| 			symbols << sym | 			symbols << sym | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// sort structs
 |  | ||||||
| 	sorted_symbols := g.sort_structs(symbols) | 	sorted_symbols := g.sort_structs(symbols) | ||||||
| 	// Generate C code
 |  | ||||||
| 	g.type_definitions.writeln('// builtin types:') |  | ||||||
| 	g.type_definitions.writeln('//------------------ #endbuiltin') |  | ||||||
| 	g.write_types(sorted_symbols) | 	g.write_types(sorted_symbols) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -4706,7 +4706,7 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // sort structs by dependant fields
 | // sort structs by dependant fields
 | ||||||
| fn (g &Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol { | fn (mut g Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol { | ||||||
| 	util.timing_start(@METHOD) | 	util.timing_start(@METHOD) | ||||||
| 	defer { | 	defer { | ||||||
| 		util.timing_measure(@METHOD) | 		util.timing_measure(@METHOD) | ||||||
|  | @ -4742,12 +4742,23 @@ fn (g &Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol { | ||||||
| 					field_deps << dep | 					field_deps << dep | ||||||
| 				} | 				} | ||||||
| 				for field in sym.info.fields { | 				for field in sym.info.fields { | ||||||
| 					dep := g.table.sym(field.typ).name | 					if field.typ.is_ptr() { | ||||||
|  | 						continue | ||||||
|  | 					} | ||||||
|  | 					fsym := g.table.sym(field.typ) | ||||||
|  | 					dep := fsym.name | ||||||
| 					// skip if not in types list or already in deps
 | 					// skip if not in types list or already in deps
 | ||||||
| 					if dep !in type_names || dep in field_deps || field.typ.is_ptr() { | 					if dep !in type_names || dep in field_deps { | ||||||
| 						continue | 						continue | ||||||
| 					} | 					} | ||||||
| 					field_deps << dep | 					field_deps << dep | ||||||
|  | 					if fsym.info is ast.Alias { | ||||||
|  | 						xdep := g.table.sym(fsym.info.parent_type).name | ||||||
|  | 						if xdep !in type_names || xdep in field_deps { | ||||||
|  | 							continue | ||||||
|  | 						} | ||||||
|  | 						field_deps << xdep | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			// ast.Interface {}
 | 			// ast.Interface {}
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | module alias_to_another_module | ||||||
|  | 
 | ||||||
|  | import another_module | ||||||
|  | 
 | ||||||
|  | pub type MyAlias = another_module.SomeStruct | ||||||
|  | 
 | ||||||
|  | pub fn (m MyAlias) alias_method() int { | ||||||
|  | 	return 42 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | module another_module | ||||||
|  | 
 | ||||||
|  | pub struct SomeStruct { | ||||||
|  | pub mut: | ||||||
|  | 	x int | ||||||
|  | 	y int | ||||||
|  | 	z int | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn (s SomeStruct) some_method() int { | ||||||
|  | 	return 999 + s.x + s.y + s.z | ||||||
|  | } | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | import alias_to_another_module | ||||||
|  | 
 | ||||||
|  | struct MyStruct { | ||||||
|  | 	myfield alias_to_another_module.MyAlias | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn test_using_struct_with_alias() { | ||||||
|  | 	m := MyStruct{ | ||||||
|  | 		myfield: alias_to_another_module.MyAlias{1, 2, 3} | ||||||
|  | 	} | ||||||
|  | 	dump(m) | ||||||
|  | 	assert m.myfield.alias_method() == 42 | ||||||
|  | 	assert m.myfield.some_method() == 1005 | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue