about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--book/src/lint_configuration.md13
-rw-r--r--clippy_config/src/conf.rs47
-rw-r--r--clippy_config/src/types.rs108
-rw-r--r--clippy_lints/src/arbitrary_source_item_ordering.rs62
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml1
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml1
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml1
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml2
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml1
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml2
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml1
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr8
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr4
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr4
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs8
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr125
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr160
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr235
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs14
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr19
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr36
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr19
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr48
-rw-r--r--tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs46
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr3
26 files changed, 851 insertions, 118 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 51441ab9fc0..00323da7745 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6372,6 +6372,7 @@ Released 2018-09-13
 [`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
 [`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
 [`module-item-order-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-item-order-groupings
+[`module-items-ordered-within-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-items-ordered-within-groupings
 [`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv
 [`pass-by-value-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pass-by-value-size-limit
 [`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md
index 28b613ea329..3cd70ed18b5 100644
--- a/book/src/lint_configuration.md
+++ b/book/src/lint_configuration.md
@@ -744,6 +744,19 @@ The named groupings of different source item kinds within modules.
 * [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)
 
 
+## `module-items-ordered-within-groupings`
+Whether the items within module groups should be ordered alphabetically or not.
+
+This option can be configured to "all", "none", or a list of specific grouping names that should be checked
+(e.g. only "enums").
+
+**Default Value:** `"none"`
+
+---
+**Affected lints:**
+* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)
+
+
 ## `msrv`
 The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
 
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs
index 5cde7c8ac35..75f68d0dc5f 100644
--- a/clippy_config/src/conf.rs
+++ b/clippy_config/src/conf.rs
@@ -3,14 +3,17 @@ use crate::types::{
     DisallowedPath, DisallowedPathWithoutReplacement, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour,
     Rename, SourceItemOrdering, SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings,
     SourceItemOrderingModuleItemKind, SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
+    SourceItemOrderingWithinModuleItemGroupings,
 };
 use clippy_utils::msrvs::Msrv;
+use itertools::Itertools;
 use rustc_errors::Applicability;
 use rustc_session::Session;
 use rustc_span::edit_distance::edit_distance;
 use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
 use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor};
 use serde::{Deserialize, Deserializer, Serialize};
+use std::collections::HashMap;
 use std::fmt::{Debug, Display, Formatter};
 use std::ops::Range;
 use std::path::PathBuf;
@@ -79,6 +82,7 @@ const DEFAULT_SOURCE_ITEM_ORDERING: &[SourceItemOrderingCategory] = {
 #[derive(Default)]
 struct TryConf {
     conf: Conf,
+    value_spans: HashMap<String, Range<usize>>,
     errors: Vec<ConfError>,
     warnings: Vec<ConfError>,
 }
@@ -87,6 +91,7 @@ impl TryConf {
     fn from_toml_error(file: &SourceFile, error: &toml::de::Error) -> Self {
         Self {
             conf: Conf::default(),
+            value_spans: HashMap::default(),
             errors: vec![ConfError::from_toml(file, error)],
             warnings: vec![],
         }
@@ -210,6 +215,7 @@ macro_rules! define_Conf {
             }
 
             fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapAccess<'de> {
+                let mut value_spans = HashMap::new();
                 let mut errors = Vec::new();
                 let mut warnings = Vec::new();
                 $(let mut $name = None;)*
@@ -232,6 +238,7 @@ macro_rules! define_Conf {
                                     }
                                     None => {
                                         $name = Some(value);
+                                        value_spans.insert(name.get_ref().as_str().to_string(), value_span);
                                         // $new_conf is the same as one of the defined `$name`s, so
                                         // this variable is defined in line 2 of this function.
                                         $(match $new_conf {
@@ -250,7 +257,7 @@ macro_rules! define_Conf {
                     }
                 }
                 let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* };
-                Ok(TryConf { conf, errors, warnings })
+                Ok(TryConf { conf, value_spans, errors, warnings })
             }
         }
 
@@ -596,6 +603,13 @@ define_Conf! {
     /// The named groupings of different source item kinds within modules.
     #[lints(arbitrary_source_item_ordering)]
     module_item_order_groupings: SourceItemOrderingModuleItemGroupings = DEFAULT_MODULE_ITEM_ORDERING_GROUPS.into(),
+    /// Whether the items within module groups should be ordered alphabetically or not.
+    ///
+    /// This option can be configured to "all", "none", or a list of specific grouping names that should be checked
+    /// (e.g. only "enums").
+    #[lints(arbitrary_source_item_ordering)]
+    module_items_ordered_within_groupings: SourceItemOrderingWithinModuleItemGroupings =
+        SourceItemOrderingWithinModuleItemGroupings::None,
     /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
     #[default_text = "current version"]
     #[lints(
@@ -815,6 +829,36 @@ fn deserialize(file: &SourceFile) -> TryConf {
                 &mut conf.conf.allow_renamed_params_for,
                 DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS,
             );
+
+            // Confirms that the user has not accidentally configured ordering requirements for groups that
+            // aren't configured.
+            if let SourceItemOrderingWithinModuleItemGroupings::Custom(groupings) =
+                &conf.conf.module_items_ordered_within_groupings
+            {
+                for grouping in groupings {
+                    if !conf.conf.module_item_order_groupings.is_grouping(grouping) {
+                        // Since this isn't fixable by rustfix, don't emit a `Suggestion`. This just adds some useful
+                        // info for the user instead.
+
+                        let names = conf.conf.module_item_order_groupings.grouping_names();
+                        let suggestion = suggest_candidate(grouping, names.iter().map(String::as_str))
+                            .map(|s| format!(" perhaps you meant `{s}`?"))
+                            .unwrap_or_default();
+                        let names = names.iter().map(|s| format!("`{s}`")).join(", ");
+                        let message = format!(
+                            "unknown ordering group: `{grouping}` was not specified in `module-items-ordered-within-groupings`,{suggestion} expected one of: {names}"
+                        );
+
+                        let span = conf
+                            .value_spans
+                            .get("module_item_order_groupings")
+                            .cloned()
+                            .unwrap_or_default();
+                        conf.errors.push(ConfError::spanned(file, message, None, span));
+                    }
+                }
+            }
+
             // TODO: THIS SHOULD BE TESTED, this comment will be gone soon
             if conf.conf.allowed_idents_below_min_chars.iter().any(|e| e == "..") {
                 conf.conf
@@ -860,6 +904,7 @@ impl Conf {
 
         let TryConf {
             mut conf,
+            value_spans: _,
             errors,
             warnings,
         } = match path {
diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs
index c72291e9799..8faac9ecffe 100644
--- a/clippy_config/src/types.rs
+++ b/clippy_config/src/types.rs
@@ -305,6 +305,7 @@ impl SourceItemOrderingModuleItemKind {
 pub struct SourceItemOrderingModuleItemGroupings {
     groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)>,
     lut: HashMap<SourceItemOrderingModuleItemKind, usize>,
+    back_lut: HashMap<SourceItemOrderingModuleItemKind, String>,
 }
 
 impl SourceItemOrderingModuleItemGroupings {
@@ -320,6 +321,30 @@ impl SourceItemOrderingModuleItemGroupings {
         lut
     }
 
+    fn build_back_lut(
+        groups: &[(String, Vec<SourceItemOrderingModuleItemKind>)],
+    ) -> HashMap<SourceItemOrderingModuleItemKind, String> {
+        let mut lut = HashMap::new();
+        for (group_name, items) in groups {
+            for item in items {
+                lut.insert(item.clone(), group_name.clone());
+            }
+        }
+        lut
+    }
+
+    pub fn grouping_name_of(&self, item: &SourceItemOrderingModuleItemKind) -> Option<&String> {
+        self.back_lut.get(item)
+    }
+
+    pub fn grouping_names(&self) -> Vec<String> {
+        self.groups.iter().map(|(name, _)| name.clone()).collect()
+    }
+
+    pub fn is_grouping(&self, grouping: &str) -> bool {
+        self.groups.iter().any(|(g, _)| g == grouping)
+    }
+
     pub fn module_level_order_of(&self, item: &SourceItemOrderingModuleItemKind) -> Option<usize> {
         self.lut.get(item).copied()
     }
@@ -330,7 +355,8 @@ impl From<&[(&str, &[SourceItemOrderingModuleItemKind])]> for SourceItemOrdering
         let groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)> =
             value.iter().map(|item| (item.0.to_string(), item.1.to_vec())).collect();
         let lut = Self::build_lut(&groups);
-        Self { groups, lut }
+        let back_lut = Self::build_back_lut(&groups);
+        Self { groups, lut, back_lut }
     }
 }
 
@@ -348,6 +374,7 @@ impl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {
         let groups = Vec::<(String, Vec<SourceItemOrderingModuleItemKind>)>::deserialize(deserializer)?;
         let items_total: usize = groups.iter().map(|(_, v)| v.len()).sum();
         let lut = Self::build_lut(&groups);
+        let back_lut = Self::build_back_lut(&groups);
 
         let mut expected_items = SourceItemOrderingModuleItemKind::all_variants();
         for item in lut.keys() {
@@ -370,7 +397,7 @@ impl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {
                 ));
             }
 
-            Ok(Self { groups, lut })
+            Ok(Self { groups, lut, back_lut })
         } else if items_total != all_items.len() {
             Err(de::Error::custom(format!(
                 "Some module item kinds were configured more than once, or were missing, in the source ordering configuration. \
@@ -482,6 +509,83 @@ impl Serialize for SourceItemOrderingTraitAssocItemKinds {
     }
 }
 
+/// Describes which specific groupings should have their items ordered
+/// alphabetically.
+///
+/// This is separate from defining and enforcing groupings. For example,
+/// defining enums are grouped before structs still allows for an enum B to be
+/// placed before an enum A. Only when enforcing ordering within the grouping,
+/// will it be checked if A is placed before B.
+#[derive(Clone, Debug)]
+pub enum SourceItemOrderingWithinModuleItemGroupings {
+    /// All groupings should have their items ordered.
+    All,
+
+    /// None of the groupings should have their order checked.
+    None,
+
+    /// Only the specified groupings should have their order checked.
+    Custom(Vec<String>),
+}
+
+impl SourceItemOrderingWithinModuleItemGroupings {
+    pub fn ordered_within(&self, grouping_name: &String) -> bool {
+        match self {
+            SourceItemOrderingWithinModuleItemGroupings::All => true,
+            SourceItemOrderingWithinModuleItemGroupings::None => false,
+            SourceItemOrderingWithinModuleItemGroupings::Custom(groups) => groups.contains(grouping_name),
+        }
+    }
+}
+
+/// Helper struct for deserializing the [`SourceItemOrderingWithinModuleItemGroupings`].
+#[derive(Deserialize)]
+#[serde(untagged)]
+enum StringOrVecOfString {
+    String(String),
+    Vec(Vec<String>),
+}
+
+impl<'de> Deserialize<'de> for SourceItemOrderingWithinModuleItemGroupings {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let description = "The available options for configuring an ordering within module item groups are: \
+                    \"all\", \"none\", or a list of module item group names \
+                    (as configured with the `module-item-order-groupings` configuration option).";
+
+        match StringOrVecOfString::deserialize(deserializer) {
+            Ok(StringOrVecOfString::String(preset)) if preset == "all" => {
+                Ok(SourceItemOrderingWithinModuleItemGroupings::All)
+            },
+            Ok(StringOrVecOfString::String(preset)) if preset == "none" => {
+                Ok(SourceItemOrderingWithinModuleItemGroupings::None)
+            },
+            Ok(StringOrVecOfString::String(preset)) => Err(de::Error::custom(format!(
+                "Unknown configuration option: {preset}.\n{description}"
+            ))),
+            Ok(StringOrVecOfString::Vec(groupings)) => {
+                Ok(SourceItemOrderingWithinModuleItemGroupings::Custom(groupings))
+            },
+            Err(e) => Err(de::Error::custom(format!("{e}\n{description}"))),
+        }
+    }
+}
+
+impl Serialize for SourceItemOrderingWithinModuleItemGroupings {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: ser::Serializer,
+    {
+        match self {
+            SourceItemOrderingWithinModuleItemGroupings::All => serializer.serialize_str("all"),
+            SourceItemOrderingWithinModuleItemGroupings::None => serializer.serialize_str("none"),
+            SourceItemOrderingWithinModuleItemGroupings::Custom(vec) => vec.serialize(serializer),
+        }
+    }
+}
+
 // these impls are never actually called but are used by the various config options that default to
 // empty lists
 macro_rules! unimplemented_serialize {
diff --git a/clippy_lints/src/arbitrary_source_item_ordering.rs b/clippy_lints/src/arbitrary_source_item_ordering.rs
index c0ae4960e10..cf4fe45936c 100644
--- a/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -2,6 +2,7 @@ use clippy_config::Conf;
 use clippy_config::types::{
     SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind,
     SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
+    SourceItemOrderingWithinModuleItemGroupings,
 };
 use clippy_utils::diagnostics::span_lint_and_note;
 use rustc_hir::{
@@ -36,7 +37,7 @@ declare_clippy_lint! {
     /// 2. Individual ordering rules per item kind.
     ///
     /// The item kinds that can be linted are:
-    /// - Module (with customized groupings, alphabetical within)
+    /// - Module (with customized groupings, alphabetical within - configurable)
     /// - Trait (with customized order of associated items, alphabetical within)
     /// - Enum, Impl, Struct (purely alphabetical)
     ///
@@ -57,8 +58,31 @@ declare_clippy_lint! {
     /// | `PascalCase`       | "ty_alias", "opaque_ty", "enum", "struct", "union", "trait", "trait_alias", "impl" |
     /// | `lower_snake_case` | "fn"                 |
     ///
+    /// The groups' names are arbitrary and can be changed to suit the
+    /// conventions that should be enforced for a specific project.
+    ///
     /// All item kinds must be accounted for to create an enforceable linting
-    /// rule set.
+    /// rule set. Following are some example configurations that may be useful.
+    ///
+    /// Example: *module inclusions and use statements to be at the top*
+    ///
+    /// ```toml
+    /// module-item-order-groupings = [
+    ///     [ "modules", [ "extern_crate", "mod", "foreign_mod" ], ],
+    ///     [ "use", [ "use", ], ],
+    ///     [ "everything_else", [ "macro", "global_asm", "static", "const", "ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl", "fn", ], ],
+    /// ]
+    /// ```
+    ///
+    /// Example: *only consts and statics should be alphabetically ordered*
+    ///
+    /// It is also possible to configure a selection of module item groups that
+    /// should be ordered alphabetically. This may be useful if for example
+    /// statics and consts should be ordered, but the rest should be left open.
+    ///
+    /// ```toml
+    /// module-items-ordered-within-groupings = ["UPPER_SNAKE_CASE"]
+    /// ```
     ///
     /// ### Known Problems
     ///
@@ -143,6 +167,7 @@ pub struct ArbitrarySourceItemOrdering {
     enable_ordering_for_struct: bool,
     enable_ordering_for_trait: bool,
     module_item_order_groupings: SourceItemOrderingModuleItemGroupings,
+    module_items_ordered_within_groupings: SourceItemOrderingWithinModuleItemGroupings,
 }
 
 impl ArbitrarySourceItemOrdering {
@@ -157,6 +182,7 @@ impl ArbitrarySourceItemOrdering {
             enable_ordering_for_struct: conf.source_item_ordering.contains(&Struct),
             enable_ordering_for_trait: conf.source_item_ordering.contains(&Trait),
             module_item_order_groupings: conf.module_item_order_groupings.clone(),
+            module_items_ordered_within_groupings: conf.module_items_ordered_within_groupings.clone(),
         }
     }
 
@@ -191,7 +217,7 @@ impl ArbitrarySourceItemOrdering {
         );
     }
 
-    fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>) {
+    fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) {
         let span = if item.ident.as_str().is_empty() {
             &item.span
         } else {
@@ -215,14 +241,7 @@ impl ArbitrarySourceItemOrdering {
             return;
         }
 
-        span_lint_and_note(
-            cx,
-            ARBITRARY_SOURCE_ITEM_ORDERING,
-            *span,
-            "incorrect ordering of items (must be alphabetically ordered)",
-            Some(*before_span),
-            note,
-        );
+        span_lint_and_note(cx, ARBITRARY_SOURCE_ITEM_ORDERING, *span, msg, Some(*before_span), note);
     }
 
     /// Produces a linting warning for incorrectly ordered trait items.
@@ -402,6 +421,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             }
 
             let item_kind = convert_module_item_kind(&item.kind);
+            let grouping_name = self.module_item_order_groupings.grouping_name_of(&item_kind);
             let module_level_order = self
                 .module_item_order_groupings
                 .module_level_order_of(&item_kind)
@@ -411,13 +431,27 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                 use std::cmp::Ordering; // Better legibility.
                 match module_level_order.cmp(&cur_t.order) {
                     Ordering::Less => {
-                        Self::lint_member_item(cx, item, cur_t.item);
+                        Self::lint_member_item(
+                            cx,
+                            item,
+                            cur_t.item,
+                            "incorrect ordering of items (module item groupings specify another order)",
+                        );
                     },
                     Ordering::Equal if item_kind == SourceItemOrderingModuleItemKind::Use => {
                         // Skip ordering use statements, as these should be ordered by rustfmt.
                     },
-                    Ordering::Equal if cur_t.name > get_item_name(item) => {
-                        Self::lint_member_item(cx, item, cur_t.item);
+                    Ordering::Equal
+                        if (grouping_name.is_some_and(|grouping_name| {
+                            self.module_items_ordered_within_groupings.ordered_within(grouping_name)
+                        }) && cur_t.name > get_item_name(item)) =>
+                    {
+                        Self::lint_member_item(
+                            cx,
+                            item,
+                            cur_t.item,
+                            "incorrect ordering of items (must be alphabetically ordered)",
+                        );
                     },
                     Ordering::Equal | Ordering::Greater => {
                         // Nothing to do in this case, they're already in the right order.
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml b/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml
new file mode 100644
index 00000000000..baf7041138f
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = true
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml b/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml
new file mode 100644
index 00000000000..1fa80c73012
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = ["madules"]
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml b/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml
new file mode 100644
index 00000000000..cee857a155b
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = ["entirely garbled"]
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml b/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
index ddca5cfa577..af3aa1cc62a 100644
--- a/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
+++ b/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
@@ -9,4 +9,4 @@ module-item-order-groupings = [
     ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]],
     ["lower_snake_case", ["fn"]]
 ]
-
+module-items-ordered-within-groupings = "none"
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml b/tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml
new file mode 100644
index 00000000000..fd961c82d6f
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = ["PascalCase"]
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml b/tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml
new file mode 100644
index 00000000000..de2a7307eca
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml
@@ -0,0 +1,2 @@
+source-item-ordering = ["module"]
+module-items-ordered-within-groupings = ["PascalCase"]
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml b/tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml
new file mode 100644
index 00000000000..e7640efde10
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = "all"
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr
new file mode 100644
index 00000000000..c38c54ffeb0
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr
@@ -0,0 +1,8 @@
+error: error reading Clippy's configuration file: data did not match any variant of untagged enum StringOrVecOfString  The available options for configuring an ordering within module item groups are: "all", "none", or a list of module item group names (as configured with the `module-item-order-groupings` configuration option).
+  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml:1:41
+   |
+LL | module-items-ordered-within-groupings = true
+   |                                         ^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr
new file mode 100644
index 00000000000..7b1dafb6d0d
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr
@@ -0,0 +1,4 @@
+error: error reading Clippy's configuration file: unknown ordering group: `madules` was not specified in `module-items-ordered-within-groupings`, perhaps you meant `modules`? expected one of: `modules`, `use`, `macros`, `global_asm`, `UPPER_SNAKE_CASE`, `PascalCase`, `lower_snake_case`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr
new file mode 100644
index 00000000000..996cabeeed4
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr
@@ -0,0 +1,4 @@
+error: error reading Clippy's configuration file: unknown ordering group: `entirely garbled` was not specified in `module-items-ordered-within-groupings`, expected one of: `modules`, `use`, `macros`, `global_asm`, `UPPER_SNAKE_CASE`, `PascalCase`, `lower_snake_case`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
index 05eb40506db..b43791521cb 100644
--- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
@@ -1,15 +1,21 @@
 //@aux-build:../../ui/auxiliary/proc_macros.rs
-//@revisions: default default_exp bad_conf_1 bad_conf_2 bad_conf_3
+//@revisions: default default_exp bad_conf_1 bad_conf_2 bad_conf_3 bad_conf_4 bad_conf_5 bad_conf_6
 //@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
 //@[default_exp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default_exp
 //@[bad_conf_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1
 //@[bad_conf_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2
 //@[bad_conf_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3
+//@[bad_conf_4] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4
+//@[bad_conf_5] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5
+//@[bad_conf_6] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6
 //@[default] check-pass
 //@[default_exp] check-pass
 //@[bad_conf_1] error-in-other-file:
 //@[bad_conf_2] error-in-other-file:
 //@[bad_conf_3] error-in-other-file:
+//@[bad_conf_4] error-in-other-file:
+//@[bad_conf_5] error-in-other-file:
+//@[bad_conf_6] error-in-other-file:
 
 #![allow(dead_code)]
 #![warn(clippy::arbitrary_source_item_ordering)]
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
index 3605952bddc..50567e32b1b 100644
--- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
@@ -1,223 +1,160 @@
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:22:14
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14
    |
 LL | use std::rc::Weak;
    |              ^^^^
    |
 note: should be placed before `SNAKE_CASE`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:20:7
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
    |
 LL | const SNAKE_CASE: &str = "zzzzzzzz";
    |       ^^^^^^^^^^
    = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:67:1
-   |
-LL | / impl CloneSelf for StructOrdered {
-LL | |
-LL | |     fn clone_self(&self) -> Self {
-LL | |         Self {
-...  |
-LL | | }
-   | |_^
-   |
-note: should be placed before the following item
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:1
-   |
-LL | / impl Default for StructOrdered {
-LL | |     fn default() -> Self {
-LL | |         Self {
-LL | |             a: true,
-...  |
-LL | | }
-   | |_^
-
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:145:7
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:149:7
    |
 LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `TraitUnorderedItemKinds`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:7
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7
    |
 LL | trait TraitUnorderedItemKinds {
    |       ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:163:1
-   |
-LL | impl BasicEmptyTrait for StructOrdered {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: should be placed before the following item
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:148:1
-   |
-LL | / impl TraitUnordered for StructUnordered {
-LL | |     const A: bool = false;
-LL | |     const C: bool = false;
-LL | |     const B: bool = false;
-...  |
-LL | | }
-   | |_^
-
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:184:5
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:188:5
    |
 LL | mod this_is_in_the_wrong_position {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `main`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:179:4
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:183:4
    |
 LL | fn main() {
    |    ^^^^
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:194:7
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:198:7
    |
 LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `ZisShouldBeBeforeZeMainFn`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:192:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:196:8
    |
 LL | struct ZisShouldBeBeforeZeMainFn;
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:12:11
-   |
-LL |     const AFTER: i8 = 0;
-   |           ^^^^^
-   |
-note: should be placed before `BEFORE`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:10:11
-   |
-LL |     const BEFORE: i8 = 0;
-   |           ^^^^^^
-
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:40:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5
    |
 LL |     B,
    |     ^
    |
 note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:39:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5
    |
 LL |     C,
    |     ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:92:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5
    |
 LL |     b: bool,
    |     ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:91:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5
    |
 LL |     c: bool,
    |     ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:101:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:105:5
    |
 LL |     b: bool,
    |     ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:100:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:104:5
    |
 LL |     c: bool,
    |     ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:11
    |
 LL |     const B: bool;
    |           ^
    |
 note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:11
    |
 LL |     const C: bool;
    |           ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:128:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:8
    |
 LL |     fn b();
    |        ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:127:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:131:8
    |
 LL |     fn c();
    |        ^
 
 error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:135:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:139:5
    |
 LL |     const A: bool;
    |     ^^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:133:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:137:5
    |
 LL |     type SomeType;
    |     ^^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:151:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:11
    |
 LL |     const B: bool = false;
    |           ^
    |
 note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:150:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:11
    |
 LL |     const C: bool = false;
    |           ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:158:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:162:8
    |
 LL |     fn b() {}
    |        ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:157:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:161:8
    |
 LL |     fn c() {}
    |        ^
 
 error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:169:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:173:5
    |
 LL |     const A: bool = false;
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:167:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:5
    |
 LL |     type SomeType = ();
    |     ^^^^^^^^^^^^^^^^^^^
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:11
-   |
-LL |     const A: i8 = 1;
-   |           ^
-   |
-note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:186:11
-   |
-LL |     const C: i8 = 0;
-   |           ^
-
-error: aborting due to 17 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr
new file mode 100644
index 00000000000..50567e32b1b
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr
@@ -0,0 +1,160 @@
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14
+   |
+LL | use std::rc::Weak;
+   |              ^^^^
+   |
+note: should be placed before `SNAKE_CASE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
+   |
+LL | const SNAKE_CASE: &str = "zzzzzzzz";
+   |       ^^^^^^^^^^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:149:7
+   |
+LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `TraitUnorderedItemKinds`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7
+   |
+LL | trait TraitUnorderedItemKinds {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:188:5
+   |
+LL | mod this_is_in_the_wrong_position {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `main`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:183:4
+   |
+LL | fn main() {
+   |    ^^^^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:198:7
+   |
+LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `ZisShouldBeBeforeZeMainFn`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:196:8
+   |
+LL | struct ZisShouldBeBeforeZeMainFn;
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5
+   |
+LL |     B,
+   |     ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5
+   |
+LL |     C,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:105:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:104:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:11
+   |
+LL |     const B: bool;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:11
+   |
+LL |     const C: bool;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:8
+   |
+LL |     fn b();
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:131:8
+   |
+LL |     fn c();
+   |        ^
+
+error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:139:5
+   |
+LL |     const A: bool;
+   |     ^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:137:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:11
+   |
+LL |     const B: bool = false;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:11
+   |
+LL |     const C: bool = false;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:162:8
+   |
+LL |     fn b() {}
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:161:8
+   |
+LL |     fn c() {}
+   |        ^
+
+error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:173:5
+   |
+LL |     const A: bool = false;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:5
+   |
+LL |     type SomeType = ();
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 13 previous errors
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr
new file mode 100644
index 00000000000..ae5261dcc6d
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr
@@ -0,0 +1,235 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
+   |
+LL | const SNAKE_CASE: &str = "zzzzzzzz";
+   |       ^^^^^^^^^^
+   |
+note: should be placed before `ZNAKE_CASE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:22:7
+   |
+LL | const ZNAKE_CASE: &str = "123";
+   |       ^^^^^^^^^^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14
+   |
+LL | use std::rc::Weak;
+   |              ^^^^
+   |
+note: should be placed before `SNAKE_CASE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
+   |
+LL | const SNAKE_CASE: &str = "zzzzzzzz";
+   |       ^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:71:1
+   |
+LL | / impl CloneSelf for StructOrdered {
+LL | |
+LL | |     fn clone_self(&self) -> Self {
+LL | |         Self {
+...  |
+LL | | }
+   | |_^
+   |
+note: should be placed before the following item
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:61:1
+   |
+LL | / impl Default for StructOrdered {
+LL | |     fn default() -> Self {
+LL | |         Self {
+LL | |             a: true,
+...  |
+LL | | }
+   | |_^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:149:7
+   |
+LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `TraitUnorderedItemKinds`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7
+   |
+LL | trait TraitUnorderedItemKinds {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:167:1
+   |
+LL | impl BasicEmptyTrait for StructOrdered {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before the following item
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:152:1
+   |
+LL | / impl TraitUnordered for StructUnordered {
+LL | |     const A: bool = false;
+LL | |     const C: bool = false;
+LL | |     const B: bool = false;
+...  |
+LL | | }
+   | |_^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:188:5
+   |
+LL | mod this_is_in_the_wrong_position {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `main`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:183:4
+   |
+LL | fn main() {
+   |    ^^^^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:198:7
+   |
+LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `ZisShouldBeBeforeZeMainFn`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:196:8
+   |
+LL | struct ZisShouldBeBeforeZeMainFn;
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:14:11
+   |
+LL |     const AFTER: i8 = 0;
+   |           ^^^^^
+   |
+note: should be placed before `BEFORE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:12:11
+   |
+LL |     const BEFORE: i8 = 0;
+   |           ^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5
+   |
+LL |     B,
+   |     ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5
+   |
+LL |     C,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:105:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:104:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:11
+   |
+LL |     const B: bool;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:11
+   |
+LL |     const C: bool;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:8
+   |
+LL |     fn b();
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:131:8
+   |
+LL |     fn c();
+   |        ^
+
+error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:139:5
+   |
+LL |     const A: bool;
+   |     ^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:137:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:11
+   |
+LL |     const B: bool = false;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:11
+   |
+LL |     const C: bool = false;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:162:8
+   |
+LL |     fn b() {}
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:161:8
+   |
+LL |     fn c() {}
+   |        ^
+
+error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:173:5
+   |
+LL |     const A: bool = false;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:5
+   |
+LL |     type SomeType = ();
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:191:11
+   |
+LL |     const A: i8 = 1;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:190:11
+   |
+LL |     const C: i8 = 0;
+   |           ^
+
+error: aborting due to 18 previous errors
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
index 9e65a9cca0d..90399470d4c 100644
--- a/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
+++ b/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
@@ -1,6 +1,8 @@
 //@aux-build:../../ui/auxiliary/proc_macros.rs
-//@revisions: default
+//@revisions: default default_exp ord_within
 //@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
+//@[default_exp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default_exp
+//@[ord_within] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_within
 
 #![allow(dead_code)]
 #![warn(clippy::arbitrary_source_item_ordering)]
@@ -10,14 +12,16 @@ mod i_am_just_right {
     const BEFORE: i8 = 0;
 
     const AFTER: i8 = 0;
-    //~^ arbitrary_source_item_ordering
+    //~[ord_within]^ arbitrary_source_item_ordering
 }
 
 // Use statements should not be linted internally - this is normally auto-sorted using rustfmt.
 use std::rc::Rc;
 use std::sync::{Arc, Barrier, RwLock};
 
+const ZNAKE_CASE: &str = "123";
 const SNAKE_CASE: &str = "zzzzzzzz";
+//~[ord_within]^ arbitrary_source_item_ordering
 
 use std::rc::Weak;
 //~^ arbitrary_source_item_ordering
@@ -65,7 +69,7 @@ impl Default for StructOrdered {
 }
 
 impl CloneSelf for StructOrdered {
-    //~^ arbitrary_source_item_ordering
+    //~[ord_within]^ arbitrary_source_item_ordering
     fn clone_self(&self) -> Self {
         Self {
             a: true,
@@ -161,7 +165,7 @@ impl TraitUnordered for StructUnordered {
 
 // Trait impls should be located just after the type they implement it for.
 impl BasicEmptyTrait for StructOrdered {}
-//~^ arbitrary_source_item_ordering
+//~[ord_within]^ arbitrary_source_item_ordering
 
 impl TraitUnorderedItemKinds for StructUnordered {
     type SomeType = ();
@@ -185,7 +189,7 @@ mod this_is_in_the_wrong_position {
     //~^ arbitrary_source_item_ordering
     const C: i8 = 0;
     const A: i8 = 1;
-    //~^ arbitrary_source_item_ordering
+    //~[ord_within]^ arbitrary_source_item_ordering
 }
 
 #[derive(Default, std::clone::Clone)]
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr
new file mode 100644
index 00000000000..7fc216b30d5
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr
@@ -0,0 +1,19 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5
+   |
+LL |     a: bool,
+   |     ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:34:5
+   |
+LL |     b: bool,
+   |     ^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:32:8
+   |
+LL | #[deny(clippy::arbitrary_source_item_ordering)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr
new file mode 100644
index 00000000000..1f75f5099ec
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr
@@ -0,0 +1,36 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:24:8
+   |
+LL | struct OrderedChecked {
+   |        ^^^^^^^^^^^^^^
+   |
+note: should be placed before `Unordered`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:18:8
+   |
+LL | struct Unordered {
+   |        ^^^^^^^^^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:9:9
+   |
+LL | #![deny(clippy::arbitrary_source_item_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5
+   |
+LL |     a: bool,
+   |     ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:34:5
+   |
+LL |     b: bool,
+   |     ^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:32:8
+   |
+LL | #[deny(clippy::arbitrary_source_item_ordering)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr
new file mode 100644
index 00000000000..8027f55add6
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr
@@ -0,0 +1,19 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:24:8
+   |
+LL | struct OrderedChecked {
+   |        ^^^^^^^^^^^^^^
+   |
+note: should be placed before `Unordered`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:18:8
+   |
+LL | struct Unordered {
+   |        ^^^^^^^^^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:9:9
+   |
+LL | #![deny(clippy::arbitrary_source_item_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr
new file mode 100644
index 00000000000..333a601f6a9
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr
@@ -0,0 +1,48 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:24:8
+   |
+LL | struct OrderedChecked {
+   |        ^^^^^^^^^^^^^^
+   |
+note: should be placed before `Unordered`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:18:8
+   |
+LL | struct Unordered {
+   |        ^^^^^^^^^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:9:9
+   |
+LL | #![deny(clippy::arbitrary_source_item_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:45:4
+   |
+LL | fn before_main() {}
+   |    ^^^^^^^^^^^
+   |
+note: should be placed before `main`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:41:4
+   |
+LL | fn main() {
+   |    ^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5
+   |
+LL |     a: bool,
+   |     ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:34:5
+   |
+LL |     b: bool,
+   |     ^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:32:8
+   |
+LL | #[deny(clippy::arbitrary_source_item_ordering)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs
new file mode 100644
index 00000000000..e32b921dd96
--- /dev/null
+++ b/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs
@@ -0,0 +1,46 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: default ord_within ord_in_2 ord_in_3
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
+//@[ord_within] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_within
+//@[ord_in_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_in_2
+//@[ord_in_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_in_3
+
+#![allow(dead_code)]
+#![deny(clippy::arbitrary_source_item_ordering)]
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+struct Ordered {
+    a: bool,
+    b: bool,
+}
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+struct Unordered {
+    b: bool,
+    a: bool,
+}
+
+#[deny(clippy::arbitrary_source_item_ordering)]
+struct OrderedChecked {
+    //~[ord_within]^ arbitrary_source_item_ordering
+    //~[ord_in_2]| arbitrary_source_item_ordering
+    //~[ord_in_3]| arbitrary_source_item_ordering
+    a: bool,
+    b: bool,
+}
+
+#[deny(clippy::arbitrary_source_item_ordering)]
+struct UnorderedChecked {
+    b: bool,
+    a: bool,
+    //~[ord_within]^ arbitrary_source_item_ordering
+    //~[default]| arbitrary_source_item_ordering
+    //~[ord_in_2]| arbitrary_source_item_ordering
+}
+
+fn main() {
+    // test code goes here
+}
+
+fn before_main() {}
+//~[ord_within]^ arbitrary_source_item_ordering
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index acfe739277c..fee5b01b689 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -60,6 +60,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            min-ident-chars-threshold
            missing-docs-in-crate-items
            module-item-order-groupings
+           module-items-ordered-within-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
@@ -152,6 +153,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            min-ident-chars-threshold
            missing-docs-in-crate-items
            module-item-order-groupings
+           module-items-ordered-within-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
@@ -244,6 +246,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            min-ident-chars-threshold
            missing-docs-in-crate-items
            module-item-order-groupings
+           module-items-ordered-within-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior