// 11. exhaustiveness 검사기가 거부해야 하는 코드 // // 철학 1의 대표 항목이자, interface hash가 enum 정의 본문을 입력으로 삼는 이유다. // upstream에 variant가 하나 늘면 downstream의 match가 깨져야 하는데, // 이 검사가 없으면 깨질 것이 없다. pub enum Shape { Circle(Int), Rect(Int, Int), Point, } // --- 통과해야 하는 것 --- pub fn area(s: Shape) -> Int { match s { Circle(r) => r * r, Rect(w, h) => w * h, Point => 0, } } pub fn with_wildcard(s: Shape) -> Int { match s { Circle(r) => r, _ => 0, } } pub fn nested_full(o: Option[Shape]) -> Int { match o { Some(Circle(r)) => r, Some(Rect(w, h)) => w * h, Some(Point) => 0, None => 0, } } pub fn results(r: Result[Int, Int]) -> Int { match r { Ok(n) => n, Err(e) => e, } } pub fn flags(b: Bool) -> Int { match b { true => 1, false => 0, } } // --- 여기서부터 전부 오류다 --- // [E-match-missing] variant 하나가 빠졌다 pub fn missing_variant(s: Shape) -> Int { match s { Circle(r) => r, Rect(w, h) => w * h, } } // [E-match-missing] Bool도 생성자 집합이 유한하다 pub fn missing_false(b: Bool) -> Int { match b { true => 1, } } // [E-match-missing] Option pub fn missing_none(o: Option[Int]) -> Int { match o { Some(n) => n, } } // [E-match-missing] 중첩된 자리에서 빠진 경우도 찾는다 pub fn missing_nested(o: Option[Shape]) -> Int { match o { Some(Circle(r)) => r, None => 0, } } // [E-match-missing] Int 리터럴은 생성자 집합이 무한하다 pub fn missing_literal(n: Int) -> Int { match n { 0 => 1, 1 => 2, } } // [E-match-unreachable] 앞의 와일드카드에 가린다 pub fn shadowed(s: Shape) -> Int { match s { _ => 0, Point => 1, } } // [E-match-unreachable] 같은 생성자가 두 번 pub fn duplicated(s: Shape) -> Int { match s { Circle(r) => r, Circle(x) => x, _ => 0, } }