@@ -136,7 +136,7 @@ fn generate_type_declarations_helper(
136136fn collect_used_types (
137137 db : & dyn SierraGenGroup ,
138138 libfunc_declarations : & [ program:: LibfuncDeclaration ] ,
139- functions : & [ Arc < pre_sierra :: Function > ] ,
139+ functions : & [ program :: Function ] ,
140140) -> OrderedHashSet < ConcreteTypeId > {
141141 // Collect types that appear in libfuncs.
142142 let types_in_libfuncs = libfunc_declarations. iter ( ) . flat_map ( |libfunc| {
@@ -160,12 +160,16 @@ fn collect_used_types(
160160 )
161161 } ) ;
162162
163- // Collect types that appear in user functions.
164- // This is only relevant for types that are arguments to entry points and are not used in
165- // any libfunc. For example, an empty entry point that gets and returns an empty struct, will
166- // have no libfuncs, but we still need to declare the struct.
167- let types_in_user_functions =
168- functions. iter ( ) . flat_map ( |func| func. parameters . iter ( ) . map ( |param| param. ty . clone ( ) ) ) ;
163+ // Gather types used in user-defined functions.
164+ // This is necessary for types that are used as entry point arguments but do not appear in any
165+ // libfunc. For instance, if an entry point takes and returns an empty struct and no
166+ // libfuncs are involved, we still need to declare that struct.
167+ // Additionally, we include the return types of functions, since with unsafe panic enabled,
168+ // a function that always panics might declare a return type that does not appear in anywhere
169+ // else in the program.
170+ let types_in_user_functions = functions
171+ . iter ( )
172+ . flat_map ( |func| chain ! ( & func. signature. param_types, & func. signature. ret_types) . cloned ( ) ) ;
169173
170174 chain ! ( types_in_libfuncs, types_in_user_functions) . collect ( )
171175}
@@ -263,31 +267,32 @@ pub fn assemble_program(
263267 functions : Vec < Arc < pre_sierra:: Function > > ,
264268 statements : Vec < pre_sierra:: StatementWithLocation > ,
265269) -> ( program:: Program , Vec < Vec < StableLocation > > ) {
270+ let label_replacer = LabelReplacer :: from_statements ( & statements) ;
271+ let funcs = functions
272+ . into_iter ( )
273+ . map ( |function| {
274+ let sierra_signature = db. get_function_signature ( function. id . clone ( ) ) . unwrap ( ) ;
275+ program:: Function :: new (
276+ function. id . clone ( ) ,
277+ function. parameters . clone ( ) ,
278+ sierra_signature. ret_types . clone ( ) ,
279+ label_replacer. handle_label_id ( function. entry_point ) ,
280+ )
281+ } )
282+ . collect_vec ( ) ;
283+
266284 let libfunc_declarations =
267285 generate_libfunc_declarations ( db, collect_used_libfuncs ( & statements) . iter ( ) ) ;
268286 let type_declarations =
269- generate_type_declarations ( db, collect_used_types ( db, & libfunc_declarations, & functions ) ) ;
287+ generate_type_declarations ( db, collect_used_types ( db, & libfunc_declarations, & funcs ) ) ;
270288 // Resolve labels.
271- let label_replacer = LabelReplacer :: from_statements ( & statements) ;
272289 let ( resolved_statements, statements_locations) =
273290 resolve_labels_and_extract_locations ( statements, & label_replacer) ;
274-
275291 let program = program:: Program {
276292 type_declarations,
277293 libfunc_declarations,
278294 statements : resolved_statements,
279- funcs : functions
280- . into_iter ( )
281- . map ( |function| {
282- let sierra_signature = db. get_function_signature ( function. id . clone ( ) ) . unwrap ( ) ;
283- program:: Function :: new (
284- function. id . clone ( ) ,
285- function. parameters . clone ( ) ,
286- sierra_signature. ret_types . clone ( ) ,
287- label_replacer. handle_label_id ( function. entry_point ) ,
288- )
289- } )
290- . collect ( ) ,
295+ funcs,
291296 } ;
292297 ( program, statements_locations)
293298}
0 commit comments