lowering: .n 은 슬라이스에게만 길이다

구조체도 필드를 n 이라 부를 수 있다. lowering 은 이름만 보고 슬라이스 길이
자리(포인터 다음 4바이트)를 읽어서, 그 자리에 있던 그럴듯한 숫자를 돌려주고
있었다. 체커는 제대로 필드로 풀고 있었으니 같은 함수 안에서 쓰기와 읽기가
어긋났다.

  Box{ room: ^[]mut u8, n: usize, m: usize }
  n 777 m 999   (전에는 n 12 -- room 의 길이)

배열/슬라이스/str 일 때만 길이로 읽는다. fieldn.fe 가 이것과, 옆의 슬라이스가
여전히 길이로 답하는 것을 함께 고정한다.

222/222, 30/30.
This commit is contained in:
2026-08-17 12:52:38 +09:00
parent e84f892147
commit abdb049d05
2 changed files with 58 additions and 3 deletions
+9 -3
View File
@@ -151,9 +151,15 @@ Slot lower_expr_core(Lower *L, FeNode *n)
return slot_place(fe_ir_at_temp(p, 0), it, ir_size(t));
}
/* `.n` is how many elements there are, which an array knows at
compile time and a slice carries beside its pointer. */
if (n->b && n->b->text && !strcmp(n->b->text, "n")) {
FeType *bt = n->a ? n->a->sem_type : 0;
compile time and a slice carries beside its pointer. Only for those:
a struct is free to have a field called `n`, and reading it as a
length would quietly hand back the wrong four bytes. */
if (n->b && n->b->text && !strcmp(n->b->text, "n") &&
n->a && n->a->sem_type &&
(n->a->sem_type->kind == FE_TYPE_ARRAY ||
n->a->sem_type->kind == FE_TYPE_SLICE ||
n->a->sem_type->kind == FE_TYPE_STR)) {
FeType *bt = n->a->sem_type;
Slot base;
if (bt && bt->kind == FE_TYPE_ARRAY)
return slot_value(fe_ir_const(L->m, L->b, FE_IR_I32,