Rust QC
이 스킬은 Rust 코드에 대한 하나의 표준을 설정하고 세 가지 모드로 적용합니다. 규칙은 Rust 스타일 가이드, Rust API 가이드라인, Microsoft의 실용적인 Rust 가이드라인(2026.6), Google의 Rust 스타일 가이드, 그리고 memchr, jiff, ripgrep, fd, dua-cli에서 볼 수 있는 관행에서 비롯됩니다. 이러한 출처가 불일치하는 경우, references/precedence.md에서 결정 사항을 기록하여 다시 논의할 필요가 없도록 합니다.
1단계: 컨텍스트 확립 (모든 모드)
코드를 작성하거나 평가하기 전에 이 작업을 수행하십시오. 전제 조건이 실패하면 중지하고 보고하십시오. 누락된 툴체인이나 매니페스트에 대해 추측하지 마십시오.
- 크레이트 루트(가장 가까운
Cargo.toml)를 찾으십시오. 워크스페이스인지, 라이브러리인지, 바이너리인지, 또는 둘 다인지, 그리고 게시되었는지(publish = false이거나 워크스페이스 내에서만 사용되거나 FFI를 통해 내부적으로 사용됨을 의미) 확인하십시오. - 프로젝트 자체 규칙을 먼저 읽으십시오. 이 규칙은 이 스킬의 기본값을 재정의합니다:
rustfmt.toml또는.rustfmt.toml,clippy.toml,Cargo.toml의[lints]및[workspace.lints],edition,rust-version(MSRV),rust-toolchain.toml,CONTRIBUTING.md,AGENTS.md또는CLAUDE.md, 그리고AI_POLICY.md.AI_POLICY.md또는CONTRIBUTING.md가 AI 또는 에이전트 기여를 제한하는 경우, 해당 저장소를 위한 변경 사항을 생성하기 전에 사용자에게 알리십시오. - 코드를 라이브러리 또는 애플리케이션으로 분류하십시오. API 설계 규칙은 라이브러리에 바인딩되며 애플리케이션에는 강력히 권장됩니다. 애플리케이션은 일반성보다 직접성을 선호해야 합니다.
- 플랫폼을 확인하십시오.
rust-toolchain.toml이 대상을 나열하거나 코드가 이 호스트 이외의 플랫폼에 대한#[cfg(windows)]스타일 게이트로 가득한 경우,--target <triple>을 사용하여 게이트도 실행하십시오(해당 대상에 대해 린트 및 문서화합니다. 테스트는 건너뜁니다). 플랫폼 게이트로 인해 호스트에서만 나타나는 죽은 코드와 같은 경고는 호스트 아티팩트이므로 발견 사항이 아닙니다. scripts/check.sh <crate-root>를 한 번 실행하여 기준을 기록하십시오. 기존 부채와 자신의 회귀를 구별하는 데 필요합니다. 크레이트에 상호 배타적인 기능이 있는 경우 기본--all-features대신--features "<list>"를 사용하십시오.
사용자가 요청하지 않는 한 툴체인, 구성 요소 또는 도구(야간, Miri, cargo-hack)를 설치하지 말고 크레이트를 가져오는 것 이상으로 네트워크를 사용하지 마십시오. 검사에 필요한 항목이 누락된 경우 그렇게 말하고 권장하십시오.
2단계: 모드 선택
생성(Create) 모드는 사용자가 새로운 함수, 메서드, 타입, 모듈 또는 크레이트를 원할 때 사용합니다. 아래의 "코드 생성"을 따르십시오.
수정(Modify) 모드는 사용자가 기존 코드를 변경하기를 원할 때 사용합니다: 기능, 개선, 버그 수정, 리팩터링 또는 감사 결과의 수정. 아래의 "코드 수정"을 따르십시오.
감사(Audit) 모드는 사용자가 기존 코드를 검토, 평가 또는 확인하고 문제를 식별하고 수정을 제안하기를 원할 때 사용합니다. 아래의 "코드 감사"를 따르십시오. 감사는 사용자가 요청하지 않는 한 코드를 변경하지 않습니다. 발견 사항을 생성합니다.
요청은 여러 모드에 걸쳐 있을 수 있습니다("이 모듈을 감사하고 발견한 것을 수정하십시오"). 먼저 감사를 실행하고 보고한 다음, 수정을 위해 모드로 전환하십시오.
불가침 규칙
이 규칙은 모든 모드에 적용됩니다. 전체 규칙 집합(ID 포함)은 마지막에 나열된 참조 파일에 있습니다.
- 포맷팅은 rustfmt의 몫입니다. rustfmt에 반대하여 수동으로 포맷팅하지 마십시오. 의도적인 정렬(표, 행렬) 또는 생성된 코드를 제외하고
#[rustfmt::skip]을 추가하지 마십시오. - 코드는 건전합니다. 안전한 코드는 정의되지 않은 동작을 유발할 수 없습니다. 모든
unsafe블록에는 각 전제 조건이 유지되는 이유를 설명하는// SAFETY:주석이 바로 위에 있습니다. 모든unsafe fn및unsafe trait에는# Safety문서 섹션이 있습니다.unsafe는 FFI, 벤치마킹된 성능 필요 또는 새로운 추상화에만 사용하고,Send,Sync또는 수명을 우회하는 데는 절대 사용하지 마십시오.references/unsafe.md를 참조하십시오. - 오류 대 패닉. 입력 또는 환경으로 인해 발생하는 복구 가능한 실패는
Result를 반환합니다(또는 원인이 명백한 경우Option). 감지된 프로그래밍 버그는 패닉을 발생시킵니다. 라이브러리 코드는 합리적으로 유효하지 않을 수 있는 호출자 입력에 대해 패닉을 발생시키지 않습니다.references/errors.md를 참조하십시오. - 라이브러리 오류는 호출자가 텍스트를 구문 분석하지 않고 분기할 수 있도록 합니다. 공개
#[non_exhaustive]열거형 또는is_*()조건자를 반환하는kind()가 있는 구체적인 오류 유형. 비공개 필드가 적절합니다. 접근자가 없는 비공개 종류는 결함입니다. 메시지는 문제가 되는 토큰과 위치를 가리키며 전체 입력을 복사하지 않습니다. - 프로덕션 코드에는
unwrap()을 사용하지 마십시오.?, 패턴 매칭, 또는 불변성이 유지되는 이유를 명시하는expect("...")를 사용하십시오.unwrap()은 테스트에서 괜찮습니다. 문서 예제는 숨겨진# Ok::<(), Box<dyn std::error::Error>>(())줄과 함께?를 사용합니다. - 모든 새 종속성에는 비용이 따르며, 개발 종속성도 포함됩니다. 실제 복잡성을 제거하거나 합리적으로 작성할 수 없는 정확성을 제공하는 경우에만 추가하십시오(유니코드 케이스 폴딩은 좋은 이유입니다. 100줄 파서를 위한 속성 테스트 프레임워크는 그렇지 않습니다). 보고서에 그 이유를 명시하십시오.
- 구조는 크기와 일치해야 합니다. 하나의 작은 함수와 해당 오류 유형을 위해 모듈을 만들지 마십시오. 모듈은 고유한 개념과 여러 항목 또는 몇 백 줄로 파일을 정당화합니다.
- 린트 재정의는
#[expect(lint, reason = "...")]를 사용하고#[allow]를 사용하지 않으므로 오래된 재정의가 표면화됩니다. - 공개 항목은 문서화되어야 하며, 첫 번째 문장은 약 15단어의 한 줄이어야 하며, 함수에는 해당되는 경우
# Errors,# Panics및# Safety섹션이 포함되어야 합니다.references/documentation.md를 참조하십시오. - 공개 유형은
Debug를 구현합니다. 사람이 읽도록 의도된 유형은Display도 구현합니다. - 주석은 이유를 설명하고, 무엇을 설명하지 않습니다. 주석이 코드를 다시 설명하는 경우 삭제하십시오.
crates/core/main.rs에 있는 ripgrep의 할당자 주석이 모델입니다: 결정, 이유 및 적용되는 조건. - 주석이나 문서에 ASCII 아트 다이어그램이나 상자 그리기 문자를 사용하지 마십시오. 구조를 문장으로 설명하십시오. 그림은 화면 읽기 프로그램으로 읽을 수 없으며 코드가 변경되면 썩습니다. (팀 규칙, 상류가 아님)
- 문서에 설계 저널 내용을 포함하지 마십시오. 문서는 현재 동작을 설명하고, 코드가 어떻게 만들어졌는지 또는 어떤 지침을 따랐는지 설명하지 않습니다.
- 테스트는 동작을 검증합니다. 상수를 다시 설명하거나 구현 분기를 미러링하는 테스트는 없습니다.
코드 생성
외부에서 내부로 작업하십시오: 타입과 시그니처를 먼저, 그다음 문서, 그다음 구현, 그다음 테스트. 본문 전에 문서 주석을 작성하는 것은 혼란스러운 API를 발견하는 가장 빠른 방법입니다.
- 배치하십시오. 항목을 해당 개념을 소유하는 모듈에 넣으십시오. 작은 크레이트에서는 종종
lib.rs입니다. 새 모듈은 기본 유형의 이름을 따서 명명되며 코드가 정당화될 때만 생성됩니다(ORG-19).references/organization.md를 참조하십시오. - 타입으로 모델링하십시오. 혼동하기 쉽거나 불변성을 전달하는 값에 대한 Newtype. 호출 사이트에서 의미가 명확하지 않은
bool매개변수 대신enum. 튜플보다 명명된 필드를 사용하십시오. 유효하지 않은 상태를 표현 불가능하게 만드십시오. - 시그니처를 형성하십시오. 읽기만 하는 것은 빌리십시오(
&str,&[T],&Path,Option<&T>), 저장하거나 소비할 때만 소유권을 가지십시오. 라이브러리에서는 마찰을 제거하는 경우impl AsRef<Path>또는impl IntoIterator를 수락하십시오. 애플리케이션에서는 구체적인 유형을 유지하십시오. 여러 선택적 설정이 있는 유형에 대한 빌더,build()에서 유효성 검사.references/api-design.md를 참조하십시오. - 이름을 지정하십시오. RFC 430 케이스 사용;
as_/to_/into_변환;new,with_*,try_new생성자;foo()게터. 모호한 단어(Manager,Service,Factory,Helper,Util)를 사용하지 말고 동일한 인터페이스에서 기존 의미와 충돌하는 이름을 사용하지 마십시오(NAME-9). references/documentation.md에 따라 문서화하십시오. 공개 항목에 대한 실행 가능한 예제와 반환하는 위치 또는 길이의 단위를 포함하십시오.- 구현하십시오. 단일 목적 함수. 조건문이나 외부 상태가 필요한 조합기 체인에 대한 일반
for루프. 추론이 독자를 추측하게 하는 경우 유형 주석. 사람이 읽는 텍스트는 유니코드 인식 처리를 받습니다: 대소문자 구분 없는 일치는 유니코드 케이스 폴딩을 사용하거나 그 한계를 문서화합니다(API-27). references/errors.md에 따라 오류를 처리하십시오: 라이브러리에서는 공개 종류 또는 조건자가 있는 구체적인 오류 유형; 애플리케이션에서는.context()와 함께anyhow.references/testing.md에 따라 테스트하십시오: 인라인 단위 테스트,tests/아래의 통합 테스트, 새 종속성이 필요 없는 광범위한 불변성 검사(짧은 입력 열거 또는 기본 참조에 대한 시드 루프).- 아래 게이트로 확인하십시오.
코드 수정
목표는 건드린 코드를 찾았을 때보다 최소한 명확하게 만드는 가장 작은 정확한 변경입니다.
- 편집하기 전에 읽으십시오. 전체 함수, 호출자, 테스트 및 주변 API를 읽으십시오. 로컬 규칙(가져오기 스타일, 오류 유형, 문서 제목 스타일(예:
# Example대# Examples), 줄 너비, 밀도, 매개변수 및 키 이름)을 식별하고 이 스킬의 기본값과 다른 경우에도 일치시키십시오. - 버그 수정은 버그 클래스를 다루는 실패하는 테스트로 시작합니다. 보고된 입력을 재현한 다음, 동일한 근본 원인이 깨뜨리는 인접 사례(더 많은 요소, 다른 순서, 조합)를 추가하십시오. 실패하는 것을 보고, 근본 원인을 수정하고, 통과하는 것을 확인하십시오. 프로젝트가 회귀 테스트를 한 곳(ripgrep의
tests/regression.rs)에 보관하는 경우 거기에 추가하십시오. - 증상이 아닌 원인을 수정하십시오. 실패를 무음으로 만드는 새로운
unwrap_or_default(),clone()또는 조기 반환은 원래 경로가 왜 잘못되었는지 설명할 수 없는 경우 수정이 아닙니다. 이유가 코드에서 명확하지 않은 경우 수정 사항에 한 줄 주석을 추가하십시오. - 수술 범위를 좁게 유지하십시오. 요청받지 않은 코드의 이름을 바꾸거나, 재정렬하거나, 포맷을 변경하지 마십시오. 관련 없는 문제를 사용자에게 나열하되 조용히 수정하지 마십시오.
- 사용자가 주요 변경을 승인하지 않는 한 공개 API 및 ABI를 안정적으로 유지하십시오. 공개 필드가 있는 공개 구조체에 필드 추가, 완전한 공개 열거형에 변형 추가, 필수 특성 메서드 추가 또는 FFI 계약 변경은 주요 변경입니다.
- 코드와 함께 문서 및 테스트를 업데이트하십시오. 변경된 시그니처 또는 동작은 동일한 변경에서
# Errors,# Panics, 예제 및 테스트가 변경되었음을 의미합니다. - 포맷팅: 기준이 rustfmt-clean인 경우
cargo fmt를 실행하십시오. 그렇지 않은 경우 변경한 부분만 포맷하고 사용자에게 알리십시오.rustfmt.toml이 야간 전용 옵션(안정적인 rustfmt는 "야간 채널에서만 사용 가능"이라고 경고)을 사용하는 경우 프로젝트 표준은cargo +nightly fmt입니다. 설치된 경우 사용하고, 그렇지 않으면 자동으로 포맷하지 말고 그렇게 말하십시오. 안정적인 rustfmt는 프로젝트 설정에 반대하여 코드를 다시 작성하기 때문입니다. - 감사 결과 수정: 심각도 순서로 발견 사항을 수정하고, 논리적 변경당 하나의 발견 사항을 수정하고, 요약에서 발견 사항의 이름을 지정하십시오.
- 아래 게이트로 확인하고 1단계에서 확인한 모든 대상에 대해 기준과 비교하여 새로운 경고가 도입되지 않았는지 확인하십시오.
코드 감사
-
scripts/check.sh --audit <crate-root>를 실행하십시오(1단계당--target추가).--audit패스는 공개 API 도달 가능성, 문서화되지 않은unsafe, 누락된 문서 및# Errors/# Panics섹션, 테스트 외부의unwrap, 이유 없는#[allow],dbg!/todo!, 글로브 가져오기, 메시지 없는 어설션을 보고합니다. 이러한 위생 결과를 간결하게 보고하십시오: 카테고리당 하나의 사소한(Minor) 발견 사항(문서,Debug, SAFETY 주석, 린트 구성), 각각 개수와 가장 중요한 몇 가지 인스턴스가 있습니다. 게이트 단계가 여기 툴체인이 프로젝트의 CI 또는rust-toolchain.toml이 사용하는 것보다 최신이기 때문에만 실패하는 경우 툴체인 드리프트입니다: 하나의 사소한 발견 사항, 주요(Major) 발견 사항이 아닙니다. -
clippy가 볼 수 없는 것을 위해
python3 -I scripts/audit_scan.py <crate-root>를 실행하십시오: 글로브 재내보내기, 모호한 단어 유형 이름, ASCII 아트 주석, 설계 기록 문서, 매개변수 테이블, 베어 TODO, 빈expect메시지, 라이브러리 코드의 print 매크로. 코드를 읽어 각 적중을 확인하고 거짓 긍정을 폐기하십시오. -
사용자가 만나는 방식으로 동작을 조사하십시오. 이것이 실제 크레이트에서 대부분의 사용자 대면 버그가 발견되는 곳이므로 감사의 대부분을 여기와 5단계에서 보내십시오. 크레이트의 문서, 사양 및 테스트를 읽어 처리한다고 주장하는 입력 기능을 나열하십시오. 각 기능에 대해 기존 테스트가 다루지 않는 작고 현실적인 입력을 만들고, 워크스페이스 외부의 임시 크레이트에서 공개 API를 통해 실행하고, 사용자가 얻어야 하는 것과 출력을 비교하십시오. 형식이 허용하지만 픽스처가 건너뛰는 기능을 다루십시오:
- 상속, 간접 또는 기본값
- 중복
- 선택적 또는 숨겨진 부분
- 다른 도구가 허용하는 경미한 손상
- 비ASCII 텍스트 및 레거시 인코딩
- 크지만 합법적인 크기
각 확인된 문제를 보여주는 입력과 함께 보고하십시오.
-
신뢰할 수 없는 입력을 활용하십시오. 신뢰할 수 없는 바이트 또는 텍스트를 구문 분석하는 모든 공개 함수에 대해 관련 알파벳에 대한 모든 짧은 입력 또는 수백만 개의 시드 무작위 변형을 공급하고 패닉을 잡으십시오. 또한 입력 크기보다 빠르게 작업을 증가시키는 제작된 구조(공유 또는 재귀 참조, 깊은 중첩)를 시간 제한 하에 시도하십시오.
-
도구가 판단할 수 없는 코드를 읽으십시오: 각
unsafe블록의 건전성, 오류 설계, API 형태, 모듈 경계, 명명, 테스트 품질, 주석이 이유를 설명하는지 여부. 운영 체제와 통신하는 코드에서는 다음도 확인하십시오:- 시스템 호출, I/O 또는 환경 실패에 대한 패닉(반환 값에 대한
assert!또는unwrap, 비UTF-8 환경 변수 또는 passwd 필드) fork와exec사이의 코드(pre_exec클로저) 또는 할당, 잠금, 포맷, 로깅 또는 종료하는 신호 처리기(이 중 어느 것도 async-signal-safe가 아님)- 유출된 파일 디스크립터 또는 핸들, 그리고 회수되어 재사용되었을 수 있는 프로세스 ID로 전송된 신호
- 크기, 개수 및 좌표에 대한 좁히기 캐스트 및 확인되지 않은 산술
references/audit-checklist.md를 사용하십시오. - 시스템 호출, I/O 또는 환경 실패에 대한 패닉(반환 값에 대한
-
아래 형식을 사용하여 보고하십시오. 모든 발견 사항에 대한 구체적인 수정 사항을 제안하십시오.
1단계와 2단계는 감사가 아닌 빠른 바닥입니다: 시간의 약 5분의 1 이상을 소비하지 마십시오. 대부분 린트, 문서 및 s
...
[truncated for translation]