주요 변경 사항과 특이점
아래 항목 중 일부는 이미 따로 언급되었지만, 이 페이지에서는 이전 트레이트 시스템 구현에서 달라진 주요 변경 사항을 정리합니다. 또한 솔버가 이상적인 구현과 크게 다른 몇 가지 지점도 다룹니다. 이 문서는 내용을 단순화하였으며 엣지 케이스는 다루지 않습니다. 각 서술에 “대체로“라는 말이 암묵적으로 붙어 있다고 여기시기를 권장합니다.
표준화
새 솔버는 중첩된 목표를 평가할 때 표준화를 사용합니다. 후보가 여러 개일 수 있는 경우에는 각 후보를 즉시 표준화합니다. 그런 다음 그 표준 응답들을 병합하려고 시도합니다. 이는 트레이트 시스템 내부에서 표준화를 사용하지 않는 이전 구현과 다른 점입니다.
이는 두 솔버의 설계에 몇 가지 큰 영향을 미칩니다. 표준화를 사용하여 후보의 제약 조건을 보관해 두지 않으면, 후보 선택 과정에서 각 후보의 제약 조건을 버려야 하며, 후보가 선택된 후 그 후보를 다시 평가해야만 제약 조건을 적용할 수 있습니다: 소스. 표준화 없이는 목표를 평가하여 얻은 추론 제약 조건을 캐시하는 것도 불가능합니다. 이 때문에 이전 구현에는 evaluate와 fulfill이라는 두 가지 시스템이 존재합니다. 평가는 캐시되고, 추론 제약 조건을 적용하지 않으며, 후보를 선택할 때 사용됩니다. 이행은 추론 제약 조건과 영역 제약 조건을 적용하며, 캐시되지 않고, 추론 제약 조건을 적용합니다.
표준화를 사용하면 새 구현은 평가와 이행을 하나로 합칠 수 있으므로, 복잡성과 미묘한 동작 차이를 피할 수 있습니다. 이는 캐싱을 크게 단순화하고, 추적되지 않는 정보에 실수로 의존하는 것을 방지합니다. 또한 선택 후 후보를 다시 평가하지 않아도 되며, 여러 후보의 응답을 병합할 수 있게 합니다. 그러나 평가 중에 목표를 표준화하기 때문에, 새 구현은 트레이트 해결 중 순환을 만났을 때 고정점 알고리즘을 사용해야 합니다: 소스.
지연된 별칭 동등성
새 구현은 별칭들을 관계 지을 때 AliasRelate 목표를 생성하는 반면, 이전 구현은 별칭들을 구조적으로 관계 짓습니다. 이를 통해 새 솔버는 관련된 별칭들을 정규화할 수 있을 때까지 동등성 판단을 보류할 수 있습니다.
기존 솔버의 동작은 불완전하며, 모호한 별칭을 추론 변수로 대체하는 즉시 정규화에 의존합니다. 바운드 변수를 포함하는 별칭에는 이 방식을 쓸 수 없기 때문에, 기존 구현은 바인더 내부의 별칭을 올바르게 처리하지 못합니다. 예를 들어 #102048이 있습니다. 자세한 내용은 정규화 장을 참고하십시오.
중첩된 목표의 즉시 평가
새 구현은 중첩된 목표를 호출자에게 반환하지 않고 즉시 처리합니다. 이전 구현은 두 가지 방식을 모두 사용합니다. 평가에서는 중첩된 목표가 즉시 처리되는 반면, 이행에서는 중첩된 목표를 단순히 나중에 처리하도록 반환합니다.
새 구현은 후보 선택을 위해 중첩된 목표를 즉시 처리할 수 있어야 하므로, 항상 그렇게 처리하면 복잡성이 줄어듭니다. 이를 통해 향후 더 많은 후보를 병합할 수 있게 될 수도 있습니다.
중첩된 목표는 고정점에 도달할 때까지 평가됩니다
새 구현은 고정점에 도달할 때까지 항상 루프를 돌며 목표를 평가합니다. 이전 구현은 이행(fulfillment)에서만 그렇게 하고, 평가(evaluation)에서는 그렇게 하지 않습니다. 항상 이렇게 하면 추론이 강화되고 트레이트 솔버의 순서 의존성이 줄어듭니다. trait-system-refactor-initiative#102를 참조하십시오.
증명 트리와 진단 정보 제공
새 구현은 진단 정보를 직접 추적하지 않고, 대신 관련 정보를 지연 계산하는 데 쓰이는 증명 트리를 제공합니다. 이 부분은 아직 완전히 다듬어지지 않았으며 다소 임시방편적입니다. 이는 성능을 높이기 위해 정상 경로에서 이 정보를 추적하지 않고, 실수로 진단 데이터에 의존하여 동작이 결정되는 일을 막기 위한 것입니다.
새 구현의 주요 특이점
환경 후보가 하나라도 있으면 impl 숨기기
어떤 Trait 목표를 증명할 ParamEnv 또는 AliasBound 후보가 하나라도 있으면, Trait 목표와 Projection 목표 모두에 대해 모든 impl 후보를 버립니다: 소스. 이렇게 하면 사용자가 where 바운드로 완전히 포괄되는 impl을 사용하지 못하게 되며, 이는 이전 구현의 동작과 일치하고 몇 가지 이상한 오류(예: trait-system-refactor-initiative#76)를 피할 수 있게 해 줍니다.
NormalizesTo 목표는 함수입니다
정규화 장을 참조하십시오. 기대 항이 정규화에 영향을 주지 않도록, NormalizesTo 목표를 계산하기 전에 기대 항을 제약되지 않은 추론 변수로 대체합니다. 이는 NormalizesTo 목표가 다른 모든 종류의 목표와 다소 다르게 처리되며 추가적인 솔버 지원이 필요하다는 뜻입니다. 가장 눈에 띄는 점은 이들의 모호한 중첩된 목표가 호출자에게 반환되고, 호출자가 이를 평가한다는 것입니다. 자세한 내용은 #122687을 참조하십시오.