Skip to content

Commit c674335

Browse files
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?
2 parents c5c6e42 + 273930e commit c674335

File tree

2 files changed

+256
-0
lines changed

2 files changed

+256
-0
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// Copyright (c) 2015 Anders Kaseorg <[email protected]>
2+
3+
// Permission is hereby granted, free of charge, to any person obtaining
4+
// a copy of this software and associated documentation files (the
5+
// “Software”), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to
8+
// permit persons to whom the Software is furnished to do so, subject to
9+
// the following conditions:
10+
11+
// The above copyright notice and this permission notice shall be
12+
// included in all copies or substantial portions of the Software.
13+
14+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
15+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19+
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
23+
//! This crate exports a macro `enum_from_primitive!` that wraps an
24+
//! `enum` declaration and automatically adds an implementation of
25+
//! `num::FromPrimitive` (reexported here), to allow conversion from
26+
//! primitive integers to the enum. It therefore provides an
27+
//! alternative to the built-in `#[derive(FromPrimitive)]`, which
28+
//! requires the unstable `std::num::FromPrimitive` and is disabled in
29+
//! Rust 1.0.
30+
//!
31+
//! # Example
32+
//!
33+
//! ```
34+
//! #[macro_use] extern crate enum_primitive;
35+
//! extern crate num_traits;
36+
//! use num_traits::FromPrimitive;
37+
//!
38+
//! enum_from_primitive! {
39+
//! #[derive(Debug, PartialEq)]
40+
//! enum FooBar {
41+
//! Foo = 17,
42+
//! Bar = 42,
43+
//! Baz,
44+
//! }
45+
//! }
46+
//!
47+
//! fn main() {
48+
//! assert_eq!(FooBar::from_i32(17), Some(FooBar::Foo));
49+
//! assert_eq!(FooBar::from_i32(42), Some(FooBar::Bar));
50+
//! assert_eq!(FooBar::from_i32(43), Some(FooBar::Baz));
51+
//! assert_eq!(FooBar::from_i32(91), None);
52+
//! }
53+
//! ```
54+
55+
56+
pub mod num_traits {
57+
pub trait FromPrimitive: Sized {
58+
fn from_i64(n: i64) -> Option<Self>;
59+
fn from_u64(n: u64) -> Option<Self>;
60+
}
61+
}
62+
63+
pub use std::option::Option;
64+
pub use num_traits::FromPrimitive;
65+
66+
/// Helper macro for internal use by `enum_from_primitive!`.
67+
#[macro_export]
68+
macro_rules! enum_from_primitive_impl_ty {
69+
($meth:ident, $ty:ty, $name:ident, $( $variant:ident )*) => {
70+
#[allow(non_upper_case_globals, unused)]
71+
fn $meth(n: $ty) -> $crate::Option<Self> {
72+
$( if n == $name::$variant as $ty {
73+
$crate::Option::Some($name::$variant)
74+
} else )* {
75+
$crate::Option::None
76+
}
77+
}
78+
};
79+
}
80+
81+
/// Helper macro for internal use by `enum_from_primitive!`.
82+
#[macro_export]
83+
#[macro_use(enum_from_primitive_impl_ty)]
84+
macro_rules! enum_from_primitive_impl {
85+
($name:ident, $( $variant:ident )*) => {
86+
impl $crate::FromPrimitive for $name {
87+
enum_from_primitive_impl_ty! { from_i64, i64, $name, $( $variant )* }
88+
enum_from_primitive_impl_ty! { from_u64, u64, $name, $( $variant )* }
89+
}
90+
};
91+
}
92+
93+
/// Wrap this macro around an `enum` declaration to get an
94+
/// automatically generated implementation of `num::FromPrimitive`.
95+
#[macro_export]
96+
#[macro_use(enum_from_primitive_impl)]
97+
macro_rules! enum_from_primitive {
98+
(
99+
$( #[$enum_attr:meta] )*
100+
enum $name:ident {
101+
$( $( #[$variant_attr:meta] )* $variant:ident ),+
102+
$( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
103+
}
104+
) => {
105+
$( #[$enum_attr] )*
106+
enum $name {
107+
$( $( #[$variant_attr] )* $variant ),+
108+
$( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
109+
}
110+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
111+
};
112+
113+
(
114+
$( #[$enum_attr:meta] )*
115+
enum $name:ident {
116+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
117+
}
118+
) => {
119+
$( #[$enum_attr] )*
120+
enum $name {
121+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
122+
}
123+
enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
124+
};
125+
126+
(
127+
$( #[$enum_attr:meta] )*
128+
enum $name:ident {
129+
$( $( #[$variant_attr:meta] )* $variant:ident ),+
130+
$( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
131+
}
132+
) => {
133+
$( #[$enum_attr] )*
134+
enum $name {
135+
$( $( #[$variant_attr] )* $variant ),+
136+
$( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
137+
}
138+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
139+
};
140+
141+
(
142+
$( #[$enum_attr:meta] )*
143+
enum $name:ident {
144+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
145+
}
146+
) => {
147+
$( #[$enum_attr] )*
148+
enum $name {
149+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
150+
}
151+
enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
152+
};
153+
154+
(
155+
$( #[$enum_attr:meta] )*
156+
pub enum $name:ident {
157+
$( $( #[$variant_attr:meta] )* $variant:ident ),+
158+
$( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*
159+
}
160+
) => {
161+
$( #[$enum_attr] )*
162+
pub enum $name {
163+
$( $( #[$variant_attr] )* $variant ),+
164+
$( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*
165+
}
166+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
167+
};
168+
169+
(
170+
$( #[$enum_attr:meta] )*
171+
pub enum $name:ident {
172+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),*
173+
}
174+
) => {
175+
$( #[$enum_attr] )*
176+
pub enum $name {
177+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),*
178+
}
179+
enum_from_primitive_impl! { $name, $( $( $variant )+ )* }
180+
};
181+
182+
(
183+
$( #[$enum_attr:meta] )*
184+
pub enum $name:ident {
185+
$( $( #[$variant_attr:meta] )* $variant:ident ),+
186+
$( = $discriminator:expr, $( $( #[$variant_two_attr:meta] )* $variant_two:ident ),+ )*,
187+
}
188+
) => {
189+
$( #[$enum_attr] )*
190+
pub enum $name {
191+
$( $( #[$variant_attr] )* $variant ),+
192+
$( = $discriminator, $( $( #[$variant_two_attr] )* $variant_two ),+ )*,
193+
}
194+
enum_from_primitive_impl! { $name, $( $variant )+ $( $( $variant_two )+ )* }
195+
};
196+
197+
(
198+
$( #[$enum_attr:meta] )*
199+
pub enum $name:ident {
200+
$( $( $( #[$variant_attr:meta] )* $variant:ident ),+ = $discriminator:expr ),+,
201+
}
202+
) => {
203+
$( #[$enum_attr] )*
204+
pub enum $name {
205+
$( $( $( #[$variant_attr] )* $variant ),+ = $discriminator ),+,
206+
}
207+
enum_from_primitive_impl! { $name, $( $( $variant )+ )+ }
208+
};
209+
}
210+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ensure this code doesn't stack overflow
12+
// aux-build:enum_primitive.rs
13+
14+
#[macro_use] extern crate enum_primitive;
15+
16+
enum_from_primitive! {
17+
pub enum Test {
18+
A1,A2,A3,A4,A5,A6,
19+
B1,B2,B3,B4,B5,B6,
20+
C1,C2,C3,C4,C5,C6,
21+
D1,D2,D3,D4,D5,D6,
22+
E1,E2,E3,E4,E5,E6,
23+
F1,F2,F3,F4,F5,F6,
24+
G1,G2,G3,G4,G5,G6,
25+
H1,H2,H3,H4,H5,H6,
26+
I1,I2,I3,I4,I5,I6,
27+
J1,J2,J3,J4,J5,J6,
28+
K1,K2,K3,K4,K5,K6,
29+
L1,L2,L3,L4,L5,L6,
30+
M1,M2,M3,M4,M5,M6,
31+
N1,N2,N3,N4,N5,N6,
32+
O1,O2,O3,O4,O5,O6,
33+
P1,P2,P3,P4,P5,P6,
34+
Q1,Q2,Q3,Q4,Q5,Q6,
35+
R1,R2,R3,R4,R5,R6,
36+
S1,S2,S3,S4,S5,S6,
37+
T1,T2,T3,T4,T5,T6,
38+
U1,U2,U3,U4,U5,U6,
39+
V1,V2,V3,V4,V5,V6,
40+
W1,W2,W3,W4,W5,W6,
41+
X1,X2,X3,X4,X5,X6,
42+
Y1,Y2,Y3,Y4,Y5,Y6,
43+
Z1,Z2,Z3,Z4,Z5,Z6,
44+
}
45+
}
46+

0 commit comments

Comments
 (0)