File tree 4 files changed +78
-0
lines changed
4 files changed +78
-0
lines changed Original file line number Diff line number Diff line change @@ -391,6 +391,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
391
391
reg. register_late_lint_pass ( box if_let_redundant_pattern_matching:: Pass ) ;
392
392
reg. register_late_lint_pass ( box partialeq_ne_impl:: Pass ) ;
393
393
reg. register_early_lint_pass ( box reference:: Pass ) ;
394
+ reg. register_early_lint_pass ( box reference:: DerefPass ) ;
394
395
reg. register_early_lint_pass ( box double_parens:: DoubleParens ) ;
395
396
reg. register_late_lint_pass ( box unused_io_amount:: UnusedIoAmount ) ;
396
397
reg. register_late_lint_pass ( box large_enum_variant:: LargeEnumVariant :: new ( conf. enum_variant_size_threshold ) ) ;
@@ -812,6 +813,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
812
813
precedence:: PRECEDENCE ,
813
814
ranges:: RANGE_ZIP_WITH_LEN ,
814
815
reference:: DEREF_ADDROF ,
816
+ reference:: REF_IN_DEREF ,
815
817
swap:: MANUAL_SWAP ,
816
818
temporary_assignment:: TEMPORARY_ASSIGNMENT ,
817
819
transmute:: CROSSPOINTER_TRANSMUTE ,
Original file line number Diff line number Diff line change @@ -52,3 +52,53 @@ impl EarlyLintPass for Pass {
52
52
}
53
53
}
54
54
}
55
+
56
+ /// **What it does:** Checks for references in expressions that use
57
+ /// auto dereference.
58
+ ///
59
+ /// **Why is this bad?** The reference is a no-op and is automatically
60
+ /// dereferenced by the compiler and makes the code less clear.
61
+ ///
62
+ /// **Example:**
63
+ /// ```rust
64
+ /// struct Point(u32, u32);
65
+ /// let point = Foo(30, 20);
66
+ /// let x = (&point).x;
67
+ /// ```
68
+ declare_clippy_lint ! {
69
+ pub REF_IN_DEREF ,
70
+ complexity,
71
+ "Use of reference in auto dereference expression."
72
+ }
73
+
74
+ pub struct DerefPass ;
75
+
76
+ impl LintPass for DerefPass {
77
+ fn get_lints ( & self ) -> LintArray {
78
+ lint_array ! ( REF_IN_DEREF )
79
+ }
80
+ }
81
+
82
+ impl EarlyLintPass for DerefPass {
83
+ fn check_expr ( & mut self , cx : & EarlyContext , e : & Expr ) {
84
+ if_chain ! {
85
+ if let ExprKind :: Field ( ref object, ref field_name) = e. node;
86
+ if let ExprKind :: Paren ( ref parened) = object. node;
87
+ if let ExprKind :: AddrOf ( _, ref inner) = parened. node;
88
+ then {
89
+ span_lint_and_sugg(
90
+ cx,
91
+ REF_IN_DEREF ,
92
+ object. span,
93
+ "Creating a reference that is immediately dereferenced." ,
94
+ "try this" ,
95
+ format!(
96
+ "{}.{}" ,
97
+ snippet( cx, inner. span, "_" ) ,
98
+ snippet( cx, field_name. span, "_" )
99
+ )
100
+ ) ;
101
+ }
102
+ }
103
+ }
104
+ }
Original file line number Diff line number Diff line change
1
+ #![ feature( tool_attributes) ]
2
+ #![ feature( stmt_expr_attributes) ]
3
+
4
+ struct Outer {
5
+ inner : u32 ,
6
+ }
7
+
8
+ #[ deny( ref_in_deref) ]
9
+ fn main ( ) {
10
+ let outer = Outer { inner : 0 } ;
11
+ let inner = ( & outer) . inner ;
12
+ }
Original file line number Diff line number Diff line change
1
+ error: Creating a reference that is immediately dereferenced.
2
+ --> $DIR/unnecessary_ref.rs:11:17
3
+ |
4
+ 11 | let inner = (&outer).inner;
5
+ | ^^^^^^^^ help: try this: `outer.inner`
6
+ |
7
+ note: lint level defined here
8
+ --> $DIR/unnecessary_ref.rs:8:8
9
+ |
10
+ 8 | #[deny(ref_in_deref)]
11
+ | ^^^^^^^^^^^^
12
+
13
+ error: aborting due to previous error
14
+
You can’t perform that action at this time.
0 commit comments