GOAL P1-4: 작은 규칙 일곱을 정하고, 어긋난 둘을 고친다
일곱 중 다섯은 구현이 이미 옳게 답하고 있었다 -- match 는 enum 전용이고,
enum payload 에 소유 타입을 담을 수 있고, undefined 배열은 원소 단위로
추적하지 않고, 다른 유닛에서 private 필드가 있는 리터럴은 거부되고,
by-value self 의 부분 이동도 mem.replace 가 필요하다. SPEC §7.9 에 적었다.
나머지 둘은 그냥 통과하고 있었다.
defer { return 1; } 이 받아들여졌다. 지연 블록은 함수가 무엇을 반환할지 이미
정한 뒤 스코프 정리 중에 도는데 거기서 return 이 뜻할 것이 없다.
for x in xs { xs[0] = 9; } 도 받아들여졌다. x 가 xs 안을 가리키는 참조이니
순회 몸통에서 xs 에 쓰는 것은 그 참조가 가리키는 것을 옮기는 일이다 (R6).
순회는 이제 도는 동안 대여한다. 읽기는 공유 순회에서 그대로 된다.
240/240, 35/35.
This commit is contained in:
@@ -986,6 +986,11 @@ void check_stmt(FeCheckerState *s, FeNode *n)
|
||||
m7_check_match_stmt(s,n);
|
||||
break;
|
||||
case FE_N_RETURN:
|
||||
/* A deferred block runs during scope cleanup, on the way out of a
|
||||
function that has already decided what it returns. There is nothing
|
||||
for a `return` in there to mean. */
|
||||
if (s->defer_depth != 0)
|
||||
err(s->c, n->loc, "cannot return from inside defer");
|
||||
expected=s->ret;
|
||||
if (n->a)
|
||||
stored=m7_check_expected(s,n->a,expected);
|
||||
|
||||
@@ -101,7 +101,18 @@ void check_for(FeCheckerState *s, FeNode *n)
|
||||
item_cname,n);
|
||||
n->cname=item_cname;
|
||||
}
|
||||
/* Walking a container borrows it for the length of the walk: the
|
||||
item is a reference into it, so writing the container underneath
|
||||
would move what that reference points at (SPEC 5 R6). */
|
||||
if (iter_sym)
|
||||
fe_own_access(s->c->diags,&iter_sym->own,
|
||||
iter_mut ? FE_OWN_BORROW_MUT : FE_OWN_BORROW_SHARED,
|
||||
n->loc);
|
||||
check_stmt(s,n->b);
|
||||
if (iter_sym) {
|
||||
if (iter_mut) fe_own_release_exclusive(&iter_sym->own);
|
||||
else fe_own_release_shared(&iter_sym->own);
|
||||
}
|
||||
s->scope=old;
|
||||
return;
|
||||
}
|
||||
@@ -459,6 +470,11 @@ void check_stmt_core(FeCheckerState *s, FeNode *n)
|
||||
if (!s->loop_depth) err(c,n->loc,"break or continue outside loop");
|
||||
break;
|
||||
case FE_N_RETURN:
|
||||
/* A deferred block runs during scope cleanup, on the way out of a
|
||||
function that has already decided what it returns. There is nothing
|
||||
for a `return` in there to mean. */
|
||||
if (s->defer_depth != 0)
|
||||
err(c, n->loc, "cannot return from inside defer");
|
||||
b = n->a ? check_expr(s, n->a) : fe_type_intern(&c->types, "void");
|
||||
if (s->ret && fe_own_is_reference_like(s->ret) &&
|
||||
!own_return_from_allowed_root(s,n->a))
|
||||
|
||||
Reference in New Issue
Block a user