diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ebf7161687..83d99c3a31 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,6 +74,16 @@ jobs: - run: cargo check --manifest-path examples/lazy-static/example/Cargo.toml - run: cargo check --manifest-path examples/trace-var/example/Cargo.toml + docs: + name: Docs + runs-on: ubuntu-latest + env: + RUSTDOCFLAGS: --cfg=doc_cfg -Dbroken_intra_doc_links + steps: + - uses: actions/checkout@v2 + - uses: dtolnay/rust-toolchain@nightly + - run: cargo doc --all-features + codegen: name: Codegen runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index 0e17af4f5a..12c810422d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "syn" -version = "1.0.48" # don't forget to update html_root_url and syn.json +version = "1.0.55" # don't forget to update html_root_url and syn.json authors = ["David Tolnay "] license = "MIT OR Apache-2.0" description = "Parser for Rust source code" @@ -48,7 +48,7 @@ ref-cast = "1.0" regex = "1.0" reqwest = { version = "0.10", features = ["blocking"] } syn-test-suite = { version = "0", path = "tests/features" } -tar = "0.4" +tar = "0.4.16" termcolor = "1.0" walkdir = "2.1" @@ -64,6 +64,7 @@ required-features = ["full", "parsing"] [package.metadata.docs.rs] all-features = true targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = ["--cfg", "doc_cfg"] [package.metadata.playground] features = ["full", "visit", "visit-mut", "fold", "extra-traits"] diff --git a/codegen/src/clone.rs b/codegen/src/clone.rs index 979ef0bd47..e5bcea1b81 100644 --- a/codegen/src/clone.rs +++ b/codegen/src/clone.rs @@ -82,8 +82,10 @@ fn expand_impl(defs: &Definitions, node: &Node) -> TokenStream { if copy { return quote! { #cfg_features + #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))] impl Copy for #ident {} #cfg_features + #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))] impl Clone for #ident { fn clone(&self) -> Self { *self @@ -96,6 +98,7 @@ fn expand_impl(defs: &Definitions, node: &Node) -> TokenStream { quote! { #cfg_features + #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))] impl Clone for #ident { fn clone(&self) -> Self { #body diff --git a/codegen/src/debug.rs b/codegen/src/debug.rs index d5db1c3ddb..74c8412889 100644 --- a/codegen/src/debug.rs +++ b/codegen/src/debug.rs @@ -81,6 +81,7 @@ fn expand_impl(defs: &Definitions, node: &Node) -> TokenStream { quote! { #cfg_features + #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl Debug for #ident { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { #body diff --git a/codegen/src/eq.rs b/codegen/src/eq.rs index 2cfee39b44..a40700e008 100644 --- a/codegen/src/eq.rs +++ b/codegen/src/eq.rs @@ -113,6 +113,7 @@ fn expand_impl(defs: &Definitions, node: &Node) -> TokenStream { let eq = quote! { #cfg_features + #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl Eq for #ident {} }; @@ -132,6 +133,7 @@ fn expand_impl(defs: &Definitions, node: &Node) -> TokenStream { #eq #cfg_features + #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl PartialEq for #ident { fn eq(&self, #other: &Self) -> bool { #body diff --git a/codegen/src/hash.rs b/codegen/src/hash.rs index 81e44b41a1..a0d04d95ed 100644 --- a/codegen/src/hash.rs +++ b/codegen/src/hash.rs @@ -131,6 +131,7 @@ fn expand_impl(defs: &Definitions, node: &Node) -> TokenStream { quote! { #cfg_features + #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] impl Hash for #ident { fn hash(&self, #state: &mut H) where diff --git a/src/attr.rs b/src/attr.rs index ea6ab09d1b..1d82190ea1 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -144,6 +144,7 @@ ast_struct! { /// }; /// assert_eq!(doc, attr); /// ``` + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct Attribute { pub pound_token: Token![#], pub style: AttrStyle, @@ -160,6 +161,7 @@ impl Attribute { /// *This function is available only if Syn is built with the `"parsing"` /// feature.* #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn parse_meta(&self) -> Result { fn clone_ident_segment(segment: &PathSegment) -> PathSegment { PathSegment { @@ -207,6 +209,7 @@ impl Attribute { /// *This function is available only if Syn is built with the `"parsing"` /// feature.* #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn parse_args(&self) -> Result { self.parse_args_with(T::parse) } @@ -216,6 +219,7 @@ impl Attribute { /// *This function is available only if Syn is built with the `"parsing"` /// feature.* #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn parse_args_with(&self, parser: F) -> Result { let parser = |input: ParseStream| { let args = enter_args(self, input)?; @@ -229,6 +233,7 @@ impl Attribute { /// *This function is available only if Syn is built with the `"parsing"` /// feature.* #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn parse_outer(input: ParseStream) -> Result> { let mut attrs = Vec::new(); while input.peek(Token![#]) { @@ -242,6 +247,7 @@ impl Attribute { /// *This function is available only if Syn is built with the `"parsing"` /// feature.* #[cfg(feature = "parsing")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn parse_inner(input: ParseStream) -> Result> { let mut attrs = Vec::new(); while input.peek(Token![#]) && input.peek2(Token![!]) { @@ -321,6 +327,7 @@ ast_enum! { /// - `#![feature(proc_macro)]` /// - `//! # Example` /// - `/*! Please file an issue */` + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum AttrStyle { Outer, Inner(Token![!]), @@ -350,10 +357,8 @@ ast_enum_of_structs! { /// /// This type is a [syntax tree enum]. /// - /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums - // - // TODO: change syntax-tree-enum link to an intra rustdoc link, currently - // blocked on https://github.com/rust-lang/rust/issues/62833 + /// [syntax tree enum]: Expr#syntax-tree-enums + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum Meta { Path(Path), @@ -370,6 +375,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct MetaList { pub path: Path, pub paren_token: token::Paren, @@ -382,6 +388,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct MetaNameValue { pub path: Path, pub eq_token: Token![=], @@ -408,6 +415,7 @@ ast_enum_of_structs! { /// /// *This type is available only if Syn is built with the `"derive"` or `"full"` /// feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum NestedMeta { /// A structured meta item, like the `Copy` in `#[derive(Copy)]` which /// would be a nested `Meta::Path`. @@ -453,6 +461,7 @@ ast_enum_of_structs! { /// # "".parse().unwrap() /// } /// ``` +#[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub type AttributeArgs = Vec; pub trait FilterAttrs<'a> { @@ -553,6 +562,7 @@ pub mod parsing { }) } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for Meta { fn parse(input: ParseStream) -> Result { let path = input.call(parse_meta_path)?; @@ -560,6 +570,7 @@ pub mod parsing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for MetaList { fn parse(input: ParseStream) -> Result { let path = input.call(parse_meta_path)?; @@ -567,6 +578,7 @@ pub mod parsing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for MetaNameValue { fn parse(input: ParseStream) -> Result { let path = input.call(parse_meta_path)?; @@ -574,6 +586,7 @@ pub mod parsing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for NestedMeta { fn parse(input: ParseStream) -> Result { if input.peek(Lit) && !(input.peek(LitBool) && input.peek2(Token![=])) { @@ -622,6 +635,7 @@ mod printing { use proc_macro2::TokenStream; use quote::ToTokens; + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for Attribute { fn to_tokens(&self, tokens: &mut TokenStream) { self.pound_token.to_tokens(tokens); @@ -635,6 +649,7 @@ mod printing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for MetaList { fn to_tokens(&self, tokens: &mut TokenStream) { self.path.to_tokens(tokens); @@ -644,6 +659,7 @@ mod printing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for MetaNameValue { fn to_tokens(&self, tokens: &mut TokenStream) { self.path.to_tokens(tokens); diff --git a/src/data.rs b/src/data.rs index bb6a854f44..731f5a0a7e 100644 --- a/src/data.rs +++ b/src/data.rs @@ -6,6 +6,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or `"full"` /// feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct Variant { /// Attributes tagged on the variant. pub attrs: Vec, @@ -31,10 +32,8 @@ ast_enum_of_structs! { /// /// This type is a [syntax tree enum]. /// - /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums - // - // TODO: change syntax-tree-enum link to an intra rustdoc link, currently - // blocked on https://github.com/rust-lang/rust/issues/62833 + /// [syntax tree enum]: Expr#syntax-tree-enums + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum Fields { /// Named fields of a struct or struct variant such as `Point { x: f64, /// y: f64 }`. @@ -54,6 +53,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct FieldsNamed { pub brace_token: token::Brace, pub named: Punctuated, @@ -65,6 +65,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct FieldsUnnamed { pub paren_token: token::Paren, pub unnamed: Punctuated, @@ -149,6 +150,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or `"full"` /// feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct Field { /// Attributes tagged on the field. pub attrs: Vec, @@ -179,10 +181,8 @@ ast_enum_of_structs! { /// /// This type is a [syntax tree enum]. /// - /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums - // - // TODO: change syntax-tree-enum link to an intra rustdoc link, currently - // blocked on https://github.com/rust-lang/rust/issues/62833 + /// [syntax tree enum]: Expr#syntax-tree-enums + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum Visibility { /// A public visibility level: `pub`. Public(VisPublic), @@ -204,6 +204,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct VisPublic { pub pub_token: Token![pub], } @@ -214,6 +215,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct VisCrate { pub crate_token: Token![crate], } @@ -225,6 +227,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct VisRestricted { pub pub_token: Token![pub], pub paren_token: token::Paren, @@ -240,6 +243,7 @@ pub mod parsing { use crate::parse::discouraged::Speculative; use crate::parse::{Parse, ParseStream, Result}; + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for Variant { fn parse(input: ParseStream) -> Result { let attrs = input.call(Attribute::parse_outer)?; @@ -269,6 +273,7 @@ pub mod parsing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for FieldsNamed { fn parse(input: ParseStream) -> Result { let content; @@ -279,6 +284,7 @@ pub mod parsing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for FieldsUnnamed { fn parse(input: ParseStream) -> Result { let content; @@ -291,6 +297,7 @@ pub mod parsing { impl Field { /// Parses a named (braced struct) field. + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn parse_named(input: ParseStream) -> Result { Ok(Field { attrs: input.call(Attribute::parse_outer)?, @@ -302,6 +309,7 @@ pub mod parsing { } /// Parses an unnamed (tuple struct) field. + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] pub fn parse_unnamed(input: ParseStream) -> Result { Ok(Field { attrs: input.call(Attribute::parse_outer)?, @@ -313,6 +321,7 @@ pub mod parsing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for Visibility { fn parse(input: ParseStream) -> Result { // Recognize an empty None-delimited group, as produced by a $:vis @@ -408,6 +417,7 @@ mod printing { use proc_macro2::TokenStream; use quote::{ToTokens, TokenStreamExt}; + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for Variant { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(&self.attrs); @@ -420,6 +430,7 @@ mod printing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for FieldsNamed { fn to_tokens(&self, tokens: &mut TokenStream) { self.brace_token.surround(tokens, |tokens| { @@ -428,6 +439,7 @@ mod printing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for FieldsUnnamed { fn to_tokens(&self, tokens: &mut TokenStream) { self.paren_token.surround(tokens, |tokens| { @@ -436,6 +448,7 @@ mod printing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for Field { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(&self.attrs); @@ -448,18 +461,21 @@ mod printing { } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for VisPublic { fn to_tokens(&self, tokens: &mut TokenStream) { self.pub_token.to_tokens(tokens) } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for VisCrate { fn to_tokens(&self, tokens: &mut TokenStream) { self.crate_token.to_tokens(tokens); } } + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for VisRestricted { fn to_tokens(&self, tokens: &mut TokenStream) { self.pub_token.to_tokens(tokens); diff --git a/src/derive.rs b/src/derive.rs index cbfd0da54a..af9bb91b7a 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -5,6 +5,7 @@ ast_struct! { /// Data structure sent to a `proc_macro_derive` macro. /// /// *This type is available only if Syn is built with the `"derive"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] pub struct DeriveInput { /// Attributes tagged on the whole struct or enum. pub attrs: Vec, @@ -32,10 +33,8 @@ ast_enum_of_structs! { /// /// This type is a [syntax tree enum]. /// - /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums - // - // TODO: change syntax-tree-enum link to an intra rustdoc link, currently - // blocked on https://github.com/rust-lang/rust/issues/62833 + /// [syntax tree enum]: Expr#syntax-tree-enums + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] pub enum Data { /// A struct input to a `proc_macro_derive` macro. Struct(DataStruct), @@ -55,6 +54,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` /// feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] pub struct DataStruct { pub struct_token: Token![struct], pub fields: Fields, @@ -67,6 +67,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` /// feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] pub struct DataEnum { pub enum_token: Token![enum], pub brace_token: token::Brace, @@ -79,6 +80,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` /// feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] pub struct DataUnion { pub union_token: Token![union], pub fields: FieldsNamed, @@ -90,6 +92,7 @@ pub mod parsing { use super::*; use crate::parse::{Parse, ParseStream, Result}; + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for DeriveInput { fn parse(input: ParseStream) -> Result { let attrs = input.call(Attribute::parse_outer)?; @@ -225,6 +228,7 @@ mod printing { use proc_macro2::TokenStream; use quote::ToTokens; + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for DeriveInput { fn to_tokens(&self, tokens: &mut TokenStream) { for attr in self.attrs.outer() { diff --git a/src/error.rs b/src/error.rs index 8d65a1b416..803b6feac5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -23,7 +23,7 @@ pub type Result = std::result::Result; /// [`compile_error!`] in the generated code. This produces a better diagnostic /// message than simply panicking the macro. /// -/// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html +/// [`compile_error!`]: std::compile_error! /// /// When parsing macro input, the [`parse_macro_input!`] macro handles the /// conversion to `compile_error!` automatically. @@ -189,7 +189,7 @@ impl Error { /// The [`parse_macro_input!`] macro provides a convenient way to invoke /// this method correctly in a procedural macro. /// - /// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html + /// [`compile_error!`]: std::compile_error! pub fn to_compile_error(&self) -> TokenStream { self.messages .iter() @@ -309,11 +309,7 @@ impl Clone for ErrorMessage { } } -impl std::error::Error for Error { - fn description(&self) -> &str { - "parse error" - } -} +impl std::error::Error for Error {} impl From for Error { fn from(err: LexError) -> Self { diff --git a/src/expr.rs b/src/expr.rs index 45dd0ce347..8417475cab 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -86,6 +86,7 @@ ast_enum_of_structs! { /// A sign that you may not be choosing the right variable names is if you /// see names getting repeated in your code, like accessing /// `receiver.receiver` or `pat.pat` or `cond.cond`. + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum Expr { /// A slice literal expression: `[a, b, c, d]`. Array(ExprArray), @@ -232,6 +233,7 @@ ast_struct! { /// A slice literal expression: `[a, b, c, d]`. /// /// *This type is available only if Syn is built with the `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprArray #full { pub attrs: Vec, pub bracket_token: token::Bracket, @@ -243,6 +245,7 @@ ast_struct! { /// An assignment expression: `a = compute()`. /// /// *This type is available only if Syn is built with the `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprAssign #full { pub attrs: Vec, pub left: Box, @@ -255,6 +258,7 @@ ast_struct! { /// A compound assignment expression: `counter += 1`. /// /// *This type is available only if Syn is built with the `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprAssignOp #full { pub attrs: Vec, pub left: Box, @@ -267,6 +271,7 @@ ast_struct! { /// An async block: `async { ... }`. /// /// *This type is available only if Syn is built with the `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprAsync #full { pub attrs: Vec, pub async_token: Token![async], @@ -279,6 +284,7 @@ ast_struct! { /// An await expression: `fut.await`. /// /// *This type is available only if Syn is built with the `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprAwait #full { pub attrs: Vec, pub base: Box, @@ -292,6 +298,7 @@ ast_struct! { /// /// *This type is available only if Syn is built with the `"derive"` or /// `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ExprBinary { pub attrs: Vec, pub left: Box, @@ -304,6 +311,7 @@ ast_struct! { /// A blocked scope: `{ ... }`. /// /// *This type is available only if Syn is built with the `"full"` feature.* + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ExprBlock #full { pub attrs: Vec, pub label: Option