//@ known-bug: #23707 //@ compile-flags: -Copt-level=0 --edition=2021 //@ only-x86_64 #![recursion_limit="2048"] use std::marker::PhantomData; use std::fmt; use std::fmt::Debug; pub struct Z( () ); pub struct S (PhantomData); pub trait Nat { fn sing() -> Self; fn get(&self) -> usize; } impl Nat for Z { fn sing() -> Z { Z( () ) } #[inline(always)] fn get(&self) -> usize { 0 } } impl Nat for S { fn sing() -> S { S::( PhantomData:: ) } #[inline(always)] fn get(&self) -> usize { let prd : T = Nat::sing(); 1 + prd.get() } } pub type N0 = Z; pub type N1 = S; pub type N2 = S; pub type N3 = S; pub type N4 = S; pub type N5 = S; pub struct Node(usize,PhantomData); impl Node { pub fn push(&self, c : usize) -> Node> { let Node(i,_) = *self; Node(10*i+c, PhantomData::>) } } impl Node> { pub fn pop(&self) -> (Node,usize) { let Node(i,_) = *self; (Node(i/10, PhantomData::), i-10*(i/10)) } } impl Debug for Node { fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result { let s : D = Nat::sing(); write!(f, "Node<{}>: i= {}", s.get(), self.0) } } pub trait Step { fn step(&self, usize) -> Self; } impl Step for Node { #[inline(always)] fn step(&self, n : usize) -> Node { println!("base case"); Node(n,PhantomData::) } } impl Step for Node> where Node : Step { #[inline(always)] fn step(&self, n : usize) -> Node> { println!("rec"); let (par,c) = self.pop(); let cnew = c+n; par.step(c).push(cnew) } } fn tst(ref p : &Node, c : usize) -> usize where Node : Step { let Node(i,_) = p.step(c); i } fn main() { let nd : Node = Node(555,PhantomData::); // overflow...core::marker::Size let Node(g,_) = tst(nd,1); // ok //let Node(g,_) = nd.step(1); println!("{:?}", g); }