CodeBlanks Logo Icon CodeBlanks

HIR

High-level IR (HIR) nedir ve ne işe yarar öğrenirsin.

HIR

rustc kodu birkaç ara gösterimden geçirir: metin → belirteçler → AST (makro açılımı, ad çözümleme) → HIR → THIR → MIR → LLVM IR → makine kodu. HIR (High-level IR), AST'nin "şekerleri" (sugar) çözülmüş halidir: for, while let, ? ve async daha temel yapılara indirgenir. Tür denetimi ve trait çözümü HIR üzerinde yapılır.

for x in v { .. }
// HIR'de kabaca:
match IntoIterator::into_iter(v) {
    mut it => loop {
        match Iterator::next(&mut it) {
            Some(x) => { .. }
            None => break,
        }
    },
}

? operatörünün indirgenmesi

? de HIR'de bir match'e dönüşür; From dönüşümü bu adımda eklenir:

let n = s.parse::<i32>()?;
// kabaca:
let n = match s.parse::<i32>() {
    Ok(v) => v,
    Err(e) => return Err(From::from(e)),
};

Bu yüzden şekerli ve indirgenmiş kod aynı makine kodunu üretir; sözdizimi kolaylıklarının çalışma anı maliyeti yoktur.

Uygulama Elle indirgenmiş for

vec![1, 2, 3] vektörünü for kullanmadan, HIR'deki gibi IntoIterator::into_iter, loop ve Iterator::next ile topla ve sonucu yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
fn main() {
    let v = vec![1, 2, 3];
    let mut toplam = 0;
    let mut it = IntoIterator::into_iter(v);
    loop {
        match Iterator::next(&mut it) {
            Some(x) => toplam += x,
            None => break,
        }
    }
    println!("{}", toplam);
}

Beklenen çıktı

6

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Bir makronun açılmış halini görmenin en kolay yolu nedir?

  • cargo expand (ya da rustc -Zunpretty=expanded) Doğru cevap
  • cargo build --verbose
  • rustfmt
  • cargo doc

Açıklama: Makro açılımı AST aşamasında olur; HIR'e gelindiğinde makrolar artık yoktur.

2 İndirgenmiş döngü

Soru
let mut it = IntoIterator::into_iter(v);
loop {
    match Iterator::____(&mut it) {
        Some(x) => toplam += x,
        None => break,
    }
}
Cevap
let mut it = IntoIterator::into_iter(v);
loop {
    match Iterator::next(&mut it) {
        Some(x) => toplam += x,
        None => break,
    }
}

Açıklama: for döngüsü her turda Iterator::next çağırır.

3 Aşama ve görevi

Kavram Anlamı
AST Makro açılımı
HIR Tür denetimi
MIR Ödünç denetimi
LLVM IR Optimizasyon ve kod üretimi

Uzman bölümündeki tüm dersler