// check-pass // https://github.com/rust-lang/rust/issues/52873 #![crate_name="foo"] // Regression test for #52873. We used to ICE due to unexpected // overflows when checking for "blanket impl inclusion". use std::marker::PhantomData; use std::cmp::Ordering; use std::ops::{Add, Mul}; pub type True = B1; pub type False = B0; pub type U0 = UTerm; pub type U1 = UInt; pub trait NonZero {} pub trait Bit { } pub trait Unsigned { } #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] pub struct B0; impl B0 { #[inline] pub fn new() -> B0 { B0 } } #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] pub struct B1; impl B1 { #[inline] pub fn new() -> B1 { B1 } } impl Bit for B0 { } impl Bit for B1 { } impl NonZero for B1 {} pub trait PrivatePow { type Output; } pub type PrivatePowOut = >::Output; pub type Add1 = >::Output; pub type Prod = >::Output; pub type Square = ::Output; pub type Sum = >::Output; #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] pub struct UTerm; impl UTerm { #[inline] pub fn new() -> UTerm { UTerm } } impl Unsigned for UTerm { } #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, Default)] pub struct UInt { _marker: PhantomData<(U, B)>, } impl UInt { #[inline] pub fn new() -> UInt { UInt { _marker: PhantomData, } } } impl Unsigned for UInt { } impl NonZero for UInt {} impl Add for UTerm { type Output = UTerm; fn add(self, _: B0) -> Self::Output { UTerm } } impl Add for UInt { type Output = UInt; fn add(self, _: B0) -> Self::Output { UInt::new() } } impl Add for UTerm { type Output = U; fn add(self, _: U) -> Self::Output { unimplemented!() } } impl Mul for UInt { type Output = UTerm; fn mul(self, _: B0) -> Self::Output { UTerm } } impl Mul for UInt { type Output = UInt; fn mul(self, _: B1) -> Self::Output { UInt::new() } } impl Mul for UTerm { type Output = UTerm; fn mul(self, _: U) -> Self::Output { UTerm } } impl Mul> for UInt where Ul: Mul>, { type Output = UInt>, B0>; fn mul(self, _: UInt) -> Self::Output { unimplemented!() } } pub trait Pow { type Output; } impl Pow for X where X: PrivatePow, { type Output = PrivatePowOut; } impl PrivatePow for X { type Output = Y; } impl PrivatePow for X where X: Mul, { type Output = Prod; } impl PrivatePow, B0>> for X where X: Mul, Square: PrivatePow>, { type Output = PrivatePowOut, Y, UInt>; }