Skip to content

Conversation

robertkirkman
Copy link
Contributor

@robertkirkman robertkirkman commented May 19, 2025

The original errors, repeated here for convenient reference by others:

error[E0308]: mismatched types
   --> src/wutil/dir_iter.rs:114:50
    |
114 |             self.typ.set(stat_mode_to_entry_type(s.st_mode));
    |                          ----------------------- ^^^^^^^^^ expected `u16`, found `u32`
    |                          |
    |                          arguments to this function are incorrect
    |
note: function defined here
   --> src/wutil/dir_iter.rs:151:4
    |
151 | fn stat_mode_to_entry_type(m: libc::mode_t) -> Option<DirEntryType> {
    |    ^^^^^^^^^^^^^^^^^^^^^^^ ---------------
help: you can convert a `u32` to a `u16` and panic if the converted value doesn't fit
    |
114 |             self.typ.set(stat_mode_to_entry_type(s.st_mode.try_into().unwrap()));
    |                                                           ++++++++++++++++++++

error[E0308]: mismatched types
   --> src/wutil/dir_iter.rs:292:32
    |
292 |             self.entry.inode = dent.d_ino;
    |             ----------------   ^^^^^^^^^^ expected `u32`, found `u64`
    |             |
    |             expected due to the type of this binding

- Fixes termux#24741

- Cherry-pick fish-shell/fish-shell@bbf678e to replace `libc-src-unix-linux_like-android-mod.rs.diff` (since `libandroid-spawn` does not currently work with `fish`)

- `libc-src-unix-linux_like-android.diff` is **causing** termux#24741 because of the problems explained by **maurer** in rust-lang/libc#4216 (comment)

- I have rewritten `libc-src-unix-linux_like-android.diff` in **my own alternative way of solving [the errors](termux#22609 (comment)
  - My personal belief is that these errors should be solved by **patching `fish`**, _not_ by patching the **`libc` cargo crate**.
  - The reason I believe that is because **`fish` is using the type `libc::ino_t` to represent a value for storing the `d_ino` member of a `dirent` struct, which **cannot work on 32-bit Android** because 32-bit Android's `d_ino` is **not** an `ino_t`. [It is a `uint64_t`](https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/include/dirent.h;l=64?q=d_ino&ss=android%2Fplatform%2Fsuperproject%2Fmain:bionic%2Flibc%2Finclude%2F&start=1).
  - Therefore, the logical conclusion is that any successful port of `fish` to 32-bit Android **must explicitly store the value of a `dirent` `d_ino` as a `u64` anywhere it appears in Rust code.**
  - The same concept applies to `st_mode` - `st_mode` of `stat` on 32-bit Android is **not** a `mode_t`. [It is an `unsigned int`](https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/include/sys/stat.h;l=87), and [on Android, `unsigned int` is a 32-bit integer](https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/include/stdint.h;l=42;drc=61197364367c9e404c7da6900658f1b16c42d0da;bpv=0;bpt=1?q=stdint.h&ss=android%2Fplatform%2Fsuperproject%2Fmain). Therefore, any successful port of `fish` to 32-bit Android must explicitly store the value of a `stat` `st_mode` as `u32`.
  - In C, `S_IFMT` is a pure typeless literal preprocessor definition, which is [`00170000` in Android](https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/include/uapi/linux/stat.h;l=9?q=S_IFMT), preprocessor definitions do not really exist in Rust so there is unfortunately no correct alternative to a hardcoded integer literal for this on 32-bit Android

- I previously read rust-lang/libc#4216 in January 2025, however, I unfortunately did not have the experience necessary at the time to fully understand how to solve this specific problem, so at the time, I did not change the version written by thunder-coding because I did not know how to make a better way to bypass the errors
  - However, in April 2025, I [ported Steel Bank Common Lisp to 64-bit Android-x86](https://github.com/robertkirkman/termux-packages/blob/b54fa7f61e3c9acdfdc13b9680b9ff023d69323d/packages/sbcl/fix-stat-st_nlink-x86.patch). In the process of doing that, I became more experienced with Android's `stat.h` and `dirent.h` files, and I have been able to use that experience to successfully create what appears to be a correct solution to termux#24741

The original errors, repeated here for convenint reference by others:

```
error[E0308]: mismatched types
   --> src/wutil/dir_iter.rs:114:50
    |
114 |             self.typ.set(stat_mode_to_entry_type(s.st_mode));
    |                          ----------------------- ^^^^^^^^^ expected `u16`, found `u32`
    |                          |
    |                          arguments to this function are incorrect
    |
note: function defined here
   --> src/wutil/dir_iter.rs:151:4
    |
151 | fn stat_mode_to_entry_type(m: libc::mode_t) -> Option<DirEntryType> {
    |    ^^^^^^^^^^^^^^^^^^^^^^^ ---------------
help: you can convert a `u32` to a `u16` and panic if the converted value doesn't fit
    |
114 |             self.typ.set(stat_mode_to_entry_type(s.st_mode.try_into().unwrap()));
    |                                                           ++++++++++++++++++++

error[E0308]: mismatched types
   --> src/wutil/dir_iter.rs:292:32
    |
292 |             self.entry.inode = dent.d_ino;
    |             ----------------   ^^^^^^^^^^ expected `u32`, found `u64`
    |             |
    |             expected due to the type of this binding
```
@robertkirkman robertkirkman force-pushed the fish-do-not-patch-libc-crate branch from f66ca02 to 80c781c Compare May 19, 2025 13:37
@robertkirkman
Copy link
Contributor Author

This is confirmed to also solve the problem on the device of the issue reporter, so I am merging it now.

@robertkirkman robertkirkman merged commit c869d61 into termux:master May 20, 2025
9 checks passed
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.

[Bug]: fish shell file globbing not working
2 participants