Skip to content

Commit 9312cd6

Browse files
committed
Auto merge of #148817 - Zalathar:rollup-tf5ti2m, r=Zalathar
Rollup of 15 pull requests Successful merges: - #141470 (Add new `function_casts_as_integer` lint) - #143619 (`c_variadic`: Add future-incompatibility warning for `...` arguments without a pattern outside of `extern` blocks) - #146495 (rustdoc: Erase `#![doc(document_private_items)]`) - #147771 (Rename `*exact_{div,shr,shl}` to `*{div,shr,shl}_exact`) - #147833 (rustdoc-json: move `target` to `json::conversions`) - #147955 (compiletest: Migrate `TestProps` directive handling to a system of named handlers) - #148480 (Add `Steal::risky_hack_borrow_mut`) - #148506 (Special case detecting `'static` lifetime requirement coming from `-> Box<dyn Trait>`) - #148508 (Provide more context when mutably borrowing an imutably borrowed value) - #148530 (update the bootstrap readme) - #148608 (Add test for --test-builder success path) - #148636 (bootstrap: respect `build.python` on macOS) - #148639 (test(rustdoc): move tests into jump-to-def) - #148647 (Check unsafety for non-macro attributes in `validate_attr`) - #148667 (a few small clippy fixes) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c8f22ca + 16944b8 commit 9312cd6

File tree

227 files changed

+2021
-956
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

227 files changed

+2021
-956
lines changed

compiler/rustc_ast_lowering/src/index.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
125125
}
126126

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

132132
fn visit_nested_item(&mut self, item: ItemId) {
133133
debug!("visit_nested_item: {:?}", item);

compiler/rustc_attr_parsing/src/validate_attr.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ pub fn check_attribute_safety(
209209

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

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

225-
// - Non-builtin attribute
226-
(None, Safety::Unsafe(_) | Safety::Default) => {
227-
// OK (not checked here)
228-
}
229-
230225
(
231226
Some(AttributeSafety::Unsafe { .. } | AttributeSafety::Normal) | None,
232227
Safety::Safe(..),

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
213213
AccessKind::Mutate => {
214214
err = self.cannot_assign(span, &(item_msg + &reason));
215215
act = "assign";
216-
acted_on = "written";
216+
acted_on = "written to";
217217
span
218218
}
219219
AccessKind::MutableBorrow => {
@@ -518,8 +518,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
518518
err.span_label(
519519
span,
520520
format!(
521-
"`{name}` is a `{pointer_sigil}` {pointer_desc}, \
522-
so the data it refers to cannot be {acted_on}",
521+
"`{name}` is a `{pointer_sigil}` {pointer_desc}, so it cannot be \
522+
{acted_on}",
523523
),
524524
);
525525

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

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

548548
match opt_source {
@@ -559,11 +559,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
559559
));
560560
self.suggest_map_index_mut_alternatives(ty, &mut err, span);
561561
}
562-
_ => (),
562+
_ => {
563+
let local = &self.body.local_decls[local];
564+
match local.local_info() {
565+
LocalInfo::StaticRef { def_id, .. } => {
566+
let span = self.infcx.tcx.def_span(def_id);
567+
err.span_label(span, format!("this `static` cannot be {acted_on}"));
568+
}
569+
LocalInfo::ConstRef { def_id } => {
570+
let span = self.infcx.tcx.def_span(def_id);
571+
err.span_label(span, format!("this `const` cannot be {acted_on}"));
572+
}
573+
LocalInfo::BlockTailTemp(_) | LocalInfo::Boring
574+
if !local.source_info.span.overlaps(span) =>
575+
{
576+
err.span_label(
577+
local.source_info.span,
578+
format!("this cannot be {acted_on}"),
579+
);
580+
}
581+
_ => {}
582+
}
583+
}
563584
}
564585
}
565586

566-
_ => {
587+
PlaceRef { local, .. } => {
588+
let local = &self.body.local_decls[local];
589+
if !local.source_info.span.overlaps(span) {
590+
err.span_label(local.source_info.span, format!("this cannot be {acted_on}"));
591+
}
567592
err.span_label(span, format!("cannot {act}"));
568593
}
569594
}

compiler/rustc_data_structures/src/steal.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::stable_hasher::{HashStable, StableHasher};
2-
use crate::sync::{MappedReadGuard, ReadGuard, RwLock};
2+
use crate::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, RwLock, WriteGuard};
33

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

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

4856
#[track_caller]

compiler/rustc_driver_impl/src/signal_handler.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ pub(super) fn install() {
152152
libc::sigaltstack(&alt_stack, ptr::null_mut());
153153

154154
let mut sa: libc::sigaction = mem::zeroed();
155-
sa.sa_sigaction = print_stack_trace as libc::sighandler_t;
155+
sa.sa_sigaction =
156+
print_stack_trace as unsafe extern "C" fn(libc::c_int) as libc::sighandler_t;
156157
sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK;
157158
libc::sigemptyset(&mut sa.sa_mask);
158159
for (signum, _signame) in KILL_SIGNALS {

compiler/rustc_errors/src/emitter.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2322,11 +2322,6 @@ impl HumanEmitter {
23222322
show_code_change
23232323
{
23242324
for part in parts {
2325-
let snippet = if let Ok(snippet) = sm.span_to_snippet(part.span) {
2326-
snippet
2327-
} else {
2328-
String::new()
2329-
};
23302325
let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display;
23312326
let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display;
23322327

@@ -2402,7 +2397,7 @@ impl HumanEmitter {
24022397
// LL - REMOVED <- row_num - 2 - (newlines - first_i - 1)
24032398
// LL + NEWER
24042399
// | <- row_num
2405-
2400+
let snippet = sm.span_to_snippet(part.span).unwrap_or_default();
24062401
let newlines = snippet.lines().count();
24072402
if newlines > 0 && row_num > newlines {
24082403
// Account for removals where the part being removed spans multiple

compiler/rustc_expand/src/expand.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,9 +886,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
886886
}
887887
}
888888
} else if let SyntaxExtensionKind::NonMacroAttr = ext {
889-
if let ast::Safety::Unsafe(span) = attr.get_normal_item().unsafety {
890-
self.cx.dcx().span_err(span, "unnecessary `unsafe` on safe attribute");
891-
}
892889
// `-Zmacro-stats` ignores these because they don't do any real expansion.
893890
self.cx.expanded_inert_attrs.mark(&attr);
894891
item.visit_attrs(|attrs| attrs.insert(pos, attr));

compiler/rustc_hir_analysis/src/variance/terms.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'a> fmt::Debug for VarianceTerm<'a> {
4444
}
4545
}
4646

47-
/// The first pass over the crate simply builds up the set of inferreds.
47+
// The first pass over the crate simply builds up the set of inferreds.
4848

4949
pub(crate) struct TermsContext<'a, 'tcx> {
5050
pub tcx: TyCtxt<'tcx>,

compiler/rustc_lint/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ lint_forgetting_copy_types = calls to `std::mem::forget` with a value that imple
265265
lint_forgetting_references = calls to `std::mem::forget` with a reference instead of an owned value does nothing
266266
.label = argument has type `{$arg_ty}`
267267
268+
lint_function_casts_as_integer = direct cast of function item into an integer
269+
.cast_as_fn = first cast to a pointer `as *const ()`
270+
268271
lint_hidden_glob_reexport = private item shadows public glob re-export
269272
.note_glob_reexport = the name `{$name}` in the {$namespace} namespace is supposed to be publicly re-exported here
270273
.note_private_item = but the private item here shadows it
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use rustc_hir as hir;
2+
use rustc_middle::ty;
3+
use rustc_session::{declare_lint, declare_lint_pass};
4+
use rustc_span::BytePos;
5+
6+
use crate::lints::{FunctionCastsAsIntegerDiag, FunctionCastsAsIntegerSugg};
7+
use crate::{LateContext, LateLintPass};
8+
9+
declare_lint! {
10+
/// The `function_casts_as_integer` lint detects cases where a function item is cast
11+
/// to an integer.
12+
///
13+
/// ### Example
14+
///
15+
/// ```rust
16+
/// fn foo() {}
17+
/// let x = foo as usize;
18+
/// ```
19+
///
20+
/// {{produces}}
21+
///
22+
/// ### Explanation
23+
///
24+
/// When casting a function item to an integer, it implicitly creates a
25+
/// function pointer that will in turn be cast to an integer. By making
26+
/// it explicit, it improves readability of the code and prevents bugs.
27+
pub FUNCTION_CASTS_AS_INTEGER,
28+
Warn,
29+
"casting a function into an integer",
30+
}
31+
32+
declare_lint_pass!(
33+
/// Lint for casts of functions into integers.
34+
FunctionCastsAsInteger => [FUNCTION_CASTS_AS_INTEGER]
35+
);
36+
37+
impl<'tcx> LateLintPass<'tcx> for FunctionCastsAsInteger {
38+
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
39+
let hir::ExprKind::Cast(cast_from_expr, cast_to_expr) = expr.kind else { return };
40+
let cast_to_ty = cx.typeck_results().expr_ty(expr);
41+
// Casting to a function (pointer?), so all good.
42+
//
43+
// Normally, only casts to integers is possible, but if it ever changed, this condition
44+
// will likely need to be updated.
45+
if matches!(cast_to_ty.kind(), ty::FnDef(..) | ty::FnPtr(..) | ty::RawPtr(..)) {
46+
return;
47+
}
48+
let cast_from_ty = cx.typeck_results().expr_ty(cast_from_expr);
49+
if matches!(cast_from_ty.kind(), ty::FnDef(..)) {
50+
cx.tcx.emit_node_span_lint(
51+
FUNCTION_CASTS_AS_INTEGER,
52+
expr.hir_id,
53+
cast_to_expr.span.with_lo(cast_from_expr.span.hi() + BytePos(1)),
54+
FunctionCastsAsIntegerDiag {
55+
sugg: FunctionCastsAsIntegerSugg {
56+
suggestion: cast_from_expr.span.shrink_to_hi(),
57+
cast_to_ty,
58+
},
59+
},
60+
);
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)