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 @@ -388,6 +388,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
388
388
reg. register_late_lint_pass ( box if_let_redundant_pattern_matching:: Pass ) ;
389
389
reg. register_late_lint_pass ( box partialeq_ne_impl:: Pass ) ;
390
390
reg. register_early_lint_pass ( box reference:: Pass ) ;
391
+ reg. register_early_lint_pass ( box reference:: DerefPass ) ;
391
392
reg. register_early_lint_pass ( box double_parens:: DoubleParens ) ;
392
393
reg. register_late_lint_pass ( box unused_io_amount:: UnusedIoAmount ) ;
393
394
reg. register_late_lint_pass ( box large_enum_variant:: LargeEnumVariant :: new ( conf. enum_variant_size_threshold ) ) ;
@@ -809,6 +810,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
809
810
precedence:: PRECEDENCE ,
810
811
ranges:: RANGE_ZIP_WITH_LEN ,
811
812
reference:: DEREF_ADDROF ,
813
+ reference:: REF_IN_DEREF ,
812
814
swap:: MANUAL_SWAP ,
813
815
temporary_assignment:: TEMPORARY_ASSIGNMENT ,
814
816
transmute:: CROSSPOINTER_TRANSMUTE ,
Original file line number Diff line number Diff line change @@ -54,3 +54,53 @@ impl EarlyLintPass for Pass {
54
54
}
55
55
}
56
56
}
57
+
58
+ /// **What it does:** Checks for references in expressions that use
59
+ /// auto dereference.
60
+ ///
61
+ /// **Why is this bad?** The reference is a no-op and is automatically
62
+ /// dereferenced by the compiler and makes the code less clear.
63
+ ///
64
+ /// **Example:**
65
+ /// ```rust
66
+ /// struct Point(u32, u32);
67
+ /// let point = Foo(30, 20);
68
+ /// let x = (&point).x;
69
+ /// ```
70
+ declare_clippy_lint ! {
71
+ pub REF_IN_DEREF ,
72
+ complexity,
73
+ "Use of reference in auto dereference expression."
74
+ }
75
+
76
+ pub struct DerefPass ;
77
+
78
+ impl LintPass for DerefPass {
79
+ fn get_lints ( & self ) -> LintArray {
80
+ lint_array ! ( REF_IN_DEREF )
81
+ }
82
+ }
83
+
84
+ impl EarlyLintPass for DerefPass {
85
+ fn check_expr ( & mut self , cx : & EarlyContext , e : & Expr ) {
86
+ if_chain ! {
87
+ if let ExprKind :: Field ( ref object, ref field_name) = e. node;
88
+ if let ExprKind :: Paren ( ref parened) = object. node;
89
+ if let ExprKind :: AddrOf ( _, ref inner) = parened. node;
90
+ then {
91
+ span_lint_and_sugg(
92
+ cx,
93
+ REF_IN_DEREF ,
94
+ object. span,
95
+ "Creating a reference that is immediately dereferenced." ,
96
+ "try this" ,
97
+ format!(
98
+ "{}.{}" ,
99
+ snippet( cx, inner. span, "_" ) ,
100
+ snippet( cx, field_name. span, "_" )
101
+ )
102
+ ) ;
103
+ }
104
+ }
105
+ }
106
+ }
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