spec: 완화했던 이동 규칙 둘을 명세에 넣는다
구현만 알고 있으면 둘 중 하나가 틀린 것이다. - 배타 대여를 호출에 넘기는 것은 재대여 -- 이미 §4.2 에 있었다. - 자기 drop 안의 부분 이동은 R7 예외다. 객체가 사라지는 중이라 drop 이 돌아간 뒤에 그 반쪽짜리 값을 읽을 코드가 없다. 다른 함수에는 예외가 없다. TODO 의 '판단을 기다리는 것' 이 비었다.
This commit is contained in:
@@ -280,6 +280,8 @@ x += 1; // OK — 여기서 r의 대여는 이미 끝났다
|
||||
|
||||
**R7 (참조 무효화와 부분 이동).** 참조 대상이 이동되거나 재대입되면 그 참조는 이후 사용 시 에러. own.c는 변수 단위 상태만 추적하므로 field/index/`.?` projection에서 비-Copy 소유값을 이동해 꺼내는 것은 금지한다. `mem.replace(&mut place, replacement)`로 유효한 대체값을 남기면서 꺼내야 한다. 배열의 선택적 소유 원소는 `?^T`로 두고 `mem.replace(&mut arr[i], null).?`로 꺼낸다. projection chain 자체(`p.?.^`, `s.field.x`)는 값을 소비하지 않는다.
|
||||
|
||||
이 금지에는 예외가 하나 있다. **타입 자신의 `drop` 안에서는 `self`의 projection에서 값을 꺼낼 수 있다.** 그 객체는 사라지는 중이고 `drop`이 돌아간 뒤에 그것을 읽을 수 있는 코드가 없으므로, R7이 막으려는 "뒤에 남은 반쪽짜리 값"이 생기지 않는다. 다른 함수에서는 예외가 없다.
|
||||
|
||||
**R8 (파생 반환).** 함수는 다음 두 경우에 한해 `&T`, `&mut T`, `[]T`, `[]mut T`와 이를 `?`로 감싼 타입을 반환할 수 있다.
|
||||
|
||||
**(a) 파라미터 파생.** 메서드는 파생 원본이 항상 참조성 `self`여야 한다. 다른 참조성 인자를 추가로 받을 수 있지만 반환값은 그 인자에서 파생될 수 없고 그 인자의 임시 대여는 문장 끝에 풀린다. 자유 함수는 참조성 파라미터(`&T`, `&mut T`, `[]T`, `[]mut T`)가 **정확히 하나**여야 한다. 두 경우 모두 반환값이 정해진 원본에서 파생됐음을 컴파일러가 함수 본문만 보고 확인한다. 파생은 슬라이싱, 인덱싱, 필드 접근, projection, `&`/`&mut` 취함과 다른 R8(a) 호출의 연쇄다. 반환의 가변성은 원본 이하여야 한다.
|
||||
|
||||
@@ -54,18 +54,6 @@ uv run python tests/exec.py 31/31 컴파일된 프로그램이 실제로
|
||||
|
||||
---
|
||||
|
||||
## 네 판단을 기다리는 것
|
||||
|
||||
세션 중에 **이동 규칙 두 곳을 완화**했다. R4(참조는 집합 저장소에 못 들어감)는
|
||||
건드리지 않았다.
|
||||
|
||||
| | 무엇 | 왜 | 대안 |
|
||||
|---|---|---|---|
|
||||
| 1 | `&mut T` 를 `&mut T` 파라미터에 넘기는 것은 이동이 아니라 **호출 동안의 재대여** | 없으면 배타 파라미터를 다시 넘기는 일이 함수당 한 번뿐이다. 렉서도 계산기도 이것 없이는 못 쓴다 | 되돌리면 재귀 하강 파서를 못 쓴다 |
|
||||
| 2 | 자기 `drop` 안에서는 필드를 꺼낼 수 있다 (R7 예외) | 객체가 사라지는 중이라 뒤에 남아 읽힐 것이 없다 | `drop(self: Self)` 로 값을 소비하게 바꾸면 R7 을 안 건드려도 된다 |
|
||||
|
||||
---
|
||||
|
||||
## 정해진 것
|
||||
|
||||
| | |
|
||||
@@ -79,6 +67,8 @@ uv run python tests/exec.py 31/31 컴파일된 프로그램이 실제로
|
||||
| 오류 코드 | `error.Name` 을 빌드 전체에서 모아 철자 순으로 1부터 |
|
||||
| 레지스터 | ebx·esi·edi 를 블록 안에 머무는 임시값에 준다. eax/ecx/edx 는 스크래치 |
|
||||
| 해제 | 소유자를 놓으면 그것이 가진 것도 놓는다 (R1). `drop` 을 부른 뒤 필드로 내려간다 — 그래서 `List`/`Arena`/`Map` 은 `drop` 이 없다 |
|
||||
| 배타 대여를 호출에 넘기기 | **이동이 아니라 호출 동안의 재대여** (SPEC §4.2, §5 R6). 없으면 배타 파라미터를 함수당 한 번만 넘길 수 있어 재귀 하강 파서를 못 쓴다 |
|
||||
| 자기 `drop` 안의 부분 이동 | **허용** (SPEC §5 R7 예외). 객체가 사라지는 중이라 뒤에 남아 읽힐 것이 없다 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user