[
  {
    "path": "LICENSE-APACHE",
    "content": "                              Apache License\n                        Version 2.0, January 2004\n                     http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n   \"License\" shall mean the terms and conditions for use, reproduction,\n   and distribution as defined by Sections 1 through 9 of this document.\n\n   \"Licensor\" shall mean the copyright owner or entity authorized by\n   the copyright owner that is granting the License.\n\n   \"Legal Entity\" shall mean the union of the acting entity and all\n   other entities that control, are controlled by, or are under common\n   control with that entity. For the purposes of this definition,\n   \"control\" means (i) the power, direct or indirect, to cause the\n   direction or management of such entity, whether by contract or\n   otherwise, or (ii) ownership of fifty percent (50%) or more of the\n   outstanding shares, or (iii) beneficial ownership of such entity.\n\n   \"You\" (or \"Your\") shall mean an individual or Legal Entity\n   exercising permissions granted by this License.\n\n   \"Source\" form shall mean the preferred form for making modifications,\n   including but not limited to software source code, documentation\n   source, and configuration files.\n\n   \"Object\" form shall mean any form resulting from mechanical\n   transformation or translation of a Source form, including but\n   not limited to compiled object code, generated documentation,\n   and conversions to other media types.\n\n   \"Work\" shall mean the work of authorship, whether in Source or\n   Object form, made available under the License, as indicated by a\n   copyright notice that is included in or attached to the work\n   (an example is provided in the Appendix below).\n\n   \"Derivative Works\" shall mean any work, whether in Source or Object\n   form, that is based on (or derived from) the Work and for which the\n   editorial revisions, annotations, elaborations, or other modifications\n   represent, as a whole, an original work of authorship. For the purposes\n   of this License, Derivative Works shall not include works that remain\n   separable from, or merely link (or bind by name) to the interfaces of,\n   the Work and Derivative Works thereof.\n\n   \"Contribution\" shall mean any work of authorship, including\n   the original version of the Work and any modifications or additions\n   to that Work or Derivative Works thereof, that is intentionally\n   submitted to Licensor for inclusion in the Work by the copyright owner\n   or by an individual or Legal Entity authorized to submit on behalf of\n   the copyright owner. For the purposes of this definition, \"submitted\"\n   means any form of electronic, verbal, or written communication sent\n   to the Licensor or its representatives, including but not limited to\n   communication on electronic mailing lists, source code control systems,\n   and issue tracking systems that are managed by, or on behalf of, the\n   Licensor for the purpose of discussing and improving the Work, but\n   excluding communication that is conspicuously marked or otherwise\n   designated in writing by the copyright owner as \"Not a Contribution.\"\n\n   \"Contributor\" shall mean Licensor and any individual or Legal Entity\n   on behalf of whom a Contribution has been received by Licensor and\n   subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   copyright license to reproduce, prepare Derivative Works of,\n   publicly display, publicly perform, sublicense, and distribute the\n   Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   (except as stated in this section) patent license to make, have made,\n   use, offer to sell, sell, import, and otherwise transfer the Work,\n   where such license applies only to those patent claims licensable\n   by such Contributor that are necessarily infringed by their\n   Contribution(s) alone or by combination of their Contribution(s)\n   with the Work to which such Contribution(s) was submitted. If You\n   institute patent litigation against any entity (including a\n   cross-claim or counterclaim in a lawsuit) alleging that the Work\n   or a Contribution incorporated within the Work constitutes direct\n   or contributory patent infringement, then any patent licenses\n   granted to You under this License for that Work shall terminate\n   as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n   Work or Derivative Works thereof in any medium, with or without\n   modifications, and in Source or Object form, provided that You\n   meet the following conditions:\n\n   (a) You must give any other recipients of the Work or\n       Derivative Works a copy of this License; and\n\n   (b) You must cause any modified files to carry prominent notices\n       stating that You changed the files; and\n\n   (c) You must retain, in the Source form of any Derivative Works\n       that You distribute, all copyright, patent, trademark, and\n       attribution notices from the Source form of the Work,\n       excluding those notices that do not pertain to any part of\n       the Derivative Works; and\n\n   (d) If the Work includes a \"NOTICE\" text file as part of its\n       distribution, then any Derivative Works that You distribute must\n       include a readable copy of the attribution notices contained\n       within such NOTICE file, excluding those notices that do not\n       pertain to any part of the Derivative Works, in at least one\n       of the following places: within a NOTICE text file distributed\n       as part of the Derivative Works; within the Source form or\n       documentation, if provided along with the Derivative Works; or,\n       within a display generated by the Derivative Works, if and\n       wherever such third-party notices normally appear. The contents\n       of the NOTICE file are for informational purposes only and\n       do not modify the License. You may add Your own attribution\n       notices within Derivative Works that You distribute, alongside\n       or as an addendum to the NOTICE text from the Work, provided\n       that such additional attribution notices cannot be construed\n       as modifying the License.\n\n   You may add Your own copyright statement to Your modifications and\n   may provide additional or different license terms and conditions\n   for use, reproduction, or distribution of Your modifications, or\n   for any such Derivative Works as a whole, provided Your use,\n   reproduction, and distribution of the Work otherwise complies with\n   the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n   any Contribution intentionally submitted for inclusion in the Work\n   by You to the Licensor shall be under the terms and conditions of\n   this License, without any additional terms or conditions.\n   Notwithstanding the above, nothing herein shall supersede or modify\n   the terms of any separate license agreement you may have executed\n   with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n   names, trademarks, service marks, or product names of the Licensor,\n   except as required for reasonable and customary use in describing the\n   origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n   agreed to in writing, Licensor provides the Work (and each\n   Contributor provides its Contributions) on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n   implied, including, without limitation, any warranties or conditions\n   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n   PARTICULAR PURPOSE. You are solely responsible for determining the\n   appropriateness of using or redistributing the Work and assume any\n   risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n   whether in tort (including negligence), contract, or otherwise,\n   unless required by applicable law (such as deliberate and grossly\n   negligent acts) or agreed to in writing, shall any Contributor be\n   liable to You for damages, including any direct, indirect, special,\n   incidental, or consequential damages of any character arising as a\n   result of this License or out of the use or inability to use the\n   Work (including but not limited to damages for loss of goodwill,\n   work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses), even if such Contributor\n   has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n   the Work or Derivative Works thereof, You may choose to offer,\n   and charge a fee for, acceptance of support, warranty, indemnity,\n   or other liability obligations and/or rights consistent with this\n   License. However, in accepting such obligations, You may act only\n   on Your own behalf and on Your sole responsibility, not on behalf\n   of any other Contributor, and only if You agree to indemnify,\n   defend, and hold each Contributor harmless for any liability\n   incurred by, or claims asserted against, such Contributor by reason\n   of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "Permission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Rust style team repository\n\nThis is the home of the [Rust style team](https://www.rust-lang.org/governance/teams/lang#Style%20team). The style team is responsible for\ndetermining the default Rust style, including styling for new language\nconstructs, as well as evolving the Rust style over time.\n\nThe [Rust style\nguide](https://github.com/rust-lang/rust/tree/HEAD/src/doc/style-guide/src)\nlives in the `rust-lang/rust` repository. In particular, see the [guiding\nprinciples](https://github.com/rust-lang/rust/blob/HEAD/src/doc/style-guide/src/principles.md)\nof the Rust style.\n\nThis repository includes:\n- The [charter](charter.md) for the style team.\n- The [policy](team-policy.md) for the style team, including the [handling of\n  style for nightly language constructs](nightly-style-procedure.md).\n\n## Code of Conduct\n\nAll interactions on this repository (whether on issues, PRs, or elsewhere), as\nin other parts of the Rust project, are governed by the [Rust Code of\nConduct](https://www.rust-lang.org/policies/code-of-conduct).\n\n## License\n[License]: #license\n\nThis repository is licensed under either of:\n\n* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)\n* MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contributions\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n"
  },
  {
    "path": "charter.md",
    "content": "# Style Team\n\n## Aims: Evolving the Rust Style over time\n\n1. Defining the style for new Rust constructs\n2. Evolving the existing style over the course of Rust editions (without breaking backwards compatibility)\n3. Defining mechanisms to evolve the Rust style while taking backwards compatibility into account, such as via Rust editions or similar mechanisms\n\n## Domains\n\n1. [Style Guide](https://github.com/rust-lang/rust/tree/HEAD/src/doc/style-guide/src)\n2. [T-style team repo](https://github.com/rust-lang/style-team/)\n3. [#T-style](https://rust-lang.zulipchat.com/#narrow/stream/346005-t-style) Zulip stream\n4. [#T-style/private](https://rust-lang.zulipchat.com/#narrow/stream/353175-t-style.2Fprivate) Zulip stream\n5. `rust-lang` issues with the `T-style` or `I-style-nominated` labels\n\n## Membership\n\nThe active membership of the style team can be found on [rust-lang.org/governance](https://github.com/rust-lang/team/blob/HEAD/teams/style.toml).\n\nThe Rust style team shall have at least 3 members and at most 8. If the team has fewer than 3 members it shall seek new members as its primary focus.\n\nMembers of the style team are nominated by existing members. All existing members of the team must affirmatively agree to the addition of a member, with zero objections; if there is any objection to a nomination, the new member will not be added. In addition, the team lead or another team member will check with the moderation team regarding any person nominated for membership, to provide an avenue for awareness of concerns or red flags.\n\n### Becoming a member of T-Style\n\nContributors who believe they'd be a good fit for the style team are encouraged to request an invite[^1] to the team, by reaching out via Zulip private message to one or more team members. The style team will consider all such requests as as a proposal to become a team member and provide clear feedback to the contributor if there are any objections so that any issues may be resolved and the contributor can apply again in the future. The style team will not consider having previously been rejected as a basis for future rejections.\n\n### Team Member Characteristics\n\nThe style team is committed to building a diverse and capable team comprising individuals who possess the following characteristics:\n\n1. Representation and Perspectives: The style team values representation from various parts of the Rust organization and ecosystem. We aim to include members with many different perspectives on the Rust language and ecosystem, to ensure that the Rust style works well for a wide variety of Rust users.\n2. Familiarity with Rust: Prospective members should have a general familiarity with Rust, including a solid understanding of its constructs, how they interact, and the overall language ecosystem. This knowledge is crucial for making informed decisions regarding style and formatting guidelines.\n3. Interest in Rust Style: Members should have a genuine interest in Rust style and a willingness to contribute to the team's efforts. It is important that members are not solely focused on advocating for their personal style preferences but are dedicated to promoting a collective and consensus-based approach.\n4. Effective Collaboration Skills: Successful candidates will have a proven track record of effective collaboration, showcasing their ability to work together with others, consider diverse perspectives, navigate conflicts, and address emotional challenges in a constructive manner.\n5. Effective Communication in Charged Conversations: Members will need to carefully navigate charged conversations and evocative feedback, and respond constructively and with empathy, to each other and to the community. Members should be able to handle passionate discussions about code style, recognize miscommunication and misunderstandings, and promote empathy and listening.\n6. Familiarity with Rust Project: Members should be familiar with the Rust project's structure, culture, and expectations upon maintainers. This knowledge helps members navigate the ecosystem more effectively, and align their style decisions with the project's broader goals.\n7. Consent to Principles and Aims: Members are expected to align with and consent to the principles and aims of the style team, as outlined in the [Rust style guide principles](https://github.com/rust-lang/rust/blob/master/src/doc/style-guide/src/principles.md) and the style team's [charter](https://github.com/rust-lang/style-team/blob/style-policy/charter.md).\n8. Pragmatic Approach: Members should prioritize pragmatism over dogmatism, even when dealing with style and formatting aspects they feel particularly strongly about. The ability to make practical and reasonable decisions that benefit the community at large is essential.\n9. Openness to Change and Learning: Members should demonstrate a willingness to seek out and receive new information, introspect on their underlying values, change their opinions based on evidence and rationale, and adapt their perspectives accordingly.\n10. Interest in Language and Syntax: Members should show interest in tracking changes to the Rust language and syntax. Keeping up-to-date with the latest developments helps inform style decisions.\n11. Ability to weigh subjective decisions, and seek out \"better\" rather than \"perfect\": We need a default Rust style, and even in the face of conflicting requirements we still need to make a decision. Style team decisions will attempt to best satisfy most members of the Rust community, but can never be perfect. Members will need to keep this in mind and help the style team make the best consent-based decisions it can.\n\n[^1]: We suggest reaching out via zulip DM to one of the current team members, and contacting the lead by default if you're unsure who to reach out to.\n"
  },
  {
    "path": "example/lists-elided.rs",
    "content": "// Copyright 2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse std::cmp;\nuse std::iter::Peekable;\n\nuse syntax::codemap::{self, CodeMap, BytePos};\n\nuse Indent;\nuse comment::{FindUncommented, rewrite_comment, find_comment_end};\nuse config::Config;\n\n/// Formatting tactic for lists. This will be cast down to a\n/// DefinitiveListTactic depending on the number and length of the items and\n/// their comments.\n#[derive(Eq, PartialEq, Debug, Copy, Clone)]\npub enum ListTactic {\n    // One item per row.\n    Vertical,\n    // All items on one row.\n    Horizontal,\n    // Try Horizontal layout, if that fails then vertical.\n    HorizontalVertical,\n    // HorizontalVertical with a soft limit of n characters.\n    LimitedHorizontalVertical(usize),\n    // Pack as many items as possible per row over (possibly) many rows.\n    Mixed,\n}\n\nimpl_enum_decodable!(ListTactic, Vertical, Horizontal, HorizontalVertical, Mixed);\n\n#[derive(Eq, PartialEq, Debug, Copy, Clone)]\npub enum SeparatorTactic {\n    Always,\n    Never,\n    Vertical,\n}\n\nimpl_enum_decodable!(SeparatorTactic, Always, Never, Vertical);\n\nimpl SeparatorTactic {\n    pub fn from_bool(b: bool) -> SeparatorTactic {\n        if b {\n            SeparatorTactic::Always\n        } else {\n            SeparatorTactic::Never\n        }\n    }\n}\n\npub struct ListFormatting<'a> {\n    pub tactic: DefinitiveListTactic,\n    pub separator: &'a str,\n    pub trailing_separator: SeparatorTactic,\n    pub indent: Indent,\n    pub width: usize,\n    // Non-expressions, e.g. items, will have a new line at the end of the list.\n    // Important for comment styles.\n    pub ends_with_newline: bool,\n    pub config: &'a Config,\n}\n\npub fn format_fn_args<I>(items: I, width: usize, offset: Indent, config: &Config) -> Option<String>\nwhere\n    I: Iterator<Item = ListItem>,\n{\n    // ...\n}\n\npub fn format_item_list<I>(\n    items: I,\n    width: usize,\n    offset: Indent,\n    config: &Config,\n) -> Option<String>\nwhere\n    I: Iterator<Item = ListItem>,\n{\n    list_helper(items, width, offset, config, ListTactic::HorizontalVertical)\n}\n\npub fn list_helper<I>(\n    items: I,\n    width: usize,\n    offset: Indent,\n    config: &Config,\n    tactic: ListTactic,\n) -> Option<String>\nwhere\n    I: Iterator<Item = ListItem>,\n{\n    let item_vec: Vec<_> = items.collect();\n    let tactic = definitive_tactic(&item_vec, tactic, width);\n    let fmt = ListFormatting {\n        tactic: tactic,\n        separator: \",\",\n        trailing_separator: SeparatorTactic::Never,\n        indent: offset,\n        width: width,\n        ends_with_newline: false,\n        config: config,\n    };\n\n    write_list(&item_vec, &fmt)\n}\n\nimpl AsRef<ListItem> for ListItem {\n    fn as_ref(&self) -> &ListItem {\n        self\n    }\n}\n\npub struct ListItem {\n    // None for comments mean that they are not present.\n    pub pre_comment: Option<String>,\n    // Item should include attributes and doc comments. None indicates a failed\n    // rewrite.\n    pub item: Option<String>,\n    pub post_comment: Option<String>,\n    // Whether there is extra whitespace before this item.\n    pub new_lines: bool,\n}\n\nimpl ListItem {\n    pub fn is_multiline(&self) -> bool {\n        // ...\n    }\n\n    pub fn has_line_pre_comment(&self) -> bool {\n        self.pre_comment.as_ref().map_or(false, |comment| comment.starts_with(\"//\"))\n    }\n\n    pub fn from_str<S: Into<String>>(s: S) -> ListItem {\n        ListItem {\n            pre_comment: None,\n            item: Some(s.into()),\n            post_comment: None,\n            new_lines: false,\n        }\n    }\n}\n\n#[derive(Eq, PartialEq, Debug, Copy, Clone)]\n/// The definitive formatting tactic for lists.\npub enum DefinitiveListTactic {\n    Vertical,\n    Horizontal,\n    Mixed,\n}\n\npub fn definitive_tactic<I, T>(items: I, tactic: ListTactic, width: usize) -> DefinitiveListTactic\nwhere\n    I: IntoIterator<Item = T> + Clone,\n    T: AsRef<ListItem>,\n{\n    let pre_line_comments =\n        items.clone().into_iter().any(|item| item.as_ref().has_line_pre_comment());\n\n    let limit = match tactic {\n        _ if pre_line_comments => return DefinitiveListTactic::Vertical,\n        ListTactic::Mixed => return DefinitiveListTactic::Mixed,\n        ListTactic::Horizontal => return DefinitiveListTactic::Horizontal,\n        ListTactic::Vertical => return DefinitiveListTactic::Vertical,\n        ListTactic::LimitedHorizontalVertical(limit) => ::std::cmp::min(width, limit),\n        ListTactic::HorizontalVertical => width,\n    };\n\n    let (sep_count, total_width) = calculate_width(items.clone());\n    let sep_len = \", \".len(); // FIXME: make more generic?\n    let total_sep_len = sep_len * sep_count.checked_sub(1).unwrap_or(0);\n    let real_total = total_width + total_sep_len;\n}\n\n// Format a list of commented items into a string.\n// TODO: add unit tests\npub fn write_list<I, T>(items: I, formatting: &ListFormatting) -> Option<String>\nwhere\n    I: IntoIterator<Item = T>,\n    T: AsRef<ListItem>,\n{\n    let tactic = formatting.tactic;\n    let sep_len = formatting.separator.len();\n\n    // Now that we know how we will layout, we can decide for sure if there\n    // will be a trailing separator.\n    let trailing_separator = needs_trailing_separator(formatting.trailing_separator, tactic);\n    let mut result = String::new();\n    let mut iter = items.into_iter().enumerate().peekable();\n\n    let mut line_len = 0;\n    let indent_str = &formatting.indent.to_string(formatting.config);\n    while let Some((i, item)) = iter.next() {\n        let item = item.as_ref();\n        let inner_item = try_opt!(item.item.as_ref());\n        let first = i == 0;\n        let last = iter.peek().is_none();\n        let separate = !last || trailing_separator;\n        let item_sep_len = if separate { sep_len } else { 0 };\n\n        // Item string may be multi-line. Its length (used for block comment alignment)\n        // Should be only the length of the last line.\n        let item_last_line = if item.is_multiline() {\n            inner_item.lines().last().unwrap_or(\"\")\n        } else {\n            inner_item.as_ref()\n        };\n        let mut item_last_line_width = item_last_line.len() + item_sep_len;\n        if item_last_line.starts_with(indent_str) {\n            item_last_line_width -= indent_str.len();\n        }\n\n        match tactic {\n            DefinitiveListTactic::Horizontal if !first => {\n                result.push(' ');\n            }\n            DefinitiveListTactic::Vertical if !first => {\n                result.push('\\n');\n                result.push_str(indent_str);\n            }\n            DefinitiveListTactic::Mixed => {\n                let total_width = total_item_width(item) + item_sep_len;\n\n                // 1 is space between separator and item.\n                if line_len > 0 && line_len + 1 + total_width > formatting.width {\n                    result.push('\\n');\n                    result.push_str(indent_str);\n                    line_len = 0;\n                }\n\n                if line_len > 0 {\n                    result.push(' ');\n                    line_len += 1;\n                }\n\n                line_len += total_width;\n            }\n            _ => {}\n        }\n\n        result.push_str(&inner_item[..]);\n\n        if separate {\n            result.push_str(formatting.separator);\n        }\n\n        if !last && tactic == DefinitiveListTactic::Vertical && item.new_lines {\n            result.push('\\n');\n        }\n    }\n\n    Some(result)\n}\n\npub struct ListItems<'a, I, F1, F2, F3>\nwhere\n    I: Iterator,\n{\n    codemap: &'a CodeMap,\n    inner: Peekable<I>,\n    get_lo: F1,\n    get_hi: F2,\n    get_item_string: F3,\n    prev_span_end: BytePos,\n    next_span_start: BytePos,\n    terminator: &'a str,\n}\n\nimpl<'a, T, I, F1, F2, F3> Iterator for ListItems<'a, I, F1, F2, F3>\nwhere\n    I: Iterator<Item = T>,\n    F1: Fn(&T) -> BytePos,\n    F2: Fn(&T) -> BytePos,\n    F3: Fn(&T) -> Option<String>,\n{\n    type Item = ListItem;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        // ...\n    }\n}\n\n// Creates an iterator over a list's items with associated comments.\npub fn itemize_list<'a, T, I, F1, F2, F3>(\n    codemap: &'a CodeMap,\n    inner: I,\n    terminator: &'a str,\n    get_lo: F1,\n    get_hi: F2,\n    get_item_string: F3,\n    prev_span_end: BytePos,\n    next_span_start: BytePos,\n) -> ListItems<'a, I, F1, F2, F3>\nwhere\n    I: Iterator<Item = T>,\n    F1: Fn(&T) -> BytePos,\n    F2: Fn(&T) -> BytePos,\n    F3: Fn(&T) -> Option<String>,\n{\n    ListItems {\n        codemap: codemap,\n        inner: inner.peekable(),\n        get_lo: get_lo,\n        get_hi: get_hi,\n        get_item_string: get_item_string,\n        prev_span_end: prev_span_end,\n        next_span_start: next_span_start,\n        terminator: terminator,\n    }\n}\n\nfn needs_trailing_separator(\n    separator_tactic: SeparatorTactic,\n    list_tactic: DefinitiveListTactic,\n) -> bool {\n    match separator_tactic {\n        SeparatorTactic::Always => true,\n        SeparatorTactic::Vertical => list_tactic == DefinitiveListTactic::Vertical,\n        SeparatorTactic::Never => false,\n    }\n}\n\n/// Returns the count and total width of the list items.\nfn calculate_width<I, T>(items: I) -> (usize, usize)\nwhere\n    I: IntoIterator<Item = T>,\n    T: AsRef<ListItem>,\n{\n    // ...\n}\n\nfn total_item_width(item: &ListItem) -> usize {\n    // ...\n}\n\nfn comment_len(comment: Option<&str>) -> usize {\n    match comment {\n        Some(s) => {\n            let text_len = s.trim().len();\n            if text_len > 0 {\n                // We'll put \" /*\" before and \" */\" after inline comments.\n                text_len + 6\n            } else {\n                text_len\n            }\n        }\n        None => 0,\n    }\n}\n"
  },
  {
    "path": "example/lists.rs",
    "content": "// Copyright 2015 The Rust Project Developers. See the COPYRIGHT\n// file at the top-level directory of this distribution and at\n// http://rust-lang.org/COPYRIGHT.\n//\n// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. This file may not be copied, modified, or distributed\n// except according to those terms.\n\nuse std::cmp;\nuse std::iter::Peekable;\n\nuse syntax::codemap::{self, BytePos, CodeMap};\n\nuse Indent;\nuse comment::{find_comment_end, rewrite_comment, FindUncommented};\nuse config::Config;\n\n#[derive(Eq, PartialEq, Debug, Copy, Clone)]\n/// Formatting tactic for lists. This will be cast down to a\n/// DefinitiveListTactic depending on the number and length of the items and\n/// their comments.\npub enum ListTactic {\n    // One item per row.\n    Vertical,\n    // All items on one row.\n    Horizontal,\n    // Try Horizontal layout, if that fails then vertical.\n    HorizontalVertical,\n    // HorizontalVertical with a soft limit of n characters.\n    LimitedHorizontalVertical(usize),\n    // Pack as many items as possible per row over (possibly) many rows.\n    Mixed,\n}\n\nimpl_enum_decodable!(ListTactic, Vertical, Horizontal, HorizontalVertical, Mixed);\n\n#[derive(Eq, PartialEq, Debug, Copy, Clone)]\npub enum SeparatorTactic {\n    Always,\n    Never,\n    Vertical,\n}\n\nimpl_enum_decodable!(SeparatorTactic, Always, Never, Vertical);\n\nimpl SeparatorTactic {\n    pub fn from_bool(b: bool) -> SeparatorTactic {\n        if b {\n            SeparatorTactic::Always\n        } else {\n            SeparatorTactic::Never\n        }\n    }\n}\n\npub struct ListFormatting<'a> {\n    pub tactic: DefinitiveListTactic,\n    pub separator: &'a str,\n    pub trailing_separator: SeparatorTactic,\n    pub indent: Indent,\n    pub width: usize,\n    // Non-expressions, e.g. items, will have a new line at the end of the list.\n    // Important for comment styles.\n    pub ends_with_newline: bool,\n    pub config: &'a Config,\n}\n\npub fn format_fn_args<I>(items: I, width: usize, offset: Indent, config: &Config) -> Option<String>\nwhere\n    I: Iterator<Item = ListItem>,\n{\n    list_helper(\n        items,\n        width,\n        offset,\n        config,\n        ListTactic::LimitedHorizontalVertical(config.fn_call_width),\n    )\n}\n\npub fn format_item_list<I>(\n    items: I,\n    width: usize,\n    offset: Indent,\n    config: &Config,\n) -> Option<String>\nwhere\n    I: Iterator<Item = ListItem>,\n{\n    list_helper(items, width, offset, config, ListTactic::HorizontalVertical)\n}\n\npub fn list_helper<I>(\n    items: I,\n    width: usize,\n    offset: Indent,\n    config: &Config,\n    tactic: ListTactic,\n) -> Option<String>\nwhere\n    I: Iterator<Item = ListItem>,\n{\n    let item_vec: Vec<_> = items.collect();\n    let tactic = definitive_tactic(&item_vec, tactic, width);\n    let fmt = ListFormatting {\n        tactic: tactic,\n        separator: \",\",\n        trailing_separator: SeparatorTactic::Never,\n        indent: offset,\n        width: width,\n        ends_with_newline: false,\n        config: config,\n    };\n\n    write_list(&item_vec, &fmt)\n}\n\nimpl AsRef<ListItem> for ListItem {\n    fn as_ref(&self) -> &ListItem {\n        self\n    }\n}\n\npub struct ListItem {\n    // None for comments mean that they are not present.\n    pub pre_comment: Option<String>,\n    // Item should include attributes and doc comments. None indicates a failed\n    // rewrite.\n    pub item: Option<String>,\n    pub post_comment: Option<String>,\n    // Whether there is extra whitespace before this item.\n    pub new_lines: bool,\n}\n\nimpl ListItem {\n    pub fn is_multiline(&self) -> bool {\n        self.item.as_ref().map_or(false, |s| s.contains('\\n')) || self.pre_comment.is_some() ||\n            self.post_comment\n                .as_ref()\n                .map_or(false, |s| s.contains('\\n'))\n    }\n\n    pub fn has_line_pre_comment(&self) -> bool {\n        self.pre_comment\n            .as_ref()\n            .map_or(false, |comment| comment.starts_with(\"//\"))\n    }\n\n    pub fn from_str<S: Into<String>>(s: S) -> ListItem {\n        ListItem {\n            pre_comment: None,\n            item: Some(s.into()),\n            post_comment: None,\n            new_lines: false,\n        }\n    }\n}\n\n#[derive(Eq, PartialEq, Debug, Copy, Clone)]\n/// The definitive formatting tactic for lists.\npub enum DefinitiveListTactic {\n    Vertical,\n    Horizontal,\n    Mixed,\n}\n\npub fn definitive_tactic<I, T>(items: I, tactic: ListTactic, width: usize) -> DefinitiveListTactic\nwhere\n    I: IntoIterator<Item = T> + Clone,\n    T: AsRef<ListItem>,\n{\n    let pre_line_comments = items\n        .clone()\n        .into_iter()\n        .any(|item| item.as_ref().has_line_pre_comment());\n\n    let limit = match tactic {\n        _ if pre_line_comments => return DefinitiveListTactic::Vertical,\n        ListTactic::Mixed => return DefinitiveListTactic::Mixed,\n        ListTactic::Horizontal => return DefinitiveListTactic::Horizontal,\n        ListTactic::Vertical => return DefinitiveListTactic::Vertical,\n        ListTactic::LimitedHorizontalVertical(limit) => ::std::cmp::min(width, limit),\n        ListTactic::HorizontalVertical => width,\n    };\n\n    let (sep_count, total_width) = calculate_width(items.clone());\n    let sep_len = \", \".len(); // FIXME: make more generic?\n    let total_sep_len = sep_len * sep_count.checked_sub(1).unwrap_or(0);\n    let real_total = total_width + total_sep_len;\n\n    if real_total <= limit && !pre_line_comments &&\n        !items.into_iter().any(|item| item.as_ref().is_multiline())\n    {\n        DefinitiveListTactic::Horizontal\n    } else {\n        DefinitiveListTactic::Vertical\n    }\n}\n\n// Format a list of commented items into a string.\n// TODO: add unit tests\npub fn write_list<I, T>(items: I, formatting: &ListFormatting) -> Option<String>\nwhere\n    I: IntoIterator<Item = T>,\n    T: AsRef<ListItem>,\n{\n    let tactic = formatting.tactic;\n    let sep_len = formatting.separator.len();\n\n    // Now that we know how we will layout, we can decide for sure if there\n    // will be a trailing separator.\n    let trailing_separator = needs_trailing_separator(formatting.trailing_separator, tactic);\n    let mut result = String::new();\n    let mut iter = items.into_iter().enumerate().peekable();\n\n    let mut line_len = 0;\n    let indent_str = &formatting.indent.to_string(formatting.config);\n    while let Some((i, item)) = iter.next() {\n        let item = item.as_ref();\n        let inner_item = try_opt!(item.item.as_ref());\n        let first = i == 0;\n        let last = iter.peek().is_none();\n        let separate = !last || trailing_separator;\n        let item_sep_len = if separate { sep_len } else { 0 };\n\n        // Item string may be multi-line. Its length (used for block comment alignment)\n        // Should be only the length of the last line.\n        let item_last_line = if item.is_multiline() {\n            inner_item.lines().last().unwrap_or(\"\")\n        } else {\n            inner_item.as_ref()\n        };\n        let mut item_last_line_width = item_last_line.len() + item_sep_len;\n        if item_last_line.starts_with(indent_str) {\n            item_last_line_width -= indent_str.len();\n        }\n\n        match tactic {\n            DefinitiveListTactic::Horizontal if !first => {\n                result.push(' ');\n            }\n            DefinitiveListTactic::Vertical if !first => {\n                result.push('\\n');\n                result.push_str(indent_str);\n            }\n            DefinitiveListTactic::Mixed => {\n                let total_width = total_item_width(item) + item_sep_len;\n\n                // 1 is space between separator and item.\n                if line_len > 0 && line_len + 1 + total_width > formatting.width {\n                    result.push('\\n');\n                    result.push_str(indent_str);\n                    line_len = 0;\n                }\n\n                if line_len > 0 {\n                    result.push(' ');\n                    line_len += 1;\n                }\n\n                line_len += total_width;\n            }\n            _ => {}\n        }\n\n        // Pre-comments\n        if let Some(ref comment) = item.pre_comment {\n            // Block style in non-vertical mode.\n            let block_mode = tactic != DefinitiveListTactic::Vertical;\n            // Width restriction is only relevant in vertical mode.\n            let max_width = formatting.width;\n            let comment = try_opt!(rewrite_comment(\n                comment,\n                block_mode,\n                max_width,\n                formatting.indent,\n                formatting.config,\n            ),);\n            result.push_str(&comment);\n\n            if tactic == DefinitiveListTactic::Vertical {\n                result.push('\\n');\n                result.push_str(indent_str);\n            } else {\n                result.push(' ');\n            }\n        }\n\n        result.push_str(&inner_item[..]);\n\n        // Post-comments\n        if tactic != DefinitiveListTactic::Vertical && item.post_comment.is_some() {\n            let comment = item.post_comment.as_ref().unwrap();\n            let formatted_comment = try_opt!(rewrite_comment(\n                comment,\n                true,\n                formatting.width,\n                Indent::empty(),\n                formatting.config,\n            ),);\n\n            result.push(' ');\n            result.push_str(&formatted_comment);\n        }\n\n        if separate {\n            result.push_str(formatting.separator);\n        }\n\n        if tactic == DefinitiveListTactic::Vertical && item.post_comment.is_some() {\n            // 1 = space between item and comment.\n            let width = formatting\n                .width\n                .checked_sub(item_last_line_width + 1)\n                .unwrap_or(1);\n            let mut offset = formatting.indent;\n            offset.alignment += item_last_line_width + 1;\n            let comment = item.post_comment.as_ref().unwrap();\n\n            debug!(\"Width = {}, offset = {:?}\", width, offset);\n            // Use block-style only for the last item or multiline comments.\n            let block_style = !formatting.ends_with_newline && last ||\n                comment.trim().contains('\\n') ||\n                comment.trim().len() > width;\n\n            let formatted_comment = try_opt!(rewrite_comment(\n                comment,\n                block_style,\n                width,\n                offset,\n                formatting.config\n            ));\n\n            result.push(' ');\n            result.push_str(&formatted_comment);\n        }\n\n        if !last && tactic == DefinitiveListTactic::Vertical && item.new_lines {\n            result.push('\\n');\n        }\n    }\n\n    Some(result)\n}\n\npub struct ListItems<'a, I, F1, F2, F3>\nwhere\n    I: Iterator,\n{\n    codemap: &'a CodeMap,\n    inner: Peekable<I>,\n    get_lo: F1,\n    get_hi: F2,\n    get_item_string: F3,\n    prev_span_end: BytePos,\n    next_span_start: BytePos,\n    terminator: &'a str,\n}\n\nimpl<'a, T, I, F1, F2, F3> Iterator for ListItems<'a, I, F1, F2, F3>\nwhere\n    I: Iterator<Item = T>,\n    F1: Fn(&T) -> BytePos,\n    F2: Fn(&T) -> BytePos,\n    F3: Fn(&T) -> Option<String>,\n{\n    type Item = ListItem;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let white_space: &[_] = &[' ', '\\t'];\n\n        self.inner.next().map(|item| {\n            let mut new_lines = false;\n            // Pre-comment\n            let pre_snippet = self.codemap\n                .span_to_snippet(codemap::mk_sp(self.prev_span_end, (self.get_lo)(&item)))\n                .unwrap();\n            let trimmed_pre_snippet = pre_snippet.trim();\n            let pre_comment = if !trimmed_pre_snippet.is_empty() {\n                Some(trimmed_pre_snippet.to_owned())\n            } else {\n                None\n            };\n\n            // Post-comment\n            let next_start = match self.inner.peek() {\n                Some(next_item) => (self.get_lo)(next_item),\n                None => self.next_span_start,\n            };\n            let post_snippet = self.codemap\n                .span_to_snippet(codemap::mk_sp((self.get_hi)(&item), next_start))\n                .unwrap();\n\n            let comment_end = match self.inner.peek() {\n                Some(..) => {\n                    let block_open_index = post_snippet.find(\"/*\");\n                    let newline_index = post_snippet.find('\\n');\n                    let separator_index = post_snippet.find_uncommented(\",\").unwrap();\n\n                    match (block_open_index, newline_index) {\n                        // Separator before comment, with the next item on same line.\n                        // Comment belongs to next item.\n                        (Some(i), None) if i > separator_index => separator_index + 1,\n                        // Block-style post-comment before the separator.\n                        (Some(i), None) => cmp::max(\n                            find_comment_end(&post_snippet[i..]).unwrap() + i,\n                            separator_index + 1,\n                        ),\n                        // Block-style post-comment. Either before or after the separator.\n                        (Some(i), Some(j)) if i < j => cmp::max(\n                            find_comment_end(&post_snippet[i..]).unwrap() + i,\n                            separator_index + 1,\n                        ),\n                        // Potential *single* line comment.\n                        (_, Some(j)) if j > separator_index => j + 1,\n                        _ => post_snippet.len(),\n                    }\n                }\n                None => post_snippet\n                    .find_uncommented(self.terminator)\n                    .unwrap_or(post_snippet.len()),\n            };\n\n            if !post_snippet.is_empty() && comment_end > 0 {\n                // Account for extra whitespace between items. This is fiddly\n                // because of the way we divide pre- and post- comments.\n\n                // Everything from the separator to the next item.\n                let test_snippet = &post_snippet[comment_end - 1..];\n                let first_newline = test_snippet.find('\\n').unwrap_or(test_snippet.len());\n                // From the end of the first line of comments.\n                let test_snippet = &test_snippet[first_newline..];\n                let first = test_snippet\n                    .find(|c: char| !c.is_whitespace())\n                    .unwrap_or(test_snippet.len());\n                // From the end of the first line of comments to the next non-whitespace char.\n                let test_snippet = &test_snippet[..first];\n\n                if test_snippet.chars().filter(|c| c == &'\\n').count() > 1 {\n                    // There were multiple line breaks which got trimmed to nothing.\n                    new_lines = true;\n                }\n            }\n\n            // Cleanup post-comment: strip separators and whitespace.\n            self.prev_span_end = (self.get_hi)(&item) + BytePos(comment_end as u32);\n            let post_snippet = post_snippet[..comment_end].trim();\n\n            let post_snippet_trimmed = if post_snippet.starts_with(',') {\n                post_snippet[1..].trim_matches(white_space)\n            } else if post_snippet.ends_with(',') {\n                post_snippet[..(post_snippet.len() - 1)].trim_matches(white_space)\n            } else {\n                post_snippet\n            };\n\n            let post_comment = if !post_snippet_trimmed.is_empty() {\n                Some(post_snippet_trimmed.to_owned())\n            } else {\n                None\n            };\n\n            ListItem {\n                pre_comment: pre_comment,\n                item: (self.get_item_string)(&item),\n                post_comment: post_comment,\n                new_lines: new_lines,\n            }\n        })\n    }\n}\n\n// Creates an iterator over a list's items with associated comments.\npub fn itemize_list<'a, T, I, F1, F2, F3>(\n    codemap: &'a CodeMap,\n    inner: I,\n    terminator: &'a str,\n    get_lo: F1,\n    get_hi: F2,\n    get_item_string: F3,\n    prev_span_end: BytePos,\n    next_span_start: BytePos,\n) -> ListItems<'a, I, F1, F2, F3>\nwhere\n    I: Iterator<Item = T>,\n    F1: Fn(&T) -> BytePos,\n    F2: Fn(&T) -> BytePos,\n    F3: Fn(&T) -> Option<String>,\n{\n    ListItems {\n        codemap: codemap,\n        inner: inner.peekable(),\n        get_lo: get_lo,\n        get_hi: get_hi,\n        get_item_string: get_item_string,\n        prev_span_end: prev_span_end,\n        next_span_start: next_span_start,\n        terminator: terminator,\n    }\n}\n\nfn needs_trailing_separator(\n    separator_tactic: SeparatorTactic,\n    list_tactic: DefinitiveListTactic,\n) -> bool {\n    match separator_tactic {\n        SeparatorTactic::Always => true,\n        SeparatorTactic::Vertical => list_tactic == DefinitiveListTactic::Vertical,\n        SeparatorTactic::Never => false,\n    }\n}\n\n/// Returns the count and total width of the list items.\nfn calculate_width<I, T>(items: I) -> (usize, usize)\nwhere\n    I: IntoIterator<Item = T>,\n    T: AsRef<ListItem>,\n{\n    items\n        .into_iter()\n        .map(|item| total_item_width(item.as_ref()))\n        .fold((0, 0), |acc, l| (acc.0 + 1, acc.1 + l))\n}\n\nfn total_item_width(item: &ListItem) -> usize {\n    comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..])) +\n        comment_len(item.post_comment.as_ref().map(|x| &(*x)[..])) +\n        item.item.as_ref().map_or(0, |str| str.len())\n}\n\nfn comment_len(comment: Option<&str>) -> usize {\n    match comment {\n        Some(s) => {\n            let text_len = s.trim().len();\n            if text_len > 0 {\n                // We'll put \" /*\" before and \" */\" after inline comments.\n                text_len + 6\n            } else {\n                text_len\n            }\n        }\n        None => 0,\n    }\n}\n"
  },
  {
    "path": "example/rustfmt.toml",
    "content": "fn_args_layout = \"Block\"\narray_layout = \"Block\"\ncontrol_style = \"Rfc\"\nwhere_style = \"Rfc\"\ngenerics_indent = \"Block\"\nfn_call_style = \"Block\"\n"
  },
  {
    "path": "nightly-style-procedure.md",
    "content": "The style guide may or may not prescribe formatting behavior for nightly syntax\nin the \"nightly\" chapter in preparation for a feature's eventual stabilization\nor to reflect actual the behavior implemented by rustfmt around nightly syntax.\nThis behavior is not binding until the feature is stabilized and the text is moved\ninto the appropriate section of the style guide.\n\nInitial PR(s) implementing new syntax filed against rust-lang/rust should\ngenerally leave the rustfmt subtree untouched. In cases that that need to\nmodify rustfmt (for example, to fix compiler errors that come from adding\nnew variants to AST representation), they should modify rustfmt in such a\nway to keep existing formatting verbatim.\n\nRustfmt is allowed to implement nightly-only formatting behavior without that\nsyntax being specified by the style guide. The initial authors of PRs\nimplementing new features in rust-lang/rust are encouraged, but not\nrequired, to open a PR against\n[rustfmt](https://github.com/rust-lang/rustfmt) suggesting an initial\nformatting behavior, or formatting may later be implemented as a PR by anyone,\npending approval of the implementation from T-rustfmt. T-style should be\nnotified to approve the interim style proposed by these PRs, but this decision\nis not binding and may be revisited until the feature is stabilized and the\nformatting is codified in the style guide. \n\nMuch like breaking nightly feature changes in the Rust compiler, any changes\nto formatting behavior for nightly syntax should be made cautiously and with\nthorough consideration to avoid churn. Changes should not be done unnecessarily,\nand should take into account the feature's adoption\nand readiness for stabilization. However, changes may be done until the feature\nis stabilized for various reasons: new understanding of the feature's usage in\nthe language, recommendation from T-style, or changes in the implementation of\nthe feature.\n\nFeature stabilization should be blocked on confirmation and codification of\nformatting behavior. At this point, T-style may also propose alternative\nformatting at the time of stabilization, with any breaking changes weighted\naccording to the breaking changes principle stated above.\n"
  },
  {
    "path": "team-policy.md",
    "content": "# Style Team Policy Document\n\nThis is a living document tracking the active policies of the style team. It is intended to fill a similar role to the books that many[^1] teams[^2] maintain[^3] independently[^4]. If in the future Rust establishes central linking/indexing/aggregating of policies, these will need to appear there.\n\n* **Original RFC**: https://rust-lang.github.io/rfcs/3309-style-team.html\n* **Charter**: https://github.com/rust-lang/style-team/blob/HEAD/charter.md\n\n## Style Guide Evolution\n\nThe Rust style guide will generally match the latest version of the Rust style; the style team does not plan to maintain multiple branches of the style guide for different editions, in part because formatting for new constructs will apply to any edition supporting those constructs.\n\nWhenever possible, style decisions should be made before a new construct is stabilized. However, style decisions shall not be considered a blocker for stabilization.\n\n## Policy Review Process\n\nTo maintain the effectiveness and relevance of our policies, the style team implements a policy review process. The following guidelines outline how we conduct policy reviews:\n\n1. **Associated Review Dates**: Each policy should have a designated review date documented alongside the policy. These review dates are also added to the team's backlog for easy tracking and planning.\n2. **Consideration Factors**: When selecting review dates for policies, we consider several factors. These include:\n  1. **Confidence Level**: If a policy has recently changed or is relatively new, we opt for a shorter review period. This allows us to course correct quickly if needed.\n  2. **Stability and Effectiveness**: Policies that have remained unchanged for a considerable period and have proven effective can have longer review periods. This prevents unnecessary time spent on policies that are working well.\n3. **Integration into Regular Meetings**: Policy reviews are treated as regular agenda items during our team meetings. They are discussed and evaluated alongside other topics of importance.\n4. Review Process: Policy reviews should use a discussion approach that encourages each team member to provide feedback regarding the policy under review and creates a constructive environment where everyone is heard equally. Our current process is a *round*, in which each person is heard once before anyone responds or chimes in a second time. We start with the prompt, \"How effective has this policy been in your experience? Is it serving its intended purpose? How has it worked well, and how can it be improved? Are there other issues with the policy that we should consider?\".\n5. **Regular Review Cadence**: We review our policies regularly to identify any issues before they escalate into urgent problems proactively. By conducting these reviews systematically, we ensure that our policies remain up-to-date and aligned with our evolving needs.\n  1. **Default disposition**: In organizations without a policy review process, policies often remain in effect by default until explicitly rescinded. The policy review process partly reverses that default disposition: policies require regular review and must be renewed to remain in effect. (Such review and renewal still consider all of these other factors, such as the degree of previously established confidence in the policy and its stability over time.)\n\nBy adhering to this policy review process, we aim to maintain a high standard of quality and relevance in our style team policies.\n\n## Operational Roles\n\nThe style team has various operational roles to delegate related and ongoing work to specific individuals, to clarify on our operations, and to coordinate sharing feedback with the members in those roles to enable iterative self improvement.\n\n### Operational Lead\n\n* Current Holder: [@calebcartwright](https://github.com/calebcartwright)\n* Next Feedback Date: TODO\n\nIn order to stay in touch with where we want to be heading in the future, we need leadership. A team leader is paying attention to the team’s operations in relation to the team’s aim. What needs to be done, who agreed to do it. What is in the future to decide?\n\nResponsibilities:\n\n* Pays attention to the operation of the team\n* Pays attention to the team members\n* Reports wider context to the team\n\n### Facilitator\n\n* Current Holder: [@yaahc](https://github.com/yaahc)\n* Next Feedback Date: Wednesday 2023-02-01\n\nIn order to be present with each other, we need a good facilitator.  The facilitator runs meetings according to the format of meetings and decision making adopted by the group. Leader and facilitator are separate roles because facilitation and overseeing operations are different skill sets. They can be held by the same individual.\n\nResponsibilities:\n\n* Facilitates team meetings.\n* Pays attention to equivalence[^5] during meetings.\n* Supports planning of the agenda.\n* Distinguishes facilitator voice from team member voice.\n\n### Scribe\n\n* Current Holder: [@calebcartwright](https://github.com/calebcartwright)\n* Next Feedback Date: TODO\n\nIn order to manage continuity with the team’s past, we need to have written records. The scribe manages the notes during the meeting, makes sure the minutes are distributed and accessible.\n\nResponsibilities:\n\n* Makes sure meeting minutes are taken, approved, and stored.\n* Keeps track of all documents of the team.\n* Default interpreter of meeting minutes in cases of disagreement.\n* Supports planning the agenda from the backlog.\n    * Tracking when policies and roles are due for review.\n\n## Meetings\n\nThe style team meets weekly on Wednesdays at 12:30pm PST [(everytimezone link)](https://everytimezone.com/s/3f88a253) for a weekly video sync. Agendas are posted in the #T-style zulip stream. \n\nUnless otherwise noted, all of our meetings are public and open for anyone to attend. You will find the timing and event details on our [style team calendar](https://calendar.google.com/calendar/embed?src=d0564ed914a41cf4915bd5ebe6e2e4ec0ee1293fdc1d09d6f5bdb27d4f91c083%40group.calendar.google.com&ctz=America%2FLos_Angeles). We publish notes and minutes in written form in this github repository.\n\n### Agenda, Backlog, and Minutes\n\nThe style team stores its agendas, backlog, and meeting minutes in a single live hackmd document (rotating as necessary when the documents reach their length limit).\n\nThe agenda should be prepared in advanced of each meeting by the facilitator with the assistance of the scribe and the lead. The lead is responsible for looking forward and adding agenda items such as new requests from other teams and users or new priorities and goals. The scribe is responsible for looking backwards and adding agenda items from existing work such as items from the backlog or policies that are due for review. The agenda proposal is then presented at the beginning of each meeting by the facilitator for the rest of the team to consent or object too.\n\nConsent not needed to add to items to the backlog, anybody is welcome to add items to the backlog, but consent needed to move from backlog to agenda (since agendas themselves require consent). An item being present on the backlog does not represent a commitment by the style team.\n\n#### Interrupting the Agenda\n\nThe style team acknowledges that urgent needs may arise during the meeting. To address these needs, participants may interrupt the meeting by speaking up and immediately saying \"Point of Order.\" This signals to the meeting facilitator and other participants that the following point is not an out-of-order interruption but rather an urgent need that must take priority. This tool is designed for meta-level concerns that take priority over the current discussion, such as the scribe interrupting the meeting to address issues preventing the recording of minutes (and stopping the discussion until they can resume recording minutes), or a team member interrupting a discussion to raise questions of time bounds or team scope.\n\nThe meeting facilitator will then pause the current discussion, allow the participant to raise the point of order to state their concern and allow the team to address that point of order. After resolving the urgent matter, the facilitator will resume the previous discussion or return to the agenda. This policy is intended to ensure that the team can address urgent issues promptly without unnecessarily interrupting the flow of the meeting.\n\n#### Inform / Explore / Decide agenda item classification\n\nAgenda items are labeled according to their desired outcome. There are three possible outcomes for any given agenda item, inform, explore, or decide. Each of these outcomes builds upon the previous outcomes. In order to explore an item it must first be understood, and in order to make a decision one must both understand and explore the item first. Inform is used for things such as status updates, and usually involves first a report, followed by a round of clarifying questions. Explore is used for situations where one would like feedback on a potential issue or proposal, and usually involves reaction rounds. Decide is used when the team must reach a decision as a group, and it is usually achieved via a consensus round.\n\nWe identify the desired outcome in advance to avoid aimless discussions with unclear goals. The desired outcome can change during discussion as new information becomes available. It is the facilitator's responsibility to notice when this happens and formally make the change in the desired outcome with consent from the rest of the team. Extra clarity can be gained if, for every agenda item, we end by measuring whether we have achieved the desired outcome. Facilitators can make it a habit to pause before moving to a new agenda item by assessing whether the desired outcome has been achieved and by asking the scribe to read out loud what has been written in the notes.\n\nThe agenda backlog and minutes document is structured according to the following template:\n\n```md\n# T-style Minutes\n\nMeeting Link: \n\n## Action Items\n\n### Pending\n\n* owner: bullet point list of items that are in progress and assigned to a specific person\n\n### Completed\n\n- [ ] owner: check list of items that are completed or assumed to be complete\n- [x] owner: items are checked off once they've been reviewed in a meeting, confirmed complete, and given any relevant final status updates.\n- [x] owner: after a meeting the items that were checked off are moved into the `#### Completed Action Items` section of the meeting they were reviewed in by the scribe\n### Granularity\n\nAction items should not generally list individual feedback/response comments within GitHub threads. An action item should generally be at the level of a GitHub PR, and people can look at the GitHub PR to find out its current status. That status may affect whether the action item is blocked, or who needs to look at it, or whether there are aspects of the action item to discuss in a meeting.\n\n## Backlog\n\n* Bullet point list of items that have not been started or assigned yet\n\n## Next Meeting Date\n\n### Attendance\n\n### Agenda\n\n* (inform) bullet point list of proposed agenda items (labeled either inform, explore, or decide)\n* Review Action Items\n* Meeting Check-out\n    * Do not record in minutes, exceptions can be made with consent of team\n\n### Minutes\n\n#### Individual Agenda Items\n\nNotes related to the given agenda item\n\n#### Completed Action Items\n\n## Previous Meeting Dates <repeats>\n\n```\n### Meeting Check-out\n\nThe style team wraps up the content part of our meetings 5-10 minutes before team members have to leave to make room for regular meeting evaluations. Meeting evaluations are an integral part of every meeting. We end the meeting with one or two rounds on:\n\n* “What worked well in the meeting?”\n* “What could be improved in future meetings?”\n* “Is there anything you are carrying out of the meeting that you’d like to get off your chest now?”\n\nMeeting evaluations are an opportunity to learn from our meetings. We can either talk about content, process, or interpersonal dynamics. We utilize meeting evaluations to help ourselves inhabit a growth mindset. Our goal is to have meetings which are well-run, refreshing, connecting, and energizing. We achieve this goal by giving space for people to speak up about both the positive and negative aspects of how we're working together so that we can prioritize continuous improvement and positive connections.\n\nMeeting check-outs are considered private and internal to the style team and are not recorded as part of our minutes. Exceptions to this can be made via an operational consent decision by the team, and are often useful in cases such as when new backlog or action items come up during the check-out.\n\n[Style Guide]: https://github.com/rust-lang/rust/tree/HEAD/src/doc/style-guide/src\n[#T-style]: https://rust-lang.zulipchat.com/#narrow/stream/346005-t-style\n\n[^1]: https://rust-lang.github.io/compiler-team/\n[^2]: https://lang-team.rust-lang.org/\n[^3]: https://std-dev-guide.rust-lang.org/\n[^4]: https://rust-lang.github.io/types-team/\n[^5]: Equality, making sure everyone's voices and feedback are receiving equitable attention.\n"
  },
  {
    "path": "triagebot.toml",
    "content": "[assign]\nwarn_non_default_branch = true\n\n[assign.owners]\n\"*\" = \"style\"\n"
  }
]