Skip to content

Rollup of 10 pull requests #139595

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

Merged
merged 27 commits into from
Apr 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
04d9d86
std: clarify Mutex::get_mut more clearly
xizheyin Mar 31, 2025
ffb2097
std: clarify RefCell::get_mut more clearly
xizheyin Mar 31, 2025
0162f29
std: clarify RwLock::get_mut more clearly
xizheyin Mar 31, 2025
39c6b6c
Fix CSS
GuillaumeGomez Apr 7, 2025
30f56df
Add regression test for #139282
GuillaumeGomez Apr 7, 2025
f2dee82
Update 'u8'-to-and-from-'i8' suggestions;
bjoernager Apr 8, 2025
ec3820a
Add .use block test
spastorino Mar 17, 2025
c717c59
Add multiple closure use variants
spastorino Mar 17, 2025
3f21ebc
Test interaction between RFC 2229 migration and use closures
spastorino Mar 13, 2025
ca4a582
Add spawn thread test
spastorino Mar 17, 2025
df6254f
report call site of inlined scopes for large assignment lints
jogru0 Apr 8, 2025
6d71fc1
for large assignment lint, use the correct span for checking for dupl…
jogru0 Apr 8, 2025
616406d
triagebot: roll compiler reviewers for rustc/unstable book
jieyouxu Apr 8, 2025
cffc5c2
compiletest: Add directive `dont-require-annotations`
petrochenkov Apr 7, 2025
1282912
Migrate some tests to `dont-require-annotations`
petrochenkov Apr 9, 2025
069fd02
Remove redundant words
timesince Apr 9, 2025
f6faaee
Report higher-ranked trait error when higher-ranked projection goal f…
compiler-errors Apr 8, 2025
2b28e6b
Rollup merge of #138470 - spastorino:test-rfc2229-and-ergonomic-clone…
matthiaskrgr Apr 9, 2025
3507f35
Rollup merge of #138628 - spastorino:add-more-ergonomic-clone-tests, …
matthiaskrgr Apr 9, 2025
d5f930f
Rollup merge of #139164 - xizheyin:issue-139034, r=joboet
matthiaskrgr Apr 9, 2025
ac41b94
Rollup merge of #139488 - GuillaumeGomez:add-missing-gui-test, r=camelid
matthiaskrgr Apr 9, 2025
4911635
Rollup merge of #139489 - petrochenkov:noreqann, r=jieyouxu
matthiaskrgr Apr 9, 2025
584cd13
Rollup merge of #139513 - compiler-errors:higher-ranked-proj, r=lcnr
matthiaskrgr Apr 9, 2025
78e59af
Rollup merge of #139521 - jieyouxu:compiler-doc-reviewers, r=Guillaum…
matthiaskrgr Apr 9, 2025
a8b0d56
Rollup merge of #139532 - bjoernager:master, r=tgross35
matthiaskrgr Apr 9, 2025
e962e52
Rollup merge of #139551 - jogru0:121672, r=oli-obk
matthiaskrgr Apr 9, 2025
7aab307
Rollup merge of #139575 - timesince:master, r=wesleywiser
matthiaskrgr Apr 9, 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
2 changes: 1 addition & 1 deletion compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1829,7 +1829,7 @@ pub struct PointeeInfo {
pub safe: Option<PointerKind>,
/// If `safe` is `Some`, then the pointer is either null or dereferenceable for this many bytes.
/// On a function argument, "dereferenceable" here means "dereferenceable for the entire duration
/// of this function call", i.e. it is UB for the memory that this pointer points to to be freed
/// of this function call", i.e. it is UB for the memory that this pointer points to be freed
/// while this function is still running.
/// The size can be zero if the pointer is not dereferenceable.
pub size: Size,
Expand Down
33 changes: 25 additions & 8 deletions compiler/rustc_monomorphize/src/mono_checks/move_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
span: Span,
) {
let source_info = self.body.source_info(location);
for reported_span in &self.move_size_spans {
if reported_span.overlaps(span) {
return;
}
}

let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
let Some(lint_root) = lint_root else {
// This happens when the issue is in a function from a foreign crate that
Expand All @@ -162,13 +158,34 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
// but correct span? This would make the lint at least accept crate-level lint attributes.
return;
};

// If the source scope is inlined by the MIR inliner, report the lint on the call site.
let reported_span = self
.body
.source_scopes
.get(source_info.scope)
.and_then(|source_scope_data| source_scope_data.inlined)
.map(|(_, call_site)| call_site)
.unwrap_or(span);

for previously_reported_span in &self.move_size_spans {
if previously_reported_span.overlaps(reported_span) {
return;
}
}

self.tcx.emit_node_span_lint(
LARGE_ASSIGNMENTS,
lint_root,
span,
LargeAssignmentsLint { span, size: too_large_size.bytes(), limit: limit as u64 },
reported_span,
LargeAssignmentsLint {
span: reported_span,
size: too_large_size.bytes(),
limit: limit as u64,
},
);
self.move_size_spans.push(span);

self.move_size_spans.push(reported_span);
}
}

Expand Down
36 changes: 33 additions & 3 deletions compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,34 @@ impl<'tcx> BestObligation<'tcx> {
}
}

/// When a higher-ranked projection goal fails, check that the corresponding
/// higher-ranked trait goal holds or not. This is because the process of
/// instantiating and then re-canonicalizing the binder of the projection goal
/// forces us to be unable to see that the leak check failed in the nested
/// `NormalizesTo` goal, so we don't fall back to the rigid projection check
/// that should catch when a projection goal fails due to an unsatisfied trait
/// goal.
fn detect_error_in_higher_ranked_projection(
&mut self,
goal: &inspect::InspectGoal<'_, 'tcx>,
) -> ControlFlow<PredicateObligation<'tcx>> {
let tcx = goal.infcx().tcx;
if let Some(projection_clause) = goal.goal().predicate.as_projection_clause()
&& !projection_clause.bound_vars().is_empty()
{
let pred = projection_clause.map_bound(|proj| proj.projection_term.trait_ref(tcx));
self.with_derived_obligation(self.obligation.with(tcx, pred), |this| {
goal.infcx().visit_proof_tree_at_depth(
goal.goal().with(tcx, pred),
goal.depth() + 1,
this,
)
})
} else {
ControlFlow::Continue(())
}
}

/// It is likely that `NormalizesTo` failed without any applicable candidates
/// because the alias is not well-formed.
///
Expand Down Expand Up @@ -374,7 +402,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
source: CandidateSource::Impl(impl_def_id),
result: _,
} = candidate.kind()
&& goal.infcx().tcx.do_not_recommend_impl(impl_def_id)
&& tcx.do_not_recommend_impl(impl_def_id)
{
trace!("#[do_not_recommend] -> exit");
return ControlFlow::Break(self.obligation.clone());
Expand Down Expand Up @@ -486,7 +514,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
if let Some(obligation) = goal
.infcx()
.visit_proof_tree_at_depth(
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(lhs.into())),
goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs.into())),
goal.depth() + 1,
self,
)
Expand All @@ -496,7 +524,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
} else if let Some(obligation) = goal
.infcx()
.visit_proof_tree_at_depth(
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(rhs.into())),
goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs.into())),
goal.depth() + 1,
self,
)
Expand All @@ -506,6 +534,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
}
}

self.detect_error_in_higher_ranked_projection(goal)?;

ControlFlow::Break(self.obligation.clone())
}
}
Expand Down
6 changes: 5 additions & 1 deletion library/core/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,9 @@ impl<T: ?Sized> RefCell<T> {
/// Since this method borrows `RefCell` mutably, it is statically guaranteed
/// that no borrows to the underlying data exist. The dynamic checks inherent
/// in [`borrow_mut`] and most other methods of `RefCell` are therefore
/// unnecessary.
/// unnecessary. Note that this method does not reset the borrowing state if borrows were previously leaked
/// (e.g., via [`forget()`] on a [`Ref`] or [`RefMut`]). For that purpose,
/// consider using the unstable [`undo_leak`] method.
///
/// This method can only be called if `RefCell` can be mutably borrowed,
/// which in general is only the case directly after the `RefCell` has
Expand All @@ -1167,6 +1169,8 @@ impl<T: ?Sized> RefCell<T> {
/// Use [`borrow_mut`] to get mutable access to the underlying data then.
///
/// [`borrow_mut`]: RefCell::borrow_mut()
/// [`forget()`]: mem::forget
/// [`undo_leak`]: RefCell::undo_leak()
///
/// # Examples
///
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ pub unsafe trait CloneToUninit {
/// read or dropped, because even if it was previously valid, it may have been partially
/// overwritten.
///
/// The caller may wish to to take care to deallocate the allocation pointed to by `dest`,
/// The caller may wish to take care to deallocate the allocation pointed to by `dest`,
/// if applicable, to avoid a memory leak (but this is not a requirement).
///
/// Implementors should avoid leaking values by, upon unwinding, dropping all component values
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ macro_rules! i8_xe_bytes_doc {

**Note**: This function is meaningless on `i8`. Byte order does not exist as a
concept for byte-sized integers. This function is only provided in symmetry
with larger integer types. You can cast from and to `u8` using `as i8` and `as
u8`.
with larger integer types. You can cast from and to `u8` using
[`cast_signed`](u8::cast_signed) and [`cast_unsigned`](Self::cast_unsigned).

"
};
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sync/poison/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,9 @@ impl<T: ?Sized> Mutex<T> {
/// Returns a mutable reference to the underlying data.
///
/// Since this call borrows the `Mutex` mutably, no actual locking needs to
/// take place -- the mutable borrow statically guarantees no locks exist.
/// take place -- the mutable borrow statically guarantees no new locks can be acquired
/// while this reference exists. Note that this method does not clear any previous abandoned locks
/// (e.g., via [`forget()`] on a [`MutexGuard`]).
///
/// # Errors
///
Expand All @@ -599,6 +601,8 @@ impl<T: ?Sized> Mutex<T> {
/// *mutex.get_mut().unwrap() = 10;
/// assert_eq!(*mutex.lock().unwrap(), 10);
/// ```
///
/// [`forget()`]: mem::forget
#[stable(feature = "mutex_get_mut", since = "1.6.0")]
pub fn get_mut(&mut self) -> LockResult<&mut T> {
let data = self.data.get_mut();
Expand Down
4 changes: 3 additions & 1 deletion library/std/src/sync/poison/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,9 @@ impl<T: ?Sized> RwLock<T> {
/// Returns a mutable reference to the underlying data.
///
/// Since this call borrows the `RwLock` mutably, no actual locking needs to
/// take place -- the mutable borrow statically guarantees no locks exist.
/// take place -- the mutable borrow statically guarantees no new locks can be acquired
/// while this reference exists. Note that this method does not clear any previously abandoned locks
/// (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]).
///
/// # Errors
///
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/solve/opaque-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ For opaque types in the defining scope and in the implicit-negative coherence mo
always done in two steps. Outside of the defining scope `normalizes-to` for opaques always
returns `Err(NoSolution)`.

We start by trying to to assign the expected type as a hidden type.
We start by trying to assign the expected type as a hidden type.

In the implicit-negative coherence mode, this currently always results in ambiguity without
interacting with the opaque types storage. We could instead add allow 'defining' all opaque types,
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
cursor: pointer;
}
.setting-check input {
flex-shrink: 0,
flex-shrink: 0;
}

.setting-radio input:checked {
Expand Down
1 change: 1 addition & 0 deletions src/tools/compiletest/src/directive-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"dont-check-compiler-stderr",
"dont-check-compiler-stdout",
"dont-check-failure-status",
"dont-require-annotations",
"edition",
"error-pattern",
"exact-llvm-major-version",
Expand Down
11 changes: 10 additions & 1 deletion src/tools/compiletest/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::sync::OnceLock;
use regex::Regex;
use tracing::*;

#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ErrorKind {
Help,
Error,
Expand Down Expand Up @@ -40,6 +40,15 @@ impl ErrorKind {
_ => return None,
})
}

pub fn expect_from_user_str(s: &str) -> ErrorKind {
ErrorKind::from_user_str(s).unwrap_or_else(|| {
panic!(
"unexpected diagnostic kind `{s}`, expected \
`ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`"
)
})
}
}

impl fmt::Display for ErrorKind {
Expand Down
20 changes: 19 additions & 1 deletion src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use std::env;
use std::fs::File;
use std::io::BufReader;
Expand All @@ -11,6 +11,7 @@ use tracing::*;

use crate::common::{Config, Debugger, FailMode, Mode, PassMode};
use crate::debuggers::{extract_cdb_version, extract_gdb_version};
use crate::errors::ErrorKind;
use crate::executor::{CollectedTestDesc, ShouldPanic};
use crate::header::auxiliary::{AuxProps, parse_and_update_aux};
use crate::header::needs::CachedNeedsConditions;
Expand Down Expand Up @@ -196,6 +197,8 @@ pub struct TestProps {
/// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios
/// that don't otherwise want/need `-Z build-std`.
pub add_core_stubs: bool,
/// Whether line annotatins are required for the given error kind.
pub require_annotations: HashMap<ErrorKind, bool>,
}

mod directives {
Expand All @@ -212,6 +215,7 @@ mod directives {
pub const CHECK_RUN_RESULTS: &'static str = "check-run-results";
pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout";
pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr";
pub const DONT_REQUIRE_ANNOTATIONS: &'static str = "dont-require-annotations";
pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic";
pub const PRETTY_MODE: &'static str = "pretty-mode";
pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only";
Expand Down Expand Up @@ -297,6 +301,13 @@ impl TestProps {
no_auto_check_cfg: false,
has_enzyme: false,
add_core_stubs: false,
require_annotations: HashMap::from([
(ErrorKind::Help, true),
(ErrorKind::Note, true),
(ErrorKind::Error, true),
(ErrorKind::Warning, true),
(ErrorKind::Suggestion, false),
]),
}
}

Expand Down Expand Up @@ -570,6 +581,13 @@ impl TestProps {
config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut self.no_auto_check_cfg);

self.update_add_core_stubs(ln, config);

if let Some(err_kind) =
config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS)
{
self.require_annotations
.insert(ErrorKind::expect_from_user_str(&err_kind), false);
}
},
);

Expand Down
24 changes: 11 additions & 13 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,10 +709,6 @@ impl<'test> TestCx<'test> {
self.testpaths.file.display().to_string()
};

// If the testcase being checked contains at least one expected "help"
// message, then we'll ensure that all "help" messages are expected.
// Otherwise, all "help" messages reported by the compiler will be ignored.
// This logic also applies to "note" messages.
let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help));
let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note));

Expand Down Expand Up @@ -800,22 +796,24 @@ impl<'test> TestCx<'test> {
}

/// Returns `true` if we should report an error about `actual_error`,
/// which did not match any of the expected error. We always require
/// errors/warnings to be explicitly listed, but only require
/// helps/notes if there are explicit helps/notes given.
/// which did not match any of the expected error.
fn is_unexpected_compiler_message(
&self,
actual_error: &Error,
expect_help: bool,
expect_note: bool,
) -> bool {
actual_error.require_annotation
&& match actual_error.kind {
Some(ErrorKind::Help) => expect_help,
Some(ErrorKind::Note) => expect_note,
Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true,
Some(ErrorKind::Suggestion) | None => false,
}
&& actual_error.kind.map_or(false, |err_kind| {
// If the test being checked doesn't contain any "help" or "note" annotations, then
// we don't require annotating "help" or "note" (respecively) diagnostics at all.
let default_require_annotations = self.props.require_annotations[&err_kind];
match err_kind {
ErrorKind::Help => expect_help && default_require_annotations,
ErrorKind::Note => expect_note && default_require_annotations,
_ => default_require_annotations,
}
})
}

fn should_emit_metadata(&self, pm: Option<PassMode>) -> Emit {
Expand Down
14 changes: 14 additions & 0 deletions tests/rustdoc-gui/settings.goml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,13 @@ compare-elements-position: (".sub form", "#settings", ["x"])
// Check that setting-line has the same margin in this mode as in the popover.
assert-css: (".setting-line", {"margin": |setting_line_margin|})

// We will check that the checkboxes size doesn't change either.
assert-size: (
"#settings label > input[type='checkbox']",
{"width": 19, "height": 19},
ALL,
)

// We now check the display with JS disabled.
assert-false: "noscript section"
javascript: false
Expand All @@ -327,3 +334,10 @@ reload:
set-window-size: (300, 1000)
wait-for: "#settings"
assert-css: (".setting-radio", {"cursor": "pointer"})

// We ensure that the checkboxes size didn't change.
assert-size: (
"#settings label > input[type='checkbox']",
{"width": 19, "height": 19},
ALL,
)
Loading