Skip to content

Commit

Permalink
Rollup merge of rust-lang#55568 - durka:rustdoc-big-enum, r=nikomatsakis
Browse files Browse the repository at this point in the history
test that rustdoc doesn't overflow on a big enum

Adds a test to close rust-lang#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?
  • Loading branch information
GuillaumeGomez authored Nov 3, 2018
2 parents c5c6e42 + 273930e commit c674335
Show file tree
Hide file tree
Showing 2 changed files with 256 additions and 0 deletions.
210 changes: 210 additions & 0 deletions src/test/rustdoc/auxiliary/enum_primitive.rs
Original file line number Diff line number Diff line change
@@ -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 )+ )+ }
};
}

46 changes: 46 additions & 0 deletions src/test/rustdoc/no-stack-overflow-25295.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}

0 comments on commit c674335

Please sign in to comment.