Skip to content

Commit

Permalink
Prevent external instantiation of the nonexhaustive variants
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Jan 24, 2021
1 parent 1368867 commit 269b422
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ pub mod parsing {

#[cfg(feature = "full")]
impl private {
pub fn attrs(outer: Vec<Attribute>, inner: Vec<Attribute>) -> Vec<Attribute> {
pub(crate) fn attrs(outer: Vec<Attribute>, inner: Vec<Attribute>) -> Vec<Attribute> {
let mut attrs = outer;
attrs.extend(inner);
attrs
Expand Down
2 changes: 2 additions & 0 deletions src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ mod help {
pub type Bool = bool;
pub type Str = str;
}

pub struct private(pub(crate) ());
10 changes: 5 additions & 5 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ ast_enum_of_structs! {
// Expr::Yield(e) => {...}
//
// #[cfg(test)]
// Expr::__TestExhaustive => unimplemented!(),
// Expr::__TestExhaustive(_) => unimplemented!(),
// #[cfg(not(test))]
// _ => { /* some sane fallback */ }
// }
Expand All @@ -244,7 +244,7 @@ ast_enum_of_structs! {
// added, so that you can add code to handle it, but your library will
// continue to compile and work for downstream users in the interim.
#[doc(hidden)]
__TestExhaustive,
__TestExhaustive(crate::private),
}
}

Expand Down Expand Up @@ -823,7 +823,7 @@ impl Expr {
| Expr::TryBlock(ExprTryBlock { attrs, .. })
| Expr::Yield(ExprYield { attrs, .. }) => mem::replace(attrs, new),
Expr::Verbatim(_) => Vec::new(),
Expr::__TestExhaustive => unreachable!(),
Expr::__TestExhaustive(_) => unreachable!(),
}
}
}
Expand Down Expand Up @@ -2322,7 +2322,7 @@ pub(crate) mod parsing {
Pat::Type(_) => unreachable!(),
Pat::Verbatim(_) => {}
Pat::Wild(pat) => pat.attrs = attrs,
Pat::__TestExhaustive => unreachable!(),
Pat::__TestExhaustive(_) => unreachable!(),
}
Ok(pat)
}
Expand Down Expand Up @@ -2673,7 +2673,7 @@ pub(crate) mod parsing {
}
for part in float_repr.split('.') {
let index = crate::parse_str(part).map_err(|err| Error::new(float.span(), err))?;
let base = mem::replace(e, Expr::__TestExhaustive);
let base = mem::replace(e, Expr::__TestExhaustive(crate::private(())));
*e = Expr::Field(ExprField {
attrs: Vec::new(),
base: Box::new(base),
Expand Down
24 changes: 12 additions & 12 deletions src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ ast_enum_of_structs! {
// Item::Verbatim(e) => {...}
//
// #[cfg(test)]
// Item::__TestExhaustive => unimplemented!(),
// Item::__TestExhaustive(_) => unimplemented!(),
// #[cfg(not(test))]
// _ => { /* some sane fallback */ }
// }
Expand All @@ -91,7 +91,7 @@ ast_enum_of_structs! {
// added, so that you can add code to handle it, but your library will
// continue to compile and work for downstream users in the interim.
#[doc(hidden)]
__TestExhaustive,
__TestExhaustive(crate::private),
}
}

Expand Down Expand Up @@ -376,7 +376,7 @@ impl Item {
| Item::Macro(ItemMacro { attrs, .. })
| Item::Macro2(ItemMacro2 { attrs, .. }) => mem::replace(attrs, new),
Item::Verbatim(_) => Vec::new(),
Item::__TestExhaustive => unreachable!(),
Item::__TestExhaustive(_) => unreachable!(),
}
}
}
Expand Down Expand Up @@ -582,7 +582,7 @@ ast_enum_of_structs! {
// ForeignItem::Verbatim(e) => {...}
//
// #[cfg(test)]
// ForeignItem::__TestExhaustive => unimplemented!(),
// ForeignItem::__TestExhaustive(_) => unimplemented!(),
// #[cfg(not(test))]
// _ => { /* some sane fallback */ }
// }
Expand All @@ -592,7 +592,7 @@ ast_enum_of_structs! {
// added, so that you can add code to handle it, but your library will
// continue to compile and work for downstream users in the interim.
#[doc(hidden)]
__TestExhaustive,
__TestExhaustive(crate::private),
}
}

Expand Down Expand Up @@ -689,7 +689,7 @@ ast_enum_of_structs! {
// TraitItem::Verbatim(e) => {...}
//
// #[cfg(test)]
// TraitItem::__TestExhaustive => unimplemented!(),
// TraitItem::__TestExhaustive(_) => unimplemented!(),
// #[cfg(not(test))]
// _ => { /* some sane fallback */ }
// }
Expand All @@ -699,7 +699,7 @@ ast_enum_of_structs! {
// added, so that you can add code to handle it, but your library will
// continue to compile and work for downstream users in the interim.
#[doc(hidden)]
__TestExhaustive,
__TestExhaustive(crate::private),
}
}

Expand Down Expand Up @@ -798,7 +798,7 @@ ast_enum_of_structs! {
// ImplItem::Verbatim(e) => {...}
//
// #[cfg(test)]
// ImplItem::__TestExhaustive => unimplemented!(),
// ImplItem::__TestExhaustive(_) => unimplemented!(),
// #[cfg(not(test))]
// _ => { /* some sane fallback */ }
// }
Expand All @@ -808,7 +808,7 @@ ast_enum_of_structs! {
// added, so that you can add code to handle it, but your library will
// continue to compile and work for downstream users in the interim.
#[doc(hidden)]
__TestExhaustive,
__TestExhaustive(crate::private),
}
}

Expand Down Expand Up @@ -1771,7 +1771,7 @@ pub mod parsing {
ForeignItem::Type(item) => &mut item.attrs,
ForeignItem::Macro(item) => &mut item.attrs,
ForeignItem::Verbatim(_) => return Ok(item),
ForeignItem::__TestExhaustive => unreachable!(),
ForeignItem::__TestExhaustive(_) => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
Expand Down Expand Up @@ -2249,7 +2249,7 @@ pub mod parsing {
TraitItem::Method(item) => &mut item.attrs,
TraitItem::Type(item) => &mut item.attrs,
TraitItem::Macro(item) => &mut item.attrs,
TraitItem::Verbatim(_) | TraitItem::__TestExhaustive => unreachable!(),
TraitItem::Verbatim(_) | TraitItem::__TestExhaustive(_) => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
Expand Down Expand Up @@ -2580,7 +2580,7 @@ pub mod parsing {
ImplItem::Type(item) => &mut item.attrs,
ImplItem::Macro(item) => &mut item.attrs,
ImplItem::Verbatim(_) => return Ok(item),
ImplItem::__TestExhaustive => unreachable!(),
ImplItem::__TestExhaustive(_) => unreachable!(),
};
attrs.extend(item_attrs.drain(..));
*item_attrs = attrs;
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
// Syn types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/syn/1.0.59")]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![allow(non_camel_case_types)]
// Ignored clippy lints.
#![allow(
clippy::doc_markdown,
Expand Down Expand Up @@ -813,10 +814,9 @@ mod verbatim;
#[cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))]
mod print;

////////////////////////////////////////////////////////////////////////////////
use crate::__private::private;

#[allow(dead_code, non_camel_case_types)]
struct private;
////////////////////////////////////////////////////////////////////////////////

// https://github.com/rust-lang/rust/issues/62830
#[cfg(feature = "parsing")]
Expand Down
16 changes: 13 additions & 3 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ macro_rules! ast_enum_of_structs_impl {
$pub:ident $enum:ident $name:ident {
$(
$(#[$variant_attr:meta])*
$variant:ident $( ($member:ident) )*,
$variant:ident $( ($($member:ident)::+) )*,
)*
}

Expand All @@ -87,15 +87,15 @@ macro_rules! ast_enum_of_structs_impl {
check_keyword_matches!(enum $enum);

$($(
ast_enum_from_struct!($name::$variant, $member);
ast_enum_from_struct!($name::$variant, $($member)::+);
)*)*

#[cfg(feature = "printing")]
generate_to_tokens! {
$($remaining)*
()
tokens
$name { $($variant $($member)*,)* }
$name { $($variant $($($member)::+)*,)* }
}
};
}
Expand All @@ -104,6 +104,9 @@ macro_rules! ast_enum_from_struct {
// No From<TokenStream> for verbatim variants.
($name:ident::Verbatim, $member:ident) => {};

// No From<TokenStream> for private variants.
($name:ident::$variant:ident, crate::private) => {};

($name:ident::$variant:ident, $member:ident) => {
impl From<$member> for $name {
fn from(e: $member) -> $name {
Expand Down Expand Up @@ -131,6 +134,13 @@ macro_rules! generate_to_tokens {
);
};

(($($arms:tt)*) $tokens:ident $name:ident { $variant:ident crate::private, $($next:tt)*}) => {
generate_to_tokens!(
($($arms)* $name::$variant(_) => unreachable!(),)
$tokens $name { $($next)* }
);
};

(($($arms:tt)*) $tokens:ident $name:ident {}) => {
#[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ::quote::ToTokens for $name {
Expand Down
4 changes: 2 additions & 2 deletions src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ ast_enum_of_structs! {
// Pat::Wild(e) => {...}
//
// #[cfg(test)]
// Pat::__TestExhaustive => unimplemented!(),
// Pat::__TestExhaustive(_) => unimplemented!(),
// #[cfg(not(test))]
// _ => { /* some sane fallback */ }
// }
Expand All @@ -92,7 +92,7 @@ ast_enum_of_structs! {
// added, so that you can add code to handle it, but your library will
// continue to compile and work for downstream users in the interim.
#[doc(hidden)]
__TestExhaustive,
__TestExhaustive(crate::private),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ mod printing {
}

impl private {
pub fn print_path(tokens: &mut TokenStream, qself: &Option<QSelf>, path: &Path) {
pub(crate) fn print_path(tokens: &mut TokenStream, qself: &Option<QSelf>, path: &Path) {
let qself = match qself {
Some(qself) => qself,
None => {
Expand Down
4 changes: 2 additions & 2 deletions src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ ast_enum_of_structs! {
// Type::Verbatim(e) => {...}
//
// #[cfg(test)]
// Type::__TestExhaustive => unimplemented!(),
// Type::__TestExhaustive(_) => unimplemented!(),
// #[cfg(not(test))]
// _ => { /* some sane fallback */ }
// }
Expand All @@ -83,7 +83,7 @@ ast_enum_of_structs! {
// added, so that you can add code to handle it, but your library will
// continue to compile and work for downstream users in the interim.
#[doc(hidden)]
__TestExhaustive,
__TestExhaustive(crate::private),
}
}

Expand Down

0 comments on commit 269b422

Please sign in to comment.