Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
044d15b
Erase `#![doc(document_private_items)]`
fmease Sep 13, 2025
329682d
rustdoc-json: move `target` to `json::conversions`
aDotInTheVoid Oct 17, 2025
b762676
Rename {i,u}N::*exact_div to *div_exact
nxsaken Nov 2, 2025
f590ae6
Rename {u,i}N::*exact_sh{l,r} to *sh{l,r}_exact
nxsaken Oct 16, 2025
79b3963
Add Steal::risky_hack_borrow_mut
Lysxia Nov 4, 2025
a49d4d7
Special case detecting `'static` lifetime requirement coming from `->…
estebank Nov 4, 2025
8075c98
Add test for success path
osamakader Nov 6, 2025
c8618d2
Refactor safety checking for attributes
JonathanBrouwer Nov 7, 2025
87b2796
Add test for unnecessary unsafe on proc macro attr
JonathanBrouwer Nov 7, 2025
09385f9
use bare_rustc to keep host toolchain
osamakader Nov 7, 2025
244eef6
a few small clippy fixes
hkBst Nov 7, 2025
1c1923f
tests: skip rustdoc test-builder success path when cross-compiling
osamakader Nov 8, 2025
ebe6c4c
update the bootstrap readme
Shourya742 Nov 9, 2025
71b0755
Provide more context when mutably borrowing an imutable borrow
estebank Nov 5, 2025
f1bbe59
tests: skip rustdoc test-builder success path for remote client
osamakader Nov 9, 2025
dc32847
Prepare `TestProps::load_from` for handler extraction
Zalathar Oct 20, 2025
a6580fb
Introduce a system of "directive handlers" indexed by directive name
Zalathar Oct 20, 2025
e00bc9c
Migrate all `TestProps` directive processing into smaller named handlers
Zalathar Oct 20, 2025
d82b84c
Remove the temporary line-break preservers
Zalathar Oct 21, 2025
33e9911
Add FIXMEs for some existing directive-handling concerns
Zalathar Nov 10, 2025
ee8c913
test(rustdoc): move tests into jump-to-def
midsterx Nov 7, 2025
02e1f44
`c_variadic`: Add future-incompatibility warning for `...` arguments …
beetrees Jul 7, 2025
425c704
use consistent terminology here. It might not be beta if we overrode …
Shourya742 Nov 10, 2025
a23b8c4
Add new `function_casts_as_integer` lint
GuillaumeGomez May 23, 2025
40be1db
Fix new `function_casts_as_integer` lint errors in core, std, panic_u…
GuillaumeGomez May 23, 2025
725f4ad
Allow `function_casts_as_integer` in non-related ui tests
GuillaumeGomez May 23, 2025
2ac32ae
Add ui test for `function_casts_as_integer` lint
GuillaumeGomez May 23, 2025
37eb906
Allow `function_casts_as_integer` in non-related clippy ui tests
GuillaumeGomez May 24, 2025
065d41e
Allow `function_casts_as_integer` in non-related miri tests
GuillaumeGomez May 27, 2025
6e14bea
Allow `function_casts_as_integer` in coretest test
GuillaumeGomez May 27, 2025
a99d100
Allow `function_casts_as_integer` in miri source code
GuillaumeGomez Oct 14, 2025
0a2c473
Convert `function_cast_as_integer` lint suggestion to plain `*const (…
GuillaumeGomez Oct 29, 2025
f22600e
Fix typos
GuillaumeGomez Oct 30, 2025
d05f297
Add more test for `function_cast_as_integer` lint
GuillaumeGomez Nov 10, 2025
66b4e93
Add instructions on what to do in case casts other than to integers i…
GuillaumeGomez Nov 10, 2025
a726de2
bootstrap: respect `build.python` on macOS
xSetech Nov 7, 2025
191a3e3
Noted the previous forced default in the change tracker
xSetech Nov 10, 2025
5b9211c
Rollup merge of #141470 - GuillaumeGomez:function_casts_as_integer, r…
Zalathar Nov 11, 2025
3538bc1
Rollup merge of #143619 - beetrees:varargs-named, r=jdonszelmann
Zalathar Nov 11, 2025
6487148
Rollup merge of #146495 - fmease:rustdoc-erase-doc-priv-items-attr, r…
Zalathar Nov 11, 2025
044c079
Rollup merge of #147771 - nxsaken:div_shlr_exact, r=dtolnay
Zalathar Nov 11, 2025
c7bfd7f
Rollup merge of #147833 - aDotInTheVoid:rdj-shuffle, r=camelid
Zalathar Nov 11, 2025
24873aa
Rollup merge of #147955 - Zalathar:handlers, r=jieyouxu
Zalathar Nov 11, 2025
01ae075
Rollup merge of #148480 - Lysxia:steal-mut, r=davidtwco
Zalathar Nov 11, 2025
eb415e9
Rollup merge of #148506 - estebank:issue-41966, r=davidtwco
Zalathar Nov 11, 2025
417bea3
Rollup merge of #148508 - estebank:issue-74617, r=nnethercote
Zalathar Nov 11, 2025
3227f26
Rollup merge of #148530 - Shourya742:2025-11-05-update-bootstrap-docu…
Zalathar Nov 11, 2025
303dd1c
Rollup merge of #148608 - osamakader:doc-test-builder, r=GuillaumeGomez
Zalathar Nov 11, 2025
e8404e4
Rollup merge of #148636 - xSetech:boostrap/set-python-on-macos, r=jie…
Zalathar Nov 11, 2025
f342c62
Rollup merge of #148639 - midsterx:test/rustdoc, r=GuillaumeGomez
Zalathar Nov 11, 2025
7327bbc
Rollup merge of #148647 - JonathanBrouwer:unsafe_attr_refactor, r=jdo…
Zalathar Nov 11, 2025
16944b8
Rollup merge of #148667 - hkBst:clippy-fix-14, r=Kivooeo
Zalathar Nov 11, 2025
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
6 changes: 3 additions & 3 deletions compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
}

impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
/// Because we want to track parent items and so forth, enable
/// deep walking so that we walk nested items in the context of
/// their outer items.
// Because we want to track parent items and so forth, enable
// deep walking so that we walk nested items in the context of
// their outer items.

fn visit_nested_item(&mut self, item: ItemId) {
debug!("visit_nested_item: {:?}", item);
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_attr_parsing/src/validate_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ pub fn check_attribute_safety(

// - Normal builtin attribute
// - Writing `#[unsafe(..)]` is not permitted on normal builtin attributes
(Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => {
(None | Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => {
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
span: unsafe_span,
name: attr_item.path.clone(),
Expand All @@ -218,15 +218,10 @@ pub fn check_attribute_safety(

// - Normal builtin attribute
// - No explicit `#[unsafe(..)]` written.
(Some(AttributeSafety::Normal), Safety::Default) => {
(None | Some(AttributeSafety::Normal), Safety::Default) => {
// OK
}

// - Non-builtin attribute
(None, Safety::Unsafe(_) | Safety::Default) => {
// OK (not checked here)
}

(
Some(AttributeSafety::Unsafe { .. } | AttributeSafety::Normal) | None,
Safety::Safe(..),
Expand Down
37 changes: 31 additions & 6 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
AccessKind::Mutate => {
err = self.cannot_assign(span, &(item_msg + &reason));
act = "assign";
acted_on = "written";
acted_on = "written to";
span
}
AccessKind::MutableBorrow => {
Expand Down Expand Up @@ -518,8 +518,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
err.span_label(
span,
format!(
"`{name}` is a `{pointer_sigil}` {pointer_desc}, \
so the data it refers to cannot be {acted_on}",
"`{name}` is a `{pointer_sigil}` {pointer_desc}, so it cannot be \
{acted_on}",
),
);

Expand All @@ -542,7 +542,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.expected_fn_found_fn_mut_call(&mut err, span, act);
}

PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => {
PlaceRef { local, projection: [.., ProjectionElem::Deref] } => {
err.span_label(span, format!("cannot {act}"));

match opt_source {
Expand All @@ -559,11 +559,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
));
self.suggest_map_index_mut_alternatives(ty, &mut err, span);
}
_ => (),
_ => {
let local = &self.body.local_decls[local];
match local.local_info() {
LocalInfo::StaticRef { def_id, .. } => {
let span = self.infcx.tcx.def_span(def_id);
err.span_label(span, format!("this `static` cannot be {acted_on}"));
}
LocalInfo::ConstRef { def_id } => {
let span = self.infcx.tcx.def_span(def_id);
err.span_label(span, format!("this `const` cannot be {acted_on}"));
}
LocalInfo::BlockTailTemp(_) | LocalInfo::Boring
if !local.source_info.span.overlaps(span) =>
{
err.span_label(
local.source_info.span,
format!("this cannot be {acted_on}"),
);
}
_ => {}
}
}
}
}

_ => {
PlaceRef { local, .. } => {
let local = &self.body.local_decls[local];
if !local.source_info.span.overlaps(span) {
err.span_label(local.source_info.span, format!("this cannot be {acted_on}"));
}
err.span_label(span, format!("cannot {act}"));
}
}
Expand Down
14 changes: 11 additions & 3 deletions compiler/rustc_data_structures/src/steal.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::stable_hasher::{HashStable, StableHasher};
use crate::sync::{MappedReadGuard, ReadGuard, RwLock};
use crate::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, RwLock, WriteGuard};

/// The `Steal` struct is intended to used as the value for a query.
/// Specifically, we sometimes have queries (*cough* MIR *cough*)
Expand Down Expand Up @@ -40,9 +40,17 @@ impl<T> Steal<T> {
ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
}

/// An escape hatch for rustc drivers to mutate `Steal` caches.
///
/// Use at your own risk. This can badly break incremental compilation
/// and anything else that relies on the immutability of query caches.
#[track_caller]
pub fn get_mut(&mut self) -> &mut T {
self.value.get_mut().as_mut().expect("attempt to read from stolen value")
pub fn risky_hack_borrow_mut(&self) -> MappedWriteGuard<'_, T> {
let borrow = self.value.borrow_mut();
if borrow.is_none() {
panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
}
WriteGuard::map(borrow, |opt| opt.as_mut().unwrap())
}

#[track_caller]
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_driver_impl/src/signal_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ pub(super) fn install() {
libc::sigaltstack(&alt_stack, ptr::null_mut());

let mut sa: libc::sigaction = mem::zeroed();
sa.sa_sigaction = print_stack_trace as libc::sighandler_t;
sa.sa_sigaction =
print_stack_trace as unsafe extern "C" fn(libc::c_int) as libc::sighandler_t;
sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK;
libc::sigemptyset(&mut sa.sa_mask);
for (signum, _signame) in KILL_SIGNALS {
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2322,11 +2322,6 @@ impl HumanEmitter {
show_code_change
{
for part in parts {
let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) {
snippet
} else {
String::new()
};
let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display;
let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display;

Expand Down Expand Up @@ -2402,7 +2397,7 @@ impl HumanEmitter {
// LL - REMOVED <- row_num - 2 - (newlines - first_i - 1)
// LL + NEWER
// | <- row_num

let snippet = sm.span_to_snippet(part.span).unwrap_or_default();
let newlines = snippet.lines().count();
if newlines > 0 && row_num > newlines {
// Account for removals where the part being removed spans multiple
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -886,9 +886,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
}
} else if let SyntaxExtensionKind::NonMacroAttr = ext {
if let ast::Safety::Unsafe(span) = attr.get_normal_item().unsafety {
self.cx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute");
}
// `-Zmacro-stats` ignores these because they don't do any real expansion.
self.cx.expanded_inert_attrs.mark(&attr);
item.visit_attrs(|attrs| attrs.insert(pos, attr));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/variance/terms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl<'a> fmt::Debug for VarianceTerm<'a> {
}
}

/// The first pass over the crate simply builds up the set of inferreds.
// The first pass over the crate simply builds up the set of inferreds.

pub(crate) struct TermsContext<'a, 'tcx> {
pub tcx: TyCtxt<'tcx>,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ lint_forgetting_copy_types = calls to `std::mem::forget` with a value that imple
lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing
.label = argument has type `{$arg_ty}`
lint_function_casts_as_integer = direct cast of function item into an integer
.cast_as_fn = first cast to a pointer `as *const ()`
lint_hidden_glob_reexport = private item shadows public glob re-export
.note_glob_reexport = the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here
.note_private_item = but the private item here shadows it
Expand Down
63 changes: 63 additions & 0 deletions compiler/rustc_lint/src/function_cast_as_integer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::BytePos;

use crate::lints::{FunctionCastsAsIntegerDiag, FunctionCastsAsIntegerSugg};
use crate::{LateContext, LateLintPass};

declare_lint! {
/// The `function_casts_as_integer` lint detects cases where a function item is cast
/// to an integer.
///
/// ### Example
///
/// ```rust
/// fn foo() {}
/// let x = foo as usize;
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// When casting a function item to an integer, it implicitly creates a
/// function pointer that will in turn be cast to an integer. By making
/// it explicit, it improves readability of the code and prevents bugs.
pub FUNCTION_CASTS_AS_INTEGER,
Warn,
"casting a function into an integer",
}

declare_lint_pass!(
/// Lint for casts of functions into integers.
FunctionCastsAsInteger => [FUNCTION_CASTS_AS_INTEGER]
);

impl<'tcx> LateLintPass<'tcx> for FunctionCastsAsInteger {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
let hir::ExprKind::Cast(cast_from_expr, cast_to_expr) = expr.kind else { return };
let cast_to_ty = cx.typeck_results().expr_ty(expr);
// Casting to a function (pointer?), so all good.
//
// Normally, only casts to integers is possible, but if it ever changed, this condition
// will likely need to be updated.
if matches!(cast_to_ty.kind(), ty::FnDef(..) | ty::FnPtr(..) | ty::RawPtr(..)) {
return;
}
let cast_from_ty = cx.typeck_results().expr_ty(cast_from_expr);
if matches!(cast_from_ty.kind(), ty::FnDef(..)) {
cx.tcx.emit_node_span_lint(
FUNCTION_CASTS_AS_INTEGER,
expr.hir_id,
cast_to_expr.span.with_lo(cast_from_expr.span.hi() + BytePos(1)),
FunctionCastsAsIntegerDiag {
sugg: FunctionCastsAsIntegerSugg {
suggestion: cast_from_expr.span.shrink_to_hi(),
cast_to_ty,
},
},
);
}
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ mod errors;
mod expect;
mod for_loops_over_fallibles;
mod foreign_modules;
mod function_cast_as_integer;
mod if_let_rescope;
mod impl_trait_overcaptures;
mod internal;
Expand Down Expand Up @@ -89,6 +90,7 @@ use deref_into_dyn_supertrait::*;
use drop_forget_useless::*;
use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
use for_loops_over_fallibles::*;
use function_cast_as_integer::*;
use if_let_rescope::IfLetRescope;
use impl_trait_overcaptures::ImplTraitOvercaptures;
use internal::*;
Expand Down Expand Up @@ -241,6 +243,7 @@ late_lint_methods!(
IfLetRescope: IfLetRescope::default(),
StaticMutRefs: StaticMutRefs,
UnqualifiedLocalImports: UnqualifiedLocalImports,
FunctionCastsAsInteger: FunctionCastsAsInteger,
CheckTransmutes: CheckTransmutes,
LifetimeSyntax: LifetimeSyntax,
]
Expand Down
20 changes: 20 additions & 0 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3019,6 +3019,26 @@ pub(crate) struct ReservedMultihash {
pub suggestion: Span,
}

#[derive(LintDiagnostic)]
#[diag(lint_function_casts_as_integer)]
pub(crate) struct FunctionCastsAsIntegerDiag<'tcx> {
#[subdiagnostic]
pub(crate) sugg: FunctionCastsAsIntegerSugg<'tcx>,
}

#[derive(Subdiagnostic)]
#[suggestion(
lint_cast_as_fn,
code = " as *const ()",
applicability = "machine-applicable",
style = "verbose"
)]
pub(crate) struct FunctionCastsAsIntegerSugg<'tcx> {
#[primary_span]
pub suggestion: Span,
pub cast_to_ty: Ty<'tcx>,
}

#[derive(Debug)]
pub(crate) struct MismatchedLifetimeSyntaxes {
pub inputs: LifetimeSyntaxCategories<Vec<Span>>,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_lint/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ macro_rules! late_lint_methods {
/// Each `check` method checks a single syntax node, and should not
/// invoke methods recursively (unlike `Visitor`). By default they
/// do nothing.
//
///
// FIXME: eliminate the duplication with `Visitor`. But this also
// contains a few lint-specific methods with no equivalent in `Visitor`.

//
macro_rules! declare_late_lint_pass {
([], [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
pub trait LateLintPass<'tcx>: LintPass {
Expand Down
48 changes: 48 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ declare_lint_pass! {
UNUSED_UNSAFE,
UNUSED_VARIABLES,
USELESS_DEPRECATED,
VARARGS_WITHOUT_PATTERN,
WARNINGS,
// tidy-alphabetical-end
]
Expand Down Expand Up @@ -5295,3 +5296,50 @@ declare_lint! {
report_in_deps: false,
};
}

declare_lint! {
/// The `varargs_without_pattern` lint detects when `...` is used as an argument to a
/// non-foreign function without any pattern being specified.
///
/// ### Example
///
/// ```rust
/// // Using `...` in non-foreign function definitions is unstable, however stability is
/// // currently only checked after attributes are expanded, so using `#[cfg(false)]` here will
/// // allow this to compile on stable Rust.
/// #[cfg(false)]
/// fn foo(...) {
///
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Patterns are currently required for all non-`...` arguments in function definitions (with
/// some exceptions in the 2015 edition). Requiring `...` arguments to have patterns in
/// non-foreign function definitions makes the language more consistent, and removes a source of
/// confusion for the unstable C variadic feature. `...` arguments without a pattern are already
/// stable and widely used in foreign function definitions; this lint only affects non-foreign
/// function definitions.
///
/// Using `...` (C varargs) in a non-foreign function definition is currently unstable. However,
/// stability checking for the `...` syntax in non-foreign function definitions is currently
/// implemented after attributes have been expanded, meaning that if the attribute removes the
/// use of the unstable syntax (e.g. `#[cfg(false)]`, or a procedural macro), the code will
/// compile on stable Rust; this is the only situation where this lint affects code that
/// compiles on stable Rust.
///
/// This is a [future-incompatible] lint to transition this to a hard error in the future.
///
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub VARARGS_WITHOUT_PATTERN,
Warn,
"detects usage of `...` arguments without a pattern in non-foreign items",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseError,
reference: "issue #145544 <https://github.com/rust-lang/rust/issues/145544>",
report_in_deps: false,
};
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::ty::{self, ConstKind, GenericArgsRef, ScalarInt, Ty, TyCtxt};

///////////////////////////////////////////////////////////////////////////
/// Evaluated Constants
///
/// Represents the result of const evaluation via the `eval_to_allocation` query.
/// Not to be confused with `ConstAllocation`, which directly refers to the underlying data!
/// Here we indirect via an `AllocId`.
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,9 @@ parse_use_if_else = use an `if-else` expression instead
parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
parse_use_let_not_var = write `let` instead of `var` to introduce a new variable
parse_varargs_without_pattern = missing pattern for `...` argument
.suggestion = name the argument, or use `_` to continue ignoring it
parse_visibility_not_followed_by_item = visibility `{$vis}` is not followed by an item
.label = the visibility
.help = you likely meant to define an item, e.g., `{$vis} fn foo() {"{}"}`
Expand Down
Loading
Loading