Skip to content

Defer type translation failures until IR-time.#374

Merged
copybara-service[bot] merged 1 commit intomainfrom
test_863057820
Feb 3, 2026
Merged

Defer type translation failures until IR-time.#374
copybara-service[bot] merged 1 commit intomainfrom
test_863057820

Conversation

@copybara-service
Copy link

@copybara-service copybara-service bot commented Jan 31, 2026

Defer type translation failures until IR-time.

This is probably necessary for fixing b/251045039: we detect overload sets by iterating over all the functions, but if a type is unknown, we don't list it as a function. Ideally we'd always generate a function ir item, even if we know it will not get bindings.

Deferring errors until we are in Rust also means we can generate bindings for more functions with comprehensive fallbacks, and can record more details about the error information. It is a generally good thing.

Finally, because these errors are deferred to later now, I had to actually fix up the later error messages to be consistent with the errors you'd get earlier in the process. This has been a net improvement in error message quality. For example, if a method Foo(wchar_t) volatile doesn't get bindings, because of both the unsupported volatile qualifier on this, and the unsupported first argument, it will explicitly name this and Parameter #0, instead of Parameter #0 and Parameter #, respectively.

The only very bad thing that I saw in this whole process was that our bridge type handling for std::string hid a failure in how we handle templates with bad types. The old version of the code accidentally failed for wstring while it was checking for string. Reproducing this behavior with deferred "errors are actually valid values" kinds of semantics is a bit of a hack. I'm not entirely sure what the right fix is -- maybe check all the template arguments are valid for an arbitrary Record template instantiation?

This also shrinks our error messages, I guess because we chain slightly fewer errors together during ASSIGN_OR_RETURN and so on. It doesn't matter a whole lot, as we name the function and what part of it failed (e.g. return type), as well as the root cause (e.g. wchar_t). I did have to explicitly work to retain some of the chaining, or else valuable information gets lost: an anonymous enum just gets Unsupported type: ''. Oof!

@copybara-service copybara-service bot force-pushed the test_863057820 branch 3 times, most recently from d17b272 to 0d2bab5 Compare February 3, 2026 20:19
This is probably necessary for fixing b/251045039: we detect overload sets by iterating over all the functions, but if a type is unknown, we don't list it as a function. Ideally we'd _always_ generate a function ir item, even if we know it will not get bindings.

Deferring errors until we are in Rust also means we can generate bindings for more functions with comprehensive fallbacks, and can record more details about the error information. It is a generally good thing.

Finally, because these errors are deferred to later now, I had to actually fix up the later error messages to be consistent with the errors you'd get earlier in the process. This has been a net improvement in error message quality. For example, if a method `Foo(wchar_t) volatile` doesn't get bindings, because of both the unsupported `volatile` qualifier on `this`, and the unsupported first argument, it will explicitly name `this` and `Parameter #0`, instead of `Parameter #0` and `Parameter #`, respectively.

The only very bad thing that I saw in this whole process was that our bridge type handling for std::string hid a failure in how we handle templates with bad types. The old version of the code accidentally failed for wstring while it was checking for string. Reproducing this behavior with deferred "errors are actually valid values" kinds of semantics is a bit of a hack. I'm not entirely sure what the right fix is -- maybe check all the template arguments are valid for an arbitrary Record template instantiation?

This also shrinks our error messages, I guess because we chain slightly fewer errors together during `ASSIGN_OR_RETURN` and so on. It doesn't matter a whole lot, as we name the function and what part of it failed (e.g. return type), as well as the root cause (e.g. wchar_t). I did have to explicitly work to retain some of the chaining, or else valuable information gets lost: an anonymous enum just gets `Unsupported type: ''`. Oof!

PiperOrigin-RevId: 864992530
@copybara-service copybara-service bot merged commit d648f66 into main Feb 3, 2026
@copybara-service copybara-service bot deleted the test_863057820 branch February 3, 2026 20:23
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.

1 participant