대여는 변수가 아니라 place 단위다
p.a 와 p.b 는 서로 다른 자리인데 한쪽을 대여하면 다른 쪽까지 잠겼다. 메서드가
하는 일의 대부분이 한 필드에 쓰면서 다른 필드를 읽는 것이라, std.map 의 keep 은
그것 때문에 함수 둘로 갈라져 있었고 파서도 같은 자리에서 걸렸다.
FeOwnState 가 필드별 칸을 넷 갖는다. 값으로 복사되는 구조체라 흐름 병합과
스냅샷은 손댈 것이 없었다. 전체를 대여하면 모든 필드와 충돌하고, 필드를
대여하면 전체 및 같은 필드와 충돌한다. 칸이 모자라면 전체 대여로 되돌아가
더 많이 보고할 뿐 놓치지 않는다.
읽기는 식별자에서 일어나는데 그 자리에서는 자기가 무엇의 밑동인지 알 수 없다.
그래서 투영이 내려가는 길에 어느 필드인지 적어두고 식별자가 그것을 집는다.
인덱스는 갈라지지 않는다 -- xs[i] 의 i 는 상수가 아닐 수 있고, 필드 이름은
상수다.
길에서 나온 것: mem.replace 가 목적지 대여를 가져가고 돌려주지 않았다. 일반
호출 인자는 문장 끝에 돌려주는데 intrinsic 경로에만 그것이 없었다. 전에는
그 자리가 어차피 거부돼서 드러나지 않았다.
var p = Pair{ a: 1, b: 2 };
let r = &mut p.a;
p.b = 3; // ok -- 전에는 에러
p.a = 3; // 에러
take(p); // 에러
SPEC §5 R6 을 고쳤고, 옛 규칙을 그대로 적어둔 문단과 예제를 갈아치웠다.
own/badrfld 는 이제 허용되는 코드였으므로 같은 필드를 건드리도록 다시 겨눴고
okrfld·badrall·badrsame·exec/fieldbrw 를 더했다.
228/228, 32/32.
This commit is contained in:
@@ -30,6 +30,8 @@ struct FeSym {
|
||||
release the root borrow without a separate alias engine. */
|
||||
FeOwnState own;
|
||||
FeSym *borrow_root;
|
||||
/* Which field of the root this binding borrowed, or null for all of it. */
|
||||
const char *borrow_field;
|
||||
int borrow_mut;
|
||||
int borrow_defer;
|
||||
FeScope *owner;
|
||||
@@ -52,6 +54,11 @@ typedef struct FeCheckerState {
|
||||
unsigned defer_depth;
|
||||
FeOwnLiveness liveness;
|
||||
FeNode *fn_node;
|
||||
/* While a projection is being checked, which field of which base it
|
||||
reaches. The read happens down at the identifier, which cannot see the
|
||||
chain above it, so the chain leaves word here on the way down. */
|
||||
const char *proj_field;
|
||||
FeNode *proj_base;
|
||||
} FeCheckerState;
|
||||
|
||||
/* The type bindings in force, saved across a nested instantiation. */
|
||||
@@ -70,6 +77,7 @@ typedef struct FeFlowSlot {
|
||||
|
||||
typedef struct FeFlowBorrow {
|
||||
FeSym *root;
|
||||
const char *field;
|
||||
int mutable;
|
||||
} FeFlowBorrow;
|
||||
|
||||
@@ -114,6 +122,7 @@ void flow_restore(FeFlowSlot *slots, unsigned count);
|
||||
void flow_merge(FeFlowSlot *base, FeFlowSlot *left, FeFlowSlot *right,
|
||||
unsigned count);
|
||||
FeSym *own_root_symbol(FeCheckerState *s, FeNode *expr);
|
||||
const char *own_projected_field(FeNode *expr, FeNode **root_out);
|
||||
int own_is_global(FeCheckerState *s, FeSym *sym);
|
||||
void own_borrow_expr(FeCheckerState *s, FeNode *expr, int mutable);
|
||||
void own_release_temporary_borrow(FeCheckerState *s, FeNode *expr);
|
||||
|
||||
Reference in New Issue
Block a user