제한

제한 (Limits)

컴파일 타임에 깊이 제한 없이 재귀를 허용하면, 매크로 확장이나 타입 치환이 끝없이 늘어나는 상황이 생겨요. Rust는 이런 무한 재귀를 막기 위해 컴파일 타임 한계를 정해 두고, 그 값을 속성으로 조절할 수 있게 합니다. 여기서 그 두 속성을 살펴볼게요.

출처: Rust Reference

다음 속성들이 컴파일 타임 한계에 영향을 줍니다.

recursion_limit 속성

recursion_limit 속성 은 크레이트(crate) 레벨에 적용해, 매크로 확장이나 auto-dereference처럼 잠재적으로 무한히 재귀할 수 있는 컴파일 타임 연산의 최대 깊이를 설정합니다.

재귀 깊이를 지정할 때는 MetaNameValueStr 문법을 사용합니다.

참고 rustc에서의 기본값은 128입니다.

#![allow(unused)]
#![recursion_limit = "4"]

fn main() {
macro_rules! a {
    () => { a!(1); };
    (1) => { a!(2); };
    (2) => { a!(3); };
    (3) => { a!(4); };
    (4) => { };
}

// This fails to expand because it requires a recursion depth greater than 4.
a!{}
}
#![allow(unused)]
#![recursion_limit = "1"]

fn main() {
// This fails because it requires two recursive steps to auto-dereference.
(|_: &u8| {})(&&&1);
}

type_length_limit 속성

type_length_limit 속성 은 단일화(monomorphization) 과정에서 구체 타입(concrete type)을 만들 때 허용되는 타입 치환의 최대 횟수를 설정합니다.

참고 rustc는 nightly의 -Zenforce-type-length-limit 플래그가 활성화되어 있을 때만 이 한계를 강제합니다. 자세한 내용은 Rust PR #127670을 참고하세요.

예시 ignore: not enforced without nightly flag #![type_length_limit = "4"]

fn f(x: T) {}

// This fails to compile because monomorphizing to // f::<((((i32,), i32), i32), i32)> requires more // than 4 type elements. f(((((1,), 2), 3), 4));

참고 rustc에서의 기본값은 1048576입니다.

type_length_limit 속성은 MetaNameValueStr 문법을 사용합니다. 문자열 안의 값은 반드시 음이 아닌 숫자여야 합니다.

type_length_limit 속성은 크레이트 루트에만 적용할 수 있습니다.

참고 rustc는 다른 위치에서의 사용을 무시하되 lint로 경고합니다. 이는 향후 에러가 될 수 있습니다.

한 아이템에서 type_length_limit를 여러 번 쓰더라도 첫 번째 사용만 효과가 있습니다.

참고 rustc는 첫 번째 이후의 모든 사용에 대해 lint 경고를 냅니다. 이는 향후 에러가 될 수 있습니다.

더 알아보기 (Learn more)