Generic Const Args and You
Generic Const Arguments와 개발자
Rust Const Generics 프로젝트 그룹이 제네릭 매개변수를 포함한 상수 인자를 지원하는 GCA 기능군의 설계와 사용법을 소개합니다. 기존 제약을 풀지만 모든 기능은 아직 실험 단계이며, 안정화 제안까지 시간이 더 필요합니다.
- 주제
AI 요약
Rust의 안정 버전에서는 Const Generics 상수 인자로 제네릭 매개변수 자체나 완전히 구체적인 상수만 쓸 수 있습니다. 따라서 [u8; N + 1]이나 [u8; T::NUM_BYTES] 같은 타입을 표현하기 어렵고, 일부 사용자는 typenum 같은 크레이트에 의존합니다. Generic Const Arguments(GCA)는 제네릭 매개변수를 포함한 더 다양한 표현식을 상수 인자에 넣도록 설계한 기능군입니다. 2021년부터 실험 기능으로 존재한 generic_const_exprs를 대체하는 방향이며, 그 기능을 구현하며 얻은 경험도 GCA 설계에 반영했습니다.
`gca!`로 표현하는 상수 인자
GCA 기능은 새로 지원하는 표현식을 gca!(...) 안에 적습니다. 예를 들어 gca_adts는 제네릭 매개변수가 들어간 구조체·열거형·배열·튜플 표현식을 지원합니다. gca!(Foo { field: N })처럼 쓸 수 있고, 상수 매개변수의 타입으로 사용자 정의 타입을 허용하는 adt_const_params는 별도 기능입니다. 배열 반복 표현식인 [N; 2]는 아직 지원하지 않습니다.
gca!(...) 안에서 제네릭 매개변수를 사용할 수 있지만, 일반 상수 인자에는 같은 규칙이 적용되지 않습니다. 반대로 이 매크로 안에서 허용하는 표현식 종류는 제한적입니다. 현재 gca!(N + 1)이나 함수 호출은 허용되지 않습니다. 제네릭 값에 따라 계산하는 표현식은 상수 항목(const item)을 활용하는 기능으로 다룹니다.
상수 항목과 최소 기능
gca_const_items는 연관 상수, 자유 상수, 타입에 연결된 상수 등을 타입 시스템 안에서 사용할 수 있게 합니다. 이 기능은 아직 불안정한 -Znext-solver도 요구합니다. 예를 들어 T::ASSOC를 배열 길이에 쓰거나, 제네릭 타입의 크기를 계산하는 상수 항목을 상수 인자로 참조할 수 있습니다. 상수 항목의 정의가 gca!(...)로 작성되면 타입 시스템이 그 표현식을 들여다보고 동등성을 판단합니다. const FREE_GCA<N> = gca!(N)이라면 FREE_GCA::<N>과 N이 같다고 판단하지만, 같은 내용을 일반 상수 항목으로 정의하면 불투명하게 취급해 두 배열 타입을 같다고 보지 않을 수 있습니다.
이 기능은 연관 상수 바인딩도 지원합니다. 트레이트의 연관 상수를 제약으로 지정하고, 연관 상수가 있는 트레이트를 dyn 타입으로 사용할 수 있습니다. 안정 버전에서는 두 사용 모두 지원하지 않습니다.
gca_min_const_items는 범위를 좁힌 대안입니다. gca!(...)를 오른쪽 항으로 쓴 상수 항목만 타입 시스템에서 사용할 수 있으며, -Znext-solver가 필요하지 않습니다. 연관 상수에는 구현이 항상 GCA 표현식이어야 한다는 rustc_always_gca 속성을 붙일 수 있습니다. 이 제한은 제네릭 상수에서 단형화 이후 오류가 발생할 가능성을 줄이고, 상수끼리 같은지 판단하는 규칙을 단순하게 만듭니다. 구현 난도도 더 낮아 안정화 기준에 먼저 도달할 가능성이 있습니다.
매크로 표기를 생략하는 실험 기능
gca!(...)를 매번 쓰는 방식은 GCA를 많이 쓰는 코드에서 번거롭습니다. 하지만 컴파일러가 문법만 보고 매크로가 필요한지 판단하면 오분류가 생길 수 있습니다. 예를 들어 Foo(N)은 제네릭 매개변수를 포함하므로 GCA 표현식이어야 하지만, 비슷한 모양의 Bar(ONE)은 함수 호출이라 GCA 표현식으로 처리하면 안 됩니다. 표기를 암묵적으로 만들면 어떤 상수 인자를 허용하는지 흐려지고, 공개 API에서 GCA 인자를 바꾸지 않겠다는 SemVer 약속도 드러나지 않습니다.
이를 별도로 다루는 기능이 gca_macroless_args와 gca_macroless_items입니다. 전자는 상수 인자에서, 후자는 상수 항목 정의에서 gca!(...) 표기를 생략하게 합니다. 둘 다 매우 실험적이며 제대로 작동하지 않는 부분이 있어 현재는 명시적으로 매크로를 쓰는 편을 권합니다. 표기를 생략해도 gca!(...) 안에서 허용하는 표현식 제한은 그대로입니다.
안정화 계획
소개한 기능 가운데 안정화 준비가 끝난 것은 없습니다. RFC 설계를 제안할 수준까지 다듬는 데도 시간이 더 필요합니다. 프로젝트 그룹은 컴파일러 충돌이나 설계 문제, 원하는 코드를 작성하기 어려운 점을 이슈 트래커나 Zulip 채널로 알려 달라고 요청합니다.
Lobsters 반응
- @gspr — 예시와 같은 코드를 쓰게 되기를 정말 기다리고 있습니다. 특히
[S; T::N + U::N]같은 표현을 원했습니다. Const Generics가 처음 나왔을 때부터 바라던 기능입니다. - @goldstein — 조금 복잡하게 느껴지지만, 제네릭 매개변수에 따라 실제 계산을 하려면
gca_const_items만 가능한 기능인 것 같습니다. 다른 댓글에서 언급한[S; T::N + U::N]도gca!(...)안에서는 계산을 할 수 없으므로 이 기능이 필요합니다.gca_min_const_items의 사용 사례는 잘 모르겠습니다. 더 실용적인 예시가 있으면 좋겠습니다.
원문: Rust Blog / 번역·요약: Trawling