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:
2026-08-17 16:10:44 +09:00
parent 1a368dc13f
commit d9bced830c
6 changed files with 68 additions and 0 deletions
+5
View File
@@ -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);
+16
View File
@@ -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))