Files
coolguy 32da64d7c1 GOAL P0-2: Name(args){...} 로 제네릭 인스턴스를 짓는다
Name{...} 과 binding.Name{...} 만 있고 호출 뒤의 { 를 아무도 받지 않았다.
그래서 타입 인자를 명시한 리터럴이 파싱되지 않았고, 제네릭의 인스턴스는
Self{...} 나 생성자 함수로만 만들 수 있었다.

파서는 호출 뒤의 { 를 struct 리터럴로 받고, 체커는 그것을 타입 표기와 똑같은
resolver 에 넘긴다 -- 같은 철자니 같은 답이어야 한다. { 의 애매함은 이미
Name{...} 에 있던 것과 같고 같은 guard 가 정리한다.

  hold.Cell(i32){ v: 7 }        다른 유닛의 제네릭
  hold.Handle(Node){ raw: 3 }   본문에서 T 를 안 쓰는 것
  Boxed(i32){ v: 9 }            이 유닛의 제네릭

미사용 타입 파라미터는 그대로 둔다. typed handle 이 바로 그 모양이고,
Handle(Node) 와 Handle(Kind) 가 실제로 다른 타입이라는 것은 badphant 가
거부로 고정한다.

233/233, 34/34.
2026-08-17 15:59:08 +09:00

39 lines
1.1 KiB
Plaintext

// EXIT:0
// OUTPUT:cell 7 41
// OUTPUT:handle 3 4 sum 7
// OUTPUT:local 9
unit main;
import std.io;
import hold;
struct Node { v: i32, }
struct Kind { v: i32, }
// A generic declared here, instantiated with an explicit argument below.
struct Boxed(T) {
v: T,
}
// Two instances of the same phantom generic are different nominal types, so
// this only accepts one of them.
fn only_node(h: hold.Handle(Node)) -> u32 { return h.raw; }
fn only_kind(h: hold.Handle(Kind)) -> u32 { return h.raw; }
fn main() -> i32 {
// `binding.Name(args){...}` -- a generic instance from another unit.
let a: hold.Cell(i32) = hold.Cell(i32){ v: 7 };
let b: hold.Cell(u8) = hold.Cell(u8){ v: 41 };
@print("cell {} {}\n", a.v, b.v);
let n: hold.Handle(Node) = hold.Handle(Node){ raw: 3 };
let k: hold.Handle(Kind) = hold.Handle(Kind){ raw: 4 };
@print("handle {} {} sum {}\n", only_node(n), only_kind(k),
only_node(n) + only_kind(k));
// `Name(args){...}` -- a generic declared in this unit.
let c: Boxed(i32) = Boxed(i32){ v: 9 };
@print("local {}\n", c.v);
return 0;
}