Closed nventuro closed 1 week ago
Interestingly do_thing_with_serialization_with_extra_steps
works fine if I add an impl
:
impl ToField for Field {
fn to_field(self) -> Field {
self
}
}
I'd want to be able to use the with_extra_steps
approach, as it doesn't force me to pollute the entire callstack with T: ToField
. It seems like this issue might be two separate issues?
do_thing_with_serialization
it's asking me to specify T: ToField
even though in the other case I can skip it and be finewith_extra_steps
case it fails to detect the origin of the issue, which is passing Field
as the concrete type with Field
does not implement the required traitsI'd want to be able to use the with_extra_steps approach, as it doesn't force me to pollute the entire callstack with T: ToField. It seems like this issue might be two separate issues?
The trait constraint is required everywhere in the call stack until T
can be resolved to a concrete type. It's just a consequence of the way we do trait dispatch where it is able to find the impl anyway once it exists - it would still panic if it did not. Without the trait constraint there would be two issues:
fn foo<T>(x: T) -> T
it should be able to take a value of any type and return a value of any type. When a trait constraint like T: Default
is added it is now restricted to only types which implement Default
. So like with mandatory parameter/return types, having trait constraints on a function is crucial for code documentation as well.So the only issue here is that the compiler does not error for the missing constraint on do_thing_with_serialization_with_extra_steps
.
I see, that makes perfect sense. It seems we've been abusing this bug a little bit, so some aztec-nr code will break due to missing where
clauses once this is fixed.
This makes me think that I'd also be good to get https://github.com/noir-lang/noir/issues/4508 done - we typically end up having to annonate all methods of an impl with the where
clause as soon as we require it in a single place.
Aim
In certain scenarios the compiler's front end does not realize that it's missing trait founds, and fails with ICE's later in the compilation pipeline. This is annoying because these errors have no context, the LSP doesn't see them, etc.
Expected Behavior
Given the following code:
Compilation fails with
This is expected: we can only serialize
MyType
if we ask thatT
can be converted into a field - otherwise the serialization trait is not implemented. However, by calling.serialize()
thorughserialize_thing
indo_thing_with_serialization_with_extra_steps
, this requirement is seemingly lifted - we can perform the same callstack without having to require theToField
impl. Seems great!Unfortunately, if we actually try to call this function we get the following nasty ICE. showing that the true issue was the frontend not checking for this trait:
This is doubly annoying when writing library code because it only shows up when using the library, not when building it.