Skip to content

Commit 7d5108c

Browse files
committed
Auto merge of rust-lang#123239 - Urgau:dangerous_implicit_autorefs, r=jdonszelmann,traviscross
Implement a lint for implicit autoref of raw pointer dereference - take 2 *[t-lang nomination comment](rust-lang#123239 (comment) This PR aims at implementing a lint for implicit autoref of raw pointer dereference, it is based on rust-lang#103735 with suggestion and improvements from rust-lang#103735 (comment). The goal is to catch cases like this, where the user probably doesn't realise it just created a reference. ```rust pub struct Test { data: [u8], } pub fn test_len(t: *const Test) -> usize { unsafe { (*t).data.len() } // this calls <[T]>::len(&self) } ``` Since rust-lang#103735 already went 2 times through T-lang, where they T-lang ended-up asking for a more restricted version (which is what this PR does), I would prefer this PR to be reviewed first before re-nominating it for T-lang. ---- Compared to the PR it is as based on, this PR adds 3 restrictions on the outer most expression, which must either be: 1. A deref followed by any non-deref place projection (that intermediate deref will typically be auto-inserted) 2. A method call annotated with `#[rustc_no_implicit_refs]`. 3. A deref followed by a `addr_of!` or `addr_of_mut!`. See bottom of post for details. There are several points that are not 100% clear to me when implementing the modifications: - ~~"4. Any number of automatically inserted deref/derefmut calls." I as never able to trigger this. Am I missing something?~~ Fixed - Are "index" and "field" enough? ---- cc `@JakobDegen` `@WaffleLapkin` r? `@RalfJung` try-job: dist-various-1 try-job: dist-various-2
2 parents 9639a38 + a35e907 commit 7d5108c

File tree

7 files changed

+15
-3
lines changed

7 files changed

+15
-3
lines changed

alloc/src/string.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1832,6 +1832,7 @@ impl String {
18321832
#[stable(feature = "rust1", since = "1.0.0")]
18331833
#[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
18341834
#[rustc_confusables("length", "size")]
1835+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
18351836
pub const fn len(&self) -> usize {
18361837
self.vec.len()
18371838
}
@@ -1851,6 +1852,7 @@ impl String {
18511852
#[must_use]
18521853
#[stable(feature = "rust1", since = "1.0.0")]
18531854
#[rustc_const_stable(feature = "const_vec_string_slice", since = "1.87.0")]
1855+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
18541856
pub const fn is_empty(&self) -> bool {
18551857
self.len() == 0
18561858
}

alloc/src/vec/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2588,7 +2588,7 @@ impl<T, A: Allocator> Vec<T, A> {
25882588
#[inline]
25892589
#[track_caller]
25902590
unsafe fn append_elements(&mut self, other: *const [T]) {
2591-
let count = unsafe { (*other).len() };
2591+
let count = other.len();
25922592
self.reserve(count);
25932593
let len = self.len();
25942594
unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) };

core/src/ops/index.rs

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub trait Index<Idx: ?Sized> {
6767
///
6868
/// May panic if the index is out of bounds.
6969
#[stable(feature = "rust1", since = "1.0.0")]
70+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
7071
#[track_caller]
7172
fn index(&self, index: Idx) -> &Self::Output;
7273
}
@@ -171,6 +172,7 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
171172
///
172173
/// May panic if the index is out of bounds.
173174
#[stable(feature = "rust1", since = "1.0.0")]
175+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
174176
#[track_caller]
175177
fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
176178
}

core/src/pin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@
676676
//! let data_ptr = unpinned_src.data.as_ptr() as *const u8;
677677
//! let slice_ptr = unpinned_src.slice.as_ptr() as *const u8;
678678
//! let offset = slice_ptr.offset_from(data_ptr) as usize;
679-
//! let len = (*unpinned_src.slice.as_ptr()).len();
679+
//! let len = unpinned_src.slice.as_ptr().len();
680680
//!
681681
//! unpinned_self.slice = NonNull::from(&mut unpinned_self.data[offset..offset+len]);
682682
//! }

core/src/slice/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ impl<T> [T] {
109109
#[lang = "slice_len_fn"]
110110
#[stable(feature = "rust1", since = "1.0.0")]
111111
#[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")]
112+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
112113
#[inline]
113114
#[must_use]
114115
pub const fn len(&self) -> usize {
@@ -128,6 +129,7 @@ impl<T> [T] {
128129
/// ```
129130
#[stable(feature = "rust1", since = "1.0.0")]
130131
#[rustc_const_stable(feature = "const_slice_is_empty", since = "1.39.0")]
132+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
131133
#[inline]
132134
#[must_use]
133135
pub const fn is_empty(&self) -> bool {
@@ -562,6 +564,7 @@ impl<T> [T] {
562564
/// assert_eq!(None, v.get(0..4));
563565
/// ```
564566
#[stable(feature = "rust1", since = "1.0.0")]
567+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
565568
#[inline]
566569
#[must_use]
567570
pub fn get<I>(&self, index: I) -> Option<&I::Output>
@@ -587,6 +590,7 @@ impl<T> [T] {
587590
/// assert_eq!(x, &[0, 42, 2]);
588591
/// ```
589592
#[stable(feature = "rust1", since = "1.0.0")]
593+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
590594
#[inline]
591595
#[must_use]
592596
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
@@ -624,6 +628,7 @@ impl<T> [T] {
624628
/// }
625629
/// ```
626630
#[stable(feature = "rust1", since = "1.0.0")]
631+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
627632
#[inline]
628633
#[must_use]
629634
pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
@@ -666,6 +671,7 @@ impl<T> [T] {
666671
/// assert_eq!(x, &[1, 13, 4]);
667672
/// ```
668673
#[stable(feature = "rust1", since = "1.0.0")]
674+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
669675
#[inline]
670676
#[must_use]
671677
pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output

core/src/str/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ impl str {
134134
#[stable(feature = "rust1", since = "1.0.0")]
135135
#[rustc_const_stable(feature = "const_str_len", since = "1.39.0")]
136136
#[rustc_diagnostic_item = "str_len"]
137+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
137138
#[must_use]
138139
#[inline]
139140
pub const fn len(&self) -> usize {
@@ -153,6 +154,7 @@ impl str {
153154
/// ```
154155
#[stable(feature = "rust1", since = "1.0.0")]
155156
#[rustc_const_stable(feature = "const_str_is_empty", since = "1.39.0")]
157+
#[cfg_attr(not(bootstrap), rustc_no_implicit_autorefs)]
156158
#[must_use]
157159
#[inline]
158160
pub const fn is_empty(&self) -> bool {

std/src/sys/pal/sgx/abi/usercalls/alloc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ where
675675

676676
/// Obtain the number of elements in this user slice.
677677
pub fn len(&self) -> usize {
678-
unsafe { (*self.0.get()).len() }
678+
unsafe { self.0.get().len() }
679679
}
680680

681681
/// Copies the value from user memory and appends it to `dest`.

0 commit comments

Comments
 (0)