Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 39323a5

Browse files
committedOct 2, 2022
Auto merge of #102586 - Dylan-DPC:rollup-g107h6z, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #100451 (Do not panic when a test function returns Result::Err.) - #102098 (Use fetch_update in sync::Weak::upgrade) - #102538 (Give `def_span` the same SyntaxContext as `span_with_body`.) - #102556 (Make `feature(const_btree_len)` implied by `feature(const_btree_new)`) - #102566 (Add a known-bug test for #102498) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 91931ec + 0b25967 commit 39323a5

File tree

14 files changed

+239
-94
lines changed

14 files changed

+239
-94
lines changed
 

‎compiler/rustc_middle/src/hir/map/mod.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,19 @@ impl<'hir> Map<'hir> {
941941

942942
let span = match self.find(hir_id)? {
943943
// Function-like.
944-
Node::Item(Item { kind: ItemKind::Fn(sig, ..), .. })
945-
| Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, ..), .. })
946-
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, ..), .. }) => sig.span,
944+
Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
945+
| Node::TraitItem(TraitItem {
946+
kind: TraitItemKind::Fn(sig, ..),
947+
span: outer_span,
948+
..
949+
})
950+
| Node::ImplItem(ImplItem {
951+
kind: ImplItemKind::Fn(sig, ..), span: outer_span, ..
952+
}) => {
953+
// Ensure that the returned span has the item's SyntaxContext, and not the
954+
// SyntaxContext of the visibility.
955+
sig.span.find_ancestor_in_same_ctxt(*outer_span).unwrap_or(*outer_span)
956+
}
947957
// Constants and Statics.
948958
Node::Item(Item {
949959
kind:
@@ -985,7 +995,11 @@ impl<'hir> Map<'hir> {
985995
}
986996
// Other cases.
987997
Node::Item(item) => match &item.kind {
988-
ItemKind::Use(path, _) => path.span,
998+
ItemKind::Use(path, _) => {
999+
// Ensure that the returned span has the item's SyntaxContext, and not the
1000+
// SyntaxContext of the path.
1001+
path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span)
1002+
}
9891003
_ => named_span(item.span, item.ident, item.kind.generics()),
9901004
},
9911005
Node::Variant(variant) => named_span(variant.span, variant.ident, None),
@@ -995,11 +1009,17 @@ impl<'hir> Map<'hir> {
9951009
_ => named_span(item.span, item.ident, None),
9961010
},
9971011
Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)),
998-
Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), .. }) => {
999-
*fn_decl_span
1012+
Node::Expr(Expr {
1013+
kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
1014+
span,
1015+
..
1016+
}) => {
1017+
// Ensure that the returned span has the item's SyntaxContext.
1018+
fn_decl_span.find_ancestor_in_same_ctxt(*span).unwrap_or(*span)
10001019
}
10011020
_ => self.span_with_body(hir_id),
10021021
};
1022+
debug_assert_eq!(span.ctxt(), self.span_with_body(hir_id).ctxt());
10031023
Some(span)
10041024
}
10051025

‎library/alloc/src/collections/btree/map.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,7 +2392,11 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
23922392
/// ```
23932393
#[must_use]
23942394
#[stable(feature = "rust1", since = "1.0.0")]
2395-
#[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
2395+
#[rustc_const_unstable(
2396+
feature = "const_btree_len",
2397+
issue = "71835",
2398+
implied_by = "const_btree_new"
2399+
)]
23962400
pub const fn len(&self) -> usize {
23972401
self.length
23982402
}
@@ -2413,7 +2417,11 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
24132417
/// ```
24142418
#[must_use]
24152419
#[stable(feature = "rust1", since = "1.0.0")]
2416-
#[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
2420+
#[rustc_const_unstable(
2421+
feature = "const_btree_len",
2422+
issue = "71835",
2423+
implied_by = "const_btree_new"
2424+
)]
24172425
pub const fn is_empty(&self) -> bool {
24182426
self.len() == 0
24192427
}

‎library/alloc/src/collections/btree/set.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,11 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
11741174
/// ```
11751175
#[must_use]
11761176
#[stable(feature = "rust1", since = "1.0.0")]
1177-
#[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
1177+
#[rustc_const_unstable(
1178+
feature = "const_btree_len",
1179+
issue = "71835",
1180+
implied_by = "const_btree_new"
1181+
)]
11781182
pub const fn len(&self) -> usize {
11791183
self.map.len()
11801184
}
@@ -1193,7 +1197,11 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
11931197
/// ```
11941198
#[must_use]
11951199
#[stable(feature = "rust1", since = "1.0.0")]
1196-
#[rustc_const_unstable(feature = "const_btree_len", issue = "71835")]
1200+
#[rustc_const_unstable(
1201+
feature = "const_btree_len",
1202+
issue = "71835",
1203+
implied_by = "const_btree_new"
1204+
)]
11971205
pub const fn is_empty(&self) -> bool {
11981206
self.len() == 0
11991207
}

‎library/alloc/src/sync.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,33 +1980,26 @@ impl<T: ?Sized> Weak<T> {
19801980
// We use a CAS loop to increment the strong count instead of a
19811981
// fetch_add as this function should never take the reference count
19821982
// from zero to one.
1983-
let inner = self.inner()?;
1984-
1985-
// Relaxed load because any write of 0 that we can observe
1986-
// leaves the field in a permanently zero state (so a
1987-
// "stale" read of 0 is fine), and any other value is
1988-
// confirmed via the CAS below.
1989-
let mut n = inner.strong.load(Relaxed);
1990-
1991-
loop {
1992-
if n == 0 {
1993-
return None;
1994-
}
1995-
1996-
// See comments in `Arc::clone` for why we do this (for `mem::forget`).
1997-
if n > MAX_REFCOUNT {
1998-
abort();
1999-
}
2000-
1983+
self.inner()?
1984+
.strong
20011985
// Relaxed is fine for the failure case because we don't have any expectations about the new state.
20021986
// Acquire is necessary for the success case to synchronise with `Arc::new_cyclic`, when the inner
20031987
// value can be initialized after `Weak` references have already been created. In that case, we
20041988
// expect to observe the fully initialized value.
2005-
match inner.strong.compare_exchange_weak(n, n + 1, Acquire, Relaxed) {
2006-
Ok(_) => return Some(unsafe { Arc::from_inner(self.ptr) }), // null checked above
2007-
Err(old) => n = old,
2008-
}
2009-
}
1989+
.fetch_update(Acquire, Relaxed, |n| {
1990+
// Any write of 0 we can observe leaves the field in permanently zero state.
1991+
if n == 0 {
1992+
return None;
1993+
}
1994+
// See comments in `Arc::clone` for why we do this (for `mem::forget`).
1995+
if n > MAX_REFCOUNT {
1996+
abort();
1997+
}
1998+
Some(n + 1)
1999+
})
2000+
.ok()
2001+
// null checked above
2002+
.map(|_| unsafe { Arc::from_inner(self.ptr) })
20102003
}
20112004

20122005
/// Gets the number of strong (`Arc`) pointers pointing to this allocation.

‎library/test/src/bench.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ impl Bencher {
4949
self.summary = Some(iter(&mut inner));
5050
}
5151

52-
pub fn bench<F>(&mut self, mut f: F) -> Option<stats::Summary>
52+
pub fn bench<F>(&mut self, mut f: F) -> Result<Option<stats::Summary>, String>
5353
where
54-
F: FnMut(&mut Bencher),
54+
F: FnMut(&mut Bencher) -> Result<(), String>,
5555
{
56-
f(self);
57-
self.summary
56+
let result = f(self);
57+
result.map(|_| self.summary)
5858
}
5959
}
6060

@@ -195,7 +195,7 @@ pub fn benchmark<F>(
195195
nocapture: bool,
196196
f: F,
197197
) where
198-
F: FnMut(&mut Bencher),
198+
F: FnMut(&mut Bencher) -> Result<(), String>,
199199
{
200200
let mut bs = Bencher { mode: BenchMode::Auto, summary: None, bytes: 0 };
201201

@@ -211,32 +211,33 @@ pub fn benchmark<F>(
211211

212212
let test_result = match result {
213213
//bs.bench(f) {
214-
Ok(Some(ns_iter_summ)) => {
214+
Ok(Ok(Some(ns_iter_summ))) => {
215215
let ns_iter = cmp::max(ns_iter_summ.median as u64, 1);
216216
let mb_s = bs.bytes * 1000 / ns_iter;
217217

218218
let bs = BenchSamples { ns_iter_summ, mb_s: mb_s as usize };
219219
TestResult::TrBench(bs)
220220
}
221-
Ok(None) => {
221+
Ok(Ok(None)) => {
222222
// iter not called, so no data.
223223
// FIXME: error in this case?
224224
let samples: &mut [f64] = &mut [0.0_f64; 1];
225225
let bs = BenchSamples { ns_iter_summ: stats::Summary::new(samples), mb_s: 0 };
226226
TestResult::TrBench(bs)
227227
}
228228
Err(_) => TestResult::TrFailed,
229+
Ok(Err(_)) => TestResult::TrFailed,
229230
};
230231

231232
let stdout = data.lock().unwrap().to_vec();
232233
let message = CompletedTest::new(id, desc, test_result, None, stdout);
233234
monitor_ch.send(message).unwrap();
234235
}
235236

236-
pub fn run_once<F>(f: F)
237+
pub fn run_once<F>(f: F) -> Result<(), String>
237238
where
238-
F: FnMut(&mut Bencher),
239+
F: FnMut(&mut Bencher) -> Result<(), String>,
239240
{
240241
let mut bs = Bencher { mode: BenchMode::Single, summary: None, bytes: 0 };
241-
bs.bench(f);
242+
bs.bench(f).map(|_| ())
242243
}

‎library/test/src/lib.rs

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
//! benchmarks themselves) should be done via the `#[test]` and
77
//! `#[bench]` attributes.
88
//!
9-
//! See the [Testing Chapter](../book/ch11-00-testing.html) of the book for more details.
9+
//! See the [Testing Chapter](../book/ch11-00-testing.html) of the book for more
10+
//! details.
1011
1112
// Currently, not much of this is meant for users. It is intended to
1213
// support the simplest interface possible for representing and
@@ -76,6 +77,7 @@ mod types;
7677
#[cfg(test)]
7778
mod tests;
7879

80+
use core::any::Any;
7981
use event::{CompletedTest, TestEvent};
8082
use helpers::concurrency::get_concurrency;
8183
use helpers::exit_code::get_exit_code;
@@ -175,17 +177,20 @@ fn make_owned_test(test: &&TestDescAndFn) -> TestDescAndFn {
175177
}
176178
}
177179

178-
/// Invoked when unit tests terminate. Should panic if the unit
179-
/// Tests is considered a failure. By default, invokes `report()`
180-
/// and checks for a `0` result.
181-
pub fn assert_test_result<T: Termination>(result: T) {
180+
/// Invoked when unit tests terminate. Returns `Result::Err` if the test is
181+
/// considered a failure. By default, invokes `report() and checks for a `0`
182+
/// result.
183+
pub fn assert_test_result<T: Termination>(result: T) -> Result<(), String> {
182184
let code = result.report().to_i32();
183-
assert_eq!(
184-
code, 0,
185-
"the test returned a termination value with a non-zero status code ({}) \
186-
which indicates a failure",
187-
code
188-
);
185+
if code == 0 {
186+
Ok(())
187+
} else {
188+
Err(format!(
189+
"the test returned a termination value with a non-zero status code \
190+
({}) which indicates a failure",
191+
code
192+
))
193+
}
189194
}
190195

191196
pub fn run_tests<F>(
@@ -478,7 +483,7 @@ pub fn run_test(
478483
id: TestId,
479484
desc: TestDesc,
480485
monitor_ch: Sender<CompletedTest>,
481-
testfn: Box<dyn FnOnce() + Send>,
486+
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
482487
opts: TestRunOpts,
483488
) -> Option<thread::JoinHandle<()>> {
484489
let concurrency = opts.concurrency;
@@ -567,19 +572,19 @@ pub fn run_test(
567572

568573
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
569574
#[inline(never)]
570-
fn __rust_begin_short_backtrace<F: FnOnce()>(f: F) {
571-
f();
575+
fn __rust_begin_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T {
576+
let result = f();
572577

573578
// prevent this frame from being tail-call optimised away
574-
black_box(());
579+
black_box(result)
575580
}
576581

577582
fn run_test_in_process(
578583
id: TestId,
579584
desc: TestDesc,
580585
nocapture: bool,
581586
report_time: bool,
582-
testfn: Box<dyn FnOnce() + Send>,
587+
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
583588
monitor_ch: Sender<CompletedTest>,
584589
time_opts: Option<time::TestTimeOptions>,
585590
) {
@@ -591,7 +596,7 @@ fn run_test_in_process(
591596
}
592597

593598
let start = report_time.then(Instant::now);
594-
let result = catch_unwind(AssertUnwindSafe(testfn));
599+
let result = fold_err(catch_unwind(AssertUnwindSafe(testfn)));
595600
let exec_time = start.map(|start| {
596601
let duration = start.elapsed();
597602
TestExecTime(duration)
@@ -608,6 +613,19 @@ fn run_test_in_process(
608613
monitor_ch.send(message).unwrap();
609614
}
610615

616+
fn fold_err<T, E>(
617+
result: Result<Result<T, E>, Box<dyn Any + Send>>,
618+
) -> Result<T, Box<dyn Any + Send>>
619+
where
620+
E: Send + 'static,
621+
{
622+
match result {
623+
Ok(Err(e)) => Err(Box::new(e)),
624+
Ok(Ok(v)) => Ok(v),
625+
Err(e) => Err(e),
626+
}
627+
}
628+
611629
fn spawn_test_subprocess(
612630
id: TestId,
613631
desc: TestDesc,
@@ -663,7 +681,10 @@ fn spawn_test_subprocess(
663681
monitor_ch.send(message).unwrap();
664682
}
665683

666-
fn run_test_in_spawned_subprocess(desc: TestDesc, testfn: Box<dyn FnOnce() + Send>) -> ! {
684+
fn run_test_in_spawned_subprocess(
685+
desc: TestDesc,
686+
testfn: Box<dyn FnOnce() -> Result<(), String> + Send>,
687+
) -> ! {
667688
let builtin_panic_hook = panic::take_hook();
668689
let record_result = Arc::new(move |panic_info: Option<&'_ PanicInfo<'_>>| {
669690
let test_result = match panic_info {
@@ -689,7 +710,9 @@ fn run_test_in_spawned_subprocess(desc: TestDesc, testfn: Box<dyn FnOnce() + Sen
689710
});
690711
let record_result2 = record_result.clone();
691712
panic::set_hook(Box::new(move |info| record_result2(Some(&info))));
692-
testfn();
713+
if let Err(message) = testfn() {
714+
panic!("{}", message);
715+
}
693716
record_result(None);
694717
unreachable!("panic=abort callback should have exited the process")
695718
}

‎library/test/src/tests.rs

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
6767
no_run: false,
6868
test_type: TestType::Unknown,
6969
},
70-
testfn: DynTestFn(Box::new(move || {})),
70+
testfn: DynTestFn(Box::new(move || Ok(()))),
7171
},
7272
TestDescAndFn {
7373
desc: TestDesc {
@@ -79,14 +79,14 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
7979
no_run: false,
8080
test_type: TestType::Unknown,
8181
},
82-
testfn: DynTestFn(Box::new(move || {})),
82+
testfn: DynTestFn(Box::new(move || Ok(()))),
8383
},
8484
]
8585
}
8686

8787
#[test]
8888
pub fn do_not_run_ignored_tests() {
89-
fn f() {
89+
fn f() -> Result<(), String> {
9090
panic!();
9191
}
9292
let desc = TestDescAndFn {
@@ -109,7 +109,9 @@ pub fn do_not_run_ignored_tests() {
109109

110110
#[test]
111111
pub fn ignored_tests_result_in_ignored() {
112-
fn f() {}
112+
fn f() -> Result<(), String> {
113+
Ok(())
114+
}
113115
let desc = TestDescAndFn {
114116
desc: TestDesc {
115117
name: StaticTestName("whatever"),
@@ -132,7 +134,7 @@ pub fn ignored_tests_result_in_ignored() {
132134
#[test]
133135
#[cfg(not(target_os = "emscripten"))]
134136
fn test_should_panic() {
135-
fn f() {
137+
fn f() -> Result<(), String> {
136138
panic!();
137139
}
138140
let desc = TestDescAndFn {
@@ -157,7 +159,7 @@ fn test_should_panic() {
157159
#[test]
158160
#[cfg(not(target_os = "emscripten"))]
159161
fn test_should_panic_good_message() {
160-
fn f() {
162+
fn f() -> Result<(), String> {
161163
panic!("an error message");
162164
}
163165
let desc = TestDescAndFn {
@@ -183,7 +185,7 @@ fn test_should_panic_good_message() {
183185
#[cfg(not(target_os = "emscripten"))]
184186
fn test_should_panic_bad_message() {
185187
use crate::tests::TrFailedMsg;
186-
fn f() {
188+
fn f() -> Result<(), String> {
187189
panic!("an error message");
188190
}
189191
let expected = "foobar";
@@ -214,7 +216,7 @@ fn test_should_panic_bad_message() {
214216
fn test_should_panic_non_string_message_type() {
215217
use crate::tests::TrFailedMsg;
216218
use std::any::TypeId;
217-
fn f() {
219+
fn f() -> Result<(), String> {
218220
std::panic::panic_any(1i32);
219221
}
220222
let expected = "foobar";
@@ -249,7 +251,9 @@ fn test_should_panic_but_succeeds() {
249251
let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")];
250252

251253
for &should_panic in should_panic_variants.iter() {
252-
fn f() {}
254+
fn f() -> Result<(), String> {
255+
Ok(())
256+
}
253257
let desc = TestDescAndFn {
254258
desc: TestDesc {
255259
name: StaticTestName("whatever"),
@@ -283,7 +287,9 @@ fn test_should_panic_but_succeeds() {
283287
}
284288

285289
fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
286-
fn f() {}
290+
fn f() -> Result<(), String> {
291+
Ok(())
292+
}
287293
let desc = TestDescAndFn {
288294
desc: TestDesc {
289295
name: StaticTestName("whatever"),
@@ -318,7 +324,9 @@ fn test_should_report_time() {
318324
}
319325

320326
fn time_test_failure_template(test_type: TestType) -> TestResult {
321-
fn f() {}
327+
fn f() -> Result<(), String> {
328+
Ok(())
329+
}
322330
let desc = TestDescAndFn {
323331
desc: TestDesc {
324332
name: StaticTestName("whatever"),
@@ -480,7 +488,7 @@ pub fn exclude_should_panic_option() {
480488
no_run: false,
481489
test_type: TestType::Unknown,
482490
},
483-
testfn: DynTestFn(Box::new(move || {})),
491+
testfn: DynTestFn(Box::new(move || Ok(()))),
484492
});
485493

486494
let filtered = filter_tests(&opts, tests);
@@ -504,7 +512,7 @@ pub fn exact_filter_match() {
504512
no_run: false,
505513
test_type: TestType::Unknown,
506514
},
507-
testfn: DynTestFn(Box::new(move || {})),
515+
testfn: DynTestFn(Box::new(move || Ok(()))),
508516
})
509517
.collect()
510518
}
@@ -580,7 +588,9 @@ fn sample_tests() -> Vec<TestDescAndFn> {
580588
"test::run_include_ignored_option".to_string(),
581589
"test::sort_tests".to_string(),
582590
];
583-
fn testfn() {}
591+
fn testfn() -> Result<(), String> {
592+
Ok(())
593+
}
584594
let mut tests = Vec::new();
585595
for name in &names {
586596
let test = TestDescAndFn {
@@ -717,21 +727,26 @@ pub fn test_metricmap_compare() {
717727

718728
#[test]
719729
pub fn test_bench_once_no_iter() {
720-
fn f(_: &mut Bencher) {}
721-
bench::run_once(f);
730+
fn f(_: &mut Bencher) -> Result<(), String> {
731+
Ok(())
732+
}
733+
bench::run_once(f).unwrap();
722734
}
723735

724736
#[test]
725737
pub fn test_bench_once_iter() {
726-
fn f(b: &mut Bencher) {
727-
b.iter(|| {})
738+
fn f(b: &mut Bencher) -> Result<(), String> {
739+
b.iter(|| {});
740+
Ok(())
728741
}
729-
bench::run_once(f);
742+
bench::run_once(f).unwrap();
730743
}
731744

732745
#[test]
733746
pub fn test_bench_no_iter() {
734-
fn f(_: &mut Bencher) {}
747+
fn f(_: &mut Bencher) -> Result<(), String> {
748+
Ok(())
749+
}
735750

736751
let (tx, rx) = channel();
737752

@@ -751,8 +766,9 @@ pub fn test_bench_no_iter() {
751766

752767
#[test]
753768
pub fn test_bench_iter() {
754-
fn f(b: &mut Bencher) {
755-
b.iter(|| {})
769+
fn f(b: &mut Bencher) -> Result<(), String> {
770+
b.iter(|| {});
771+
Ok(())
756772
}
757773

758774
let (tx, rx) = channel();
@@ -821,3 +837,33 @@ fn should_sort_failures_before_printing_them() {
821837
let bpos = s.find("b").unwrap();
822838
assert!(apos < bpos);
823839
}
840+
841+
#[test]
842+
#[cfg(not(target_os = "emscripten"))]
843+
fn test_dyn_bench_returning_err_fails_when_run_as_test() {
844+
fn f(_: &mut Bencher) -> Result<(), String> {
845+
Result::Err("An error".into())
846+
}
847+
let desc = TestDescAndFn {
848+
desc: TestDesc {
849+
name: StaticTestName("whatever"),
850+
ignore: false,
851+
ignore_message: None,
852+
should_panic: ShouldPanic::No,
853+
compile_fail: false,
854+
no_run: false,
855+
test_type: TestType::Unknown,
856+
},
857+
testfn: DynBenchFn(Box::new(f)),
858+
};
859+
let (tx, rx) = channel();
860+
let notify = move |event: TestEvent| {
861+
if let TestEvent::TeResult(result) = event {
862+
tx.send(result).unwrap();
863+
}
864+
Ok(())
865+
};
866+
run_tests(&TestOpts { run_tests: true, ..TestOpts::new() }, vec![desc], notify).unwrap();
867+
let result = rx.recv().unwrap().result;
868+
assert_eq!(result, TrFailed);
869+
}

‎library/test/src/types.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,15 @@ impl fmt::Display for TestName {
7575
}
7676

7777
// A function that runs a test. If the function returns successfully,
78-
// the test succeeds; if the function panics then the test fails. We
79-
// may need to come up with a more clever definition of test in order
80-
// to support isolation of tests into threads.
78+
// the test succeeds; if the function panics or returns Result::Err
79+
// then the test fails. We may need to come up with a more clever
80+
// definition of test in order to support isolation of tests into
81+
// threads.
8182
pub enum TestFn {
82-
StaticTestFn(fn()),
83-
StaticBenchFn(fn(&mut Bencher)),
84-
DynTestFn(Box<dyn FnOnce() + Send>),
85-
DynBenchFn(Box<dyn Fn(&mut Bencher) + Send>),
83+
StaticTestFn(fn() -> Result<(), String>),
84+
StaticBenchFn(fn(&mut Bencher) -> Result<(), String>),
85+
DynTestFn(Box<dyn FnOnce() -> Result<(), String> + Send>),
86+
DynBenchFn(Box<dyn Fn(&mut Bencher) -> Result<(), String> + Send>),
8687
}
8788

8889
impl TestFn {

‎src/librustdoc/doctest.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,7 @@ impl Tester for Collector {
11341134

11351135
panic::resume_unwind(Box::new(()));
11361136
}
1137+
Ok(())
11371138
})),
11381139
});
11391140
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// known-bug: #102498
2+
3+
#![feature(const_trait_impl, generic_const_exprs)]
4+
5+
pub trait Tr {
6+
fn a() -> usize;
7+
}
8+
9+
impl Tr for () {
10+
fn a() -> usize {
11+
1
12+
}
13+
}
14+
15+
const fn foo<T: ~const Tr>() -> [u8; T::a()] {
16+
[0; T::a()]
17+
}
18+
19+
fn main() {
20+
foo::<()>();
21+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/constifconst-call-in-const-position.rs:3:30
3+
|
4+
LL | #![feature(const_trait_impl, generic_const_exprs)]
5+
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
11+
--> $DIR/constifconst-call-in-const-position.rs:15:38
12+
|
13+
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
14+
| ^^^^^^ calling non-const function `<() as Tr>::a`
15+
16+
error: aborting due to previous error; 1 warning emitted
17+
18+
For more information about this error, try `rustc --explain E0080`.

‎src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LL | | }
1313
note: required by a bound in `assert_test_result`
1414
--> $SRC_DIR/test/src/lib.rs:LL:COL
1515
|
16-
LL | pub fn assert_test_result<T: Termination>(result: T) {
16+
LL | pub fn assert_test_result<T: Termination>(result: T) -> Result<(), String> {
1717
| ^^^^^^^^^^^ required by this bound in `assert_test_result`
1818
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
1919

‎src/tools/compiletest/src/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,10 @@ fn make_test_closure(
797797
let config = config.clone();
798798
let testpaths = testpaths.clone();
799799
let revision = revision.cloned();
800-
test::DynTestFn(Box::new(move || runtest::run(config, &testpaths, revision.as_deref())))
800+
test::DynTestFn(Box::new(move || {
801+
runtest::run(config, &testpaths, revision.as_deref());
802+
Ok(())
803+
}))
801804
}
802805

803806
/// Returns `true` if the given target is an Android target for the

‎src/tools/tidy/src/features.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,9 @@ fn map_lib_features(
538538
becoming_feature = None;
539539
if line.contains("rustc_const_unstable(") {
540540
// `const fn` features are handled specially.
541-
let feature_name = match find_attr_val(line, "feature") {
541+
let feature_name = match find_attr_val(line, "feature").or_else(|| {
542+
iter_lines.peek().and_then(|next| find_attr_val(next.1, "feature"))
543+
}) {
542544
Some(name) => name,
543545
None => err!("malformed stability attribute: missing `feature` key"),
544546
};

0 commit comments

Comments
 (0)
Please sign in to comment.