트레이트 해결(신규)
이 장에서는 rustc_trait_selection/solve에 있는, 현재 개발 중인(WIP) 새 솔버에서 트레이트 해결이 어떻게 동작하는지 설명합니다. 현재 솔버와 chalk 솔버에 관한 문서도 자유롭게 참고하십시오.
핵심 개념
트레이트 시스템의 목표는 주어진 트레이트 바운드가 충족되는지 확인하는 것입니다. 이는 특히 제네릭일 수도 있는 함수의 본문을 타입 검사할 때 중요합니다. 예를 들면 다음과 같습니다.
#![allow(unused)]
fn main() {
fn uses_vec_clone<T: Clone>(x: Vec<T>) -> (Vec<T>, Vec<T>) {
(x.clone(), x)
}
}
여기서 x.clone()을 호출하려면 T: Clone이 참이라는 가정하에 Vec<T>가 Clone을 구현한다는 것을 증명해야 합니다. T: Clone은 이 함수의 호출자가 증명할 것이므로 이를 가정할 수 있습니다.
“T: Clone이라는 가정하에 Vec<T>: Clone을 증명하라“라는 개념을 Goal이라고 합니다. Vec<T>: Clone과 T: Clone은 모두 Predicate를 사용하여 표현됩니다. 다른 술어도 있으며, 그중 가장 대표적인 것은 연관 항목에 대한 동등성 바운드인 <Vec<T> as IntoIterator>::Item == T입니다. 전체 목록은 PredicateKind 열거형을 참고하십시오. Goal은 증명해야 하는 predicate와 이 술어가 성립해야 하는 param_env로 표현됩니다.
목표를 증명할 때는 가능한 각 Candidate가 주어진 목표에 적용되는지를, 그 후보의 중첩된 목표를 재귀적으로 증명하는 방식으로 확인합니다. 가능한 후보 목록과 예시는 CandidateSource를 참고하십시오. 가장 중요한 후보는 사용자가 작성한 트레이트 구현인 Impl 후보와, 현재 환경의 가정인 ParamEnv 후보입니다.
위의 예시에서 Vec<T>: Clone을 증명하려면 먼저 impl<T: Clone> Clone for Vec<T>를 사용합니다. 이 impl을 사용하려면 T: Clone이 성립한다는 중첩된 목표를 증명해야 합니다. 이 목표는 중첩된 목표가 없는 ParamEnv의 가정 T: Clone을 사용해 증명할 수 있습니다. 따라서 Vec<T>: Clone이 성립합니다.
트레이트 솔버는 성공, 모호성, 오류 중 하나를 CanonicalResponse로 반환합니다. 성공과 모호성의 경우에는 추론 제약과 영역 제약도 함께 반환합니다.