Skip to content

Commit 716e056

Browse files
committed
Auto merge of #140335 - matthiaskrgr:rollup-aa0aqxv, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #123239 (Implement a lint for implicit autoref of raw pointer dereference - take 2) - #140215 (transmutability: Support char, NonZeroXxx) - #140226 (Update wasm-component-ld to 0.5.13) - #140317 (Remove redundant check) - #140318 (Simply try to unpeel AsyncFnKindHelper goal in `emit_specialized_closure_kind_error`) - #140325 (Grammar fixes for BufRead::has_data_left docs) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5ae50d3 + 01d18c2 commit 716e056

File tree

32 files changed

+1009
-144
lines changed

32 files changed

+1009
-144
lines changed

Cargo.lock

+26-61
Original file line numberDiff line numberDiff line change
@@ -4918,15 +4918,6 @@ dependencies = [
49184918
"color-eyre",
49194919
]
49204920

4921-
[[package]]
4922-
name = "spdx"
4923-
version = "0.10.8"
4924-
source = "registry+https://github.com/rust-lang/crates.io-index"
4925-
checksum = "58b69356da67e2fc1f542c71ea7e654a361a79c938e4424392ecf4fa065d2193"
4926-
dependencies = [
4927-
"smallvec",
4928-
]
4929-
49304921
[[package]]
49314922
name = "spdx-expression"
49324923
version = "0.5.2"
@@ -5746,9 +5737,9 @@ dependencies = [
57465737

57475738
[[package]]
57485739
name = "wasi-preview1-component-adapter-provider"
5749-
version = "29.0.1"
5740+
version = "31.0.0"
57505741
source = "registry+https://github.com/rust-lang/crates.io-index"
5751-
checksum = "dcd9f21bbde82ba59e415a8725e6ad0d0d7e9e460b1a3ccbca5bdee952c1a324"
5742+
checksum = "86fabda09a0d89ffd1615b297b4a5d4b4d99df9598aeb24685837e63019e927b"
57525743

57535744
[[package]]
57545745
name = "wasm-bindgen"
@@ -5810,17 +5801,17 @@ dependencies = [
58105801

58115802
[[package]]
58125803
name = "wasm-component-ld"
5813-
version = "0.5.12"
5804+
version = "0.5.13"
58145805
source = "registry+https://github.com/rust-lang/crates.io-index"
5815-
checksum = "580305a8e3f1b7a79859a8db897de643533b2851c5eb080fe5800233f16dec88"
5806+
checksum = "a60a07a994a3538b57d8c5f8caba19f4793fb4c7156276e5e90e90acbb829e20"
58165807
dependencies = [
58175808
"anyhow",
58185809
"clap",
58195810
"lexopt",
58205811
"libc",
58215812
"tempfile",
58225813
"wasi-preview1-component-adapter-provider",
5823-
"wasmparser 0.223.1",
5814+
"wasmparser 0.229.0",
58245815
"wat",
58255816
"windows-sys 0.59.0",
58265817
"winsplit",
@@ -5847,39 +5838,24 @@ dependencies = [
58475838

58485839
[[package]]
58495840
name = "wasm-encoder"
5850-
version = "0.223.1"
5851-
source = "registry+https://github.com/rust-lang/crates.io-index"
5852-
checksum = "7a0a96fdeaee8fbeb4bd917fb8157d48c0d61c3b1f4ee4c363c8e8d68b2f4fe8"
5853-
dependencies = [
5854-
"leb128",
5855-
"wasmparser 0.223.1",
5856-
]
5857-
5858-
[[package]]
5859-
name = "wasm-encoder"
5860-
version = "0.228.0"
5841+
version = "0.229.0"
58615842
source = "registry+https://github.com/rust-lang/crates.io-index"
5862-
checksum = "05d30290541f2d4242a162bbda76b8f2d8b1ac59eab3568ed6f2327d52c9b2c4"
5843+
checksum = "38ba1d491ecacb085a2552025c10a675a6fddcbd03b1fc9b36c536010ce265d2"
58635844
dependencies = [
58645845
"leb128fmt",
5865-
"wasmparser 0.228.0",
5846+
"wasmparser 0.229.0",
58665847
]
58675848

58685849
[[package]]
58695850
name = "wasm-metadata"
5870-
version = "0.223.1"
5851+
version = "0.229.0"
58715852
source = "registry+https://github.com/rust-lang/crates.io-index"
5872-
checksum = "e2e7e37883181704d96b89dbd8f1291be13694c71cd0663aebb94b46d235a377"
5853+
checksum = "78fdb7d29a79191ab363dc90c1ddd3a1e880ffd5348d92d48482393a9e6c5f4d"
58735854
dependencies = [
58745855
"anyhow",
58755856
"indexmap",
5876-
"serde",
5877-
"serde_derive",
5878-
"serde_json",
5879-
"spdx",
5880-
"url",
5881-
"wasm-encoder 0.223.1",
5882-
"wasmparser 0.223.1",
5857+
"wasm-encoder 0.229.0",
5858+
"wasmparser 0.229.0",
58835859
]
58845860

58855861
[[package]]
@@ -5903,9 +5879,9 @@ dependencies = [
59035879

59045880
[[package]]
59055881
name = "wasmparser"
5906-
version = "0.223.1"
5882+
version = "0.229.0"
59075883
source = "registry+https://github.com/rust-lang/crates.io-index"
5908-
checksum = "664b980991ed9a8c834eb528a8979ab1109edcf52dc05dd5751e2cc3fb31035d"
5884+
checksum = "0cc3b1f053f5d41aa55640a1fa9b6d1b8a9e4418d118ce308d20e24ff3575a8c"
59095885
dependencies = [
59105886
"bitflags",
59115887
"hashbrown",
@@ -5914,35 +5890,24 @@ dependencies = [
59145890
"serde",
59155891
]
59165892

5917-
[[package]]
5918-
name = "wasmparser"
5919-
version = "0.228.0"
5920-
source = "registry+https://github.com/rust-lang/crates.io-index"
5921-
checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3"
5922-
dependencies = [
5923-
"bitflags",
5924-
"indexmap",
5925-
"semver",
5926-
]
5927-
59285893
[[package]]
59295894
name = "wast"
5930-
version = "228.0.0"
5895+
version = "229.0.0"
59315896
source = "registry+https://github.com/rust-lang/crates.io-index"
5932-
checksum = "9e5aae124478cb51439f6587f074a3a5e835afd22751c59a87b2e2a882727c97"
5897+
checksum = "63fcaff613c12225696bb163f79ca38ffb40e9300eff0ff4b8aa8b2f7eadf0d9"
59335898
dependencies = [
59345899
"bumpalo",
59355900
"leb128fmt",
59365901
"memchr",
59375902
"unicode-width 0.2.0",
5938-
"wasm-encoder 0.228.0",
5903+
"wasm-encoder 0.229.0",
59395904
]
59405905

59415906
[[package]]
59425907
name = "wat"
5943-
version = "1.228.0"
5908+
version = "1.229.0"
59445909
source = "registry+https://github.com/rust-lang/crates.io-index"
5945-
checksum = "7ec29c89a8d055df988de7236483bf569988ac3d6905899f6af5ef920f9385ad"
5910+
checksum = "4189bad08b70455a9e9e67dc126d2dcf91fac143a80f1046747a5dde6d4c33e0"
59465911
dependencies = [
59475912
"wast",
59485913
]
@@ -6401,9 +6366,9 @@ dependencies = [
64016366

64026367
[[package]]
64036368
name = "wit-component"
6404-
version = "0.223.1"
6369+
version = "0.229.0"
64056370
source = "registry+https://github.com/rust-lang/crates.io-index"
6406-
checksum = "3fc2fcc52a79f6f010a89c867e53e06d4227f86c58984add3e37f32b8e7af5f0"
6371+
checksum = "7f550067740e223bfe6c4878998e81cdbe2529dd9a793dc49248dd6613394e8b"
64076372
dependencies = [
64086373
"anyhow",
64096374
"bitflags",
@@ -6412,17 +6377,17 @@ dependencies = [
64126377
"serde",
64136378
"serde_derive",
64146379
"serde_json",
6415-
"wasm-encoder 0.223.1",
6380+
"wasm-encoder 0.229.0",
64166381
"wasm-metadata",
6417-
"wasmparser 0.223.1",
6382+
"wasmparser 0.229.0",
64186383
"wit-parser",
64196384
]
64206385

64216386
[[package]]
64226387
name = "wit-parser"
6423-
version = "0.223.1"
6388+
version = "0.229.0"
64246389
source = "registry+https://github.com/rust-lang/crates.io-index"
6425-
checksum = "263fde17f1fbe55a413f16eb59094bf751795c6da469a05c3d45ea6c77df6b40"
6390+
checksum = "459c6ba62bf511d6b5f2a845a2a736822e38059c1cfa0b644b467bbbfae4efa6"
64266391
dependencies = [
64276392
"anyhow",
64286393
"id-arena",
@@ -6433,7 +6398,7 @@ dependencies = [
64336398
"serde_derive",
64346399
"serde_json",
64356400
"unicode-xid",
6436-
"wasmparser 0.223.1",
6401+
"wasmparser 0.229.0",
64376402
]
64386403

64396404
[[package]]

compiler/rustc_feature/src/builtin_attrs.rs

+4
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
918918
EncodeCrossCrate::Yes,
919919
"#[rustc_never_returns_null_ptr] is used to mark functions returning non-null pointers."
920920
),
921+
rustc_attr!(
922+
rustc_no_implicit_autorefs, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
923+
"`#[rustc_no_implicit_autorefs]` is used to mark functions for which an autoref to the dereference of a raw pointer should not be used as an argument."
924+
),
921925
rustc_attr!(
922926
rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
923927
"#![rustc_coherence_is_core] allows inherent methods on builtin types, only intended to be used in `core`."

compiler/rustc_hir_analysis/src/check/check.rs

-1
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
730730
.is_ok()
731731
{
732732
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
733-
check_on_unimplemented(tcx, def_id);
734733
}
735734
}
736735
}

compiler/rustc_lint/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,10 @@ lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than pos
360360
lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
361361
.suggestion = remove the `use<...>` syntax
362362
363+
lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer
364+
.note = creating a reference requires the pointer target to be valid and imposes aliasing requirements
365+
.suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit
366+
363367
lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
364368
.label = not FFI-safe
365369
.note = the type is defined here

compiler/rustc_lint/src/autorefs.rs

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
use rustc_ast::{BorrowKind, UnOp};
2+
use rustc_hir::{Expr, ExprKind, Mutability};
3+
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDeref};
4+
use rustc_session::{declare_lint, declare_lint_pass};
5+
use rustc_span::sym;
6+
7+
use crate::lints::{ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsSuggestion};
8+
use crate::{LateContext, LateLintPass, LintContext};
9+
10+
declare_lint! {
11+
/// The `dangerous_implicit_autorefs` lint checks for implicitly taken references
12+
/// to dereferences of raw pointers.
13+
///
14+
/// ### Example
15+
///
16+
/// ```rust
17+
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
18+
/// &raw mut (*ptr)[..16]
19+
/// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
20+
/// // implicitly creating a reference
21+
/// }
22+
/// ```
23+
///
24+
/// {{produces}}
25+
///
26+
/// ### Explanation
27+
///
28+
/// When working with raw pointers it's usually undesirable to create references,
29+
/// since they inflict additional safety requirements. Unfortunately, it's possible
30+
/// to take a reference to the dereference of a raw pointer implicitly, which inflicts
31+
/// the usual reference requirements.
32+
///
33+
/// If you are sure that you can soundly take a reference, then you can take it explicitly:
34+
///
35+
/// ```rust
36+
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
37+
/// &raw mut (&mut *ptr)[..16]
38+
/// }
39+
/// ```
40+
///
41+
/// Otherwise try to find an alternative way to achive your goals using only raw pointers:
42+
///
43+
/// ```rust
44+
/// use std::slice;
45+
///
46+
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
47+
/// slice::from_raw_parts_mut(ptr.cast(), 16)
48+
/// }
49+
/// ```
50+
pub DANGEROUS_IMPLICIT_AUTOREFS,
51+
Warn,
52+
"implicit reference to a dereference of a raw pointer",
53+
report_in_external_macro
54+
}
55+
56+
declare_lint_pass!(ImplicitAutorefs => [DANGEROUS_IMPLICIT_AUTOREFS]);
57+
58+
impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
59+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
60+
// This logic has mostly been taken from
61+
// <https://github.com/rust-lang/rust/pull/103735#issuecomment-1370420305>
62+
63+
// 5. Either of the following:
64+
// a. A deref followed by any non-deref place projection (that intermediate
65+
// deref will typically be auto-inserted).
66+
// b. A method call annotated with `#[rustc_no_implicit_refs]`.
67+
// c. A deref followed by a `&raw const` or `&raw mut`.
68+
let mut is_coming_from_deref = false;
69+
let inner = match expr.kind {
70+
ExprKind::AddrOf(BorrowKind::Raw, _, inner) => match inner.kind {
71+
ExprKind::Unary(UnOp::Deref, inner) => {
72+
is_coming_from_deref = true;
73+
inner
74+
}
75+
_ => return,
76+
},
77+
ExprKind::Index(base, _, _) => base,
78+
ExprKind::MethodCall(_, inner, _, _)
79+
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
80+
&& cx.tcx.has_attr(def_id, sym::rustc_no_implicit_autorefs) =>
81+
{
82+
inner
83+
}
84+
ExprKind::Field(inner, _) => inner,
85+
_ => return,
86+
};
87+
88+
let typeck = cx.typeck_results();
89+
let adjustments_table = typeck.adjustments();
90+
91+
if let Some(adjustments) = adjustments_table.get(inner.hir_id)
92+
// 4. Any number of automatically inserted deref/derefmut calls.
93+
&& let adjustments = peel_derefs_adjustments(&**adjustments)
94+
// 3. An automatically inserted reference (might come from a deref).
95+
&& let [adjustment] = adjustments
96+
&& let Some(borrow_mutbl) = has_implicit_borrow(adjustment)
97+
&& let ExprKind::Unary(UnOp::Deref, dereferenced) =
98+
// 2. Any number of place projections.
99+
peel_place_mappers(inner).kind
100+
// 1. Deref of a raw pointer.
101+
&& typeck.expr_ty(dereferenced).is_raw_ptr()
102+
{
103+
cx.emit_span_lint(
104+
DANGEROUS_IMPLICIT_AUTOREFS,
105+
expr.span.source_callsite(),
106+
ImplicitUnsafeAutorefsDiag {
107+
suggestion: ImplicitUnsafeAutorefsSuggestion {
108+
mutbl: borrow_mutbl.ref_prefix_str(),
109+
deref: if is_coming_from_deref { "*" } else { "" },
110+
start_span: inner.span.shrink_to_lo(),
111+
end_span: inner.span.shrink_to_hi(),
112+
},
113+
},
114+
)
115+
}
116+
}
117+
}
118+
119+
/// Peels expressions from `expr` that can map a place.
120+
fn peel_place_mappers<'tcx>(mut expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
121+
loop {
122+
match expr.kind {
123+
ExprKind::Index(base, _idx, _) => expr = &base,
124+
ExprKind::Field(e, _) => expr = &e,
125+
_ => break expr,
126+
}
127+
}
128+
}
129+
130+
/// Peel derefs adjustments until the last last element.
131+
fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustment<'a>] {
132+
while let [Adjustment { kind: Adjust::Deref(_), .. }, end @ ..] = adjs
133+
&& !end.is_empty()
134+
{
135+
adjs = end;
136+
}
137+
adjs
138+
}
139+
140+
/// Test if some adjustment has some implicit borrow.
141+
///
142+
/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
143+
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<Mutability> {
144+
match kind {
145+
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some(mutbl),
146+
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some(mutbl.into()),
147+
Adjust::NeverToAny
148+
| Adjust::Pointer(..)
149+
| Adjust::ReborrowPin(..)
150+
| Adjust::Deref(None)
151+
| Adjust::Borrow(AutoBorrow::RawPtr(..)) => None,
152+
}
153+
}

compiler/rustc_lint/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
mod async_closures;
3838
mod async_fn_in_trait;
39+
mod autorefs;
3940
pub mod builtin;
4041
mod context;
4142
mod dangling;
@@ -83,6 +84,7 @@ mod utils;
8384

8485
use async_closures::AsyncClosureUsage;
8586
use async_fn_in_trait::AsyncFnInTrait;
87+
use autorefs::*;
8688
use builtin::*;
8789
use dangling::*;
8890
use default_could_be_derived::DefaultCouldBeDerived;
@@ -200,6 +202,7 @@ late_lint_methods!(
200202
PathStatements: PathStatements,
201203
LetUnderscore: LetUnderscore,
202204
InvalidReferenceCasting: InvalidReferenceCasting,
205+
ImplicitAutorefs: ImplicitAutorefs,
203206
// Depends on referenced function signatures in expressions
204207
UnusedResults: UnusedResults,
205208
UnitBindings: UnitBindings,

0 commit comments

Comments
 (0)