Skip to content

Commit 356f201

Browse files
committed
implicit_unsafe_autorefs: support overloaded deref
1 parent 274eba7 commit 356f201

File tree

4 files changed

+66
-11
lines changed

4 files changed

+66
-11
lines changed

compiler/rustc_lint/src/implicit_unsafe_autorefs.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{LateContext, LateLintPass, LintContext};
22

33
use rustc_errors::Applicability;
4-
use rustc_hir::{self as hir, Expr, ExprKind, UnOp};
4+
use rustc_hir::{Expr, ExprKind, Mutability, UnOp};
55
use rustc_middle::ty::{
6-
adjustment::{Adjust, AutoBorrow},
6+
adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDeref},
77
TyCtxt, TypeckResults,
88
};
99

@@ -63,13 +63,13 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitUnsafeAutorefs {
6363
if let Some(adjustments) = adjustments_table.get(expr.hir_id)
6464
&& let [adjustment] = &**adjustments
6565
// An auto-borrow
66-
&& let Adjust::Borrow(AutoBorrow::Ref(_, mutbl)) = adjustment.kind
66+
&& let Some(mutbl) = has_implicit_borrow(adjustment)
6767
// ... of a place derived from a deref
6868
&& let ExprKind::Unary(UnOp::Deref, dereferenced) = peel_place_mappers(cx.tcx, typeck, &expr).kind
6969
// ... of a raw pointer
7070
&& typeck.expr_ty(dereferenced).is_unsafe_ptr()
7171
{
72-
let mutbl = hir::Mutability::prefix_str(&mutbl.into());
72+
let mutbl = Mutability::prefix_str(&mutbl.into());
7373

7474
let msg = "implicit auto-ref creates a reference to a dereference of a raw pointer";
7575
cx.struct_span_lint(IMPLICIT_UNSAFE_AUTOREFS, expr.span, msg, |lint| {
@@ -109,3 +109,12 @@ fn peel_place_mappers<'tcx>(
109109
}
110110
}
111111
}
112+
113+
/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
114+
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<Mutability> {
115+
match kind {
116+
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some(mutbl),
117+
&Adjust::Borrow(AutoBorrow::Ref(_, mutbl)) => Some(mutbl.into()),
118+
_ => None,
119+
}
120+
}

src/test/ui/lint/implicit_unsafe_autorefs.fixed

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// check-pass
22
// run-rustfix
33
#![allow(dead_code)]
4+
use std::mem::ManuallyDrop;
45
use std::ptr::{addr_of, addr_of_mut};
56

67
unsafe fn test_mut(ptr: *mut [u8]) -> *mut [u8] {
@@ -35,4 +36,14 @@ unsafe fn test_builtin_index(a: *mut [String]) {
3536
//~^ warn: implicit auto-ref creates a reference to a dereference of a raw pointer
3637
}
3738

39+
unsafe fn test_overloaded_deref_const(ptr: *const ManuallyDrop<Test>) {
40+
_ = addr_of!((&(*ptr)).field);
41+
//~^ warn: implicit auto-ref creates a reference to a dereference of a raw pointer
42+
}
43+
44+
unsafe fn test_overloaded_deref_mut(ptr: *mut ManuallyDrop<Test>) {
45+
_ = addr_of_mut!((&mut (*ptr)).field);
46+
//~^ warn: implicit auto-ref creates a reference to a dereference of a raw pointer
47+
}
48+
3849
fn main() {}

src/test/ui/lint/implicit_unsafe_autorefs.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// check-pass
22
// run-rustfix
33
#![allow(dead_code)]
4+
use std::mem::ManuallyDrop;
45
use std::ptr::{addr_of, addr_of_mut};
56

67
unsafe fn test_mut(ptr: *mut [u8]) -> *mut [u8] {
@@ -35,4 +36,14 @@ unsafe fn test_builtin_index(a: *mut [String]) {
3536
//~^ warn: implicit auto-ref creates a reference to a dereference of a raw pointer
3637
}
3738

39+
unsafe fn test_overloaded_deref_const(ptr: *const ManuallyDrop<Test>) {
40+
_ = addr_of!((*ptr).field);
41+
//~^ warn: implicit auto-ref creates a reference to a dereference of a raw pointer
42+
}
43+
44+
unsafe fn test_overloaded_deref_mut(ptr: *mut ManuallyDrop<Test>) {
45+
_ = addr_of_mut!((*ptr).field);
46+
//~^ warn: implicit auto-ref creates a reference to a dereference of a raw pointer
47+
}
48+
3849
fn main() {}

src/test/ui/lint/implicit_unsafe_autorefs.stderr

+31-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
2-
--> $DIR/implicit_unsafe_autorefs.rs:7:18
2+
--> $DIR/implicit_unsafe_autorefs.rs:8:18
33
|
44
LL | addr_of_mut!((*ptr)[..16])
55
| ^^^^^^
@@ -12,7 +12,7 @@ LL | addr_of_mut!((&mut (*ptr))[..16])
1212
| +++++ +
1313

1414
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
15-
--> $DIR/implicit_unsafe_autorefs.rs:12:14
15+
--> $DIR/implicit_unsafe_autorefs.rs:13:14
1616
|
1717
LL | addr_of!((*ptr)[..16])
1818
| ^^^^^^
@@ -24,7 +24,7 @@ LL | addr_of!((&(*ptr))[..16])
2424
| ++ +
2525

2626
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
27-
--> $DIR/implicit_unsafe_autorefs.rs:21:13
27+
--> $DIR/implicit_unsafe_autorefs.rs:22:13
2828
|
2929
LL | let l = (*ptr).field.len();
3030
| ^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL | let l = (&(*ptr).field).len();
3636
| ++ +
3737

3838
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
39-
--> $DIR/implicit_unsafe_autorefs.rs:24:14
39+
--> $DIR/implicit_unsafe_autorefs.rs:25:14
4040
|
4141
LL | addr_of!((*ptr).field[..l - 1])
4242
| ^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL | addr_of!((&(*ptr).field)[..l - 1])
4848
| ++ +
4949

5050
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
51-
--> $DIR/implicit_unsafe_autorefs.rs:30:9
51+
--> $DIR/implicit_unsafe_autorefs.rs:31:9
5252
|
5353
LL | _ = (*a)[0].len();
5454
| ^^^^^^^
@@ -60,7 +60,7 @@ LL | _ = (&(*a)[0]).len();
6060
| ++ +
6161

6262
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
63-
--> $DIR/implicit_unsafe_autorefs.rs:34:9
63+
--> $DIR/implicit_unsafe_autorefs.rs:35:9
6464
|
6565
LL | _ = (*a)[..1][0].len();
6666
| ^^^^
@@ -71,5 +71,29 @@ help: try using a raw pointer method instead; or if this reference is intentiona
7171
LL | _ = (&(*a))[..1][0].len();
7272
| ++ +
7373

74-
warning: 6 warnings emitted
74+
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
75+
--> $DIR/implicit_unsafe_autorefs.rs:40:18
76+
|
77+
LL | _ = addr_of!((*ptr).field);
78+
| ^^^^^^
79+
|
80+
= note: creating a reference requires the pointer to be valid and imposes aliasing requirements
81+
help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
82+
|
83+
LL | _ = addr_of!((&(*ptr)).field);
84+
| ++ +
85+
86+
warning: implicit auto-ref creates a reference to a dereference of a raw pointer
87+
--> $DIR/implicit_unsafe_autorefs.rs:45:22
88+
|
89+
LL | _ = addr_of_mut!((*ptr).field);
90+
| ^^^^^^
91+
|
92+
= note: creating a reference requires the pointer to be valid and imposes aliasing requirements
93+
help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
94+
|
95+
LL | _ = addr_of_mut!((&mut (*ptr)).field);
96+
| +++++ +
97+
98+
warning: 8 warnings emitted
7599

0 commit comments

Comments
 (0)