Skip to content

Provide unique name from closures with same name#488

Open
kvpanch wants to merge 1 commit intomainfrom
kvpanch/issue_474
Open

Provide unique name from closures with same name#488
kvpanch wants to merge 1 commit intomainfrom
kvpanch/issue_474

Conversation

@kvpanch
Copy link
Contributor

@kvpanch kvpanch commented Mar 4, 2026

In YUL it's possible to declare closure with a same name, but in different scope, which previously resulted to func name conflict during LLVM IR construction.
To solve this, track YUL scope when building LLVM IR and a special counter that increments every time function with the same name exists in LLVM module.
There's still assert if somehow within the same scope there 2 functions with the same name, which should be forbidden by Yul

Fixes: #474

In YUL it's possible to declare closure with a same name, but in
different scope, which previously resulted to func name conflict during LLVM
IR construction.
To solve this, track YUL scope when building LLVM IR and a special
counter that increments every time function with the same name exists in
LLVM module.
There's still assert if somehow within the same scope there 2 functions
with the same name, which should be forbidden by Yul

Fixes: #474
@kvpanch kvpanch requested review from elle-j and xermicus March 4, 2026 20:01
Comment on lines +88 to +91
/// Monotonic counter for unique frontend function name mangling.
function_counter: usize,
/// Scope stack mapping Yul names to mangled LLVM names.
function_scope: Vec<BTreeMap<String, String>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: What do you think about prefixing with frontend_ for more clarity?

}
let counter = self.function_counter;
self.function_counter += 1;
let mangled = format!("{name}_{}__{counter}", self.code_type().unwrap());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the double _ intentional here?

Suggested change
let mangled = format!("{name}_{}__{counter}", self.code_type().unwrap());
let mangled = format!("{name}_{}_{counter}", self.code_type().unwrap());

Comment on lines +467 to +472
if let Some(scope) = self.function_scope.last() {
assert!(
!scope.contains_key(name),
"ICE: function '{name}' declared subsequently in the same scope"
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should always expect the function scope to have been pushed, otherwise it's an internal error (currently the mangled name would otherwise silently not be inserted). (The last_mut() can be used here to replace the later self.function_scope.last_mut() as well 👍 )

Suggested change
if let Some(scope) = self.function_scope.last() {
assert!(
!scope.contains_key(name),
"ICE: function '{name}' declared subsequently in the same scope"
);
}
let scope = self
.function_scope
.last_mut()
.expect("ICE: function scope must be pushed before declaring frontend functions");
assert!(
!scope.contains_key(name),
"ICE: function '{name}' declared subsequently in the same scope"
);


/// Pops the current function scope.
pub fn pop_function_scope(&mut self) {
self.function_scope.pop();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could indicate an internal error here.

Suggested change
self.function_scope.pop();
self.function_scope
.pop()
.expect("ICE: tried to pop an empty function scope stack");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ICE same-named Yul functions in sibling blocks

2 participants