Skip to content

Rollup of 6 pull requests #140335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 26 additions & 61 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4918,15 +4918,6 @@ dependencies = [
"color-eyre",
]

[[package]]
name = "spdx"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58b69356da67e2fc1f542c71ea7e654a361a79c938e4424392ecf4fa065d2193"
dependencies = [
"smallvec",
]

[[package]]
name = "spdx-expression"
version = "0.5.2"
Expand Down Expand Up @@ -5746,9 +5737,9 @@ dependencies = [

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

[[package]]
name = "wasm-bindgen"
Expand Down Expand Up @@ -5810,17 +5801,17 @@ dependencies = [

[[package]]
name = "wasm-component-ld"
version = "0.5.12"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "580305a8e3f1b7a79859a8db897de643533b2851c5eb080fe5800233f16dec88"
checksum = "a60a07a994a3538b57d8c5f8caba19f4793fb4c7156276e5e90e90acbb829e20"
dependencies = [
"anyhow",
"clap",
"lexopt",
"libc",
"tempfile",
"wasi-preview1-component-adapter-provider",
"wasmparser 0.223.1",
"wasmparser 0.229.0",
"wat",
"windows-sys 0.59.0",
"winsplit",
Expand All @@ -5847,39 +5838,24 @@ dependencies = [

[[package]]
name = "wasm-encoder"
version = "0.223.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a0a96fdeaee8fbeb4bd917fb8157d48c0d61c3b1f4ee4c363c8e8d68b2f4fe8"
dependencies = [
"leb128",
"wasmparser 0.223.1",
]

[[package]]
name = "wasm-encoder"
version = "0.228.0"
version = "0.229.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d30290541f2d4242a162bbda76b8f2d8b1ac59eab3568ed6f2327d52c9b2c4"
checksum = "38ba1d491ecacb085a2552025c10a675a6fddcbd03b1fc9b36c536010ce265d2"
dependencies = [
"leb128fmt",
"wasmparser 0.228.0",
"wasmparser 0.229.0",
]

[[package]]
name = "wasm-metadata"
version = "0.223.1"
version = "0.229.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7e37883181704d96b89dbd8f1291be13694c71cd0663aebb94b46d235a377"
checksum = "78fdb7d29a79191ab363dc90c1ddd3a1e880ffd5348d92d48482393a9e6c5f4d"
dependencies = [
"anyhow",
"indexmap",
"serde",
"serde_derive",
"serde_json",
"spdx",
"url",
"wasm-encoder 0.223.1",
"wasmparser 0.223.1",
"wasm-encoder 0.229.0",
"wasmparser 0.229.0",
]

[[package]]
Expand All @@ -5903,9 +5879,9 @@ dependencies = [

[[package]]
name = "wasmparser"
version = "0.223.1"
version = "0.229.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "664b980991ed9a8c834eb528a8979ab1109edcf52dc05dd5751e2cc3fb31035d"
checksum = "0cc3b1f053f5d41aa55640a1fa9b6d1b8a9e4418d118ce308d20e24ff3575a8c"
dependencies = [
"bitflags",
"hashbrown",
Expand All @@ -5914,35 +5890,24 @@ dependencies = [
"serde",
]

[[package]]
name = "wasmparser"
version = "0.228.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4abf1132c1fdf747d56bbc1bb52152400c70f336870f968b85e89ea422198ae3"
dependencies = [
"bitflags",
"indexmap",
"semver",
]

[[package]]
name = "wast"
version = "228.0.0"
version = "229.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5aae124478cb51439f6587f074a3a5e835afd22751c59a87b2e2a882727c97"
checksum = "63fcaff613c12225696bb163f79ca38ffb40e9300eff0ff4b8aa8b2f7eadf0d9"
dependencies = [
"bumpalo",
"leb128fmt",
"memchr",
"unicode-width 0.2.0",
"wasm-encoder 0.228.0",
"wasm-encoder 0.229.0",
]

[[package]]
name = "wat"
version = "1.228.0"
version = "1.229.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ec29c89a8d055df988de7236483bf569988ac3d6905899f6af5ef920f9385ad"
checksum = "4189bad08b70455a9e9e67dc126d2dcf91fac143a80f1046747a5dde6d4c33e0"
dependencies = [
"wast",
]
Expand Down Expand Up @@ -6401,9 +6366,9 @@ dependencies = [

[[package]]
name = "wit-component"
version = "0.223.1"
version = "0.229.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fc2fcc52a79f6f010a89c867e53e06d4227f86c58984add3e37f32b8e7af5f0"
checksum = "7f550067740e223bfe6c4878998e81cdbe2529dd9a793dc49248dd6613394e8b"
dependencies = [
"anyhow",
"bitflags",
Expand All @@ -6412,17 +6377,17 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"wasm-encoder 0.223.1",
"wasm-encoder 0.229.0",
"wasm-metadata",
"wasmparser 0.223.1",
"wasmparser 0.229.0",
"wit-parser",
]

[[package]]
name = "wit-parser"
version = "0.223.1"
version = "0.229.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "263fde17f1fbe55a413f16eb59094bf751795c6da469a05c3d45ea6c77df6b40"
checksum = "459c6ba62bf511d6b5f2a845a2a736822e38059c1cfa0b644b467bbbfae4efa6"
dependencies = [
"anyhow",
"id-arena",
Expand All @@ -6433,7 +6398,7 @@ dependencies = [
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser 0.223.1",
"wasmparser 0.229.0",
]

[[package]]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
EncodeCrossCrate::Yes,
"#[rustc_never_returns_null_ptr] is used to mark functions returning non-null pointers."
),
rustc_attr!(
rustc_no_implicit_autorefs, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
"`#[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."
),
rustc_attr!(
rustc_coherence_is_core, AttributeType::CrateLevel, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
"#![rustc_coherence_is_core] allows inherent methods on builtin types, only intended to be used in `core`."
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
.is_ok()
{
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
check_on_unimplemented(tcx, def_id);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than pos
lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
.suggestion = remove the `use<...>` syntax

lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer
.note = creating a reference requires the pointer target to be valid and imposes aliasing requirements
.suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit

lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
.label = not FFI-safe
.note = the type is defined here
Expand Down
153 changes: 153 additions & 0 deletions compiler/rustc_lint/src/autorefs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
use rustc_ast::{BorrowKind, UnOp};
use rustc_hir::{Expr, ExprKind, Mutability};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDeref};
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::sym;

use crate::lints::{ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsSuggestion};
use crate::{LateContext, LateLintPass, LintContext};

declare_lint! {
/// The `dangerous_implicit_autorefs` lint checks for implicitly taken references
/// to dereferences of raw pointers.
///
/// ### Example
///
/// ```rust
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
/// &raw mut (*ptr)[..16]
/// // ^^^^^^ this calls `IndexMut::index_mut(&mut ..., ..16)`,
/// // implicitly creating a reference
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// When working with raw pointers it's usually undesirable to create references,
/// since they inflict additional safety requirements. Unfortunately, it's possible
/// to take a reference to the dereference of a raw pointer implicitly, which inflicts
/// the usual reference requirements.
///
/// If you are sure that you can soundly take a reference, then you can take it explicitly:
///
/// ```rust
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
/// &raw mut (&mut *ptr)[..16]
/// }
/// ```
///
/// Otherwise try to find an alternative way to achive your goals using only raw pointers:
///
/// ```rust
/// use std::slice;
///
/// unsafe fn fun(ptr: *mut [u8]) -> *mut [u8] {
/// slice::from_raw_parts_mut(ptr.cast(), 16)
/// }
/// ```
pub DANGEROUS_IMPLICIT_AUTOREFS,
Warn,
"implicit reference to a dereference of a raw pointer",
report_in_external_macro
}

declare_lint_pass!(ImplicitAutorefs => [DANGEROUS_IMPLICIT_AUTOREFS]);

impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// This logic has mostly been taken from
// <https://github.com/rust-lang/rust/pull/103735#issuecomment-1370420305>

// 5. Either of the following:
// a. A deref followed by any non-deref place projection (that intermediate
// deref will typically be auto-inserted).
// b. A method call annotated with `#[rustc_no_implicit_refs]`.
// c. A deref followed by a `&raw const` or `&raw mut`.
let mut is_coming_from_deref = false;
let inner = match expr.kind {
ExprKind::AddrOf(BorrowKind::Raw, _, inner) => match inner.kind {
ExprKind::Unary(UnOp::Deref, inner) => {
is_coming_from_deref = true;
inner
}
_ => return,
},
ExprKind::Index(base, _, _) => base,
ExprKind::MethodCall(_, inner, _, _)
if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
&& cx.tcx.has_attr(def_id, sym::rustc_no_implicit_autorefs) =>
{
inner
}
ExprKind::Field(inner, _) => inner,
_ => return,
};

let typeck = cx.typeck_results();
let adjustments_table = typeck.adjustments();

if let Some(adjustments) = adjustments_table.get(inner.hir_id)
// 4. Any number of automatically inserted deref/derefmut calls.
&& let adjustments = peel_derefs_adjustments(&**adjustments)
// 3. An automatically inserted reference (might come from a deref).
&& let [adjustment] = adjustments
&& let Some(borrow_mutbl) = has_implicit_borrow(adjustment)
&& let ExprKind::Unary(UnOp::Deref, dereferenced) =
// 2. Any number of place projections.
peel_place_mappers(inner).kind
// 1. Deref of a raw pointer.
&& typeck.expr_ty(dereferenced).is_raw_ptr()
{
cx.emit_span_lint(
DANGEROUS_IMPLICIT_AUTOREFS,
expr.span.source_callsite(),
ImplicitUnsafeAutorefsDiag {
suggestion: ImplicitUnsafeAutorefsSuggestion {
mutbl: borrow_mutbl.ref_prefix_str(),
deref: if is_coming_from_deref { "*" } else { "" },
start_span: inner.span.shrink_to_lo(),
end_span: inner.span.shrink_to_hi(),
},
},
)
}
}
}

/// Peels expressions from `expr` that can map a place.
fn peel_place_mappers<'tcx>(mut expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
loop {
match expr.kind {
ExprKind::Index(base, _idx, _) => expr = &base,
ExprKind::Field(e, _) => expr = &e,
_ => break expr,
}
}
}

/// Peel derefs adjustments until the last last element.
fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustment<'a>] {
while let [Adjustment { kind: Adjust::Deref(_), .. }, end @ ..] = adjs
&& !end.is_empty()
{
adjs = end;
}
adjs
}

/// Test if some adjustment has some implicit borrow.
///
/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<Mutability> {
match kind {
&Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some(mutbl),
&Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some(mutbl.into()),
Adjust::NeverToAny
| Adjust::Pointer(..)
| Adjust::ReborrowPin(..)
| Adjust::Deref(None)
| Adjust::Borrow(AutoBorrow::RawPtr(..)) => None,
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

mod async_closures;
mod async_fn_in_trait;
mod autorefs;
pub mod builtin;
mod context;
mod dangling;
Expand Down Expand Up @@ -83,6 +84,7 @@ mod utils;

use async_closures::AsyncClosureUsage;
use async_fn_in_trait::AsyncFnInTrait;
use autorefs::*;
use builtin::*;
use dangling::*;
use default_could_be_derived::DefaultCouldBeDerived;
Expand Down Expand Up @@ -200,6 +202,7 @@ late_lint_methods!(
PathStatements: PathStatements,
LetUnderscore: LetUnderscore,
InvalidReferenceCasting: InvalidReferenceCasting,
ImplicitAutorefs: ImplicitAutorefs,
// Depends on referenced function signatures in expressions
UnusedResults: UnusedResults,
UnitBindings: UnitBindings,
Expand Down
Loading
Loading