flypig.co.uk

List items

Items from the current list are shown below.

Gecko

18 Aug 2024 : Day 323 #
I spent most of my day yesterday installing Sailfish OS 4.6 on one of my dev phones and adding 4.6.0.11EA-aarch64 to the list of targets supported by the Sailfish SDK installed on my laptop. I eventually got to the point where the dependencies were available and the build was failing on some Rust code. Although it's pretty clear from the context that the reason is down to the Rust version in the SDK being newer than that expected for the build, I wasn't able to figure out how to fix it yesterday. Here's the error again that's causing the build to fail:
25:56.21 error[E0597]: `desc_set` does not live long enough
25:56.21     --> gfx/wgpu/wgpu-core/src/device/mod.rs:1795:26
25:56.21      |
25:56.21 1782 |         let mut desc_set = desc_sets.pop().unwrap();
25:56.21      |             ------------ binding `desc_set` declared here
25:56.21 ...
25:56.21 1795 |                     set: desc_set.raw_mut(),
25:56.21      |                          ^^^^^^^^ borrowed value does not live 
                                                  long enough
25:56.21 ...
25:56.21 1816 |     }
25:56.21      |     -
25:56.21      |     |
25:56.21      |     `desc_set` dropped here while still borrowed
25:56.22      |     borrow might be used here, when `write_map` is dropped and 
                    runs the `Drop` code for type `BTreeMap`
25:56.22      |
25:56.22      = note: values in a scope are dropped in the opposite order they 
                are defined
25:57.25 For more information about this error, try `rustc --explain E0597`.
25:57.26 warning: `wgpu-core` (lib) generated 1 warning
25:57.26 error: could not compile `wgpu-core` (lib) due to previous error; 1 
    warning emitted
This is happening in the wgpu project code, which is external to but used by the gecko engine. The Rust compiler is famous for generating high quality error messages alongside useful tips for how to fix the problem causing it. Here the reason for the error is clear, but the way to fix it is less so.

The problems seems to be that desc_set is being taken from write_map and borrowed by the DescriptorSetWrite structure, the lifetime of which extends beyond the lifetime of write_map. As a mutable variable this means there's a risk that the variable may be read from or written to after it's been dropped when write_map> is dropped at the end of the method.

There are typically a few ways to tackle this. Since variables are dropped in the opposite order to their creation, often the error can be removed simply by reordering the variable declarations. On other occasions cloning the variable may be a way to avoid the problem. Finally it can sometimes be solved by adding in suitable lifetime annotations.

In this case, it appears it can be fixed by moving where the desc_set variable is created. If it's created before the wraite_map variable, then it won't be dropped when write_map is dropped.

There's actually a fix for this in the wgpu repository which is both simple and clear. There's also a little background explaining why this is necessary in the associated PR. I've therefore applied the changes from this patch and set the build running again.

The build quickly gets to the point it was failing before and continues past it. That's a good sign!

But, not much later, it hits a second, different, problem:
 2:28.66    Compiling mp4parse v0.11.5 (https://github.com/mozilla/
    mp4parse-rust?rev=1bb484e96ae724309e3346968e8ffd4c25e61616#1bb484e9)
 2:28.78 error[E0277]: cannot multiply `u64` by `NonZeroU8`
 2:28.78     --> ${PROJECT}/gecko-dev/third_party/rust/mp4parse/src/lib.rs:2318:
    62
 2:28.78      |
 2:28.78 2318 |                 static_assertions::const_assert!(<$lhs>::MAX * 
    <$rhs>::MAX <= <$output>::MAX);
 2:28.78      |                                                              ^ 
    no implementation for `u64 * NonZeroU8`
 2:28.78 ...
 2:28.78 2328 | impl_mul!((U8, std::num::NonZeroU8) => (U16, u16));
 2:28.78      | -------------------------------------------------- in this 
    macro invocation
 2:28.78      |
 2:28.79      = help: the trait `Mul<NonZeroU8>` is not implemented for `u64`
 2:28.79      = help: the following other types implement trait `Mul<Rhs>`:
 2:28.79                <u64 as Mul>
 2:28.79                <u64 as Mul<&u64>>
 2:28.79                <&'a u64 as Mul<u64>>
 2:28.79                <&u64 as Mul<&u64>>
 2:28.79      = note: this error originates in the macro `impl_mul` (in Nightly 
    builds, run with -Z macro-backtrace for more info)
 2:28.79 error[E0277]: cannot multiply `u64` by `NonZeroU8`
 2:28.79     --> ${PROJECT}/gecko-dev/third_party/rust/mp4parse/src/lib.rs:2318:
    62
 2:28.79      |
 2:28.79 2318 |                 static_assertions::const_assert!(<$lhs>::MAX * 
    <$rhs>::MAX <= <$output>::MAX);
 2:28.79      |                                                              ^ 
    no implementation for `u64 * NonZeroU8`
 2:28.79 ...
 2:28.79 2329 | impl_mul!((U32, std::num::NonZeroU8) => (U32MulU8, u64));
 2:28.79      | -------------------------------------------------------- in 
    this macro invocation
 2:28.79      |
 2:28.79      = help: the trait `Mul<NonZeroU8>` is not implemented for `u64`
 2:28.79      = help: the following other types implement trait `Mul<Rhs>`:
 2:28.79                <u64 as Mul>
 2:28.79                <u64 as Mul<&u64>>
 2:28.79                <&'a u64 as Mul<u64>>
 2:28.79                <&u64 as Mul<&u64>>
 2:28.79      = note: this error originates in the macro `impl_mul` (in Nightly 
    builds, run with -Z macro-backtrace for more info)
 2:28.93 For more information about this error, try `rustc --explain E0277`.
 2:28.93 error: could not compile `mp4parse` (lib) due to 2 previous errors
Here we have something else. It seems that the trait that allows u64 and Non?ZeroUB values to be multiplied together is missing. Again, we're not the first people to hit this problem and a helpful discussion on the mp4parse-rust issue tracker shows that a solution has already been implemented for this.

It's a straightforward change and transferring it over to the gecko code turns out to be straightforward as well. After doing this, however, the build doesn't get as far as it did before, failing with the following error:
 1:58.55 toolkit/library/rust/force-cargo-library-build
 2:01.62 error: the listed checksum of `${PROJECT}/gecko-dev/third_party/rust/
    mp4parse/src/lib.rs` has changed:
 2:01.62 expected: 
    ea3d90a541bd01cbb9f8e25599e77600f2ab011535b23334a433e5bd0d8ac7df
 2:01.62 actual:   
    9176ca468fe94f8988893e8249a7dd781dc641461109b6f08ae33f75b4989e90
 2:01.62 directory sources are not intended to be edited, if modifications are 
    required then it is recommended that `[patch]` is used with a forked copy 
    of the source
 2:01.63 make[4]: *** [${PROJECT}/gecko-dev/config/makefiles/rust.mk:405: 
    force-cargo-library-build] Error 101
This is an issue we've seen multiple times previously. The Rust sources are pinned using checksums in various .cargo-checksum.json files. This means the source can't be changed without also updating the checksums to match. This is a little tiresome, but also important for supporting consistent and reproducible builds. So since I've edited one of the mp4parse source files, I have to update the checksum to match.

The error message helpfully provides both the value stored currently in the checksum file and the value that's being generated from the sources. The two have to match in order for the build to continue.

So I've edited the third_party/rust/mp4parse/.cargo-checksum.json file to switch out the former checksum value with the latter value. I've set the build running again and now we'll have to wait and see what happens.

And what happens is looking good: the build passes all of the previous errors and now, after running for five hours the build is continuing without error.

There are plenty of places for it still to fail, but this is promising nevertheless. I'll have to wait for the build to complete before I can do any more significant work on this, so I'll likely have to pick this up again in the morning.

If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.

Comments

Uncover Disqus comments