提交 03c8ffaa 编写于 作者: B bors

Auto merge of #94350 - matthiaskrgr:rollup-eesfiyr, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #92714 (Provide ignore message in the result of test)
 - #93273 (Always check cg_llvm with ./x.py check)
 - #94068 (Consider mutations as borrows in generator drop tracking)
 - #94184 (BTree: simplify test code)
 - #94297 (update const_generics_defaults release notes)
 - #94341 (Remove a duplicate space)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
......@@ -4,7 +4,7 @@ Version 1.59.0 (2022-02-24)
Language
--------
- [Stabilize default arguments for const generics][90207]
- [Stabilize default arguments for const parameters and remove the ordering restriction for type and const parameters][90207]
- [Stabilize destructuring assignment][90521]
- [Relax private in public lint on generic bounds and where clauses of trait impls][90586]
- [Stabilize asm! and global_asm! for x86, x86_64, ARM, Aarch64, and RISC-V][91728]
......@@ -18,6 +18,21 @@ Compiler
- [Warn when a `#[test]`-like built-in attribute macro is present multiple times.][91172]
- [Add support for riscv64gc-unknown-freebsd][91284]
- [Stabilize `-Z emit-future-incompat` as `--json future-incompat`][91535]
- [Soft disable incremental compilation][94124]
This release disables incremental compilation, unless the user has explicitly
opted in via the newly added RUSTC_FORCE_INCREMENTAL=1 environment variable.
This is due to a known and relatively frequently occurring bug in incremental
compilation, which causes builds to issue internal compiler errors. This
particular bug is already fixed on nightly, but that fix has not yet rolled out
to stable and is deemed too risky for a direct stable backport.
As always, we encourage users to test with nightly and report bugs so that we
can track failures and fix issues earlier.
See [94124] for more details.
[94124]: https://github.com/rust-lang/rust/issues/94124
Libraries
---------
......@@ -86,6 +101,7 @@ Compatibility Notes
- [Weaken guarantee around advancing underlying iterators in zip][83791]
- [Make split_inclusive() on an empty slice yield an empty output][89825]
- [Update std::env::temp_dir to use GetTempPath2 on Windows when available.][89999]
- [unreachable! was updated to match other formatting macro behavior on Rust 2021][92137]
Internal Changes
----------------
......@@ -127,6 +143,7 @@ and related tools.
[91984]: https://github.com/rust-lang/rust/pull/91984/
[92020]: https://github.com/rust-lang/rust/pull/92020/
[92034]: https://github.com/rust-lang/rust/pull/92034/
[92137]: https://github.com/rust-lang/rust/pull/92137/
[92483]: https://github.com/rust-lang/rust/pull/92483/
[cargo/10088]: https://github.com/rust-lang/cargo/pull/10088/
[cargo/10133]: https://github.com/rust-lang/cargo/pull/10133/
......
......@@ -262,6 +262,15 @@ pub fn expand_test_or_bench(
"ignore",
cx.expr_bool(sp, should_ignore(&cx.sess, &item)),
),
// ignore_message: Some("...") | None
field(
"ignore_message",
if let Some(msg) = should_ignore_message(cx, &item) {
cx.expr_some(sp, cx.expr_str(sp, msg))
} else {
cx.expr_none(sp)
},
),
// compile_fail: true | false
field("compile_fail", cx.expr_bool(sp, false)),
// no_run: true | false
......@@ -364,6 +373,20 @@ fn should_ignore(sess: &Session, i: &ast::Item) -> bool {
sess.contains_name(&i.attrs, sym::ignore)
}
fn should_ignore_message(cx: &ExtCtxt<'_>, i: &ast::Item) -> Option<Symbol> {
match cx.sess.find_by_name(&i.attrs, sym::ignore) {
Some(attr) => {
match attr.meta_item_list() {
// Handle #[ignore(bar = "foo")]
Some(_) => None,
// Handle #[ignore] and #[ignore = "message"]
None => attr.value_str(),
}
}
None => None,
}
}
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
match cx.sess.find_by_name(&i.attrs, sym::should_panic) {
Some(attr) => {
......
......@@ -329,6 +329,10 @@ pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
self.expr_call_global(sp, some, vec![expr])
}
pub fn expr_none(&self, sp: Span) -> P<ast::Expr> {
let none = self.std_path(&[sym::option, sym::Option, sym::None]);
self.expr_path(self.path_global(sp, none))
}
pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
self.expr(sp, ast::ExprKind::Tup(exprs))
}
......
......@@ -633,7 +633,7 @@ fn try_suggest_return_impl_trait(
})
.collect::<Result<Vec<_>, _>>();
let Ok(where_predicates) = where_predicates else { return };
let Ok(where_predicates) = where_predicates else { return };
// now get all predicates in the same types as the where bounds, so we can chain them
let predicates_from_where =
......
......@@ -93,9 +93,10 @@ fn consume(
fn borrow(
&mut self,
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
_diag_expr_id: HirId,
diag_expr_id: HirId,
_bk: rustc_middle::ty::BorrowKind,
) {
debug!("borrow {:?}; diag_expr_id={:?}", place_with_id, diag_expr_id);
self.places
.borrowed
.insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
......@@ -103,9 +104,14 @@ fn borrow(
fn mutate(
&mut self,
_assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
_diag_expr_id: HirId,
assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
diag_expr_id: HirId,
) {
debug!("mutate {:?}; diag_expr_id={:?}", assignee_place, diag_expr_id);
// Count mutations as a borrow.
self.places
.borrowed
.insert(TrackedValue::from_place_with_projections_allowed(assignee_place));
}
fn fake_read(
......
......@@ -1539,7 +1539,7 @@ fn next(&mut self) -> Option<&'a T> {
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_len, b_len) = self.0.lens();
// No checked_add, because even if a and b refer to the same set,
// and T is an empty type, the storage overhead of sets limits
// and T is a zero-sized type, the storage overhead of sets limits
// the number of elements to less than half the range of usize.
(0, Some(a_len + b_len))
}
......
......@@ -91,7 +91,7 @@ fn check_intersection(a: &[i32], b: &[i32], expected: &[i32]) {
return;
}
let large = (0..100).collect::<Vec<_>>();
let large = Vec::from_iter(0..100);
check_intersection(&[], &large, &[]);
check_intersection(&large, &[], &[]);
check_intersection(&[-1], &large, &[]);
......@@ -107,8 +107,8 @@ fn check_intersection(a: &[i32], b: &[i32], expected: &[i32]) {
#[test]
fn test_intersection_size_hint() {
let x: BTreeSet<i32> = [3, 4].iter().copied().collect();
let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
let x = BTreeSet::from([3, 4]);
let y = BTreeSet::from([1, 2, 3]);
let mut iter = x.intersection(&y);
assert_eq!(iter.size_hint(), (1, Some(1)));
assert_eq!(iter.next(), Some(&3));
......@@ -145,7 +145,7 @@ fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
return;
}
let large = (0..100).collect::<Vec<_>>();
let large = Vec::from_iter(0..100);
check_difference(&[], &large, &[]);
check_difference(&[-1], &large, &[-1]);
check_difference(&[0], &large, &[]);
......@@ -159,43 +159,43 @@ fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
#[test]
fn test_difference_size_hint() {
let s246: BTreeSet<i32> = [2, 4, 6].iter().copied().collect();
let s23456: BTreeSet<i32> = (2..=6).collect();
let s246 = BTreeSet::from([2, 4, 6]);
let s23456 = BTreeSet::from_iter(2..=6);
let mut iter = s246.difference(&s23456);
assert_eq!(iter.size_hint(), (0, Some(3)));
assert_eq!(iter.next(), None);
let s12345: BTreeSet<i32> = (1..=5).collect();
let s12345 = BTreeSet::from_iter(1..=5);
iter = s246.difference(&s12345);
assert_eq!(iter.size_hint(), (0, Some(3)));
assert_eq!(iter.next(), Some(&6));
assert_eq!(iter.size_hint(), (0, Some(0)));
assert_eq!(iter.next(), None);
let s34567: BTreeSet<i32> = (3..=7).collect();
let s34567 = BTreeSet::from_iter(3..=7);
iter = s246.difference(&s34567);
assert_eq!(iter.size_hint(), (0, Some(3)));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.size_hint(), (0, Some(2)));
assert_eq!(iter.next(), None);
let s1: BTreeSet<i32> = (-9..=1).collect();
let s1 = BTreeSet::from_iter(-9..=1);
iter = s246.difference(&s1);
assert_eq!(iter.size_hint(), (3, Some(3)));
let s2: BTreeSet<i32> = (-9..=2).collect();
let s2 = BTreeSet::from_iter(-9..=2);
iter = s246.difference(&s2);
assert_eq!(iter.size_hint(), (2, Some(2)));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.size_hint(), (1, Some(1)));
let s23: BTreeSet<i32> = (2..=3).collect();
let s23 = BTreeSet::from([2, 3]);
iter = s246.difference(&s23);
assert_eq!(iter.size_hint(), (1, Some(3)));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.size_hint(), (1, Some(1)));
let s4: BTreeSet<i32> = (4..=4).collect();
let s4 = BTreeSet::from([4]);
iter = s246.difference(&s4);
assert_eq!(iter.size_hint(), (2, Some(3)));
assert_eq!(iter.next(), Some(&2));
......@@ -204,19 +204,19 @@ fn test_difference_size_hint() {
assert_eq!(iter.size_hint(), (0, Some(0)));
assert_eq!(iter.next(), None);
let s56: BTreeSet<i32> = (5..=6).collect();
let s56 = BTreeSet::from([5, 6]);
iter = s246.difference(&s56);
assert_eq!(iter.size_hint(), (1, Some(3)));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.size_hint(), (0, Some(2)));
let s6: BTreeSet<i32> = (6..=19).collect();
let s6 = BTreeSet::from_iter(6..=19);
iter = s246.difference(&s6);
assert_eq!(iter.size_hint(), (2, Some(2)));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.size_hint(), (1, Some(1)));
let s7: BTreeSet<i32> = (7..=19).collect();
let s7 = BTreeSet::from_iter(7..=19);
iter = s246.difference(&s7);
assert_eq!(iter.size_hint(), (3, Some(3)));
}
......@@ -235,8 +235,8 @@ fn check_symmetric_difference(a: &[i32], b: &[i32], expected: &[i32]) {
#[test]
fn test_symmetric_difference_size_hint() {
let x: BTreeSet<i32> = [2, 4].iter().copied().collect();
let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
let x = BTreeSet::from([2, 4]);
let y = BTreeSet::from([1, 2, 3]);
let mut iter = x.symmetric_difference(&y);
assert_eq!(iter.size_hint(), (0, Some(5)));
assert_eq!(iter.next(), Some(&1));
......@@ -263,8 +263,8 @@ fn check_union(a: &[i32], b: &[i32], expected: &[i32]) {
#[test]
fn test_union_size_hint() {
let x: BTreeSet<i32> = [2, 4].iter().copied().collect();
let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
let x = BTreeSet::from([2, 4]);
let y = BTreeSet::from([1, 2, 3]);
let mut iter = x.union(&y);
assert_eq!(iter.size_hint(), (3, Some(5)));
assert_eq!(iter.next(), Some(&1));
......@@ -276,8 +276,8 @@ fn test_union_size_hint() {
#[test]
// Only tests the simple function definition with respect to intersection
fn test_is_disjoint() {
let one = [1].iter().collect::<BTreeSet<_>>();
let two = [2].iter().collect::<BTreeSet<_>>();
let one = BTreeSet::from([1]);
let two = BTreeSet::from([2]);
assert!(one.is_disjoint(&two));
}
......@@ -285,8 +285,8 @@ fn test_is_disjoint() {
// Also implicitly tests the trivial function definition of is_superset
fn test_is_subset() {
fn is_subset(a: &[i32], b: &[i32]) -> bool {
let set_a = a.iter().collect::<BTreeSet<_>>();
let set_b = b.iter().collect::<BTreeSet<_>>();
let set_a = BTreeSet::from_iter(a.iter());
let set_b = BTreeSet::from_iter(b.iter());
set_a.is_subset(&set_b)
}
......@@ -310,7 +310,7 @@ fn is_subset(a: &[i32], b: &[i32]) -> bool {
return;
}
let large = (0..100).collect::<Vec<_>>();
let large = Vec::from_iter(0..100);
assert_eq!(is_subset(&[], &large), true);
assert_eq!(is_subset(&large, &[]), false);
assert_eq!(is_subset(&[-1], &large), false);
......@@ -321,8 +321,7 @@ fn is_subset(a: &[i32], b: &[i32]) -> bool {
#[test]
fn test_retain() {
let xs = [1, 2, 3, 4, 5, 6];
let mut set: BTreeSet<i32> = xs.iter().cloned().collect();
let mut set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
set.retain(|&k| k % 2 == 0);
assert_eq!(set.len(), 3);
assert!(set.contains(&2));
......@@ -332,8 +331,8 @@ fn test_retain() {
#[test]
fn test_drain_filter() {
let mut x: BTreeSet<_> = [1].iter().copied().collect();
let mut y: BTreeSet<_> = [1].iter().copied().collect();
let mut x = BTreeSet::from([1]);
let mut y = BTreeSet::from([1]);
x.drain_filter(|_| true);
y.drain_filter(|_| false);
......@@ -417,7 +416,7 @@ fn test_zip() {
fn test_from_iter() {
let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let set: BTreeSet<_> = xs.iter().cloned().collect();
let set = BTreeSet::from_iter(xs.iter());
for x in &xs {
assert!(set.contains(x));
......
......@@ -103,17 +103,32 @@ pub fn write_log_result(
exec_time: Option<&TestExecTime>,
) -> io::Result<()> {
self.write_log(|| {
let TestDesc {
name,
#[cfg(not(bootstrap))]
ignore_message,
..
} = test;
format!(
"{} {}",
match *result {
TestResult::TrOk => "ok".to_owned(),
TestResult::TrFailed => "failed".to_owned(),
TestResult::TrFailedMsg(ref msg) => format!("failed: {}", msg),
TestResult::TrIgnored => "ignored".to_owned(),
TestResult::TrIgnored => {
#[cfg(not(bootstrap))]
if let Some(msg) = ignore_message {
format!("ignored, {}", msg)
} else {
"ignored".to_owned()
}
#[cfg(bootstrap)]
"ignored".to_owned()
}
TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
},
test.name,
name,
)
})?;
if let Some(exec_time) = exec_time {
......
......@@ -61,6 +61,8 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
desc: TestDesc {
name: StaticTestName("1"),
ignore: true,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -74,6 +76,8 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
desc: TestDesc {
name: StaticTestName("2"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -95,6 +99,8 @@ fn f() {
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: true,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -117,6 +123,8 @@ fn f() {}
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: true,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -143,6 +151,8 @@ fn f() {
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::Yes,
compile_fail: false,
no_run: false,
......@@ -169,6 +179,8 @@ fn f() {
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::YesWithMessage("error message"),
compile_fail: false,
no_run: false,
......@@ -200,6 +212,8 @@ fn f() {
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::YesWithMessage(expected),
compile_fail: false,
no_run: false,
......@@ -235,6 +249,8 @@ fn f() {
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::YesWithMessage(expected),
compile_fail: false,
no_run: false,
......@@ -262,6 +278,8 @@ fn f() {}
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic,
compile_fail: false,
no_run: false,
......@@ -297,6 +315,8 @@ fn f() {}
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -333,6 +353,8 @@ fn f() {}
desc: TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -373,6 +395,8 @@ fn typed_test_desc(test_type: TestType) -> TestDesc {
TestDesc {
name: StaticTestName("whatever"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -486,6 +510,8 @@ pub fn exclude_should_panic_option() {
desc: TestDesc {
name: StaticTestName("3"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::Yes,
compile_fail: false,
no_run: false,
......@@ -511,6 +537,8 @@ fn tests() -> Vec<TestDescAndFn> {
desc: TestDesc {
name: StaticTestName(name),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -601,6 +629,8 @@ fn testfn() {}
desc: TestDesc {
name: DynTestName((*name).clone()),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -753,6 +783,8 @@ fn f(_: &mut Bencher) {}
let desc = TestDesc {
name: StaticTestName("f"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -776,6 +808,8 @@ fn f(b: &mut Bencher) {
let desc = TestDesc {
name: StaticTestName("f"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -793,6 +827,8 @@ fn should_sort_failures_before_printing_them() {
let test_a = TestDesc {
name: StaticTestName("a"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......@@ -804,6 +840,8 @@ fn should_sort_failures_before_printing_them() {
let test_b = TestDesc {
name: StaticTestName("b"),
ignore: false,
#[cfg(not(bootstrap))]
ignore_message: None,
should_panic: ShouldPanic::No,
compile_fail: false,
no_run: false,
......
......@@ -117,6 +117,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
pub struct TestDesc {
pub name: TestName,
pub ignore: bool,
#[cfg(not(bootstrap))]
pub ignore_message: Option<&'static str>,
pub should_panic: options::ShouldPanic,
pub compile_fail: bool,
pub no_run: bool,
......
......@@ -648,7 +648,7 @@ fn run(self, builder: &Builder<'_>) {
pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
cargo
.arg("--features")
.arg(builder.rustc_features())
.arg(builder.rustc_features(builder.kind))
.arg("--manifest-path")
.arg(builder.src.join("compiler/rustc/Cargo.toml"));
rustc_cargo_env(builder, cargo, target);
......
......@@ -119,6 +119,7 @@
use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed};
use filetime::FileTime;
use crate::builder::Kind;
use crate::config::{LlvmLibunwind, TargetSelection};
use crate::util::{exe, libdir, CiEnv};
......@@ -669,12 +670,12 @@ fn std_features(&self, target: TargetSelection) -> String {
}
/// Gets the space-separated set of activated features for the compiler.
fn rustc_features(&self) -> String {
fn rustc_features(&self, kind: Kind) -> String {
let mut features = String::new();
if self.config.jemalloc {
features.push_str("jemalloc");
}
if self.config.llvm_enabled() {
if self.config.llvm_enabled() || kind == Kind::Check {
features.push_str(" llvm");
}
......
......@@ -946,6 +946,8 @@ fn add_test(&mut self, test: String, config: LangString, line: usize) {
Ignore::None => false,
Ignore::Some(ref ignores) => ignores.iter().any(|s| target_str.contains(s)),
},
#[cfg(not(bootstrap))]
ignore_message: None,
// compiler failures are test failures
should_panic: test::ShouldPanic::No,
compile_fail: config.compile_fail,
......
// Derived from an ICE found in tokio-xmpp during a crater run.
// edition:2021
// compile-flags: -Zdrop-tracking
#![allow(dead_code)]
#[derive(Clone)]
struct InfoResult {
node: Option<std::rc::Rc<String>>
}
struct Agent {
info_result: InfoResult
}
impl Agent {
async fn handle(&mut self) {
let mut info = self.info_result.clone();
info.node = None;
let element = parse_info(info);
let _ = send_element(element).await;
}
}
struct Element {
}
async fn send_element(_: Element) {}
fn parse(_: &[u8]) -> Result<(), ()> {
Ok(())
}
fn parse_info(_: InfoResult) -> Element {
Element { }
}
fn assert_send<T: Send>(_: T) {}
fn main() {
let agent = Agent { info_result: InfoResult { node: None } };
// FIXME: It would be nice for this to work. See #94067.
assert_send(agent.handle());
//~^ cannot be sent between threads safely
}
error: future cannot be sent between threads safely
--> $DIR/drop-track-field-assign-nonsend.rs:43:17
|
LL | assert_send(agent.handle());
| ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
note: future is not `Send` as this value is used across an await
--> $DIR/drop-track-field-assign-nonsend.rs:21:38
|
LL | let mut info = self.info_result.clone();
| -------- has type `InfoResult` which is not `Send`
...
LL | let _ = send_element(element).await;
| ^^^^^^ await occurs here, with `mut info` maybe used later
LL | }
| - `mut info` is later dropped here
note: required by a bound in `assert_send`
--> $DIR/drop-track-field-assign-nonsend.rs:38:19
|
LL | fn assert_send<T: Send>(_: T) {}
| ^^^^ required by this bound in `assert_send`
error: aborting due to previous error
// Derived from an ICE found in tokio-xmpp during a crater run.
// edition:2021
// compile-flags: -Zdrop-tracking
// build-pass
#![allow(dead_code)]
#[derive(Clone)]
struct InfoResult {
node: Option<String>
}
struct Agent {
info_result: InfoResult
}
impl Agent {
async fn handle(&mut self) {
let mut info = self.info_result.clone();
info.node = Some("bar".into());
let element = parse_info(info);
let _ = send_element(element).await;
}
}
struct Element {
}
async fn send_element(_: Element) {}
fn parse(_: &[u8]) -> Result<(), ()> {
Ok(())
}
fn parse_info(_: InfoResult) -> Element {
Element { }
}
fn main() {
let mut agent = Agent {
info_result: InfoResult { node: None }
};
let _ = agent.handle();
}
......@@ -806,6 +806,8 @@ pub fn make_test_description<R: Read>(
cfg: Option<&str>,
) -> test::TestDesc {
let mut ignore = false;
#[cfg(not(bootstrap))]
let ignore_message: Option<String> = None;
let mut should_fail = false;
let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
......@@ -877,6 +879,8 @@ pub fn make_test_description<R: Read>(
test::TestDesc {
name,
ignore,
#[cfg(not(bootstrap))]
ignore_message,
should_panic,
compile_fail: false,
no_run: false,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册