MIR 빌림 검사
빌림 검사는 Rust의 “비법 소스“로, 다음과 같은 여러 속성을 강제하는 역할을 맡습니다.
- 모든 변수는 사용되기 전에 초기화되어야 합니다.
- 같은 값을 두 번 이동할 수 없습니다.
- 빌려진 상태의 값은 이동할 수 없습니다.
- 가변으로 빌려진 상태의 장소에는 (해당 참조를 통하는 경우를 제외하고) 접근할 수 없습니다.
- 불변으로 빌려진 상태의 장소는 변경할 수 없습니다.
- 등
빌림 검사기는 MIR 위에서 동작합니다. 이전 구현은 HIR 위에서 동작했습니다. MIR에서 빌림 검사를 수행하면 여러 가지 이점이 있습니다.
- MIR은 HIR보다 훨씬 덜 복잡하며, 이러한 과감한 디슈가링은 빌림 검사기의 버그를 예방하는 데 도움이 됩니다. (궁금하다면 MIR 기반 빌림 검사기가 수정한 버그 목록을 여기에서 볼 수 있습니다.)
- 더욱 중요한 점은, MIR을 사용하면 제어 흐름 그래프로부터 도출되는 영역인 “비어휘적 라이프타임(non-lexical lifetimes)”이 가능해진다는 것입니다.
빌림 검사기의 주요 단계
빌림 검사기의 소스는 rustc_borrowck 크레이트에 있습니다. 주요 진입점은 mir_borrowck 쿼리입니다.
- 먼저 MIR의 로컬 복사본을 만듭니다. 이후 단계에서는 이 복사본을 제자리에서 수정하여, 타입 등이 우리가 계산하고 있는 새로운 영역에 대한 참조를 포함하도록 변경합니다.
- 그다음
replace_regions_in_mir를 호출하여 로컬 MIR을 수정합니다. 이 함수는 여러 작업 중에서도 특히 MIR 안의 모든 영역을 새로운 추론 변수로 대체합니다. - 다음으로, 어떤 데이터가 언제 이동되는지를 계산하는 여러 데이터 흐름 분석을 수행합니다.
- 그다음 MIR 전체에 걸쳐 두 번째 타입 검사를 수행합니다. 이 타입 검사의 목적은 서로 다른 영역 사이의 모든 제약 조건을 결정하는 것입니다.
- 다음으로 영역 추론을 수행하는데, 이는 각 영역의 값, 즉 기본적으로 우리가 수집한 제약 조건에 따라 각 라이프타임이 유효해야 하는 제어 흐름 그래프상의 지점들을 계산합니다.
- 이 시점에서 각 지점의 “스코프 내 빌림“을 계산할 수 있습니다.
- 마지막으로 MIR을 한 번 더 순회하면서 MIR이 수행하는 동작을 살펴보고 오류를 보고합니다. 예를 들어
*a + 1과 같은 문장을 발견하면, 변수a가 초기화되어 있는지, 그리고 가변으로 빌려진 상태가 아닌지를 검사합니다. 둘 중 어느 경우든 오류를 보고해야 하기 때문입니다. 이 검사를 수행하려면 앞선 모든 분석의 결과가 필요합니다.
빌림 검사기 디버깅
빌림 검사기 디버깅과 MIR 디버깅을 참고하십시오.