Inline calls to constant functions and evaluate them at compile time
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Rust
- Sterne
- 3.4k
- Forks
- 126
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
Originally posted by @nazar-pc in #300
The basic problem right now is that calls into const fn are not inlined recursively. Here is an example:
const K: u8 = 20;
const PARAM_EXT: u8 = 6;
const fn y_size_bits(k: u8) -> u32 {
k as u32 + PARAM_EXT as u32
}
const fn metadata_size_bits(k: u8, table_number: u8) -> u32 {
k as u32
* match table_number {
1 => 1,
2 => 2,
3 | 4 => 4,
5 => 3,
6 => 2,
7 => 0,
_ => unreachable!(),
}
}
fn compute_fn_impl<const PARENT_TABLE_NUMBER: u8>(
) -> u32 {
let parent_metadata_bits = metadata_size_bits(K, PARENT_TABLE_NUMBER);
let num_bytes_with_data = (y_size_bits(K) + parent_metadata_bits * 2).div_ceil(u8::BITS);
// ..
}
Right now this requires Int8 capability:
error: Missing required capabilities for types
|
= note: `u8` type used without `OpCapability Int8`
Even though the exact value of num_bytes_with_data is known at compile time for every instantiation of the function and no u8 should actually exist anywhere in runtime. Some workarounds exist:
-
This helps with the first variable, but doesn't scale further.let parent_metadata_bits = const { metadata_size_bits(K, PARENT_TABLE_NUMBER) }; - Making ^ a proper constant doesn't work due to "error[E0401]: can’t use generic parameters from outer function" error
The only real solution is to inline everything recursively manually and wrap with const {}, which hurts code readability a lot, but perhaps this is something compiler can do as a workaround without redesigning too many of things.
In the end, I expect that all constants, variables and const fn calls to be inlined into a single constant value at compile time automatically, including any possible integer casts (like u8 -> u32), which for constant values are also known at compile time.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginnen Sie damit, das Rust-Beispiel und seinen Fehler wegen der fehlenden Int8-Fähigkeit in der Compiler- oder Codegenerierungs-Pipeline zu reproduzieren. Verfolgen Sie, wie Aufrufe von const fn, generische Instanziierungen, Casts und konstante Ausdrücke abgesenkt werden, und überprüfen Sie anschließend, dass das Beispiel ohne Laufzeitwerte vom Typ u8 oder eine Int8-Fähigkeit kompiliert.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- rust
- Bereich
- compilers
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 35/100