Если я правильно понимаю вопрос, вы задаете две вещи:
- Будут ли встроенные вызовы компилятора
magnitude
?
- Сможет ли компилятор встроить вызов к
square_magnitude
внутри magnitude
, если square_magnitude
сам объявлен inline
, даже если код для square_magnitude
недоступен в признаке?
Что касается первого, нет причины, по которой он не мог. Что касается второго ответа, да, компилятор сможет встроить обе функции, потому что к тому времени, когда он генерирует код, источник для обеих функций доступен. Это можно увидеть в разборке :
trait Magnitude {
fn square_magnitude( &self ) -> f64;
#[inline]
fn magnitude( &self ) -> f64 {
self.square_magnitude().sqrt()
}
}
struct Vector { x: f64, y: f64 }
impl Magnitude for Vector {
#[inline]
fn square_magnitude (&self) -> f64 {
self.x*self.x + self.y*self.y
}
}
pub fn test (x: f64, y: f64) -> f64 {
let v = Vector { x: x, y: y };
v.magnitude()
}
Скомпилировано с rustc v1.28.0 и опцией -O
:
example::test:
mulsd xmm0, xmm0
mulsd xmm1, xmm1
addsd xmm1, xmm0
xorps xmm0, xmm0
sqrtsd xmm0, xmm1
ret
Обратите внимание, что компилятор будет не встроенным square_magnitude
внутри magnitude
, если square_magnitude
не объявлено inline
само по себе :
impl Magnitude for Vector {
fn square_magnitude (&self) -> f64 {
self.x*self.x + self.y*self.y
}
}
Формирует:
<example::Vector as example::Magnitude>::square_magnitude:
movsd xmm1, qword ptr [rdi]
movsd xmm0, qword ptr [rdi + 8]
mulsd xmm1, xmm1
mulsd xmm0, xmm0
addsd xmm0, xmm1
ret
example::test:
mulsd xmm0, xmm0
mulsd xmm1, xmm1
addsd xmm1, xmm0
xorps xmm0, xmm0
sqrtsd xmm0, xmm1
ret