Lobsters

Why 'externalized' proofs of cyclic trait impls does not work

순환 트레이트 구현에서 외부 증명 방식이 통하지 않는 이유

Rust의 슈퍼트레이트를 확인하는 두 방식, 모듈식 증명과 외부 증명을 비교합니다. 외부 증명은 호출자가 슈퍼트레이트까지 확인하게 하지만 unsafe 트레이트에서는 잘못된 구현을 호출자가 신뢰해야 하는 모순이 생기므로, 글은 모듈식 증명이 필요하다고 주장합니다.

AI 요약

Rust에서 트레이트 구현과 슈퍼트레이트 조건을 누가 증명할지에 따라 모듈식 증명(modular proof)과 외부 증명(external proof)을 나눠 설명합니다. 글의 주장은 순환 트레이트 구현을 지원하려면 모듈식 방식이 필요하며, 외부 증명은 Rust의 unsafe 트레이트 설계와 맞지 않는다는 것입니다.

슈퍼트레이트 조건은 누가 확인하나요?

trait Magic: Copy {}라고 선언하면 T: Magic인 경우 T: Copy도 성립해야 합니다. 따라서 T: Magic을 받는 제네릭 함수 안에서 T를 Copy가 필요한 함수에 넘길 수 있습니다. 컴파일러는 모든 Magic 구현에서 이 조건이 맞는지 확인해야 합니다.

모듈식 증명에서는 각 impl이 슈퍼트레이트 조건을 직접 만족해야 합니다. 예를 들어 impl Magic for String은 String: Copy를 요구하므로 거부됩니다. 반대로 유효한 구현이 있다면 나머지 코드는 그 구현을 신뢰하고 String: Magic, 나아가 String: Copy를 사용할 수 있습니다. 함수 호출자가 함수 본문을 다시 검사하지 않고 함수의 타입 서명을 신뢰하는 것과 같은 방식입니다.

모듈식 증명과 순환 추론

모듈식 방식에도 해결할 문제가 있습니다. impl Magic for String의 유효성을 확인하면서 그 구현 자체를 근거로 String: Magic을 증명하면, Magic이 Copy를 보장한다는 규칙을 거쳐 String: Copy까지 잘못 도출할 수 있습니다. 따라서 구현의 유효성을 검사할 때 해당 구현에 재귀적으로 의존하는 증명을 막아야 합니다. 글은 이 종료성 문제를 다루는 구체적 규칙은 후속 글에서 설명하겠다고 밝힙니다.

외부 증명은 호출자에게 검증을 맡깁니다

외부 증명 방식에서는 impl Magic for String이 String: Magic 전체를 확정하지 않습니다. 구현은 얕은 조건인 Shallow(String: Magic)만 제공하고, 실제로 String: Magic을 사용하려는 코드가 Shallow(String: Copy)도 따로 증명해야 합니다. 따라서 String이 Copy가 아니어도 해당 impl 자체는 허용될 수 있지만, 호출자는 이를 사용할 수 없습니다.

이 방식은 구현의 슈퍼트레이트 조건을 다시 검사하므로 함수 호출자가 함수 본문까지 확인해야 하는 것처럼 어색합니다. 그래도 순환 추론은 막습니다. 얕은 Magic 구현만으로는 String: Copy를 증명할 수 없기 때문입니다.

unsafe 트레이트와의 충돌

글쓴이는 Ralf Jung과 lcnr이 지적한 문제를 근거로 외부 증명이 Rust의 unsafe 트레이트와 양립하기 어렵다고 설명합니다. NullWord 같은 unsafe 트레이트는 값이 0인 usize를 해당 타입으로 안전하게 변환할 수 있다는 조건을 나타냅니다. 이 트레이트를 요구하는 함수가 transmute(0_usize)를 수행한다면, 호출자는 트레이트 구현이 그 조건을 지킨다고 신뢰합니다.

그런데 Box<T>가 null 값도 안전하다고 잘못 선언하는 unsafe 구현이 있다고 가정하면, 호출자는 그 구현을 믿고 함수를 실행할 수 있고 정의되지 않은 동작(undefined behavior)이 발생합니다. Rust에서는 unsafe 구현이 안전 조건을 충족할 책임을 집니다. 그런데 슈퍼트레이트에 대해서만 호출자에게 구현을 재검증하라고 하면, 구현은 unsafe 조건에는 신뢰를 요구하면서 슈퍼트레이트 조건에는 신뢰를 받지 못하는 불일치가 생깁니다.

글은 unsafe 구현이 증명해야 하는 추가 조건을 일반적인 트레이트 구현 의무의 한 종류로 봐야 하며, 따라서 구현이 슈퍼트레이트까지 보이는 모듈식 증명을 택해야 한다고 결론짓습니다. 다음 글에서는 귀납적 순환을 허용하는 모듈식 증명 방식과 다른 대안을 다룰 예정이라고 덧붙입니다.

원문: Lobsters / 번역·요약: Trawling