rokdocs
v0.1

0.4. #[lang] 슬롯 매핑 표

#[lang(slot_name)] 속성(refs-lang 6.4) 은 표준 라이브러리 항목을 컴파일러가 lookup 할 수 있는 슬롯 에 등록합니다. 이 장은 모든 슬롯 이름과 그 의미, 그리고 부착 대상 항목을 표 형태로 정리하여 한 자리에 모아 둡니다.

slot 표는 spec 의 권위 있는 자리이며, 컴파일러와 표준 라이브러리, 그리고 사용자가 모두 이 표를 참조하여 일관성을 유지합니다. 슬롯 이름이 흔들리면 언어와 라이브러리 사이의 약속이 무너지기 때문에, 변경은 본 표에서부터 시작합니다.

0.4.1. slot 분류

먼저 전체 48 개 슬롯이 어떤 책임을 지느냐에 따라 네 그룹으로 나뉩니다. 아래 표는 각 그룹의 역할과 슬롯 수를 한눈에 보여 주며, 이후 절들의 세부 표가 어떤 카테고리에 속하는지 가늠하게 합니다.

그룹책임slot 수
타입rok 이 구체 타입 으로 인식하는 표준 라이브러리 타입14
트레잇rok 이 operator / 제어 흐름 desugar, derive, 스레드 경계 검사에 쓰는 트레잇30
메서드rok 이 자동 호출 하는 메서드 (drop)1
함수rok 이 intrinsic 호출 로 부르는 표준 라이브러리 함수3
합계48

0.4.2. 타입 슬롯 (14)

타입 슬롯은 컴파일러가 리터럴이나 키워드를 만났을 때 lower 시킬 구체 타입을 가리키는 자리입니다. 이 그룹은 다시 두 부류로 나뉘는데, 먼저 lowercase 식별자로 곧장 노출되는 언어 기본값 타입들이 있습니다. 이들은 키워드 등록이 따로 필요하지 않으며, 사용자가 매일 마주치는 primitive 들에 해당합니다.

언어 기본값 (lowercase struct, #[keyword] 불필요):

slot 이름의미표준 라이브러리 항목참조
i32_typei32 primitiverok::core::num::i322.1
i64_typei64 primitiverok::core::num::i642.1
f32_typef32 primitiverok::core::num::f322.1
f64_typef64 primitiverok::core::num::f642.1
usize_typeusize primitiverok::core::num::usize2.1
isize_typeisize primitiverok::core::num::isize2.1
bool_typebool primitiverok::core::num::bool2.1
cchar_typec_char primitive (FFI)rok::core::str::c_char2.15
str_typestr primitive (UTF-8 view)rok::core::str::str2.15
char_typechar primitive (Unicode scalar)char (메서드: rok::core::str)2.15

다음으로 표준 라이브러리가 추가로 제공하는 PascalCase 타입들이 있습니다. 이쪽은 #[keyword(...)] 로 사용자에게 익숙한 소문자 별칭을 따로 노출하는데, int 와 float 의 auto-promote, none sentinel, Range 리터럴 같이 언어 문법과 직접 얽힌 항목들이 여기에 모입니다.

표준 라이브러리 추가 (PascalCase struct + #[keyword(...)]):

slot 이름의미표준 라이브러리 항목참조
none_typenone 리터럴의 타입rok::core::marker::NoneSentinel2.13
int_typeint auto-promote 타입rok::core::num::Int + #[keyword("int")]2.1
float_typefloat auto-promote 타입rok::core::num::Float + #[keyword("float")]2.1
range_typeRange<T> (a..b)rok::core::range::Range + #[literal( expr ".." expr )]2.7

기본 타입을 내장으로 제공하는 컴파일러는 i32_type ... str_type, none_type, char_type 을 붙이지 않은 채 둘 수 있습니다.

0.4.3. 트레잇 슬롯 (30)

트레잇 슬롯은 사용자가 작성한 문법이 표준 라이브러리 트레잇 호출로 desugar 될 때 컴파일러가 어떤 트레잇을 찾아갈지 가리키는 자리입니다. for 루프나 인덱싱, 슬라이싱, 포맷, await 같은 핵심 문법이 모두 여기 등록된 트레잇을 통해 풀려나가므로, 이 표는 언어 문법과 라이브러리 사이의 가장 굵은 다리에 해당합니다.

slot 이름의미표준 라이브러리 트레잇참조
iterator_traitfor x in xs 의 단계 진행rok::core::iter::Iterator2.7
into_iterator_traitfor x in xs 의 시작rok::core::iter::IntoIterator2.7
index_traitarr[i] 읽기rok::core::ops::Index2.3
index_set_traitarr[i] = v 쓰기rok::core::ops::IndexSet2.3
slice_traits[1:3] 슬라이싱rok::core::ops::Sliceable2.3
display_traitf"{x}" 기본 포맷rok::core::fmt::Display2.10
debug_traitf"{x:?}" 디버그 포맷rok::core::fmt::Debug2.10
future_traitawait expr 의 단계 진행rok::core::future::Future2.20

다음으로 연산자 트레잇 슬롯이 있습니다. 연산자 토큰의 dispatch 대상은 각 트레잇 메서드에 부착된 #[infix] / #[prefix] (refs-lang 6.7) 가 결정하고 우선순위는 refs-lang 3.2 표가 고정하며, 아래 슬롯은 컴파일러가 primitive lowering 과 진단에서 "덧셈 트레잇", "비교 트레잇" 을 이름으로 찾을 수 있게 하는 고정 자리입니다. 복합 대입 (AddAssign 등, 2.4), broadcast (DotAdd 등, 2.6), floored modulo (Modulo, %%) 트레잇은 #[infix] 등록만으로 충분하므로 슬롯을 두지 않습니다.

slot 이름의미표준 라이브러리 트레잇참조
add_traita + brok::core::ops::Add2.3
sub_traita - brok::core::ops::Sub2.3
mul_traita * brok::core::ops::Mul2.3
div_traita / brok::core::ops::Div2.3
rem_traita % brok::core::ops::Rem2.3
neg_trait-a (전위)rok::core::ops::Neg2.3
not_trait!arok::core::ops::Not2.3
bitnot_trait~arok::core::ops::BitNot2.3
bitand_traita & brok::core::ops::BitAnd2.3
bitor_traita | brok::core::ops::BitOr2.3
bitxor_traita ^ brok::core::ops::BitXor2.3
shl_traita << brok::core::ops::Shl2.3
shr_traita >> brok::core::ops::Shr2.3
logical_and_traita && brok::core::ops::LogicalAnd2.3
logical_or_traita || brok::core::ops::LogicalOr2.3
eq_trait== / !=, literal 패턴rok::core::cmp::PartialEq2.5
cmp_trait< / > / <= / >=, range 패턴rok::core::cmp::PartialOrd2.5
ord_trait완전 순서 (#[derive(Ord)])rok::core::cmp::Ord2.5
hash_trait해시 (#[derive(Hash)])rok::core::cmp::Hash2.5
clone_trait복제 (#[derive(Clone)])rok::core::marker::Clone2.13
send_trait자동 marker - 스레드 이동 안전rok::core::marker::Send2.13
sync_trait자동 marker - 스레드 공유 안전rok::core::marker::Sync2.13

참고

비교 슬롯의 이름과 트레잇 이름은 일대일로 겹치지 않습니다. eq_trait 는 동등 연산자를 정의하는 PartialEq 에, cmp_trait 는 순서 비교 연산자를 정의하는 PartialOrd 에 부착됩니다. marker 트레잇 Eq, Copy, Default 에는 슬롯이 없습니다: 합 타입이 이들을 구조적으로 얻으므로 (T 가 Eq 이면 T | none 도 Eq, 그 Default 는 none), 컴파일러는 rok::core 의 고정 경로로 이들을 찾습니다.

0.4.4. 함수 슬롯 (3)

함수 슬롯은 컴파일러가 intrinsic 처럼 직접 호출하는 표준 라이브러리 함수의 자리입니다. 주로 비정상 종료 경로 - throw, OOM, 도달 불가 - 가 여기 모이며, 정상 흐름이 아닌 곳에서 통일된 진입점이 필요할 때 이 슬롯들이 쓰입니다.

slot 이름의미표준 라이브러리 함수참조
panic_fnpanic 시 호출하는 abort 함수rok::core::panic::panic2.14
oom_fnOOM abort (런타임 할당 실패는 rok_oom 직접)rok::core::panic::oom2.14
unreachable_fn컴파일러가 unreachable 자리 호출rok::core::panic::unreachable2.14

0.4.5. 메서드 슬롯 (1)

메서드 슬롯은 사용자가 명시적으로 적지 않아도 컴파일러가 자동으로 부르는 메서드의 자리입니다. using 바인딩 해제 시의 폐기 하나뿐입니다. ? 연산자는 T | none 에 대해 컴파일러가 직접 풀어 쓰므로 (refs-lang 3.14.10) 메서드 슬롯을 두지 않습니다. 값의 복제 (Clone::clone) 는 자동으로 호출되지 않으므로 (2.13.2) 메서드 슬롯이 아니라 트레잇 슬롯 clone_trait 로 등록됩니다.

slot 이름의미표준 라이브러리 메서드참조
drop_methodusing 블록 해제 시 호출rok::core::marker::Drop::drop2.13

0.4.6. 슬롯 사용 측, 컴파일러의 lookup 위치

앞 절들이 "어떤 슬롯이 존재하는가" 를 나열했다면, 이번 절은 거꾸로 "컴파일러가 언제 어떤 슬롯을 찾는가" 를 정리합니다. 사용자가 작성한 문법 한 줄이 표준 라이브러리의 어떤 항목으로 풀려나가는지 추적하고 싶을 때, 다음 표가 출발점이 됩니다.

컴파일러 동작lookup 슬롯
none 리터럴 lowernone_type
42 (기대 타입 없음) literal typei32_type
3.14 (기대 타입 없음) literal typef64_type
"hello" literal typestr_type
for x in xs desugarinto_iterator_trait, iterator_trait
arr[i] desugarindex_trait
arr[i] = v desugarindex_set_trait
s[1:3] desugarslice_trait
f"{x}" 기본 자리 desugardisplay_trait
f"{x:?}" desugardebug_trait
await expr desugarfuture_trait
산술 / 비트 / 논리 연산자 primitive loweringadd_trait ... logical_or_trait
== / !=, literal 패턴 매칭eq_trait
< / > / <= / >=, range 패턴 매칭cmp_trait
#[derive(Clone / Ord / Hash)] 확장clone_trait, ord_trait, hash_trait
panic (try! 실패 포함) lowerpanic_fn
OOM 발생 시oom_fn
match 모든 arm exhaustive 체크 unreachableunreachable_fn
using 블록 해제drop_method
Send / Sync 자동 구현, + Send 검사send_trait, sync_trait

0.4.7. 중복 / 누락 검출

같은 슬롯에 두 표준 라이브러리 항목이 부착되면 컴파일러가 이를 거부합니다(refs-lang 6.4.6 의 중복 검출 규칙). 반대로 필수 슬롯, 예컨대 iterator_trait 가 누락되면 그 슬롯에 의존하는 기능, 곧 for 루프의 컴파일이 거부됩니다. 양쪽 모두 슬롯이라는 약속이 단 하나의 진실을 갖도록 강제하는 장치입니다.

실제 부착 항목은 200-core/ 의 각 장에 명시됩니다. 본 표의 모든 슬롯은 "참조" 열이 가리키는 장에 #[lang(...)] 부착 위치를 가집니다. 이 표에 없는 슬롯 이름은 refs-lang 6.4.8 에 따라 컴파일 에러입니다 - 예컨대 Stream 은 슬롯을 두지 않습니다 (2.8.10).

0.4.8. 슬롯 이름 정책

마지막으로 새 슬롯을 추가하거나 기존 이름을 바꿀 때 따라야 할 명명 규칙을 정리해 둡니다. 일관된 이름은 표를 훑는 것만으로 슬롯의 종류를 짐작하게 해 주므로, 정책을 가볍게 보지 않습니다.

이름은 snake_case 로 적고, type 슬롯에는 _type 접미사를, trait 슬롯에는 _trait 접미사를 붙입니다. function 슬롯에는 _fn 접미사가 따라오며, method 슬롯에는 _method 접미사가 붙습니다 (drop_method). 트레잇 전체를 가리키는 슬롯은 컴파일러가 그 트레잇의 여러 메서드나 derive 를 다루더라도 _trait 하나로 통일하며, 메서드 슬롯은 컴파일러가 특정 메서드 하나를 자동 호출 하는 경우로 한정합니다. 이 기준에 따라 Clone 은 clone_method 가 아닌 clone_trait 로 등록됩니다. 접미사는 부착 위치도 결정합니다. _trait 슬롯은 트레잇 선언 자체 에, _method 슬롯은 트레잇 안의 해당 메서드 에, _type 슬롯은 타입 선언에, _fn 슬롯은 함수 선언에 부착하며, 다른 위치에 부착하면 refs-lang 6.4.7 의 시그니처 검사에서 거부됩니다.

GitHub에서 이 페이지 고치기