Skip to content

Commit 2076173

Browse files
committed
Auto merge of rust-lang#119604 - matthiaskrgr:rollup-vd0snqf, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#117556 (Disallow reference to `static mut` and adding `static_mut_ref` lint) - rust-lang#119354 (Make `negative_bounds` internal & fix some of its issues) - rust-lang#119420 (Handle ForeignItem as TAIT scope.) - rust-lang#119506 (Use `resolutions(()).effective_visiblities` to avoid cycle errors in `report_object_error`) - rust-lang#119566 (Remove `-Zdump-mir-spanview`) - rust-lang#119567 (Remove `-Zreport-delayed-bugs`.) - rust-lang#119577 (Migrate memory overlap check from validator to lint) - rust-lang#119586 ([rustdoc] Fix invalid handling for static method calls in jump to definition feature) - rust-lang#119588 (Move `i586-unknown-netbsd` from tier 2 to tier 3 platform support table) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5113ed2 + cd5f42f commit 2076173

File tree

121 files changed

+2018
-1552
lines changed

Some content is hidden

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

121 files changed

+2018
-1552
lines changed

Diff for: Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3877,6 +3877,7 @@ dependencies = [
38773877
"rustc_feature",
38783878
"rustc_fluent_macro",
38793879
"rustc_hir",
3880+
"rustc_hir_pretty",
38803881
"rustc_index",
38813882
"rustc_infer",
38823883
"rustc_lint_defs",

Diff for: compiler/rustc_ast_passes/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ ast_passes_module_nonascii = trying to load file for module `{$name}` with non-a
188188
ast_passes_negative_bound_not_supported =
189189
negative bounds are not supported
190190
191+
ast_passes_negative_bound_with_parenthetical_notation =
192+
parenthetical notation may not be used for negative bounds
193+
191194
ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
192195
.outer = outer `impl Trait`
193196
.inner = nested `impl Trait` here

Diff for: compiler/rustc_ast_passes/src/ast_validation.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -1312,13 +1312,24 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13121312
if let GenericBound::Trait(trait_ref, modifiers) = bound
13131313
&& let BoundPolarity::Negative(_) = modifiers.polarity
13141314
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
1315-
&& let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref()
13161315
{
1317-
for arg in &args.args {
1318-
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
1319-
self.dcx()
1320-
.emit_err(errors::ConstraintOnNegativeBound { span: constraint.span });
1316+
match segment.args.as_deref() {
1317+
Some(ast::GenericArgs::AngleBracketed(args)) => {
1318+
for arg in &args.args {
1319+
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
1320+
self.dcx().emit_err(errors::ConstraintOnNegativeBound {
1321+
span: constraint.span,
1322+
});
1323+
}
1324+
}
1325+
}
1326+
// The lowered form of parenthesized generic args contains a type binding.
1327+
Some(ast::GenericArgs::Parenthesized(args)) => {
1328+
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
1329+
span: args.span,
1330+
});
13211331
}
1332+
None => {}
13221333
}
13231334
}
13241335

Diff for: compiler/rustc_ast_passes/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,13 @@ pub struct ConstraintOnNegativeBound {
763763
pub span: Span,
764764
}
765765

766+
#[derive(Diagnostic)]
767+
#[diag(ast_passes_negative_bound_with_parenthetical_notation)]
768+
pub struct NegativeBoundWithParentheticalNotation {
769+
#[primary_span]
770+
pub span: Span,
771+
}
772+
766773
#[derive(Diagnostic)]
767774
#[diag(ast_passes_invalid_unnamed_field_ty)]
768775
pub struct InvalidUnnamedFieldTy {

Diff for: compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

+3
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ fn start<T: Termination + 'static>(
111111
}
112112

113113
static mut NUM: u8 = 6 * 7;
114+
115+
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
116+
#[allow(static_mut_ref)]
114117
static NUM_REF: &'static u8 = unsafe { &NUM };
115118

116119
unsafe fn zeroed<T>() -> T {

Diff for: compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs

+3
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ fn start<T: Termination + 'static>(
9898
}
9999

100100
static mut NUM: u8 = 6 * 7;
101+
102+
// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
103+
#[allow(static_mut_ref)]
101104
static NUM_REF: &'static u8 = unsafe { &NUM };
102105

103106
macro_rules! assert {

Diff for: compiler/rustc_const_eval/src/transform/validate.rs

+3-43
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ impl<'tcx> MirPass<'tcx> for Validator {
7474
mir_phase,
7575
unwind_edge_count: 0,
7676
reachable_blocks: traversal::reachable_as_bitset(body),
77-
place_cache: FxHashSet::default(),
7877
value_cache: FxHashSet::default(),
7978
can_unwind,
8079
};
@@ -106,7 +105,6 @@ struct CfgChecker<'a, 'tcx> {
106105
mir_phase: MirPhase,
107106
unwind_edge_count: usize,
108107
reachable_blocks: BitSet<BasicBlock>,
109-
place_cache: FxHashSet<PlaceRef<'tcx>>,
110108
value_cache: FxHashSet<u128>,
111109
// If `false`, then the MIR must not contain `UnwindAction::Continue` or
112110
// `TerminatorKind::Resume`.
@@ -294,19 +292,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
294292

295293
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
296294
match &statement.kind {
297-
StatementKind::Assign(box (dest, rvalue)) => {
298-
// FIXME(JakobDegen): Check this for all rvalues, not just this one.
299-
if let Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) = rvalue {
300-
// The sides of an assignment must not alias. Currently this just checks whether
301-
// the places are identical.
302-
if dest == src {
303-
self.fail(
304-
location,
305-
"encountered `Assign` statement with overlapping memory",
306-
);
307-
}
308-
}
309-
}
310295
StatementKind::AscribeUserType(..) => {
311296
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
312297
self.fail(
@@ -341,7 +326,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
341326
self.fail(location, format!("explicit `{kind:?}` is forbidden"));
342327
}
343328
}
344-
StatementKind::StorageLive(_)
329+
StatementKind::Assign(..)
330+
| StatementKind::StorageLive(_)
345331
| StatementKind::StorageDead(_)
346332
| StatementKind::Intrinsic(_)
347333
| StatementKind::Coverage(_)
@@ -404,10 +390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
404390
}
405391

406392
// The call destination place and Operand::Move place used as an argument might be
407-
// passed by a reference to the callee. Consequently they must be non-overlapping
408-
// and cannot be packed. Currently this simply checks for duplicate places.
409-
self.place_cache.clear();
410-
self.place_cache.insert(destination.as_ref());
393+
// passed by a reference to the callee. Consequently they cannot be packed.
411394
if is_within_packed(self.tcx, &self.body.local_decls, *destination).is_some() {
412395
// This is bad! The callee will expect the memory to be aligned.
413396
self.fail(
@@ -418,10 +401,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
418401
),
419402
);
420403
}
421-
let mut has_duplicates = false;
422404
for arg in args {
423405
if let Operand::Move(place) = arg {
424-
has_duplicates |= !self.place_cache.insert(place.as_ref());
425406
if is_within_packed(self.tcx, &self.body.local_decls, *place).is_some() {
426407
// This is bad! The callee will expect the memory to be aligned.
427408
self.fail(
@@ -434,16 +415,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
434415
}
435416
}
436417
}
437-
438-
if has_duplicates {
439-
self.fail(
440-
location,
441-
format!(
442-
"encountered overlapping memory in `Move` arguments to `Call` terminator: {:?}",
443-
terminator.kind,
444-
),
445-
);
446-
}
447418
}
448419
TerminatorKind::Assert { target, unwind, .. } => {
449420
self.check_edge(location, *target, EdgeKind::Normal);
@@ -1112,17 +1083,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
11121083
)
11131084
}
11141085
}
1115-
// FIXME(JakobDegen): Check this for all rvalues, not just this one.
1116-
if let Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) = rvalue {
1117-
// The sides of an assignment must not alias. Currently this just checks whether
1118-
// the places are identical.
1119-
if dest == src {
1120-
self.fail(
1121-
location,
1122-
"encountered `Assign` statement with overlapping memory",
1123-
);
1124-
}
1125-
}
11261086
}
11271087
StatementKind::AscribeUserType(..) => {
11281088
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {

Diff for: compiler/rustc_error_codes/src/error_codes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ E0792: include_str!("./error_codes/E0792.md"),
515515
E0793: include_str!("./error_codes/E0793.md"),
516516
E0794: include_str!("./error_codes/E0794.md"),
517517
E0795: include_str!("./error_codes/E0795.md"),
518+
E0796: include_str!("./error_codes/E0796.md"),
518519
}
519520

520521
// Undocumented removed error codes. Note that many removed error codes are kept in the list above

Diff for: compiler/rustc_error_codes/src/error_codes/E0796.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Reference of mutable static.
2+
3+
Erroneous code example:
4+
5+
```compile_fail,edition2024,E0796
6+
static mut X: i32 = 23;
7+
static mut Y: i32 = 24;
8+
9+
unsafe {
10+
let y = &X;
11+
let ref x = X;
12+
let (x, y) = (&X, &Y);
13+
foo(&X);
14+
}
15+
16+
fn foo<'a>(_x: &'a i32) {}
17+
```
18+
19+
Mutable statics can be written to by multiple threads: aliasing violations or
20+
data races will cause undefined behavior.
21+
22+
Reference of mutable static is a hard error from 2024 edition.

Diff for: compiler/rustc_errors/src/lib.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,6 @@ pub struct DiagCtxtFlags {
525525
/// If true, immediately emit diagnostics that would otherwise be buffered.
526526
/// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`)
527527
pub dont_buffer_diagnostics: bool,
528-
/// If true, immediately print bugs registered with `span_delayed_bug`.
529-
/// (rustc: see `-Z report-delayed-bugs`)
530-
pub report_delayed_bugs: bool,
531528
/// Show macro backtraces.
532529
/// (rustc: see `-Z macro-backtrace`)
533530
pub macro_backtrace: bool,
@@ -1004,7 +1001,6 @@ impl DiagCtxt {
10041001
) -> ErrorGuaranteed {
10051002
let treat_next_err_as_bug = self.inner.borrow().treat_next_err_as_bug();
10061003
if treat_next_err_as_bug {
1007-
// FIXME: don't abort here if report_delayed_bugs is off
10081004
self.span_bug(sp, msg);
10091005
}
10101006
let mut diagnostic = Diagnostic::new(DelayedBug, msg);
@@ -1016,11 +1012,7 @@ impl DiagCtxt {
10161012
// where the explanation of what "good path" is (also, it should be renamed).
10171013
pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
10181014
let mut inner = self.inner.borrow_mut();
1019-
1020-
let mut diagnostic = Diagnostic::new(DelayedBug, msg);
1021-
if inner.flags.report_delayed_bugs {
1022-
inner.emit_diagnostic_without_consuming(&mut diagnostic);
1023-
}
1015+
let diagnostic = Diagnostic::new(DelayedBug, msg);
10241016
let backtrace = std::backtrace::Backtrace::capture();
10251017
inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
10261018
}
@@ -1430,10 +1422,8 @@ impl DiagCtxtInner {
14301422
self.span_delayed_bugs
14311423
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
14321424

1433-
if !self.flags.report_delayed_bugs {
1434-
#[allow(deprecated)]
1435-
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
1436-
}
1425+
#[allow(deprecated)]
1426+
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
14371427
}
14381428

14391429
if diagnostic.has_future_breakage() {

Diff for: compiler/rustc_feature/src/unstable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ declare_features! (
210210
/// Allows the `multiple_supertrait_upcastable` lint.
211211
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
212212
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
213-
(incomplete, negative_bounds, "1.71.0", None),
213+
(internal, negative_bounds, "1.71.0", None),
214214
/// Allows using `#[omit_gdb_pretty_printer_section]`.
215215
(internal, omit_gdb_pretty_printer_section, "1.5.0", None),
216216
/// Allows using `#[prelude_import]` on glob `use` items.

Diff for: compiler/rustc_hir_analysis/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ rustc_errors = { path = "../rustc_errors" }
1717
rustc_feature = { path = "../rustc_feature" }
1818
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1919
rustc_hir = { path = "../rustc_hir" }
20+
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
2021
rustc_index = { path = "../rustc_index" }
2122
rustc_infer = { path = "../rustc_infer" }
2223
rustc_lint_defs = { path = "../rustc_lint_defs" }

Diff for: compiler/rustc_hir_analysis/messages.ftl

+14
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,20 @@ hir_analysis_start_not_target_feature = `#[start]` function is not allowed to ha
346346
hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
347347
.label = `#[start]` function is not allowed to be `#[track_caller]`
348348
349+
hir_analysis_static_mut_ref = reference of mutable static is disallowed
350+
.label = reference of mutable static
351+
.note = mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
352+
.suggestion = shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
353+
.suggestion_mut = mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
354+
355+
hir_analysis_static_mut_ref_lint = {$shared}reference of mutable static is discouraged
356+
.label = shared reference of mutable static
357+
.label_mut = mutable reference of mutable static
358+
.suggestion = shared references are dangerous since if there's any kind of mutation of that static while the reference lives, that's UB; use `addr_of!` instead to create a raw pointer
359+
.suggestion_mut = mutable references are dangerous since if there's any other pointer or reference used for that static while the reference lives, that's UB; use `addr_of_mut!` instead to create a raw pointer
360+
.note = reference of mutable static is a hard error from 2024 edition
361+
.why_note = mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
362+
349363
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
350364
351365
hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl

Diff for: compiler/rustc_hir_analysis/src/astconv/bounds.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,36 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
2626
span: Span,
2727
) {
2828
let tcx = self.tcx();
29+
let sized_def_id = tcx.lang_items().sized_trait();
30+
let mut seen_negative_sized_bound = false;
2931

3032
// Try to find an unbound in bounds.
3133
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
3234
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
3335
for ab in ast_bounds {
34-
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
35-
unbounds.push(ptr)
36+
let hir::GenericBound::Trait(ptr, modifier) = ab else {
37+
continue;
38+
};
39+
match modifier {
40+
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
41+
hir::TraitBoundModifier::Negative => {
42+
if let Some(sized_def_id) = sized_def_id
43+
&& ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
44+
{
45+
seen_negative_sized_bound = true;
46+
}
47+
}
48+
_ => {}
3649
}
3750
}
3851
};
3952
search_bounds(ast_bounds);
4053
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
4154
for clause in where_clause {
42-
if let hir::WherePredicate::BoundPredicate(pred) = clause {
43-
if pred.is_param_bound(self_ty.to_def_id()) {
44-
search_bounds(pred.bounds);
45-
}
55+
if let hir::WherePredicate::BoundPredicate(pred) = clause
56+
&& pred.is_param_bound(self_ty.to_def_id())
57+
{
58+
search_bounds(pred.bounds);
4659
}
4760
}
4861
}
@@ -53,15 +66,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
5366
});
5467
}
5568

56-
let sized_def_id = tcx.lang_items().sized_trait();
57-
5869
let mut seen_sized_unbound = false;
5970
for unbound in unbounds {
60-
if let Some(sized_def_id) = sized_def_id {
61-
if unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) {
62-
seen_sized_unbound = true;
63-
continue;
64-
}
71+
if let Some(sized_def_id) = sized_def_id
72+
&& unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
73+
{
74+
seen_sized_unbound = true;
75+
continue;
6576
}
6677
// There was a `?Trait` bound, but it was not `?Sized`; warn.
6778
tcx.dcx().span_warn(
@@ -71,15 +82,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
7182
);
7283
}
7384

74-
// If the above loop finished there was no `?Sized` bound; add implicitly sized if `Sized` is available.
75-
if sized_def_id.is_none() {
76-
// No lang item for `Sized`, so we can't add it as a bound.
77-
return;
78-
}
79-
if seen_sized_unbound {
80-
// There was in fact a `?Sized` bound, return without doing anything
81-
} else {
82-
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
85+
if seen_sized_unbound || seen_negative_sized_bound {
86+
// There was in fact a `?Sized` or `!Sized` bound;
87+
// we don't need to do anything.
88+
} else if sized_def_id.is_some() {
89+
// There was no `?Sized` or `!Sized` bound;
90+
// add `Sized` if it's available.
8391
bounds.push_sized(tcx, self_ty, span);
8492
}
8593
}

0 commit comments

Comments
 (0)