diff --git a/src/test/rustdoc/issue-52873.rs b/src/test/rustdoc/issue-52873.rs new file mode 100644 index 00000000000..9138dd50def --- /dev/null +++ b/src/test/rustdoc/issue-52873.rs @@ -0,0 +1,171 @@ +// 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 { + unsafe { ::std::mem::uninitialized() } + } +} + +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 { + unsafe { ::std::mem::uninitialized() } + } +} + +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>; +}