Skip to content

Commit 51548ce

Browse files
committedApr 9, 2025·
Auto merge of #139595 - matthiaskrgr:rollup-kaa8aim, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #138470 (Test interaction between RFC 2229 migration and use closures) - #138628 (Add more ergonomic clone tests) - #139164 (std: improve documentation for get_mut() methods regarding forgotten guards) - #139488 (Add missing regression GUI test) - #139489 (compiletest: Add directive `dont-require-annotations`) - #139513 (Report higher-ranked trait error when higher-ranked projection goal fails in new solver) - #139521 (triagebot: roll compiler reviewers for rustc/unstable book) - #139532 (Update `u8`-to-and-from-`i8` suggestions.) - #139551 (report call site of inlined scopes for large assignment lints) - #139575 (Remove redundant words) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 934880f + 7aab307 commit 51548ce

36 files changed

+493
-86
lines changed
 

‎compiler/rustc_abi/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1829,7 +1829,7 @@ pub struct PointeeInfo {
18291829
pub safe: Option<PointerKind>,
18301830
/// If `safe` is `Some`, then the pointer is either null or dereferenceable for this many bytes.
18311831
/// On a function argument, "dereferenceable" here means "dereferenceable for the entire duration
1832-
/// of this function call", i.e. it is UB for the memory that this pointer points to to be freed
1832+
/// of this function call", i.e. it is UB for the memory that this pointer points to be freed
18331833
/// while this function is still running.
18341834
/// The size can be zero if the pointer is not dereferenceable.
18351835
pub size: Size,

‎compiler/rustc_monomorphize/src/mono_checks/move_check.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
148148
span: Span,
149149
) {
150150
let source_info = self.body.source_info(location);
151-
for reported_span in &self.move_size_spans {
152-
if reported_span.overlaps(span) {
153-
return;
154-
}
155-
}
151+
156152
let lint_root = source_info.scope.lint_root(&self.body.source_scopes);
157153
let Some(lint_root) = lint_root else {
158154
// This happens when the issue is in a function from a foreign crate that
@@ -162,13 +158,34 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
162158
// but correct span? This would make the lint at least accept crate-level lint attributes.
163159
return;
164160
};
161+
162+
// If the source scope is inlined by the MIR inliner, report the lint on the call site.
163+
let reported_span = self
164+
.body
165+
.source_scopes
166+
.get(source_info.scope)
167+
.and_then(|source_scope_data| source_scope_data.inlined)
168+
.map(|(_, call_site)| call_site)
169+
.unwrap_or(span);
170+
171+
for previously_reported_span in &self.move_size_spans {
172+
if previously_reported_span.overlaps(reported_span) {
173+
return;
174+
}
175+
}
176+
165177
self.tcx.emit_node_span_lint(
166178
LARGE_ASSIGNMENTS,
167179
lint_root,
168-
span,
169-
LargeAssignmentsLint { span, size: too_large_size.bytes(), limit: limit as u64 },
180+
reported_span,
181+
LargeAssignmentsLint {
182+
span: reported_span,
183+
size: too_large_size.bytes(),
184+
limit: limit as u64,
185+
},
170186
);
171-
self.move_size_spans.push(span);
187+
188+
self.move_size_spans.push(reported_span);
172189
}
173190
}
174191

‎compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,34 @@ impl<'tcx> BestObligation<'tcx> {
291291
}
292292
}
293293

294+
/// When a higher-ranked projection goal fails, check that the corresponding
295+
/// higher-ranked trait goal holds or not. This is because the process of
296+
/// instantiating and then re-canonicalizing the binder of the projection goal
297+
/// forces us to be unable to see that the leak check failed in the nested
298+
/// `NormalizesTo` goal, so we don't fall back to the rigid projection check
299+
/// that should catch when a projection goal fails due to an unsatisfied trait
300+
/// goal.
301+
fn detect_error_in_higher_ranked_projection(
302+
&mut self,
303+
goal: &inspect::InspectGoal<'_, 'tcx>,
304+
) -> ControlFlow<PredicateObligation<'tcx>> {
305+
let tcx = goal.infcx().tcx;
306+
if let Some(projection_clause) = goal.goal().predicate.as_projection_clause()
307+
&& !projection_clause.bound_vars().is_empty()
308+
{
309+
let pred = projection_clause.map_bound(|proj| proj.projection_term.trait_ref(tcx));
310+
self.with_derived_obligation(self.obligation.with(tcx, pred), |this| {
311+
goal.infcx().visit_proof_tree_at_depth(
312+
goal.goal().with(tcx, pred),
313+
goal.depth() + 1,
314+
this,
315+
)
316+
})
317+
} else {
318+
ControlFlow::Continue(())
319+
}
320+
}
321+
294322
/// It is likely that `NormalizesTo` failed without any applicable candidates
295323
/// because the alias is not well-formed.
296324
///
@@ -374,7 +402,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
374402
source: CandidateSource::Impl(impl_def_id),
375403
result: _,
376404
} = candidate.kind()
377-
&& goal.infcx().tcx.do_not_recommend_impl(impl_def_id)
405+
&& tcx.do_not_recommend_impl(impl_def_id)
378406
{
379407
trace!("#[do_not_recommend] -> exit");
380408
return ControlFlow::Break(self.obligation.clone());
@@ -486,7 +514,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
486514
if let Some(obligation) = goal
487515
.infcx()
488516
.visit_proof_tree_at_depth(
489-
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(lhs.into())),
517+
goal.goal().with(tcx, ty::ClauseKind::WellFormed(lhs.into())),
490518
goal.depth() + 1,
491519
self,
492520
)
@@ -496,7 +524,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
496524
} else if let Some(obligation) = goal
497525
.infcx()
498526
.visit_proof_tree_at_depth(
499-
goal.goal().with(goal.infcx().tcx, ty::ClauseKind::WellFormed(rhs.into())),
527+
goal.goal().with(tcx, ty::ClauseKind::WellFormed(rhs.into())),
500528
goal.depth() + 1,
501529
self,
502530
)
@@ -506,6 +534,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
506534
}
507535
}
508536

537+
self.detect_error_in_higher_ranked_projection(goal)?;
538+
509539
ControlFlow::Break(self.obligation.clone())
510540
}
511541
}

‎library/core/src/cell.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,9 @@ impl<T: ?Sized> RefCell<T> {
11561156
/// Since this method borrows `RefCell` mutably, it is statically guaranteed
11571157
/// that no borrows to the underlying data exist. The dynamic checks inherent
11581158
/// in [`borrow_mut`] and most other methods of `RefCell` are therefore
1159-
/// unnecessary.
1159+
/// unnecessary. Note that this method does not reset the borrowing state if borrows were previously leaked
1160+
/// (e.g., via [`forget()`] on a [`Ref`] or [`RefMut`]). For that purpose,
1161+
/// consider using the unstable [`undo_leak`] method.
11601162
///
11611163
/// This method can only be called if `RefCell` can be mutably borrowed,
11621164
/// which in general is only the case directly after the `RefCell` has
@@ -1167,6 +1169,8 @@ impl<T: ?Sized> RefCell<T> {
11671169
/// Use [`borrow_mut`] to get mutable access to the underlying data then.
11681170
///
11691171
/// [`borrow_mut`]: RefCell::borrow_mut()
1172+
/// [`forget()`]: mem::forget
1173+
/// [`undo_leak`]: RefCell::undo_leak()
11701174
///
11711175
/// # Examples
11721176
///

‎library/core/src/clone.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ pub unsafe trait CloneToUninit {
427427
/// read or dropped, because even if it was previously valid, it may have been partially
428428
/// overwritten.
429429
///
430-
/// The caller may wish to to take care to deallocate the allocation pointed to by `dest`,
430+
/// The caller may wish to take care to deallocate the allocation pointed to by `dest`,
431431
/// if applicable, to avoid a memory leak (but this is not a requirement).
432432
///
433433
/// Implementors should avoid leaking values by, upon unwinding, dropping all component values

‎library/core/src/num/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ macro_rules! i8_xe_bytes_doc {
9999
100100
**Note**: This function is meaningless on `i8`. Byte order does not exist as a
101101
concept for byte-sized integers. This function is only provided in symmetry
102-
with larger integer types. You can cast from and to `u8` using `as i8` and `as
103-
u8`.
102+
with larger integer types. You can cast from and to `u8` using
103+
[`cast_signed`](u8::cast_signed) and [`cast_unsigned`](Self::cast_unsigned).
104104
105105
"
106106
};

‎library/std/src/sync/poison/mutex.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,9 @@ impl<T: ?Sized> Mutex<T> {
582582
/// Returns a mutable reference to the underlying data.
583583
///
584584
/// Since this call borrows the `Mutex` mutably, no actual locking needs to
585-
/// take place -- the mutable borrow statically guarantees no locks exist.
585+
/// take place -- the mutable borrow statically guarantees no new locks can be acquired
586+
/// while this reference exists. Note that this method does not clear any previous abandoned locks
587+
/// (e.g., via [`forget()`] on a [`MutexGuard`]).
586588
///
587589
/// # Errors
588590
///
@@ -599,6 +601,8 @@ impl<T: ?Sized> Mutex<T> {
599601
/// *mutex.get_mut().unwrap() = 10;
600602
/// assert_eq!(*mutex.lock().unwrap(), 10);
601603
/// ```
604+
///
605+
/// [`forget()`]: mem::forget
602606
#[stable(feature = "mutex_get_mut", since = "1.6.0")]
603607
pub fn get_mut(&mut self) -> LockResult<&mut T> {
604608
let data = self.data.get_mut();

‎library/std/src/sync/poison/rwlock.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,9 @@ impl<T: ?Sized> RwLock<T> {
608608
/// Returns a mutable reference to the underlying data.
609609
///
610610
/// Since this call borrows the `RwLock` mutably, no actual locking needs to
611-
/// take place -- the mutable borrow statically guarantees no locks exist.
611+
/// take place -- the mutable borrow statically guarantees no new locks can be acquired
612+
/// while this reference exists. Note that this method does not clear any previously abandoned locks
613+
/// (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]).
612614
///
613615
/// # Errors
614616
///

‎src/doc/rustc-dev-guide/src/solve/opaque-types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ For opaque types in the defining scope and in the implicit-negative coherence mo
3333
always done in two steps. Outside of the defining scope `normalizes-to` for opaques always
3434
returns `Err(NoSolution)`.
3535

36-
We start by trying to to assign the expected type as a hidden type.
36+
We start by trying to assign the expected type as a hidden type.
3737

3838
In the implicit-negative coherence mode, this currently always results in ambiguity without
3939
interacting with the opaque types storage. We could instead add allow 'defining' all opaque types,

‎src/librustdoc/html/static/css/rustdoc.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
14471447
cursor: pointer;
14481448
}
14491449
.setting-check input {
1450-
flex-shrink: 0,
1450+
flex-shrink: 0;
14511451
}
14521452

14531453
.setting-radio input:checked {

‎src/tools/compiletest/src/directive-list.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
2222
"dont-check-compiler-stderr",
2323
"dont-check-compiler-stdout",
2424
"dont-check-failure-status",
25+
"dont-require-annotations",
2526
"edition",
2627
"error-pattern",
2728
"exact-llvm-major-version",

‎src/tools/compiletest/src/errors.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::sync::OnceLock;
88
use regex::Regex;
99
use tracing::*;
1010

11-
#[derive(Copy, Clone, Debug, PartialEq)]
11+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1212
pub enum ErrorKind {
1313
Help,
1414
Error,
@@ -40,6 +40,15 @@ impl ErrorKind {
4040
_ => return None,
4141
})
4242
}
43+
44+
pub fn expect_from_user_str(s: &str) -> ErrorKind {
45+
ErrorKind::from_user_str(s).unwrap_or_else(|| {
46+
panic!(
47+
"unexpected diagnostic kind `{s}`, expected \
48+
`ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`"
49+
)
50+
})
51+
}
4352
}
4453

4554
impl fmt::Display for ErrorKind {

‎src/tools/compiletest/src/header.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashSet;
1+
use std::collections::{HashMap, HashSet};
22
use std::env;
33
use std::fs::File;
44
use std::io::BufReader;
@@ -11,6 +11,7 @@ use tracing::*;
1111

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

201204
mod directives {
@@ -212,6 +215,7 @@ mod directives {
212215
pub const CHECK_RUN_RESULTS: &'static str = "check-run-results";
213216
pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout";
214217
pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr";
218+
pub const DONT_REQUIRE_ANNOTATIONS: &'static str = "dont-require-annotations";
215219
pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic";
216220
pub const PRETTY_MODE: &'static str = "pretty-mode";
217221
pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only";
@@ -297,6 +301,13 @@ impl TestProps {
297301
no_auto_check_cfg: false,
298302
has_enzyme: false,
299303
add_core_stubs: false,
304+
require_annotations: HashMap::from([
305+
(ErrorKind::Help, true),
306+
(ErrorKind::Note, true),
307+
(ErrorKind::Error, true),
308+
(ErrorKind::Warning, true),
309+
(ErrorKind::Suggestion, false),
310+
]),
300311
}
301312
}
302313

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

572583
self.update_add_core_stubs(ln, config);
584+
585+
if let Some(err_kind) =
586+
config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS)
587+
{
588+
self.require_annotations
589+
.insert(ErrorKind::expect_from_user_str(&err_kind), false);
590+
}
573591
},
574592
);
575593

‎src/tools/compiletest/src/runtest.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -709,10 +709,6 @@ impl<'test> TestCx<'test> {
709709
self.testpaths.file.display().to_string()
710710
};
711711

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

@@ -800,22 +796,24 @@ impl<'test> TestCx<'test> {
800796
}
801797

802798
/// Returns `true` if we should report an error about `actual_error`,
803-
/// which did not match any of the expected error. We always require
804-
/// errors/warnings to be explicitly listed, but only require
805-
/// helps/notes if there are explicit helps/notes given.
799+
/// which did not match any of the expected error.
806800
fn is_unexpected_compiler_message(
807801
&self,
808802
actual_error: &Error,
809803
expect_help: bool,
810804
expect_note: bool,
811805
) -> bool {
812806
actual_error.require_annotation
813-
&& match actual_error.kind {
814-
Some(ErrorKind::Help) => expect_help,
815-
Some(ErrorKind::Note) => expect_note,
816-
Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true,
817-
Some(ErrorKind::Suggestion) | None => false,
818-
}
807+
&& actual_error.kind.map_or(false, |err_kind| {
808+
// If the test being checked doesn't contain any "help" or "note" annotations, then
809+
// we don't require annotating "help" or "note" (respecively) diagnostics at all.
810+
let default_require_annotations = self.props.require_annotations[&err_kind];
811+
match err_kind {
812+
ErrorKind::Help => expect_help && default_require_annotations,
813+
ErrorKind::Note => expect_note && default_require_annotations,
814+
_ => default_require_annotations,
815+
}
816+
})
819817
}
820818

821819
fn should_emit_metadata(&self, pm: Option<PassMode>) -> Emit {

‎tests/rustdoc-gui/settings.goml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ compare-elements-position: (".sub form", "#settings", ["x"])
314314
// Check that setting-line has the same margin in this mode as in the popover.
315315
assert-css: (".setting-line", {"margin": |setting_line_margin|})
316316

317+
// We will check that the checkboxes size doesn't change either.
318+
assert-size: (
319+
"#settings label > input[type='checkbox']",
320+
{"width": 19, "height": 19},
321+
ALL,
322+
)
323+
317324
// We now check the display with JS disabled.
318325
assert-false: "noscript section"
319326
javascript: false
@@ -327,3 +334,10 @@ reload:
327334
set-window-size: (300, 1000)
328335
wait-for: "#settings"
329336
assert-css: (".setting-radio", {"cursor": "pointer"})
337+
338+
// We ensure that the checkboxes size didn't change.
339+
assert-size: (
340+
"#settings label > input[type='checkbox']",
341+
{"width": 19, "height": 19},
342+
ALL,
343+
)

‎tests/ui/cfg/cfg_false_no_std-2.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Error, the linked empty library is `no_std` and doesn't provide a panic handler.
22

3-
//@ compile-flags: --error-format=human
4-
//@ error-pattern: `#[panic_handler]` function required, but not found
3+
//@ dont-require-annotations:ERROR
54
//@ dont-check-compiler-stderr
65
//@ aux-build: cfg_false_lib_no_std_before.rs
76

@@ -11,6 +10,7 @@ extern crate cfg_false_lib_no_std_before as _;
1110

1211
fn main() {}
1312

14-
// FIXME: The second error is target-dependent.
15-
//FIXME~? ERROR `#[panic_handler]` function required, but not found
13+
//~? ERROR `#[panic_handler]` function required, but not found
14+
// FIXME: This error is target-dependent, could be served by some "optional error" annotation
15+
// instead of `dont-require-annotations`.
1616
//FIXME~? ERROR unwinding panics are not supported without std
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![feature(ergonomic_clones)]
2+
#![allow(incomplete_features)]
3+
4+
use std::clone::UseCloned;
5+
6+
fn takes_val<T>(_: T) {}
7+
fn takes_ref<'a, T>(_: &'a T) {}
8+
9+
#[derive(Clone)]
10+
struct Inner<'a, T>(&'a T);
11+
12+
impl<'a, T> UseCloned for Inner<'a, T> where T: Clone {}
13+
14+
fn main() {
15+
let v = String::new();
16+
let inner = Inner(&v);
17+
18+
let _ = use || {
19+
takes_ref(inner.0);
20+
takes_val(inner.0)
21+
};
22+
let _ = use || {
23+
takes_ref(inner.0);
24+
takes_val(inner.0);
25+
takes_val(inner.0);
26+
takes_val(inner)
27+
};
28+
let _ = use || {
29+
takes_ref(inner.0);
30+
takes_val(inner.0);
31+
takes_val(inner);
32+
takes_val(inner)
33+
//~^ ERROR: use of moved value: `inner` [E0382]
34+
};
35+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0382]: use of moved value: `inner`
2+
--> $DIR/multiple-use-variants.rs:32:19
3+
|
4+
LL | takes_val(inner);
5+
| ----- value moved here
6+
LL | takes_val(inner)
7+
| ^^^^^ value used here after move
8+
|
9+
= note: move occurs because `inner` has type `Inner<'_, String>`, which does not implement the `Copy` trait
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0382`.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ run-rustfix
2+
//@ edition:2018
3+
//@ check-pass
4+
#![feature(ergonomic_clones)]
5+
#![warn(rust_2021_compatibility)]
6+
#![allow(incomplete_features)]
7+
8+
#[derive(Debug)]
9+
struct Foo(i32);
10+
impl Drop for Foo {
11+
fn drop(&mut self) {
12+
println!("{:?} dropped", self.0);
13+
}
14+
}
15+
16+
fn main() {
17+
let a = (Foo(0), Foo(1));
18+
let f = use || {
19+
let _ = &a;
20+
//~^ HELP: add a dummy
21+
//~| WARNING: drop order
22+
let x = a.0;
23+
println!("{:?}", x);
24+
};
25+
f();
26+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//@ run-rustfix
2+
//@ edition:2018
3+
//@ check-pass
4+
#![feature(ergonomic_clones)]
5+
#![warn(rust_2021_compatibility)]
6+
#![allow(incomplete_features)]
7+
8+
#[derive(Debug)]
9+
struct Foo(i32);
10+
impl Drop for Foo {
11+
fn drop(&mut self) {
12+
println!("{:?} dropped", self.0);
13+
}
14+
}
15+
16+
fn main() {
17+
let a = (Foo(0), Foo(1));
18+
let f = use || {
19+
//~^ HELP: add a dummy
20+
//~| WARNING: drop order
21+
let x = a.0;
22+
println!("{:?}", x);
23+
};
24+
f();
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
warning: changes to closure capture in Rust 2021 will affect drop order
2+
--> $DIR/rfc2229-migration.rs:18:13
3+
|
4+
LL | let f = use || {
5+
| ^^^^^^
6+
...
7+
LL | let x = a.0;
8+
| --- in Rust 2018, this closure captures all of `a`, but in Rust 2021, it will only capture `a.0`
9+
...
10+
LL | }
11+
| - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure
12+
|
13+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
14+
note: the lint level is defined here
15+
--> $DIR/rfc2229-migration.rs:5:9
16+
|
17+
LL | #![warn(rust_2021_compatibility)]
18+
| ^^^^^^^^^^^^^^^^^^^^^^^
19+
= note: `#[warn(rust_2021_incompatible_closure_captures)]` implied by `#[warn(rust_2021_compatibility)]`
20+
help: add a dummy let to cause `a` to be fully captured
21+
|
22+
LL ~ let f = use || {
23+
LL + let _ = &a;
24+
|
25+
26+
warning: 1 warning emitted
27+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error[E0382]: use of moved value: `x`
2+
--> $DIR/spawn-thread.rs:15:42
3+
|
4+
LL | let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1));
5+
| - move occurs because `x` has type `(Arc<String>, Arc<Vec<i32>>, Arc<i32>)`, which does not implement the `Copy` trait
6+
LL | for _ in 0..10 {
7+
| -------------- inside of this loop
8+
LL | let handler = std::thread::spawn(use || {
9+
| __________________________________________-^^^^^
10+
LL | |
11+
LL | | drop((x.0, x.1, x.2));
12+
| | --- use occurs due to use in closure
13+
LL | | });
14+
| |_________- value moved here, in previous iteration of loop
15+
|
16+
help: consider moving the expression out of the loop so it is only moved once
17+
|
18+
LL ~ let mut value = std::thread::spawn(use || {
19+
LL +
20+
LL + drop((x.0, x.1, x.2));
21+
LL + });
22+
LL ~ for _ in 0..10 {
23+
LL ~ let handler = value;
24+
|
25+
26+
error: aborting due to 1 previous error
27+
28+
For more information about this error, try `rustc --explain E0382`.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//@ revisions: edition2018 edition2024
2+
//@ [edition2018] edition: 2018
3+
//@ [edition2024] edition: 2024
4+
//@ [edition2024] check-pass
5+
6+
#![feature(ergonomic_clones)]
7+
#![allow(incomplete_features)]
8+
9+
use std::sync::Arc;
10+
11+
fn foo() {
12+
// The type is a tuple and doesn't implement UseCloned
13+
let x = (Arc::new("foo".to_owned()), Arc::new(vec![1, 2, 3]), Arc::new(1));
14+
for _ in 0..10 {
15+
let handler = std::thread::spawn(use || {
16+
//[edition2018]~^ ERROR use of moved value: `x` [E0382]
17+
drop((x.0, x.1, x.2));
18+
});
19+
handler.join().unwrap();
20+
}
21+
}
22+
23+
fn bar() {
24+
let x = Arc::new("foo".to_owned());
25+
let y = Arc::new(vec![1, 2, 3]);
26+
let z = Arc::new(1);
27+
28+
for _ in 0..10 {
29+
let handler = std::thread::spawn(use || {
30+
drop((x, y, z));
31+
});
32+
handler.join().unwrap();
33+
}
34+
}
35+
36+
fn baz() {
37+
use std::sync::Arc;
38+
use std::thread;
39+
40+
let five = Arc::new(5);
41+
42+
for _ in 0..10 {
43+
let handler = thread::spawn(use || {
44+
println!("{five:?}");
45+
});
46+
handler.join().unwrap();
47+
}
48+
}
49+
50+
fn main() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@ check-pass
2+
3+
#![feature(ergonomic_clones)]
4+
#![allow(incomplete_features)]
5+
6+
fn use_block_test(x: i32) -> i32 {
7+
let x = { let x = x + 1; x }.use;
8+
x
9+
}
10+
11+
fn main() {}

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
1313
| ^^^^^^^^^^^^^
1414

1515
error[E0308]: mismatched types
16-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
16+
--> $DIR/candidate-from-env-universe-err-project.rs:52:30
1717
|
1818
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@@ -22,7 +22,7 @@ LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
2222
found associated type `<T as Trait<'a>>::Assoc`
2323

2424
error[E0308]: mismatched types
25-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
25+
--> $DIR/candidate-from-env-universe-err-project.rs:52:30
2626
|
2727
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
2828
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,20 @@ note: required by a bound in `projection_bound`
2222
LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
2323
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound`
2424

25-
error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
26-
--> $DIR/candidate-from-env-universe-err-project.rs:38:24
27-
|
28-
LL | projection_bound::<T>();
29-
| ^ type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
30-
|
31-
note: types differ
32-
--> $DIR/candidate-from-env-universe-err-project.rs:14:18
33-
|
34-
LL | type Assoc = usize;
35-
| ^^^^^
36-
note: required by a bound in `projection_bound`
37-
--> $DIR/candidate-from-env-universe-err-project.rs:18:42
38-
|
39-
LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
40-
| ^^^^^^^^^^^^^ required by this bound in `projection_bound`
41-
4225
error: higher-ranked subtype error
43-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
26+
--> $DIR/candidate-from-env-universe-err-project.rs:52:30
4427
|
4528
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
4629
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4730

4831
error: higher-ranked subtype error
49-
--> $DIR/candidate-from-env-universe-err-project.rs:53:30
32+
--> $DIR/candidate-from-env-universe-err-project.rs:52:30
5033
|
5134
LL | let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
5235
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5336
|
5437
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
5538

56-
error: aborting due to 5 previous errors
39+
error: aborting due to 4 previous errors
5740

58-
Some errors have detailed explanations: E0271, E0277.
59-
For more information about an error, try `rustc --explain E0271`.
41+
For more information about this error, try `rustc --explain E0277`.

‎tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ fn function2<T: Trait<'static, Assoc = usize>>() {
3636
// does not use the leak check when trying the where-bound, causing us
3737
// to prefer it over the impl, resulting in a placeholder error.
3838
projection_bound::<T>();
39-
//[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
40-
//[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
41-
//[current]~^^^ ERROR mismatched types
39+
//[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
40+
//[current]~^^ ERROR mismatched types
4241
}
4342

4443
fn function3<T: Trait<'static, Assoc = usize>>() {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![feature(large_assignments)]
2+
#![deny(large_assignments)]
3+
#![move_size_limit = "1000"]
4+
5+
//! Tests that with `-Zinline-mir`, we do NOT get an error that points to the
6+
//! implementation of `UnsafeCell` since that is not actionable by the user:
7+
//!
8+
//! ```text
9+
//! error: moving 9999 bytes
10+
//! --> /rustc/FAKE_PREFIX/library/core/src/cell.rs:2054:9
11+
//! |
12+
//! = note: value moved from here
13+
//! ```
14+
//!
15+
//! We want the diagnostics to point to the relevant user code.
16+
17+
//@ build-fail
18+
//@ compile-flags: -Zmir-opt-level=1 -Zinline-mir
19+
20+
pub fn main() {
21+
let data = [10u8; 9999];
22+
let cell = std::cell::UnsafeCell::new(data); //~ ERROR large_assignments
23+
std::hint::black_box(cell);
24+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: moving 9999 bytes
2+
--> $DIR/inline_mir.rs:22:16
3+
|
4+
LL | let cell = std::cell::UnsafeCell::new(data);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here
6+
|
7+
= note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]`
8+
note: the lint level is defined here
9+
--> $DIR/inline_mir.rs:2:9
10+
|
11+
LL | #![deny(large_assignments)]
12+
| ^^^^^^^^^^^^^^^^^
13+
14+
error: aborting due to 1 previous error
15+

‎tests/ui/mismatched_types/closure-mismatch.stderr renamed to ‎tests/ui/mismatched_types/closure-mismatch.current.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: implementation of `FnOnce` is not general enough
2-
--> $DIR/closure-mismatch.rs:8:5
2+
--> $DIR/closure-mismatch.rs:12:5
33
|
44
LL | baz(|_| ());
55
| ^^^^^^^^^^^ implementation of `FnOnce` is not general enough
@@ -8,7 +8,7 @@ LL | baz(|_| ());
88
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
99

1010
error: implementation of `Fn` is not general enough
11-
--> $DIR/closure-mismatch.rs:8:5
11+
--> $DIR/closure-mismatch.rs:12:5
1212
|
1313
LL | baz(|_| ());
1414
| ^^^^^^^^^^^ implementation of `Fn` is not general enough
@@ -17,7 +17,7 @@ LL | baz(|_| ());
1717
= note: ...but it actually implements `Fn<(&'2 (),)>`, for some specific lifetime `'2`
1818

1919
error: implementation of `FnOnce` is not general enough
20-
--> $DIR/closure-mismatch.rs:11:5
20+
--> $DIR/closure-mismatch.rs:16:5
2121
|
2222
LL | baz(|x| ());
2323
| ^^^^^^^^^^^ implementation of `FnOnce` is not general enough
@@ -26,7 +26,7 @@ LL | baz(|x| ());
2626
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
2727

2828
error: implementation of `Fn` is not general enough
29-
--> $DIR/closure-mismatch.rs:11:5
29+
--> $DIR/closure-mismatch.rs:16:5
3030
|
3131
LL | baz(|x| ());
3232
| ^^^^^^^^^^^ implementation of `Fn` is not general enough
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
error[E0277]: the trait bound `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}: Foo` is not satisfied
2+
--> $DIR/closure-mismatch.rs:12:9
3+
|
4+
LL | baz(|_| ());
5+
| --- ^^^^^^ unsatisfied trait bound
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}`
10+
= note: expected a closure with signature `for<'a> fn(&'a ())`
11+
found a closure with signature `fn(&())`
12+
note: this is a known limitation of the trait solver that will be lifted in the future
13+
--> $DIR/closure-mismatch.rs:12:9
14+
|
15+
LL | baz(|_| ());
16+
| ----^^^----
17+
| | |
18+
| | the trait solver is unable to infer the generic types that should be inferred from this argument
19+
| add turbofish arguments to this call to specify the types manually, even if it's redundant
20+
note: required for `{closure@$DIR/closure-mismatch.rs:12:9: 12:12}` to implement `Foo`
21+
--> $DIR/closure-mismatch.rs:7:18
22+
|
23+
LL | impl<T: Fn(&())> Foo for T {}
24+
| ------- ^^^ ^
25+
| |
26+
| unsatisfied trait bound introduced here
27+
note: required by a bound in `baz`
28+
--> $DIR/closure-mismatch.rs:9:11
29+
|
30+
LL | fn baz<T: Foo>(_: T) {}
31+
| ^^^ required by this bound in `baz`
32+
33+
error[E0277]: the trait bound `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}: Foo` is not satisfied
34+
--> $DIR/closure-mismatch.rs:16:9
35+
|
36+
LL | baz(|x| ());
37+
| --- ^^^^^^ unsatisfied trait bound
38+
| |
39+
| required by a bound introduced by this call
40+
|
41+
= help: the trait `for<'a> FnOnce(&'a ())` is not implemented for closure `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}`
42+
= note: expected a closure with signature `for<'a> fn(&'a ())`
43+
found a closure with signature `fn(&())`
44+
note: this is a known limitation of the trait solver that will be lifted in the future
45+
--> $DIR/closure-mismatch.rs:16:9
46+
|
47+
LL | baz(|x| ());
48+
| ----^^^----
49+
| | |
50+
| | the trait solver is unable to infer the generic types that should be inferred from this argument
51+
| add turbofish arguments to this call to specify the types manually, even if it's redundant
52+
note: required for `{closure@$DIR/closure-mismatch.rs:16:9: 16:12}` to implement `Foo`
53+
--> $DIR/closure-mismatch.rs:7:18
54+
|
55+
LL | impl<T: Fn(&())> Foo for T {}
56+
| ------- ^^^ ^
57+
| |
58+
| unsatisfied trait bound introduced here
59+
note: required by a bound in `baz`
60+
--> $DIR/closure-mismatch.rs:9:11
61+
|
62+
LL | fn baz<T: Foo>(_: T) {}
63+
| ^^^ required by this bound in `baz`
64+
65+
error: aborting due to 2 previous errors
66+
67+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
//@ revisions: current next
2+
//@ ignore-compare-mode-next-solver (explicit revisions)
3+
//@[next] compile-flags: -Znext-solver
4+
15
trait Foo {}
26

37
impl<T: Fn(&())> Foo for T {}
@@ -6,9 +10,11 @@ fn baz<T: Foo>(_: T) {}
610

711
fn main() {
812
baz(|_| ());
9-
//~^ ERROR implementation of `FnOnce` is not general enough
10-
//~| ERROR implementation of `Fn` is not general enough
13+
//[current]~^ ERROR implementation of `FnOnce` is not general enough
14+
//[current]~| ERROR implementation of `Fn` is not general enough
15+
//[next]~^^^ ERROR Foo` is not satisfied
1116
baz(|x| ());
12-
//~^ ERROR implementation of `FnOnce` is not general enough
13-
//~| ERROR implementation of `Fn` is not general enough
17+
//[current]~^ ERROR implementation of `FnOnce` is not general enough
18+
//[current]~| ERROR implementation of `Fn` is not general enough
19+
//[next]~^^^ ERROR Foo` is not satisfied
1420
}

‎tests/ui/panic-runtime/two-panic-runtimes.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// ignore-tidy-linelength
22
//@ build-fail
3-
//@ compile-flags: --error-format=human
4-
//@ error-pattern: cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
3+
//@ dont-require-annotations:ERROR
54
//@ dont-check-compiler-stderr
65
//@ aux-build:panic-runtime-unwind.rs
76
//@ aux-build:panic-runtime-unwind2.rs
@@ -16,7 +15,8 @@ extern crate panic_runtime_lang_items;
1615

1716
fn main() {}
1817

19-
// FIXME: The second and third errors are target-dependent.
20-
//FIXME~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
18+
//~? ERROR cannot link together two panic runtimes: panic_runtime_unwind and panic_runtime_unwind2
19+
// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
20+
// instead of `dont-require-annotations`.
2121
//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind2` is not compiled with this crate's panic strategy `abort`
2222
//FIXME~? ERROR the crate `panic_runtime_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// ignore-tidy-linelength
22
//@ build-fail
3-
//@ compile-flags: --error-format=human
4-
//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
3+
//@ dont-require-annotations:ERROR
54
//@ dont-check-compiler-stderr
65
//@ aux-build:panic-runtime-unwind.rs
76
//@ compile-flags:-C panic=abort
@@ -10,7 +9,8 @@ extern crate panic_runtime_unwind;
109

1110
fn main() {}
1211

13-
// FIXME: The first and third errors are target-dependent.
12+
//~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
13+
// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
14+
// instead of `dont-require-annotations`.
1415
//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
15-
//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
1616
//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// ignore-tidy-linelength
22
//@ build-fail
3-
//@ compile-flags: --error-format=human
4-
//@ error-pattern: the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
3+
//@ dont-require-annotations:ERROR
54
//@ dont-check-compiler-stderr
65
//@ aux-build:panic-runtime-unwind.rs
76
//@ aux-build:wants-panic-runtime-unwind.rs
@@ -11,7 +10,8 @@ extern crate wants_panic_runtime_unwind;
1110

1211
fn main() {}
1312

14-
// FIXME: The first and third errors are target-dependent.
13+
//~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
14+
// FIXME: These errors are target-dependent, could be served by some "optional error" annotation
15+
// instead of `dont-require-annotations`.
1516
//FIXME~? ERROR cannot link together two panic runtimes: panic_unwind and panic_runtime_unwind
16-
//FIXME~? ERROR the linked panic runtime `panic_runtime_unwind` is not compiled with this crate's panic strategy `abort`
1717
//FIXME~? ERROR the crate `panic_unwind` requires panic strategy `unwind` which is incompatible with this crate's strategy of `abort`

‎triagebot.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,9 +1338,11 @@ compiletest = [
13381338
"/src/doc/nomicon" = ["@ehuss"]
13391339
"/src/doc/reference" = ["@ehuss"]
13401340
"/src/doc/rust-by-example" = ["@ehuss"]
1341+
"/src/doc/rustc" = ["compiler", "@ehuss"]
13411342
"/src/doc/rustc-dev-guide" = ["compiler"]
13421343
"/src/doc/rustdoc" = ["rustdoc"]
13431344
"/src/doc/style-guide" = ["style-team"]
1345+
"/src/doc/unstable-book" = ["compiler"]
13441346
"/src/etc" = ["@Mark-Simulacrum"]
13451347
"/src/librustdoc" = ["rustdoc"]
13461348
"/src/llvm-project" = ["@cuviper"]

0 commit comments

Comments
 (0)
Please sign in to comment.