Skip to content

Commit 844fadb

Browse files
authored
Check structs and enums for use_self (rust-lang#15566)
Closes rust-lang/rust-clippy#15555 changelog: [`use_self`]: Check structs and enums
2 parents 57913b4 + b71fe92 commit 844fadb

File tree

18 files changed

+463
-10
lines changed

18 files changed

+463
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7052,6 +7052,7 @@ Released 2018-09-13
70527052
[`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv
70537053
[`pass-by-value-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pass-by-value-size-limit
70547054
[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
7055+
[`recursive-self-in-type-definitions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#recursive-self-in-type-definitions
70557056
[`semicolon-inside-block-ignore-singleline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-inside-block-ignore-singleline
70567057
[`semicolon-outside-block-ignore-multiline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-outside-block-ignore-multiline
70577058
[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold

book/src/lint_configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,16 @@ exported visibility, or whether they are marked as "pub".
927927
* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
928928

929929

930+
## `recursive-self-in-type-definitions`
931+
Whether the type itself in a struct or enum should be replaced with `Self` when encountering recursive types.
932+
933+
**Default Value:** `true`
934+
935+
---
936+
**Affected lints:**
937+
* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
938+
939+
930940
## `semicolon-inside-block-ignore-singleline`
931941
Whether to lint only if it's multiline.
932942

clippy_config/src/conf.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,9 @@ define_Conf! {
809809
/// exported visibility, or whether they are marked as "pub".
810810
#[lints(pub_underscore_fields)]
811811
pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PubliclyExported,
812+
/// Whether the type itself in a struct or enum should be replaced with `Self` when encountering recursive types.
813+
#[lints(use_self)]
814+
recursive_self_in_type_definitions: bool = true,
812815
/// Whether to lint only if it's multiline.
813816
#[lints(semicolon_inside_block)]
814817
semicolon_inside_block_ignore_singleline: bool = false,

clippy_lints/src/matches/single_match.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ enum PatState<'a> {
224224
/// A std enum we know won't be extended. Tracks the states of each variant separately.
225225
///
226226
/// This is not used for `Option` since it uses the current pattern to track its state.
227-
StdEnum(&'a mut [PatState<'a>]),
227+
StdEnum(&'a mut [Self]),
228228
/// Either the initial state for a pattern or a non-std enum. There is currently no need to
229229
/// distinguish these cases.
230230
///

clippy_lints/src/use_self.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,15 @@ declare_clippy_lint! {
5858
pub struct UseSelf {
5959
msrv: Msrv,
6060
stack: Vec<StackItem>,
61+
recursive_self_in_type_definitions: bool,
6162
}
6263

6364
impl UseSelf {
6465
pub fn new(conf: &'static Conf) -> Self {
6566
Self {
6667
msrv: conf.msrv,
6768
stack: Vec::new(),
69+
recursive_self_in_type_definitions: conf.recursive_self_in_type_definitions,
6870
}
6971
}
7072
}
@@ -84,10 +86,10 @@ const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
8486

8587
impl<'tcx> LateLintPass<'tcx> for UseSelf {
8688
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
87-
// We push the self types of `impl`s on a stack here. Only the top type on the stack is
88-
// relevant for linting, since this is the self type of the `impl` we're currently in. To
89-
// avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that
90-
// we're in an `impl` or nested item, that we don't want to lint
89+
// We push the self types of items on a stack here. Only the top type on the stack is
90+
// relevant for linting, since this is the self type of the item we're currently in. To
91+
// avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal that
92+
// we're in an item or nested item that we don't want to lint
9193
let stack_item = if let ItemKind::Impl(Impl { self_ty, generics, .. }) = item.kind
9294
&& let TyKind::Path(QPath::Resolved(_, item_path)) = self_ty.kind
9395
&& let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args
@@ -112,6 +114,15 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
112114
impl_id: item.owner_id.def_id,
113115
types_to_skip,
114116
}
117+
} else if let ItemKind::Struct(..) | ItemKind::Enum(..) = item.kind
118+
&& self.recursive_self_in_type_definitions
119+
&& !item.span.from_expansion()
120+
&& !is_from_proc_macro(cx, item)
121+
{
122+
StackItem::Check {
123+
impl_id: item.owner_id.def_id,
124+
types_to_skip: FxHashSet::default(),
125+
}
115126
} else {
116127
StackItem::NoCheck
117128
};

clippy_utils/src/consts.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ pub enum Constant {
5050
/// `true` or `false`.
5151
Bool(bool),
5252
/// An array of constants.
53-
Vec(Vec<Constant>),
53+
Vec(Vec<Self>),
5454
/// Also an array, but with only one constant, repeated N times.
55-
Repeat(Box<Constant>, u64),
55+
Repeat(Box<Self>, u64),
5656
/// A tuple of constants.
57-
Tuple(Vec<Constant>),
57+
Tuple(Vec<Self>),
5858
/// A raw pointer.
5959
RawPtr(u128),
6060
/// A reference
61-
Ref(Box<Constant>),
61+
Ref(Box<Self>),
6262
/// A literal with syntax error.
6363
Err,
6464
}

clippy_utils/src/sugg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub enum Sugg<'a> {
3333
/// or `-`, but only if the type with and without the operator is kept identical.
3434
/// It means that doubling the operator can be used to remove it instead, in
3535
/// order to provide better suggestions.
36-
UnOp(UnOp, Box<Sugg<'a>>),
36+
UnOp(UnOp, Box<Self>),
3737
}
3838

3939
/// Literal constant `0`, for convenience.

tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
6666
msrv
6767
pass-by-value-size-limit
6868
pub-underscore-fields-behavior
69+
recursive-self-in-type-definitions
6970
semicolon-inside-block-ignore-singleline
7071
semicolon-outside-block-ignore-multiline
7172
single-char-binding-names-threshold
@@ -161,6 +162,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
161162
msrv
162163
pass-by-value-size-limit
163164
pub-underscore-fields-behavior
165+
recursive-self-in-type-definitions
164166
semicolon-inside-block-ignore-singleline
165167
semicolon-outside-block-ignore-multiline
166168
single-char-binding-names-threshold
@@ -256,6 +258,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
256258
msrv
257259
pass-by-value-size-limit
258260
pub-underscore-fields-behavior
261+
recursive-self-in-type-definitions
259262
semicolon-inside-block-ignore-singleline
260263
semicolon-outside-block-ignore-multiline
261264
single-char-binding-names-threshold

tests/ui-toml/use_self/default/clippy.toml

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
recursive-self-in-type-definitions = false

0 commit comments

Comments
 (0)