Skip to content
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

Rollup of 9 pull requests #119604

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
5f56465
Make feature `negative_bounds` internal
fmease Dec 27, 2023
a251974
Deny parenthetical notation for negative bounds
fmease Dec 27, 2023
32cea61
Don't elaborate `!Sized` to `!Sized + Sized`
fmease Dec 27, 2023
977546d
rustc_middle: Pretty-print negative bounds correctly
fmease Dec 27, 2023
76d616d
Handle ForeignItem as TAIT scope.
cjgillot Dec 29, 2023
9faa4b5
Disallow reference to `static mut` for expressions
obeis Dec 22, 2023
11129a8
Disallow reference to `static mut` for statements
obeis Dec 22, 2023
5e01c26
Call `maybe_expr_static_mut` inside `resolve_expr`
obeis Dec 22, 2023
a4a774a
Call `maybe_stmt_static_mut` inside `resolve_stmt`
obeis Dec 22, 2023
cd07eb1
Add test for `E0796` and `static_mut_ref` lint
obeis Dec 22, 2023
7fd2d8d
Do not run check on foreign items.
cjgillot Dec 31, 2023
03e9eff
Use `resolutions(()).effective_visiblities` to avoid cycle errors
compiler-errors Jan 4, 2024
af32054
Remove `-Zdump-mir-spanview`
Zalathar Jan 4, 2024
ddc5a82
Update test for `E0796` and `static_mut_ref` lint
obeis Dec 22, 2023
cf9484e
Remove `-Zreport-delayed-bugs`.
nnethercote Jan 4, 2024
35ad2ae
Fix invalid handling for static method calls in jump to definition fe…
GuillaumeGomez Jan 4, 2024
5bc7687
Add regression test for jump to def static method calls
GuillaumeGomez Jan 4, 2024
073ed0e
Move `i586-unknown-netbsd` from tier 2 to tier 3 platform support table
Nemo157 Jan 4, 2024
12b92c8
Visit only reachable blocks in MIR lint
tmiasko Dec 30, 2023
a084e06
Fix validation and linting of injected MIR
tmiasko Jan 1, 2024
df116ec
Migrate memory overlap check from validator to lint
tmiasko Jan 4, 2024
3010173
Rollup merge of #117556 - obeis:static-mut-ref-lint, r=davidtwco
matthiaskrgr Jan 5, 2024
eef7457
Rollup merge of #119354 - fmease:negative_bounds-fixes, r=compiler-er…
matthiaskrgr Jan 5, 2024
3f5d62b
Rollup merge of #119420 - cjgillot:issue-119295, r=compiler-errors
matthiaskrgr Jan 5, 2024
5ab7d7d
Rollup merge of #119506 - compiler-errors:visibilities-for-object-saf…
matthiaskrgr Jan 5, 2024
23b3822
Rollup merge of #119566 - Zalathar:remove-spanview, r=Swatinem,Nilstrieb
matthiaskrgr Jan 5, 2024
c29fa7e
Rollup merge of #119567 - nnethercote:rm-Zreport-delayed-bugs, r=oli-obk
matthiaskrgr Jan 5, 2024
894cc61
Rollup merge of #119577 - tmiasko:lint, r=oli-obk
matthiaskrgr Jan 5, 2024
28c794b
Rollup merge of #119586 - GuillaumeGomez:jump-to-def-static-methods, …
matthiaskrgr Jan 5, 2024
cd5f42f
Rollup merge of #119588 - Nemo157:i586-netbsd-tier-3, r=Nilstrieb
matthiaskrgr Jan 5, 2024
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3877,6 +3877,7 @@ dependencies = [
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_hir_pretty",
"rustc_index",
"rustc_infer",
"rustc_lint_defs",
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ ast_passes_module_nonascii = trying to load file for module `{$name}` with non-a
ast_passes_negative_bound_not_supported =
negative bounds are not supported

ast_passes_negative_bound_with_parenthetical_notation =
parenthetical notation may not be used for negative bounds

ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
.outer = outer `impl Trait`
.inner = nested `impl Trait` here
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1312,13 +1312,24 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let GenericBound::Trait(trait_ref, modifiers) = bound
&& let BoundPolarity::Negative(_) = modifiers.polarity
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref()
{
for arg in &args.args {
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
self.dcx()
.emit_err(errors::ConstraintOnNegativeBound { span: constraint.span });
match segment.args.as_deref() {
Some(ast::GenericArgs::AngleBracketed(args)) => {
for arg in &args.args {
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
self.dcx().emit_err(errors::ConstraintOnNegativeBound {
span: constraint.span,
});
}
}
}
// The lowered form of parenthesized generic args contains a type binding.
Some(ast::GenericArgs::Parenthesized(args)) => {
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
span: args.span,
});
}
None => {}
}
}

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,13 @@ pub struct ConstraintOnNegativeBound {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(ast_passes_negative_bound_with_parenthetical_notation)]
pub struct NegativeBoundWithParentheticalNotation {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(ast_passes_invalid_unnamed_field_ty)]
pub struct InvalidUnnamedFieldTy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ fn start<T: Termination + 'static>(
}

static mut NUM: u8 = 6 * 7;

// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[allow(static_mut_ref)]
static NUM_REF: &'static u8 = unsafe { &NUM };

unsafe fn zeroed<T>() -> T {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ fn start<T: Termination + 'static>(
}

static mut NUM: u8 = 6 * 7;

// FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
#[allow(static_mut_ref)]
static NUM_REF: &'static u8 = unsafe { &NUM };

macro_rules! assert {
Expand Down
46 changes: 3 additions & 43 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ impl<'tcx> MirPass<'tcx> for Validator {
mir_phase,
unwind_edge_count: 0,
reachable_blocks: traversal::reachable_as_bitset(body),
place_cache: FxHashSet::default(),
value_cache: FxHashSet::default(),
can_unwind,
};
Expand Down Expand Up @@ -106,7 +105,6 @@ struct CfgChecker<'a, 'tcx> {
mir_phase: MirPhase,
unwind_edge_count: usize,
reachable_blocks: BitSet<BasicBlock>,
place_cache: FxHashSet<PlaceRef<'tcx>>,
value_cache: FxHashSet<u128>,
// If `false`, then the MIR must not contain `UnwindAction::Continue` or
// `TerminatorKind::Resume`.
Expand Down Expand Up @@ -294,19 +292,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {

fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
match &statement.kind {
StatementKind::Assign(box (dest, rvalue)) => {
// FIXME(JakobDegen): Check this for all rvalues, not just this one.
if let Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) = rvalue {
// The sides of an assignment must not alias. Currently this just checks whether
// the places are identical.
if dest == src {
self.fail(
location,
"encountered `Assign` statement with overlapping memory",
);
}
}
}
StatementKind::AscribeUserType(..) => {
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(
Expand Down Expand Up @@ -341,7 +326,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
self.fail(location, format!("explicit `{kind:?}` is forbidden"));
}
}
StatementKind::StorageLive(_)
StatementKind::Assign(..)
| StatementKind::StorageLive(_)
| StatementKind::StorageDead(_)
| StatementKind::Intrinsic(_)
| StatementKind::Coverage(_)
Expand Down Expand Up @@ -404,10 +390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
}

// The call destination place and Operand::Move place used as an argument might be
// passed by a reference to the callee. Consequently they must be non-overlapping
// and cannot be packed. Currently this simply checks for duplicate places.
self.place_cache.clear();
self.place_cache.insert(destination.as_ref());
// passed by a reference to the callee. Consequently they cannot be packed.
if is_within_packed(self.tcx, &self.body.local_decls, *destination).is_some() {
// This is bad! The callee will expect the memory to be aligned.
self.fail(
Expand All @@ -418,10 +401,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
),
);
}
let mut has_duplicates = false;
for arg in args {
if let Operand::Move(place) = arg {
has_duplicates |= !self.place_cache.insert(place.as_ref());
if is_within_packed(self.tcx, &self.body.local_decls, *place).is_some() {
// This is bad! The callee will expect the memory to be aligned.
self.fail(
Expand All @@ -434,16 +415,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
}
}
}

if has_duplicates {
self.fail(
location,
format!(
"encountered overlapping memory in `Move` arguments to `Call` terminator: {:?}",
terminator.kind,
),
);
}
}
TerminatorKind::Assert { target, unwind, .. } => {
self.check_edge(location, *target, EdgeKind::Normal);
Expand Down Expand Up @@ -1112,17 +1083,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
)
}
}
// FIXME(JakobDegen): Check this for all rvalues, not just this one.
if let Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) = rvalue {
// The sides of an assignment must not alias. Currently this just checks whether
// the places are identical.
if dest == src {
self.fail(
location,
"encountered `Assign` statement with overlapping memory",
);
}
}
}
StatementKind::AscribeUserType(..) => {
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ E0792: include_str!("./error_codes/E0792.md"),
E0793: include_str!("./error_codes/E0793.md"),
E0794: include_str!("./error_codes/E0794.md"),
E0795: include_str!("./error_codes/E0795.md"),
E0796: include_str!("./error_codes/E0796.md"),
}

// Undocumented removed error codes. Note that many removed error codes are kept in the list above
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0796.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Reference of mutable static.

Erroneous code example:

```compile_fail,edition2024,E0796
static mut X: i32 = 23;
static mut Y: i32 = 24;

unsafe {
let y = &X;
let ref x = X;
let (x, y) = (&X, &Y);
foo(&X);
}

fn foo<'a>(_x: &'a i32) {}
```

Mutable statics can be written to by multiple threads: aliasing violations or
data races will cause undefined behavior.

Reference of mutable static is a hard error from 2024 edition.
16 changes: 3 additions & 13 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,9 +525,6 @@ pub struct DiagCtxtFlags {
/// If true, immediately emit diagnostics that would otherwise be buffered.
/// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`)
pub dont_buffer_diagnostics: bool,
/// If true, immediately print bugs registered with `span_delayed_bug`.
/// (rustc: see `-Z report-delayed-bugs`)
pub report_delayed_bugs: bool,
/// Show macro backtraces.
/// (rustc: see `-Z macro-backtrace`)
pub macro_backtrace: bool,
Expand Down Expand Up @@ -1004,7 +1001,6 @@ impl DiagCtxt {
) -> ErrorGuaranteed {
let treat_next_err_as_bug = self.inner.borrow().treat_next_err_as_bug();
if treat_next_err_as_bug {
// FIXME: don't abort here if report_delayed_bugs is off
self.span_bug(sp, msg);
}
let mut diagnostic = Diagnostic::new(DelayedBug, msg);
Expand All @@ -1016,11 +1012,7 @@ impl DiagCtxt {
// where the explanation of what "good path" is (also, it should be renamed).
pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
let mut inner = self.inner.borrow_mut();

let mut diagnostic = Diagnostic::new(DelayedBug, msg);
if inner.flags.report_delayed_bugs {
inner.emit_diagnostic_without_consuming(&mut diagnostic);
}
let diagnostic = Diagnostic::new(DelayedBug, msg);
let backtrace = std::backtrace::Backtrace::capture();
inner.good_path_delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
}
Expand Down Expand Up @@ -1430,10 +1422,8 @@ impl DiagCtxtInner {
self.span_delayed_bugs
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));

if !self.flags.report_delayed_bugs {
#[allow(deprecated)]
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
}
#[allow(deprecated)]
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
}

if diagnostic.has_future_breakage() {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ declare_features! (
/// Allows the `multiple_supertrait_upcastable` lint.
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
(incomplete, negative_bounds, "1.71.0", None),
(internal, negative_bounds, "1.71.0", None),
/// Allows using `#[omit_gdb_pretty_printer_section]`.
(internal, omit_gdb_pretty_printer_section, "1.5.0", None),
/// Allows using `#[prelude_import]` on glob `use` items.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_index = { path = "../rustc_index" }
rustc_infer = { path = "../rustc_infer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,20 @@ hir_analysis_start_not_target_feature = `#[start]` function is not allowed to ha
hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
.label = `#[start]` function is not allowed to be `#[track_caller]`

hir_analysis_static_mut_ref = reference of mutable static is disallowed
.label = reference of mutable static
.note = mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior
.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
.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

hir_analysis_static_mut_ref_lint = {$shared}reference of mutable static is discouraged
.label = shared reference of mutable static
.label_mut = mutable reference of mutable static
.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
.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
.note = reference of mutable static is a hard error from 2024 edition
.why_note = mutable statics can be written to by multiple threads: aliasing violations or data races will cause undefined behavior

hir_analysis_static_specialize = cannot specialize on `'static` lifetime

hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl
Expand Down
52 changes: 30 additions & 22 deletions compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,36 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
span: Span,
) {
let tcx = self.tcx();
let sized_def_id = tcx.lang_items().sized_trait();
let mut seen_negative_sized_bound = false;

// Try to find an unbound in bounds.
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
for ab in ast_bounds {
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
unbounds.push(ptr)
let hir::GenericBound::Trait(ptr, modifier) = ab else {
continue;
};
match modifier {
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
hir::TraitBoundModifier::Negative => {
if let Some(sized_def_id) = sized_def_id
&& ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
{
seen_negative_sized_bound = true;
}
}
_ => {}
}
}
};
search_bounds(ast_bounds);
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
for clause in where_clause {
if let hir::WherePredicate::BoundPredicate(pred) = clause {
if pred.is_param_bound(self_ty.to_def_id()) {
search_bounds(pred.bounds);
}
if let hir::WherePredicate::BoundPredicate(pred) = clause
&& pred.is_param_bound(self_ty.to_def_id())
{
search_bounds(pred.bounds);
}
}
}
Expand All @@ -53,15 +66,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
});
}

let sized_def_id = tcx.lang_items().sized_trait();

let mut seen_sized_unbound = false;
for unbound in unbounds {
if let Some(sized_def_id) = sized_def_id {
if unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) {
seen_sized_unbound = true;
continue;
}
if let Some(sized_def_id) = sized_def_id
&& unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
{
seen_sized_unbound = true;
continue;
}
// There was a `?Trait` bound, but it was not `?Sized`; warn.
tcx.dcx().span_warn(
Expand All @@ -71,15 +82,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
);
}

// If the above loop finished there was no `?Sized` bound; add implicitly sized if `Sized` is available.
if sized_def_id.is_none() {
// No lang item for `Sized`, so we can't add it as a bound.
return;
}
if seen_sized_unbound {
// There was in fact a `?Sized` bound, return without doing anything
} else {
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
if seen_sized_unbound || seen_negative_sized_bound {
// There was in fact a `?Sized` or `!Sized` bound;
// we don't need to do anything.
} else if sized_def_id.is_some() {
// There was no `?Sized` or `!Sized` bound;
// add `Sized` if it's available.
bounds.push_sized(tcx, self_ty, span);
}
}
Expand Down
Loading
Loading