about summary refs log tree commit diff
path: root/src/test/rustdoc
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2018-11-03 13:40:37 +0100
committerGitHub <noreply@github.com>2018-11-03 13:40:37 +0100
commitc674335ba352c526b75483856d33d6479c286f5d (patch)
tree94c688232b4326d84ff7001b80d3ad66d51844ca /src/test/rustdoc
parentc5c6e4239f1e8043e87859b4cdac322172cc4f73 (diff)
parent273930e59fff70b0e5b981a81e89b3007679bf66 (diff)
downloadrust-c674335ba352c526b75483856d33d6479c286f5d.tar.gz
rust-c674335ba352c526b75483856d33d6479c286f5d.zip
Rollup merge of #55568 - durka:rustdoc-big-enum, r=nikomatsakis
test that rustdoc doesn't overflow on a big enum

Adds a test to close #25295. The test case depended on `enum_primitive` so I just basically pulled its source into an auxiliary file, is that the right way to do it?
Diffstat (limited to 'src/test/rustdoc')
-rw-r--r--src/test/rustdoc/auxiliary/enum_primitive.rs210
-rw-r--r--src/test/rustdoc/no-stack-overflow-25295.rs46
2 files changed, 256 insertions, 0 deletions
diff --git a/src/test/rustdoc/auxiliary/enum_primitive.rs b/src/test/rustdoc/auxiliary/enum_primitive.rs
new file mode 100644
index 00000000000..c265ae44f0d
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/enum_primitive.rs
@@ -0,0 +1,210 @@
+// Copyright (c) 2015 Anders Kaseorg <andersk@mit.edu>
+
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// “Software”), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+//! This crate exports a macro `enum_from_primitive!` that wraps an
+//! `enum` declaration and automatically adds an implementation of
+//! `num::FromPrimitive` (reexported here), to allow conversion from
+//! primitive integers to the enum.  It therefore provides an
+//! alternative to the built-in `#[derive(FromPrimitive)]`, which
+//! requires the unstable `std::num::FromPrimitive` and is disabled in
+//! Rust 1.0.
+//!
+//! # Example
+//!
+//! ```
+//! #[macro_use] extern crate enum_primitive;
+//! extern crate num_traits;
+//! use num_traits::FromPrimitive;
+//!
+//! enum_from_primitive! {
+//! #[derive(Debug, PartialEq)]
+//! enum FooBar {
+//!     Foo = 17,
+//!     Bar = 42,
+//!     Baz,
+//! }
+//! }
+//!
+//! fn main() {
+//!     assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo));
+//!     assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar));
+//!     assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz));
+//!     assert_eq!(FooBar::from_i32(91), None);
+//! }
+//! ```
+
+
+pub mod num_traits {
+    pub trait FromPrimitive: Sized {
+        fn from_i64(n: i64) -> Option<Self>;
+        fn from_u64(n: u64) -> Option<Self>;
+    }
+}
+
+pub use std::option::Option;
+pub use num_traits::FromPrimitive;
+
+/// Helper macro for internal use by `enum_from_primitive!`.
+#[macro_export]
+macro_rules! enum_from_primitive_impl_ty {
+    ($meth:ident, $ty:ty, $name:ident, $( $variant:ident )*) => {
+        #[allow(non_upper_case_globals, unused)]
+        fn $meth(n: $ty) -> $crate::Option<Self> {
+            $( if n == $name::$variant as $ty {
+                $crate::Option::Some($name::$variant)
+            } else )* {
+                $crate::Option::None
+            }
+        }
+    };
+}
+
+/// Helper macro for internal use by `enum_from_primitive!`.
+#[macro_export]
+#[macro_use(enum_from_primitive_impl_ty)]
+macro_rules! enum_from_primitive_impl {
+    ($name:ident, $( $variant:ident )*) => {
+        impl $crate::FromPrimitive for $name {
+            enum_from_primitive_impl_ty! { from_i64, i64, $name, $( $variant )* }
+            enum_from_primitive_impl_ty! { from_u64, u64, $name, $( $variant )* }
+        }
+    };
+}
+
+/// Wrap this macro around an `enum` declaration to get an
+/// automatically generated implementation of `num::FromPrimitive`.
+#[macro_export]
+#[macro_use(enum_from_primitive_impl)]
+macro_rules! enum_from_primitive {
+    (
+        $( #[$enum_attr:meta] )*
+        enum $name:ident {
+            $( $( #[$variant_attr:meta] )* $variant:ident ),+
+            $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        enum $name {
+            $( $( #[$variant_attr] )* $variant ),+
+            $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
+        }
+        enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+    };
+
+    (
+        $( #[$enum_attr:meta] )*
+        enum $name:ident {
+            $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        enum $name {
+            $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
+        }
+        enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
+    };
+
+    (
+        $( #[$enum_attr:meta] )*
+        enum $name:ident {
+            $( $( #[$variant_attr:meta] )* $variant:ident ),+
+            $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        enum $name {
+            $( $( #[$variant_attr] )* $variant ),+
+            $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
+        }
+        enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+    };
+
+    (
+        $( #[$enum_attr:meta] )*
+        enum $name:ident {
+            $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        enum $name {
+            $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
+        }
+        enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
+    };
+
+    (
+        $( #[$enum_attr:meta] )*
+        pub enum $name:ident {
+            $( $( #[$variant_attr:meta] )* $variant:ident ),+
+            $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        pub enum $name {
+            $( $( #[$variant_attr] )* $variant ),+
+            $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
+        }
+        enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+    };
+
+    (
+        $( #[$enum_attr:meta] )*
+        pub enum $name:ident {
+            $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        pub enum $name {
+            $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
+        }
+        enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
+    };
+
+    (
+        $( #[$enum_attr:meta] )*
+        pub enum $name:ident {
+            $( $( #[$variant_attr:meta] )* $variant:ident ),+
+            $( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        pub enum $name {
+            $( $( #[$variant_attr] )* $variant ),+
+            $( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
+        }
+        enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
+    };
+
+    (
+        $( #[$enum_attr:meta] )*
+        pub enum $name:ident {
+            $( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
+        }
+    ) => {
+        $( #[$enum_attr] )*
+        pub enum $name {
+            $( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
+        }
+        enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
+    };
+}
+
diff --git a/src/test/rustdoc/no-stack-overflow-25295.rs b/src/test/rustdoc/no-stack-overflow-25295.rs
new file mode 100644
index 00000000000..37b0aca4b00
--- /dev/null
+++ b/src/test/rustdoc/no-stack-overflow-25295.rs
@@ -0,0 +1,46 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ensure this code doesn't stack overflow
+// aux-build:enum_primitive.rs
+
+#[macro_use] extern crate enum_primitive;
+
+enum_from_primitive! {
+    pub enum Test {
+        A1,A2,A3,A4,A5,A6,
+        B1,B2,B3,B4,B5,B6,
+        C1,C2,C3,C4,C5,C6,
+        D1,D2,D3,D4,D5,D6,
+        E1,E2,E3,E4,E5,E6,
+        F1,F2,F3,F4,F5,F6,
+        G1,G2,G3,G4,G5,G6,
+        H1,H2,H3,H4,H5,H6,
+        I1,I2,I3,I4,I5,I6,
+        J1,J2,J3,J4,J5,J6,
+        K1,K2,K3,K4,K5,K6,
+        L1,L2,L3,L4,L5,L6,
+        M1,M2,M3,M4,M5,M6,
+        N1,N2,N3,N4,N5,N6,
+        O1,O2,O3,O4,O5,O6,
+        P1,P2,P3,P4,P5,P6,
+        Q1,Q2,Q3,Q4,Q5,Q6,
+        R1,R2,R3,R4,R5,R6,
+        S1,S2,S3,S4,S5,S6,
+        T1,T2,T3,T4,T5,T6,
+        U1,U2,U3,U4,U5,U6,
+        V1,V2,V3,V4,V5,V6,
+        W1,W2,W3,W4,W5,W6,
+        X1,X2,X3,X4,X5,X6,
+        Y1,Y2,Y3,Y4,Y5,Y6,
+        Z1,Z2,Z3,Z4,Z5,Z6,
+    }
+}
+