diff options
Diffstat (limited to 'tests')
180 files changed, 2467 insertions, 243 deletions
diff --git a/tests/assembly-llvm/asm/loongarch-type.rs b/tests/assembly-llvm/asm/loongarch-type.rs index c782be19f1d..95d811a6bd0 100644 --- a/tests/assembly-llvm/asm/loongarch-type.rs +++ b/tests/assembly-llvm/asm/loongarch-type.rs @@ -1,8 +1,15 @@ //@ add-core-stubs +//@ revisions: loongarch32 loongarch64 + //@ assembly-output: emit-asm -//@ compile-flags: --target loongarch64-unknown-linux-gnu + +//@[loongarch32] compile-flags: --target loongarch32-unknown-none +//@[loongarch32] needs-llvm-components: loongarch + +//@[loongarch64] compile-flags: --target loongarch64-unknown-none +//@[loongarch64] needs-llvm-components: loongarch + //@ compile-flags: -Zmerge-functions=disabled -//@ needs-llvm-components: loongarch #![feature(no_core, f16)] #![crate_type = "rlib"] @@ -22,7 +29,7 @@ extern "C" { // CHECK-LABEL: sym_fn: // CHECK: #APP // CHECK: pcalau12i $t0, %got_pc_hi20(extern_func) -// CHECK: ld.d $t0, $t0, %got_pc_lo12(extern_func) +// CHECK: ld.{{[wd]}} $t0, $t0, %got_pc_lo12(extern_func) // CHECK: #NO_APP #[no_mangle] pub unsafe fn sym_fn() { @@ -32,7 +39,7 @@ pub unsafe fn sym_fn() { // CHECK-LABEL: sym_static: // CHECK: #APP // CHECK: pcalau12i $t0, %got_pc_hi20(extern_static) -// CHECK: ld.d $t0, $t0, %got_pc_lo12(extern_static) +// CHECK: ld.{{[wd]}} $t0, $t0, %got_pc_lo12(extern_static) // CHECK: #NO_APP #[no_mangle] pub unsafe fn sym_static() { @@ -87,16 +94,18 @@ check!(reg_i32, i32, reg, "move"); // CHECK: #NO_APP check!(reg_f32, f32, reg, "move"); -// CHECK-LABEL: reg_i64: -// CHECK: #APP -// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} -// CHECK: #NO_APP +// loongarch64-LABEL: reg_i64: +// loongarch64: #APP +// loongarch64: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// loongarch64: #NO_APP +#[cfg(loongarch64)] check!(reg_i64, i64, reg, "move"); -// CHECK-LABEL: reg_f64: -// CHECK: #APP -// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} -// CHECK: #NO_APP +// loongarch64-LABEL: reg_f64: +// loongarch64: #APP +// loongarch64: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// loongarch64: #NO_APP +#[cfg(loongarch64)] check!(reg_f64, f64, reg, "move"); // CHECK-LABEL: reg_ptr: @@ -153,16 +162,18 @@ check_reg!(r4_i32, i32, "$r4", "move"); // CHECK: #NO_APP check_reg!(r4_f32, f32, "$r4", "move"); -// CHECK-LABEL: r4_i64: -// CHECK: #APP -// CHECK: move $a0, $a0 -// CHECK: #NO_APP +// loongarch64-LABEL: r4_i64: +// loongarch64: #APP +// loongarch64: move $a0, $a0 +// loongarch64: #NO_APP +#[cfg(loongarch64)] check_reg!(r4_i64, i64, "$r4", "move"); -// CHECK-LABEL: r4_f64: -// CHECK: #APP -// CHECK: move $a0, $a0 -// CHECK: #NO_APP +// loongarch64-LABEL: r4_f64: +// loongarch64: #APP +// loongarch64: move $a0, $a0 +// loongarch64: #NO_APP +#[cfg(loongarch64)] check_reg!(r4_f64, f64, "$r4", "move"); // CHECK-LABEL: r4_ptr: diff --git a/tests/assembly-llvm/x86_64-bigint-helpers.rs b/tests/assembly-llvm/x86_64-bigint-helpers.rs index 58785932bc2..c5efda58fd6 100644 --- a/tests/assembly-llvm/x86_64-bigint-helpers.rs +++ b/tests/assembly-llvm/x86_64-bigint-helpers.rs @@ -2,9 +2,7 @@ //@ assembly-output: emit-asm //@ compile-flags: --crate-type=lib -Copt-level=3 -C target-cpu=x86-64-v4 //@ compile-flags: -C llvm-args=-x86-asm-syntax=intel -//@ revisions: llvm-pre-20 llvm-20 -//@ [llvm-20] min-llvm-version: 20 -//@ [llvm-pre-20] max-llvm-major-version: 19 +//@ min-llvm-version: 20 #![no_std] #![feature(bigint_helper_methods)] @@ -23,16 +21,15 @@ pub unsafe extern "sysv64" fn bigint_chain_carrying_add( n: usize, mut carry: bool, ) -> bool { - // llvm-pre-20: mov [[TEMP:r..]], qword ptr [rsi + 8*[[IND:r..]] + 8] - // llvm-pre-20: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8] - // llvm-pre-20: mov qword ptr [rdi + 8*[[IND]] + 8], [[TEMP]] - // llvm-pre-20: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 16] - // llvm-pre-20: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 16] - // llvm-pre-20: mov qword ptr [rdi + 8*[[IND]] + 16], [[TEMP]] - // llvm-20: adc [[TEMP:r..]], qword ptr [rdx + 8*[[IND:r..]]] - // llvm-20: mov qword ptr [rdi + 8*[[IND]]], [[TEMP]] - // llvm-20: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 8] - // llvm-20: adc [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8] + // Even if we emit A+B, LLVM will sometimes reorder that to B+A, so this + // test doesn't actually check which register is mov vs which is adc. + + // CHECK: mov [[TEMP1:.+]], qword ptr [{{rdx|rsi}} + 8*[[IND:.+]] + 8] + // CHECK: adc [[TEMP1]], qword ptr [{{rdx|rsi}} + 8*[[IND]] + 8] + // CHECK: mov qword ptr [rdi + 8*[[IND]] + 8], [[TEMP1]] + // CHECK: mov [[TEMP2:.+]], qword ptr [{{rdx|rsi}} + 8*[[IND]] + 16] + // CHECK: adc [[TEMP2]], qword ptr [{{rdx|rsi}} + 8*[[IND]] + 16] + // CHECK: mov qword ptr [rdi + 8*[[IND]] + 16], [[TEMP2]] for i in 0..n { (*dest.add(i), carry) = u64::carrying_add(*src1.add(i), *src2.add(i), carry); } diff --git a/tests/codegen-llvm/bigint-helpers.rs b/tests/codegen-llvm/bigint-helpers.rs index 355cccb8150..ec70a3eabed 100644 --- a/tests/codegen-llvm/bigint-helpers.rs +++ b/tests/codegen-llvm/bigint-helpers.rs @@ -3,11 +3,20 @@ #![crate_type = "lib"] #![feature(bigint_helper_methods)] +// Note that there's also an assembly test for this, which is what checks for +// the `ADC` (Add with Carry) instruction on x86 now that the IR we emit uses +// the preferred instruction phrasing instead of the intrinsic. + // CHECK-LABEL: @u32_carrying_add #[no_mangle] pub fn u32_carrying_add(a: u32, b: u32, c: bool) -> (u32, bool) { - // CHECK: @llvm.uadd.with.overflow.i32 - // CHECK: @llvm.uadd.with.overflow.i32 - // CHECK: or disjoint i1 + // CHECK: %[[AB:.+]] = add i32 {{%a, %b|%b, %a}} + // CHECK: %[[O1:.+]] = icmp ult i32 %[[AB]], %a + // CHECK: %[[CEXT:.+]] = zext i1 %c to i32 + // CHECK: %[[ABC:.+]] = add i32 %[[AB]], %[[CEXT]] + // CHECK: %[[O2:.+]] = icmp ult i32 %[[ABC]], %[[AB]] + // CHECK: %[[O:.+]] = or disjoint i1 %[[O1]], %[[O2]] + // CHECK: insertvalue {{.+}}, i32 %[[ABC]], 0 + // CHECK: insertvalue {{.+}}, i1 %[[O]], 1 u32::carrying_add(a, b, c) } diff --git a/tests/codegen-llvm/issues/saturating-sub-index-139759.rs b/tests/codegen-llvm/issues/saturating-sub-index-139759.rs new file mode 100644 index 00000000000..eac2f4d306b --- /dev/null +++ b/tests/codegen-llvm/issues/saturating-sub-index-139759.rs @@ -0,0 +1,19 @@ +// Test that calculating an index with saturating subtraction from an in-bounds +// index doesn't generate another bounds check. + +//@ compile-flags: -Copt-level=3 +//@ min-llvm-version: 21 + +#![crate_type = "lib"] + +// CHECK-LABEL: @bounds_check_is_elided +#[no_mangle] +pub fn bounds_check_is_elided(s: &[i32], index: usize) -> i32 { + // CHECK-NOT: panic_bounds_check + if index < s.len() { + let lower_bound = index.saturating_sub(1); + s[lower_bound] + } else { + -1 + } +} diff --git a/tests/crashes/135646.rs b/tests/crashes/135646.rs deleted file mode 100644 index 841ea5b81b4..00000000000 --- a/tests/crashes/135646.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ known-bug: #135646 -//@ compile-flags: -Zpolonius=next -//@ edition: 2024 - -fn main() { - &{ [1, 2, 3][4] }; -} diff --git a/tests/run-make/raw-dylib-link-ordinal/exporter.def b/tests/run-make/raw-dylib-link-ordinal/exporter.def index 5d87c580a54..0544e9f1803 100644 --- a/tests/run-make/raw-dylib-link-ordinal/exporter.def +++ b/tests/run-make/raw-dylib-link-ordinal/exporter.def @@ -1,5 +1,5 @@ LIBRARY exporter EXPORTS exported_function @13 NONAME - exported_variable @5 NONAME + exported_variable @5 NONAME DATA print_exported_variable @9 NONAME diff --git a/tests/run-make/raw-dylib-link-ordinal/rmake.rs b/tests/run-make/raw-dylib-link-ordinal/rmake.rs index 43274b9765b..b9254b16753 100644 --- a/tests/run-make/raw-dylib-link-ordinal/rmake.rs +++ b/tests/run-make/raw-dylib-link-ordinal/rmake.rs @@ -11,7 +11,7 @@ //@ only-windows -use run_make_support::{cc, diff, is_windows_msvc, run, rustc}; +use run_make_support::{cc, diff, extra_c_flags, is_windows_msvc, run, rustc}; // NOTE: build_native_dynamic lib is not used, as the special `def` files // must be passed to the CC compiler. @@ -24,6 +24,7 @@ fn main() { cc().input("exporter.obj") .arg("exporter.def") .args(&["-link", "-dll", "-noimplib", "-out:exporter.dll"]) + .args(extra_c_flags()) .run(); } else { cc().arg("-v").arg("-c").out_exe("exporter.obj").input("exporter.c").run(); diff --git a/tests/ui-fulldeps/auxiliary/parser.rs b/tests/ui-fulldeps/auxiliary/parser.rs index 8a370512460..6726969350d 100644 --- a/tests/ui-fulldeps/auxiliary/parser.rs +++ b/tests/ui-fulldeps/auxiliary/parser.rs @@ -10,7 +10,6 @@ extern crate rustc_span; use rustc_ast::ast::{AttrKind, Attribute, DUMMY_NODE_ID, Expr}; use rustc_ast::mut_visit::{self, MutVisitor}; use rustc_ast::node_id::NodeId; -use rustc_ast::ptr::P; use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream::{AttrTokenStream, AttrTokenTree, LazyAttrTokenStream}; use rustc_errors::Diag; @@ -19,7 +18,7 @@ use rustc_session::parse::ParseSess; use rustc_span::{AttrId, DUMMY_SP, FileName, Span}; use std::sync::Arc; -pub fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<P<Expr>> { +pub fn parse_expr(psess: &ParseSess, source_code: &str) -> Option<Box<Expr>> { let parser = rustc_parse::unwrap_or_emit_fatal(rustc_parse::new_parser_from_source_str( psess, FileName::anon_source_code(source_code), diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index 8bca20852ad..08ded2aee53 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -35,7 +35,6 @@ extern crate rustc_driver; use parser::parse_expr; use rustc_ast::mut_visit::MutVisitor; -use rustc_ast::ptr::P; use rustc_ast::*; use rustc_ast_pretty::pprust; use rustc_session::parse::ParseSess; @@ -45,11 +44,11 @@ use rustc_span::DUMMY_SP; use thin_vec::{thin_vec, ThinVec}; // Helper functions for building exprs -fn expr(kind: ExprKind) -> P<Expr> { - P(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None }) +fn expr(kind: ExprKind) -> Box<Expr> { + Box::new(Expr { id: DUMMY_NODE_ID, kind, span: DUMMY_SP, attrs: AttrVec::new(), tokens: None }) } -fn make_x() -> P<Expr> { +fn make_x() -> Box<Expr> { let seg = PathSegment::from_ident(Ident::from_str("x")); let path = Path { segments: thin_vec![seg], span: DUMMY_SP, tokens: None }; expr(ExprKind::Path(None, path)) @@ -58,7 +57,7 @@ fn make_x() -> P<Expr> { /// Iterate over exprs of depth up to `depth`. The goal is to explore all "interesting" /// combinations of expression nesting. For example, we explore combinations using `if`, but not /// `while` or `match`, since those should print and parse in much the same way as `if`. -fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { +fn iter_exprs(depth: usize, f: &mut dyn FnMut(Box<Expr>)) { if depth == 0 { f(make_x()); return; @@ -108,7 +107,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { iter_exprs(depth - 1, &mut |e| g(ExprKind::Unary(UnOp::Deref, e))); } 9 => { - let block = P(Block { + let block = Box::new(Block { stmts: ThinVec::new(), id: DUMMY_NODE_ID, rules: BlockCheckMode::Default, @@ -118,7 +117,10 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None))); } 10 => { - let decl = P(FnDecl { inputs: thin_vec![], output: FnRetTy::Default(DUMMY_SP) }); + let decl = Box::new(FnDecl { + inputs: thin_vec![], + output: FnRetTy::Default(DUMMY_SP), + }); iter_exprs(depth - 1, &mut |e| { g(ExprKind::Closure(Box::new(Closure { binder: ClosureBinder::NotPresent, @@ -159,7 +161,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { } 16 => { let path = Path::from_ident(Ident::from_str("S")); - g(ExprKind::Struct(P(StructExpr { + g(ExprKind::Struct(Box::new(StructExpr { qself: None, path, fields: thin_vec![], @@ -170,8 +172,12 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e))); } 18 => { - let pat = - P(Pat { id: DUMMY_NODE_ID, kind: PatKind::Wild, span: DUMMY_SP, tokens: None }); + let pat = Box::new(Pat { + id: DUMMY_NODE_ID, + kind: PatKind::Wild, + span: DUMMY_SP, + tokens: None, + }); iter_exprs(depth - 1, &mut |e| { g(ExprKind::Let(pat.clone(), e, DUMMY_SP, Recovered::No)) }) @@ -204,7 +210,7 @@ impl MutVisitor for AddParens { mut_visit::walk_expr(self, e); let expr = std::mem::replace(e, Expr::dummy()); - e.kind = ExprKind::Paren(P(expr)); + e.kind = ExprKind::Paren(Box::new(expr)); } } diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr new file mode 100644 index 00000000000..8742d4bd82c --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr @@ -0,0 +1,38 @@ +error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:27:18 + | +LL | asm!("", out("$r0") _); + | ^^^^^^^^^^^^ + +error: invalid register `$tp`: reserved for TLS + --> $DIR/bad-reg.rs:29:18 + | +LL | asm!("", out("$tp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:31:18 + | +LL | asm!("", out("$sp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r21`: reserved by the ABI + --> $DIR/bad-reg.rs:33:18 + | +LL | asm!("", out("$r21") _); + | ^^^^^^^^^^^^^ + +error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:35:18 + | +LL | asm!("", out("$fp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:37:18 + | +LL | asm!("", out("$r31") _); + | ^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr new file mode 100644 index 00000000000..e6cb6e40c70 --- /dev/null +++ b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr @@ -0,0 +1,62 @@ +error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:27:18 + | +LL | asm!("", out("$r0") _); + | ^^^^^^^^^^^^ + +error: invalid register `$tp`: reserved for TLS + --> $DIR/bad-reg.rs:29:18 + | +LL | asm!("", out("$tp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:31:18 + | +LL | asm!("", out("$sp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r21`: reserved by the ABI + --> $DIR/bad-reg.rs:33:18 + | +LL | asm!("", out("$r21") _); + | ^^^^^^^^^^^^^ + +error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:35:18 + | +LL | asm!("", out("$fp") _); + | ^^^^^^^^^^^^ + +error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:37:18 + | +LL | asm!("", out("$r31") _); + | ^^^^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:41:26 + | +LL | asm!("/* {} */", in(freg) f); + | ^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:43:26 + | +LL | asm!("/* {} */", out(freg) _); + | ^^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:45:26 + | +LL | asm!("/* {} */", in(freg) d); + | ^^^^^^^^^^ + +error: register class `freg` requires at least one of the following target features: d, f + --> $DIR/bad-reg.rs:47:26 + | +LL | asm!("/* {} */", out(freg) d); + | ^^^^^^^^^^^ + +error: aborting due to 10 previous errors + diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr index 0e544119650..8742d4bd82c 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr @@ -1,35 +1,35 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:22:18 + --> $DIR/bad-reg.rs:27:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:24:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:26:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr index 6d0410dc6a1..e6cb6e40c70 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr @@ -1,59 +1,59 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:22:18 + --> $DIR/bad-reg.rs:27:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:24:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:26:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:36:26 + --> $DIR/bad-reg.rs:41:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:38:26 + --> $DIR/bad-reg.rs:43:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:40:26 + --> $DIR/bad-reg.rs:45:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:42:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs index 685b460bc92..0d3eba07f14 100644 --- a/tests/ui/asm/loongarch/bad-reg.rs +++ b/tests/ui/asm/loongarch/bad-reg.rs @@ -1,6 +1,11 @@ //@ add-core-stubs //@ needs-asm-support -//@ revisions: loongarch64_lp64d loongarch64_lp64s +//@ revisions: loongarch32_ilp32d loongarch32_ilp32s loongarch64_lp64d loongarch64_lp64s +//@ min-llvm-version: 20 +//@[loongarch32_ilp32d] compile-flags: --target loongarch32-unknown-none +//@[loongarch32_ilp32d] needs-llvm-components: loongarch +//@[loongarch32_ilp32s] compile-flags: --target loongarch32-unknown-none-softfloat +//@[loongarch32_ilp32s] needs-llvm-components: loongarch //@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu //@[loongarch64_lp64d] needs-llvm-components: loongarch //@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat @@ -34,12 +39,12 @@ fn f() { asm!("", out("$f0") _); // ok asm!("/* {} */", in(freg) f); - //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f asm!("/* {} */", out(freg) _); - //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f asm!("/* {} */", in(freg) d); - //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f asm!("/* {} */", out(freg) d); - //[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f + //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f } } diff --git a/tests/ui/issues/issue-23442.rs b/tests/ui/associated-types/unioned-keys-with-associated-type-23442.rs index 883c5bb511a..89a2d0177a3 100644 --- a/tests/ui/issues/issue-23442.rs +++ b/tests/ui/associated-types/unioned-keys-with-associated-type-23442.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/23442 //@ check-pass #![allow(dead_code)] use std::marker::PhantomData; diff --git a/tests/ui/async-await/drop-live-upvar-2.may_not_dangle.stderr b/tests/ui/async-await/drop-live-upvar-2.may_not_dangle.stderr new file mode 100644 index 00000000000..34f6ba79246 --- /dev/null +++ b/tests/ui/async-await/drop-live-upvar-2.may_not_dangle.stderr @@ -0,0 +1,18 @@ +error[E0597]: `y` does not live long enough + --> $DIR/drop-live-upvar-2.rs:31:26 + | +LL | let y = (); + | - binding `y` declared here +LL | drop_me = Droppy(&y); + | ^^ borrowed value does not live long enough +... +LL | } + | - `y` dropped here while still borrowed +LL | } + | - borrow might be used here, when `fut` is dropped and runs the destructor for coroutine + | + = note: values in a scope are dropped in the opposite order they are defined + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/async-await/drop-live-upvar-2.rs b/tests/ui/async-await/drop-live-upvar-2.rs new file mode 100644 index 00000000000..605db4c8f76 --- /dev/null +++ b/tests/ui/async-await/drop-live-upvar-2.rs @@ -0,0 +1,37 @@ +//@ revisions: may_dangle may_not_dangle +//@[may_dangle] check-pass +//@ edition: 2018 + +// Ensure that if a coroutine's interior has no drop types then we don't require the upvars to +// be *use-live*, but instead require them to be *drop-live*. In this case, `Droppy<&'?0 ()>` +// does not require that `'?0` is live for drops since the parameter is `#[may_dangle]` in +// the may_dangle revision, but not in the may_not_dangle revision. + +#![feature(dropck_eyepatch)] + +struct Droppy<T>(T); + +#[cfg(may_dangle)] +unsafe impl<#[may_dangle] T> Drop for Droppy<T> { + fn drop(&mut self) { + // This does not use `T` of course. + } +} + +#[cfg(may_not_dangle)] +impl<T> Drop for Droppy<T> { + fn drop(&mut self) {} +} + +fn main() { + let drop_me; + let fut; + { + let y = (); + drop_me = Droppy(&y); + //[may_not_dangle]~^ ERROR `y` does not live long enough + fut = async { + std::mem::drop(drop_me); + }; + } +} diff --git a/tests/ui/async-await/drop-live-upvar.rs b/tests/ui/async-await/drop-live-upvar.rs new file mode 100644 index 00000000000..8e881f729b9 --- /dev/null +++ b/tests/ui/async-await/drop-live-upvar.rs @@ -0,0 +1,23 @@ +//@ edition: 2018 +// Regression test for <https://github.com/rust-lang/rust/issues/144155>. + +struct NeedsDrop<'a>(&'a Vec<i32>); + +async fn await_point() {} + +impl Drop for NeedsDrop<'_> { + fn drop(&mut self) {} +} + +fn foo() { + let v = vec![1, 2, 3]; + let x = NeedsDrop(&v); + let c = async { + std::future::ready(()).await; + drop(x); + }; + drop(v); + //~^ ERROR cannot move out of `v` because it is borrowed +} + +fn main() {} diff --git a/tests/ui/async-await/drop-live-upvar.stderr b/tests/ui/async-await/drop-live-upvar.stderr new file mode 100644 index 00000000000..f804484536b --- /dev/null +++ b/tests/ui/async-await/drop-live-upvar.stderr @@ -0,0 +1,22 @@ +error[E0505]: cannot move out of `v` because it is borrowed + --> $DIR/drop-live-upvar.rs:19:10 + | +LL | let v = vec![1, 2, 3]; + | - binding `v` declared here +LL | let x = NeedsDrop(&v); + | -- borrow of `v` occurs here +... +LL | drop(v); + | ^ move out of `v` occurs here +LL | +LL | } + | - borrow might be used here, when `c` is dropped and runs the destructor for coroutine + | +help: consider cloning the value if the performance cost is acceptable + | +LL | let x = NeedsDrop(&v.clone()); + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0505`. diff --git a/tests/ui/async-await/recursive-async-auto-trait-overflow.rs b/tests/ui/async-await/recursive-async-auto-trait-overflow.rs new file mode 100644 index 00000000000..716600ce472 --- /dev/null +++ b/tests/ui/async-await/recursive-async-auto-trait-overflow.rs @@ -0,0 +1,14 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/145151>. + +//@ edition: 2024 +//@ check-pass + +async fn process<'a>() { + Box::pin(process()).await; +} + +fn require_send(_: impl Send) {} + +fn main() { + require_send(process()); +} diff --git a/tests/ui/attributes/lint_on_root.stderr b/tests/ui/attributes/lint_on_root.stderr index aaa46e6f54b..aa0645b6194 100644 --- a/tests/ui/attributes/lint_on_root.stderr +++ b/tests/ui/attributes/lint_on_root.stderr @@ -10,3 +10,14 @@ LL | #![inline = ""] error: aborting due to 1 previous error +Future incompatibility report: Future breakage diagnostic: +error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` + --> $DIR/lint_on_root.rs:3:1 + | +LL | #![inline = ""] + | ^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index e8ae4715398..dd9dd3a6ce7 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -660,3 +660,69 @@ error: aborting due to 74 previous errors; 3 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. +Future incompatibility report: Future breakage diagnostic: +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` + --> $DIR/malformed-attrs.rs:40:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` + --> $DIR/malformed-attrs.rs:73:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + --> $DIR/malformed-attrs.rs:80:1 + | +LL | #[link] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` + --> $DIR/malformed-attrs.rs:50:1 + | +LL | #[inline = 5] + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` + --> $DIR/malformed-attrs.rs:91:1 + | +LL | #[ignore()] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` + --> $DIR/malformed-attrs.rs:220:1 + | +LL | #[ignore = 1] + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + diff --git a/tests/ui/issues/issue-91489.rs b/tests/ui/autoref-autoderef/auto-deref-on-cow-regression-91489.rs index 0566302c481..929e98ad719 100644 --- a/tests/ui/issues/issue-91489.rs +++ b/tests/ui/autoref-autoderef/auto-deref-on-cow-regression-91489.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/91489 //@ check-pass // regression test for #91489 diff --git a/tests/ui/issues/issue-9725.rs b/tests/ui/binding/struct-destructuring-repeated-bindings-9725.rs index 360effbd119..6b0b8e37b8c 100644 --- a/tests/ui/issues/issue-9725.rs +++ b/tests/ui/binding/struct-destructuring-repeated-bindings-9725.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9725 struct A { foo: isize } fn main() { diff --git a/tests/ui/issues/issue-9725.stderr b/tests/ui/binding/struct-destructuring-repeated-bindings-9725.stderr index 687e0cc0f3e..f4d19bed419 100644 --- a/tests/ui/issues/issue-9725.stderr +++ b/tests/ui/binding/struct-destructuring-repeated-bindings-9725.stderr @@ -1,11 +1,11 @@ error[E0416]: identifier `foo` is bound more than once in the same pattern - --> $DIR/issue-9725.rs:4:18 + --> $DIR/struct-destructuring-repeated-bindings-9725.rs:5:18 | LL | let A { foo, foo } = A { foo: 3 }; | ^^^ used in a pattern more than once error[E0025]: field `foo` bound multiple times in the pattern - --> $DIR/issue-9725.rs:4:18 + --> $DIR/struct-destructuring-repeated-bindings-9725.rs:5:18 | LL | let A { foo, foo } = A { foo: 3 }; | --- ^^^ multiple uses of `foo` in pattern diff --git a/tests/ui/issues/issue-15783.rs b/tests/ui/borrowck/array-slice-coercion-mismatch-15783.rs index ef948a1a88c..3322ed71c60 100644 --- a/tests/ui/issues/issue-15783.rs +++ b/tests/ui/borrowck/array-slice-coercion-mismatch-15783.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15783 + //@ dont-require-annotations: NOTE pub fn foo(params: Option<&[&str]>) -> usize { diff --git a/tests/ui/issues/issue-15783.stderr b/tests/ui/borrowck/array-slice-coercion-mismatch-15783.stderr index c9c9a723a86..050eb4baa41 100644 --- a/tests/ui/issues/issue-15783.stderr +++ b/tests/ui/borrowck/array-slice-coercion-mismatch-15783.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-15783.rs:10:19 + --> $DIR/array-slice-coercion-mismatch-15783.rs:12:19 | LL | let msg = foo(x); | --- ^ expected `Option<&[&str]>`, found `Option<&[&str; 1]>` @@ -9,7 +9,7 @@ LL | let msg = foo(x); = note: expected enum `Option<&[&str]>` found enum `Option<&[&str; 1]>` note: function defined here - --> $DIR/issue-15783.rs:3:8 + --> $DIR/array-slice-coercion-mismatch-15783.rs:5:8 | LL | pub fn foo(params: Option<&[&str]>) -> usize { | ^^^ ----------------------- diff --git a/tests/ui/borrowck/borrowck-in-static.stderr b/tests/ui/borrowck/borrowck-in-static.stderr index 9bcf64dd62e..d85f6f5fdd5 100644 --- a/tests/ui/borrowck/borrowck-in-static.stderr +++ b/tests/ui/borrowck/borrowck-in-static.stderr @@ -10,6 +10,7 @@ LL | Box::new(|| x) | | | captured by this `Fn` closure | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: consider cloning the value if the performance cost is acceptable | LL | Box::new(|| x.clone()) diff --git a/tests/ui/borrowck/borrowck-move-by-capture.stderr b/tests/ui/borrowck/borrowck-move-by-capture.stderr index 732af1593d6..e9e05440766 100644 --- a/tests/ui/borrowck/borrowck-move-by-capture.stderr +++ b/tests/ui/borrowck/borrowck-move-by-capture.stderr @@ -12,6 +12,11 @@ LL | let _h = to_fn_once(move || -> isize { *bar }); | | | `bar` is moved here | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/borrowck-move-by-capture.rs:3:37 + | +LL | fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f } + | ^^^^^^^^ help: consider cloning the value before moving it into the closure | LL ~ let value = bar.clone(); diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index af65deb16dc..ef022808886 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -13,6 +13,11 @@ LL | LL | self.b; | ^^^^^^ `self.b` is moved here | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/issue-103624.rs:7:36 + | +LL | async fn spawn_blocking<T>(f: impl (Fn() -> T) + Send + Sync + 'static) -> T { + | ^^^^^^^^^^^ note: if `StructB` implemented `Clone`, you could clone the value --> $DIR/issue-103624.rs:23:1 | diff --git a/tests/ui/borrowck/issue-87456-point-to-closure.stderr b/tests/ui/borrowck/issue-87456-point-to-closure.stderr index a0c7cac2add..043e336cd86 100644 --- a/tests/ui/borrowck/issue-87456-point-to-closure.stderr +++ b/tests/ui/borrowck/issue-87456-point-to-closure.stderr @@ -10,6 +10,11 @@ LL | LL | let _foo: String = val; | ^^^ move occurs because `val` has type `String`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/issue-87456-point-to-closure.rs:3:24 + | +LL | fn take_mut(_val: impl FnMut()) {} + | ^^^^^^^ help: consider borrowing here | LL | let _foo: String = &val; diff --git a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr index 177e9c8d248..d3333041310 100644 --- a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr +++ b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr @@ -10,6 +10,11 @@ LL | y.into_iter(); | | | move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:5:28 + | +LL | fn call<F>(f: F) where F : Fn() { + | ^^^^ note: `into_iter` takes ownership of the receiver `self`, which moves `y` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL help: you can `clone` the value and consume it, but this might not be your desired behavior diff --git a/tests/ui/issues/issue-9942.rs b/tests/ui/cast/constant-expression-cast-9942.rs index 6332d9b3e08..d0a6f27b7e3 100644 --- a/tests/ui/issues/issue-9942.rs +++ b/tests/ui/cast/constant-expression-cast-9942.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9942 //@ run-pass pub fn main() { diff --git a/tests/ui/issues/issue-9129.rs b/tests/ui/closures/closure-type-inference-in-context-9129.rs index 3856cd133e8..53ee8faab85 100644 --- a/tests/ui/issues/issue-9129.rs +++ b/tests/ui/closures/closure-type-inference-in-context-9129.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9129 //@ run-pass #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/issue-16256.rs b/tests/ui/closures/unused-closure-ice-16256.rs index 1024e4511d6..fd569dd8a0a 100644 --- a/tests/ui/issues/issue-16256.rs +++ b/tests/ui/closures/unused-closure-ice-16256.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16256 + //@ run-pass fn main() { diff --git a/tests/ui/issues/issue-16256.stderr b/tests/ui/closures/unused-closure-ice-16256.stderr index 75c3ec1bd1c..9df433add5d 100644 --- a/tests/ui/issues/issue-16256.stderr +++ b/tests/ui/closures/unused-closure-ice-16256.stderr @@ -1,5 +1,5 @@ warning: unused closure that must be used - --> $DIR/issue-16256.rs:5:5 + --> $DIR/unused-closure-ice-16256.rs:7:5 | LL | |c: u8| buf.push(c); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-15793.rs b/tests/ui/codegen/nested-enum-match-optimization-15793.rs index af92e9dfa4c..420e3ad82b2 100644 --- a/tests/ui/issues/issue-15793.rs +++ b/tests/ui/codegen/nested-enum-match-optimization-15793.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15793 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-9951.rs b/tests/ui/coercion/trait-object-coercion-distribution-9951.rs index 2cd7cd4f430..526d6561510 100644 --- a/tests/ui/issues/issue-9951.rs +++ b/tests/ui/coercion/trait-object-coercion-distribution-9951.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9951 //@ run-pass #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-9951.stderr b/tests/ui/coercion/trait-object-coercion-distribution-9951.stderr index 62ed9f3e0cc..0c672aa9b33 100644 --- a/tests/ui/issues/issue-9951.stderr +++ b/tests/ui/coercion/trait-object-coercion-distribution-9951.stderr @@ -1,5 +1,5 @@ warning: method `noop` is never used - --> $DIR/issue-9951.rs:6:6 + --> $DIR/trait-object-coercion-distribution-9951.rs:7:6 | LL | trait Bar { | --- method in this trait diff --git a/tests/ui/issues/issue-98299.rs b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs index ba63d963475..49c88856bc9 100644 --- a/tests/ui/issues/issue-98299.rs +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/98299 use std::convert::TryFrom; pub fn test_usage(p: ()) { diff --git a/tests/ui/issues/issue-98299.stderr b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr index b645267e3b9..1557b83b00e 100644 --- a/tests/ui/issues/issue-98299.stderr +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr @@ -1,5 +1,5 @@ error[E0284]: type annotations needed for `SmallCString<_>` - --> $DIR/issue-98299.rs:4:36 + --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); | ------------ ^^^^ @@ -7,7 +7,7 @@ LL | SmallCString::try_from(p).map(|cstr| cstr); | type must be known at this point | note: required by a const generic parameter in `SmallCString` - --> $DIR/issue-98299.rs:10:25 + --> $DIR/try-from-with-const-genericsrs-98299.rs:11:25 | LL | pub struct SmallCString<const N: usize> {} | ^^^^^^^^^^^^^^ required by this const generic parameter in `SmallCString` @@ -17,7 +17,7 @@ LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); | +++++++++++++++++ error[E0284]: type annotations needed for `SmallCString<_>` - --> $DIR/issue-98299.rs:4:36 + --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); | ------------ ^^^^ @@ -25,7 +25,7 @@ LL | SmallCString::try_from(p).map(|cstr| cstr); | type must be known at this point | note: required for `SmallCString<_>` to implement `TryFrom<()>` - --> $DIR/issue-98299.rs:12:22 + --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 | LL | impl<const N: usize> TryFrom<()> for SmallCString<N> { | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | SmallCString::try_from(p).map(|cstr: SmallCString<N>| cstr); | +++++++++++++++++ error[E0284]: type annotations needed for `SmallCString<_>` - --> $DIR/issue-98299.rs:4:36 + --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); | ------------------------- ^^^^ @@ -45,7 +45,7 @@ LL | SmallCString::try_from(p).map(|cstr| cstr); | type must be known at this point | note: required for `SmallCString<_>` to implement `TryFrom<()>` - --> $DIR/issue-98299.rs:12:22 + --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 | LL | impl<const N: usize> TryFrom<()> for SmallCString<N> { | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/auxiliary/issue-9155.rs b/tests/ui/cross-crate/auxiliary/aux-9155.rs index 049a96a655a..049a96a655a 100644 --- a/tests/ui/issues/auxiliary/issue-9155.rs +++ b/tests/ui/cross-crate/auxiliary/aux-9155.rs diff --git a/tests/ui/issues/auxiliary/issue-9906.rs b/tests/ui/cross-crate/auxiliary/aux-9906.rs index 8a3eea790a2..8a3eea790a2 100644 --- a/tests/ui/issues/auxiliary/issue-9906.rs +++ b/tests/ui/cross-crate/auxiliary/aux-9906.rs diff --git a/tests/ui/cross-crate/generic-newtypes-cross-crate-usage-9155.rs b/tests/ui/cross-crate/generic-newtypes-cross-crate-usage-9155.rs new file mode 100644 index 00000000000..35286615980 --- /dev/null +++ b/tests/ui/cross-crate/generic-newtypes-cross-crate-usage-9155.rs @@ -0,0 +1,11 @@ +// https://github.com/rust-lang/rust/issues/9155 +//@ run-pass +//@ aux-build:aux-9155.rs + +extern crate aux_9155; + +struct Baz; + +pub fn main() { + aux_9155::Foo::new(Baz); +} diff --git a/tests/ui/cross-crate/reexported-structs-impls-link-error-9906.rs b/tests/ui/cross-crate/reexported-structs-impls-link-error-9906.rs new file mode 100644 index 00000000000..b49951bd1f9 --- /dev/null +++ b/tests/ui/cross-crate/reexported-structs-impls-link-error-9906.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/9906 +//@ run-pass +//@ aux-build:aux-9906.rs + +extern crate aux_9906 as testmod; + +pub fn main() { + testmod::foo(); + testmod::FooBar::new(1); +} diff --git a/tests/ui/issues/issue-22992.rs b/tests/ui/deref/dereferenceable-type-behavior-22992.rs index 3bc15cc948a..19fc2e7eb0b 100644 --- a/tests/ui/issues/issue-22992.rs +++ b/tests/ui/deref/dereferenceable-type-behavior-22992.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/22992 //@ run-pass struct X { val: i32 } @@ -6,7 +7,6 @@ impl std::ops::Deref for X { fn deref(&self) -> &i32 { &self.val } } - trait M { fn m(self); } impl M for i32 { fn m(self) { println!("i32::m()"); } } impl M for X { fn m(self) { println!("X::m()"); } } diff --git a/tests/ui/issues/issue-15523-big.rs b/tests/ui/derives/derive-partial-ord-discriminant-64bit.rs index 7214a4fb1d5..5b6bf6fbf1f 100644 --- a/tests/ui/issues/issue-15523-big.rs +++ b/tests/ui/derives/derive-partial-ord-discriminant-64bit.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15523 + //@ run-pass // Issue 15523: derive(PartialOrd) should use the provided // discriminant values for the derived ordering. @@ -28,7 +30,6 @@ fn main() { assert!(Eu64::Pos2 < Eu64::PosMax); assert!(Eu64::Pos1 < Eu64::PosMax); - assert!(Ei64::Pos2 > Ei64::Pos1); assert!(Ei64::Pos2 > Ei64::Neg1); assert!(Ei64::Pos1 > Ei64::Neg1); diff --git a/tests/ui/issues/issue-15523.rs b/tests/ui/derives/derive-partial-ord-discriminant.rs index 9fc2e51c6ab..28f325ec966 100644 --- a/tests/ui/issues/issue-15523.rs +++ b/tests/ui/derives/derive-partial-ord-discriminant.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15523 + //@ run-pass // Issue 15523: derive(PartialOrd) should use the provided // discriminant values for the derived ordering. diff --git a/tests/ui/drop/dropck-normalize-errors.stderr b/tests/ui/drop/dropck-normalize-errors.nll.stderr index 2bb5909c6b2..b008daa51a3 100644 --- a/tests/ui/drop/dropck-normalize-errors.stderr +++ b/tests/ui/drop/dropck-normalize-errors.nll.stderr @@ -1,44 +1,44 @@ error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>` - --> $DIR/dropck-normalize-errors.rs:15:28 + --> $DIR/dropck-normalize-errors.rs:19:28 | LL | fn make_a_decoder<'a>() -> ADecoder<'a> { | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | help: this trait has no implementations, consider adding one - --> $DIR/dropck-normalize-errors.rs:7:1 + --> $DIR/dropck-normalize-errors.rs:11:1 | LL | trait NonImplementedTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: required because it appears within the type `BDecoder` - --> $DIR/dropck-normalize-errors.rs:26:12 + --> $DIR/dropck-normalize-errors.rs:30:12 | LL | pub struct BDecoder { | ^^^^^^^^ note: required because it appears within the type `ADecoder<'a>` - --> $DIR/dropck-normalize-errors.rs:12:12 + --> $DIR/dropck-normalize-errors.rs:16:12 | LL | pub struct ADecoder<'a> { | ^^^^^^^^ = note: the return type of a function must have a statically known size error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder` - --> $DIR/dropck-normalize-errors.rs:23:20 + --> $DIR/dropck-normalize-errors.rs:27:20 | LL | type Decoder = BDecoder; | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | help: this trait has no implementations, consider adding one - --> $DIR/dropck-normalize-errors.rs:7:1 + --> $DIR/dropck-normalize-errors.rs:11:1 | LL | trait NonImplementedTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: required because it appears within the type `BDecoder` - --> $DIR/dropck-normalize-errors.rs:26:12 + --> $DIR/dropck-normalize-errors.rs:30:12 | LL | pub struct BDecoder { | ^^^^^^^^ note: required by a bound in `Decode::Decoder` - --> $DIR/dropck-normalize-errors.rs:4:5 + --> $DIR/dropck-normalize-errors.rs:8:5 | LL | type Decoder; | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder` @@ -48,25 +48,25 @@ LL | type Decoder: ?Sized; | ++++++++ error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied - --> $DIR/dropck-normalize-errors.rs:27:22 + --> $DIR/dropck-normalize-errors.rs:31:22 | LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | help: this trait has no implementations, consider adding one - --> $DIR/dropck-normalize-errors.rs:7:1 + --> $DIR/dropck-normalize-errors.rs:11:1 | LL | trait NonImplementedTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied - --> $DIR/dropck-normalize-errors.rs:15:28 + --> $DIR/dropck-normalize-errors.rs:19:28 | LL | fn make_a_decoder<'a>() -> ADecoder<'a> { | ^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` | help: this trait has no implementations, consider adding one - --> $DIR/dropck-normalize-errors.rs:7:1 + --> $DIR/dropck-normalize-errors.rs:11:1 | LL | trait NonImplementedTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/drop/dropck-normalize-errors.polonius.stderr b/tests/ui/drop/dropck-normalize-errors.polonius.stderr new file mode 100644 index 00000000000..f8674b8e34a --- /dev/null +++ b/tests/ui/drop/dropck-normalize-errors.polonius.stderr @@ -0,0 +1,64 @@ +error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>` + --> $DIR/dropck-normalize-errors.rs:19:28 + | +LL | fn make_a_decoder<'a>() -> ADecoder<'a> { + | ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` + | +help: this trait has no implementations, consider adding one + --> $DIR/dropck-normalize-errors.rs:11:1 + | +LL | trait NonImplementedTrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required because it appears within the type `BDecoder` + --> $DIR/dropck-normalize-errors.rs:30:12 + | +LL | pub struct BDecoder { + | ^^^^^^^^ +note: required because it appears within the type `ADecoder<'a>` + --> $DIR/dropck-normalize-errors.rs:16:12 + | +LL | pub struct ADecoder<'a> { + | ^^^^^^^^ + = note: the return type of a function must have a statically known size + +error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder` + --> $DIR/dropck-normalize-errors.rs:27:20 + | +LL | type Decoder = BDecoder; + | ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` + | +help: this trait has no implementations, consider adding one + --> $DIR/dropck-normalize-errors.rs:11:1 + | +LL | trait NonImplementedTrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required because it appears within the type `BDecoder` + --> $DIR/dropck-normalize-errors.rs:30:12 + | +LL | pub struct BDecoder { + | ^^^^^^^^ +note: required by a bound in `Decode::Decoder` + --> $DIR/dropck-normalize-errors.rs:8:5 + | +LL | type Decoder; + | ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder` +help: consider relaxing the implicit `Sized` restriction + | +LL | type Decoder: ?Sized; + | ++++++++ + +error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied + --> $DIR/dropck-normalize-errors.rs:31:22 + | +LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct` + | +help: this trait has no implementations, consider adding one + --> $DIR/dropck-normalize-errors.rs:11:1 + | +LL | trait NonImplementedTrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/drop/dropck-normalize-errors.rs b/tests/ui/drop/dropck-normalize-errors.rs index 793122bd33d..2ade63f27c5 100644 --- a/tests/ui/drop/dropck-normalize-errors.rs +++ b/tests/ui/drop/dropck-normalize-errors.rs @@ -1,5 +1,9 @@ // Test that we don't ICE when computing the drop types for +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius +//@ [polonius] compile-flags: -Zpolonius=next + trait Decode<'a> { type Decoder; } @@ -14,7 +18,7 @@ pub struct ADecoder<'a> { } fn make_a_decoder<'a>() -> ADecoder<'a> { //~^ ERROR the trait bound - //~| ERROR the trait bound + //[nll]~| ERROR the trait bound panic!() } diff --git a/tests/ui/issues/issue-15063.rs b/tests/ui/drop/enum-drop-impl-15063.rs index 969dbe5fad2..a8198abafa0 100644 --- a/tests/ui/issues/issue-15063.rs +++ b/tests/ui/drop/enum-drop-impl-15063.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15063 + //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-15858.rs b/tests/ui/drop/generic-drop-trait-bound-15858.rs index 27887d49e3e..682604d17d8 100644 --- a/tests/ui/issues/issue-15858.rs +++ b/tests/ui/drop/generic-drop-trait-bound-15858.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15858 + //@ run-pass // FIXME(static_mut_refs): this could use an atomic #![allow(static_mut_refs)] diff --git a/tests/ui/issues/issue-15858.stderr b/tests/ui/drop/generic-drop-trait-bound-15858.stderr index 0c082cc0862..86cd6cb6026 100644 --- a/tests/ui/issues/issue-15858.stderr +++ b/tests/ui/drop/generic-drop-trait-bound-15858.stderr @@ -1,5 +1,5 @@ warning: method `do_something` is never used - --> $DIR/issue-15858.rs:7:8 + --> $DIR/generic-drop-trait-bound-15858.rs:9:8 | LL | trait Bar { | --- method in this trait diff --git a/tests/ui/issues/issue-25549-multiple-drop.rs b/tests/ui/drop/multiple-drop-safe-code-25549.rs index 1eec15a4aa2..dcf7a3fc79c 100644 --- a/tests/ui/issues/issue-25549-multiple-drop.rs +++ b/tests/ui/drop/multiple-drop-safe-code-25549.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/25549 //@ run-pass #![allow(unused_variables)] struct Foo<'r>(&'r mut i32); diff --git a/tests/ui/issues/issue-15763.rs b/tests/ui/drop/nested-return-drop-order.rs index 0ebadd80541..67ab52e6250 100644 --- a/tests/ui/issues/issue-15763.rs +++ b/tests/ui/drop/nested-return-drop-order.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15763 + //@ run-pass #![allow(unreachable_code)] diff --git a/tests/ui/drop/same-alloca-reassigned-match-binding-16151.rs b/tests/ui/drop/same-alloca-reassigned-match-binding-16151.rs new file mode 100644 index 00000000000..ecc862ec7be --- /dev/null +++ b/tests/ui/drop/same-alloca-reassigned-match-binding-16151.rs @@ -0,0 +1,34 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16151 + +//@ run-pass + +// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint +#![allow(static_mut_refs)] + +use std::mem; + +static mut DROP_COUNT: usize = 0; + +struct Fragment; + +impl Drop for Fragment { + fn drop(&mut self) { + unsafe { + DROP_COUNT += 1; + } + } +} + +fn main() { + { + let mut fragments = vec![Fragment, Fragment, Fragment]; + let _new_fragments: Vec<Fragment> = mem::replace(&mut fragments, vec![]) + .into_iter() + .skip_while(|_fragment| { + true + }).collect(); + } + unsafe { + assert_eq!(DROP_COUNT, 3); + } +} diff --git a/tests/ui/issues/issue-9243.rs b/tests/ui/drop/static-variable-with-drop-trait-9243.rs index 34ae944d1d8..0ae32c983e9 100644 --- a/tests/ui/issues/issue-9243.rs +++ b/tests/ui/drop/static-variable-with-drop-trait-9243.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9243 //@ build-pass #![allow(dead_code)] // Regression test for issue 9243 diff --git a/tests/ui/issues/issue-16492.rs b/tests/ui/drop/struct-field-drop-order.rs index cfdba5fda35..80e3ea616a5 100644 --- a/tests/ui/issues/issue-16492.rs +++ b/tests/ui/drop/struct-field-drop-order.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16492 + //@ run-pass #![allow(non_snake_case)] diff --git a/tests/ui/issues/issue-53333.rs b/tests/ui/editions/edition-specific-identifier-shadowing-53333.rs index 468b7d8075f..dd973bb8439 100644 --- a/tests/ui/issues/issue-53333.rs +++ b/tests/ui/editions/edition-specific-identifier-shadowing-53333.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/53333 //@ run-pass #![allow(unused_imports)] //@ edition:2018 diff --git a/tests/ui/issues/issue-9837.rs b/tests/ui/enum-discriminant/enum-discriminant-const-eval-truncation-9837.rs index 33152a5d077..8768d81b93f 100644 --- a/tests/ui/issues/issue-9837.rs +++ b/tests/ui/enum-discriminant/enum-discriminant-const-eval-truncation-9837.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9837 //@ run-pass const C1: i32 = 0x12345678; const C2: isize = C1 as i16 as isize; diff --git a/tests/ui/issues/issue-9814.rs b/tests/ui/enum/single-variant-enum-deref-error-9814.rs index a87478e221b..f10d665299c 100644 --- a/tests/ui/issues/issue-9814.rs +++ b/tests/ui/enum/single-variant-enum-deref-error-9814.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9814 // Verify that single-variant enums can't be de-referenced // Regression test for issue #9814 diff --git a/tests/ui/issues/issue-9814.stderr b/tests/ui/enum/single-variant-enum-deref-error-9814.stderr index fa23fb7c176..5e069f4c21d 100644 --- a/tests/ui/issues/issue-9814.stderr +++ b/tests/ui/enum/single-variant-enum-deref-error-9814.stderr @@ -1,5 +1,5 @@ error[E0614]: type `Foo` cannot be dereferenced - --> $DIR/issue-9814.rs:7:13 + --> $DIR/single-variant-enum-deref-error-9814.rs:8:13 | LL | let _ = *Foo::Bar(2); | ^^^^^^^^^^^^ can't be dereferenced diff --git a/tests/ui/issues/issue-3037.rs b/tests/ui/enum/zero-variant-enum-pattern-matching-3037.rs index 933b450ac8e..7a7abb1c67c 100644 --- a/tests/ui/issues/issue-3037.rs +++ b/tests/ui/enum/zero-variant-enum-pattern-matching-3037.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/3037 //@ run-pass #![allow(dead_code)] #![allow(non_camel_case_types)] diff --git a/tests/ui/issues/issue-16441.rs b/tests/ui/extern/empty-struct-extern-fn-16441.rs index 58cfb389297..82f2eee611d 100644 --- a/tests/ui/issues/issue-16441.rs +++ b/tests/ui/extern/empty-struct-extern-fn-16441.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16441 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 4cba54bf67c..324f7e9fd8a 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -318,3 +318,14 @@ error: aborting due to 38 previous errors Some errors have detailed explanations: E0517, E0518, E0658. For more information about an error, try `rustc --explain E0517`. +Future incompatibility report: Future breakage diagnostic: +error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + | +LL | #[inline = "2100"] fn f() { } + | ^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + diff --git a/tests/ui/issues/issue-15094.rs b/tests/ui/fn/fn-traits-call-once-signature-15094.rs index 408ab82eb8c..f550bafe43d 100644 --- a/tests/ui/issues/issue-15094.rs +++ b/tests/ui/fn/fn-traits-call-once-signature-15094.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15094 + #![feature(fn_traits, unboxed_closures)] use std::{fmt, ops}; diff --git a/tests/ui/issues/issue-15094.stderr b/tests/ui/fn/fn-traits-call-once-signature-15094.stderr index 8e0fc8f1770..bb1d336e848 100644 --- a/tests/ui/issues/issue-15094.stderr +++ b/tests/ui/fn/fn-traits-call-once-signature-15094.stderr @@ -1,5 +1,5 @@ error[E0053]: method `call_once` has an incompatible type for trait - --> $DIR/issue-15094.rs:11:5 + --> $DIR/fn-traits-call-once-signature-15094.rs:13:5 | LL | fn call_once(self, _args: ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "rust-call" fn, found "Rust" fn diff --git a/tests/ui/issues/auxiliary/issue-9968.rs b/tests/ui/imports/auxiliary/aux-9968.rs index 8d795b59ea8..8d795b59ea8 100644 --- a/tests/ui/issues/auxiliary/issue-9968.rs +++ b/tests/ui/imports/auxiliary/aux-9968.rs diff --git a/tests/ui/issues/issue-15774.rs b/tests/ui/imports/enum-variant-import-path-15774.rs index dadd59cc077..583fe4da179 100644 --- a/tests/ui/issues/issue-15774.rs +++ b/tests/ui/imports/enum-variant-import-path-15774.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15774 + //@ edition: 2015 //@ run-pass diff --git a/tests/ui/imports/pub-use-link-errors-9968.rs b/tests/ui/imports/pub-use-link-errors-9968.rs new file mode 100644 index 00000000000..517a0049ce0 --- /dev/null +++ b/tests/ui/imports/pub-use-link-errors-9968.rs @@ -0,0 +1,12 @@ +// https://github.com/rust-lang/rust/issues/9968 +//@ run-pass +//@ aux-build:aux-9968.rs + +extern crate aux_9968 as lib; + +use lib::{Trait, Struct}; + +pub fn main() +{ + Struct::init().test(); +} diff --git a/tests/ui/inference/iterator-sum-array-15673.rs b/tests/ui/inference/iterator-sum-array-15673.rs new file mode 100644 index 00000000000..c3d94415aff --- /dev/null +++ b/tests/ui/inference/iterator-sum-array-15673.rs @@ -0,0 +1,11 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15673 + +//@ run-pass +#![allow(stable_features)] + +#![feature(iter_arith)] + +fn main() { + let x: [u64; 3] = [1, 2, 3]; + assert_eq!(6, (0..3).map(|i| x[i]).sum::<u64>()); +} diff --git a/tests/ui/issues/issue-15965.rs b/tests/ui/inference/return-block-type-inference-15965.rs index eef4900d432..50753e309e8 100644 --- a/tests/ui/issues/issue-15965.rs +++ b/tests/ui/inference/return-block-type-inference-15965.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15965 + fn main() { return { return () } diff --git a/tests/ui/issues/issue-15965.stderr b/tests/ui/inference/return-block-type-inference-15965.stderr index 14727e74334..fc4f2defe7f 100644 --- a/tests/ui/issues/issue-15965.stderr +++ b/tests/ui/inference/return-block-type-inference-15965.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/issue-15965.rs:3:9 + --> $DIR/return-block-type-inference-15965.rs:5:9 | LL | / { return () } LL | | diff --git a/tests/ui/issues/issue-4335.stderr b/tests/ui/issues/issue-4335.stderr index 42ac6322564..b6d8f086163 100644 --- a/tests/ui/issues/issue-4335.stderr +++ b/tests/ui/issues/issue-4335.stderr @@ -10,6 +10,7 @@ LL | id(Box::new(|| *v)) | | | captured by this `FnMut` closure | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-4335.rs:5:10 | diff --git a/tests/ui/issues/issue-9155.rs b/tests/ui/issues/issue-9155.rs deleted file mode 100644 index dfd9dea2009..00000000000 --- a/tests/ui/issues/issue-9155.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -//@ aux-build:issue-9155.rs - - -extern crate issue_9155; - -struct Baz; - -pub fn main() { - issue_9155::Foo::new(Baz); -} diff --git a/tests/ui/issues/issue-9906.rs b/tests/ui/issues/issue-9906.rs deleted file mode 100644 index 50417d3e456..00000000000 --- a/tests/ui/issues/issue-9906.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ aux-build:issue-9906.rs - - -extern crate issue_9906 as testmod; - -pub fn main() { - testmod::foo(); - testmod::FooBar::new(1); -} diff --git a/tests/ui/issues/issue-9968.rs b/tests/ui/issues/issue-9968.rs deleted file mode 100644 index 89e60ba5ac7..00000000000 --- a/tests/ui/issues/issue-9968.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -//@ aux-build:issue-9968.rs - - -extern crate issue_9968 as lib; - -use lib::{Trait, Struct}; - -pub fn main() -{ - Struct::init().test(); -} diff --git a/tests/ui/issues/issue-15756.rs b/tests/ui/iterators/explicit-deref-non-deref-type-15756.rs index e0861dee61e..6d4a3bffcf7 100644 --- a/tests/ui/issues/issue-15756.rs +++ b/tests/ui/iterators/explicit-deref-non-deref-type-15756.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15756 + use std::slice::Chunks; use std::slice::ChunksMut; diff --git a/tests/ui/issues/issue-15756.stderr b/tests/ui/iterators/explicit-deref-non-deref-type-15756.stderr index a487d360bef..b4f9aab8496 100644 --- a/tests/ui/issues/issue-15756.stderr +++ b/tests/ui/iterators/explicit-deref-non-deref-type-15756.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[T]` cannot be known at compilation time - --> $DIR/issue-15756.rs:7:10 + --> $DIR/explicit-deref-non-deref-type-15756.rs:9:10 | LL | &mut something | ^^^^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/issues/issue-21655.rs b/tests/ui/iterators/for-loop-over-mut-iterator-21655.rs index 1068b28b338..b5c9826bd45 100644 --- a/tests/ui/issues/issue-21655.rs +++ b/tests/ui/iterators/for-loop-over-mut-iterator-21655.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/21655 //@ run-pass fn test(it: &mut dyn Iterator<Item=i32>) { diff --git a/tests/ui/issues/issue-15034.rs b/tests/ui/lifetimes/nondeterministic-lifetime-errors-15034.rs index 9ea6ed89ca2..e7f9a94231f 100644 --- a/tests/ui/issues/issue-15034.rs +++ b/tests/ui/lifetimes/nondeterministic-lifetime-errors-15034.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15034 + pub struct Lexer<'a> { input: &'a str, } diff --git a/tests/ui/issues/issue-15034.stderr b/tests/ui/lifetimes/nondeterministic-lifetime-errors-15034.stderr index 7db8ade2e48..0762714d259 100644 --- a/tests/ui/issues/issue-15034.stderr +++ b/tests/ui/lifetimes/nondeterministic-lifetime-errors-15034.stderr @@ -1,5 +1,5 @@ error[E0621]: explicit lifetime required in the type of `lexer` - --> $DIR/issue-15034.rs:17:9 + --> $DIR/nondeterministic-lifetime-errors-15034.rs:19:9 | LL | Parser { lexer: lexer } | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required diff --git a/tests/ui/lifetimes/struct-lifetime-inference-15735.rs b/tests/ui/lifetimes/struct-lifetime-inference-15735.rs new file mode 100644 index 00000000000..39e619648eb --- /dev/null +++ b/tests/ui/lifetimes/struct-lifetime-inference-15735.rs @@ -0,0 +1,19 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15735 + +//@ check-pass +#![allow(dead_code)] +struct A<'a> { + a: &'a i32, + b: &'a i32, +} + +impl <'a> A<'a> { + fn foo<'b>(&'b self) { + A { + a: self.a, + b: self.b, + }; + } +} + +fn main() { } diff --git a/tests/ui/issues/issue-9259.rs b/tests/ui/lifetimes/struct-with-lifetime-parameters-9259.rs index c45288f7d65..7e39fdc3f10 100644 --- a/tests/ui/issues/issue-9259.rs +++ b/tests/ui/lifetimes/struct-with-lifetime-parameters-9259.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9259 //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/link-native-libs/link-attr-validation-early.stderr b/tests/ui/link-native-libs/link-attr-validation-early.stderr index 24ad9d825f8..c69899275d5 100644 --- a/tests/ui/link-native-libs/link-attr-validation-early.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-early.stderr @@ -19,3 +19,25 @@ LL | #[link = "foo"] error: aborting due to 2 previous errors +Future incompatibility report: Future breakage diagnostic: +error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + --> $DIR/link-attr-validation-early.rs:2:1 + | +LL | #[link] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + --> $DIR/link-attr-validation-early.rs:4:1 + | +LL | #[link = "foo"] + | ^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + diff --git a/tests/ui/issues/issue-29710.rs b/tests/ui/lint/unused-results-lint-triggered-by-derive-debug-29710.rs index 906ffe9e77b..51702f69c20 100644 --- a/tests/ui/issues/issue-29710.rs +++ b/tests/ui/lint/unused-results-lint-triggered-by-derive-debug-29710.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/29710 //@ check-pass #![deny(unused_results)] #![allow(dead_code)] diff --git a/tests/ui/issues/issue-9047.rs b/tests/ui/loops/loop-with-label-9047.rs index 97733588d51..29e6dba0b9e 100644 --- a/tests/ui/issues/issue-9047.rs +++ b/tests/ui/loops/loop-with-label-9047.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9047 //@ run-pass #![allow(unused_mut)] #![allow(unused_variables)] diff --git a/tests/ui/issues/issue-15189.rs b/tests/ui/macros/for-loop-macro-rules-hygiene.rs index 4dbe2179dd9..fcebda1b9da 100644 --- a/tests/ui/issues/issue-15189.rs +++ b/tests/ui/macros/for-loop-macro-rules-hygiene.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15189 + //@ run-pass macro_rules! third { ($e:expr) => ({let x = 2; $e[x]}) diff --git a/tests/ui/macros/issue-111749.stderr b/tests/ui/macros/issue-111749.stderr index 7db2b8e6ad1..884537ef531 100644 --- a/tests/ui/macros/issue-111749.stderr +++ b/tests/ui/macros/issue-111749.stderr @@ -16,3 +16,14 @@ LL | cbor_map! { #[test(test)] 4}; error: aborting due to 2 previous errors +Future incompatibility report: Future breakage diagnostic: +error: attribute must be of the form `#[test]` + --> $DIR/issue-111749.rs:8:17 + | +LL | cbor_map! { #[test(test)] 4}; + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + diff --git a/tests/ui/issues/issue-9110.rs b/tests/ui/macros/macro-expansion-module-structure-9110.rs index 47533dc43b5..b6241a7c18e 100644 --- a/tests/ui/issues/issue-9110.rs +++ b/tests/ui/macros/macro-expansion-module-structure-9110.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9110 //@ check-pass #![allow(dead_code)] #![allow(non_snake_case)] diff --git a/tests/ui/issues/issue-15167.rs b/tests/ui/macros/macro-hygiene-scope-15167.rs index a2653c10ea4..6578f898a5f 100644 --- a/tests/ui/issues/issue-15167.rs +++ b/tests/ui/macros/macro-hygiene-scope-15167.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15167 + // macro f should not be able to inject a reference to 'n'. macro_rules! f { () => (n) } diff --git a/tests/ui/issues/issue-15167.stderr b/tests/ui/macros/macro-hygiene-scope-15167.stderr index 53082ea0ec6..58112c52df1 100644 --- a/tests/ui/issues/issue-15167.stderr +++ b/tests/ui/macros/macro-hygiene-scope-15167.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `n` in this scope - --> $DIR/issue-15167.rs:3:25 + --> $DIR/macro-hygiene-scope-15167.rs:5:25 | LL | macro_rules! f { () => (n) } | ^ not found in this scope @@ -10,7 +10,7 @@ LL | println!("{}", f!()); = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope - --> $DIR/issue-15167.rs:3:25 + --> $DIR/macro-hygiene-scope-15167.rs:5:25 | LL | macro_rules! f { () => (n) } | ^ not found in this scope @@ -21,7 +21,7 @@ LL | println!("{}", f!()); = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope - --> $DIR/issue-15167.rs:3:25 + --> $DIR/macro-hygiene-scope-15167.rs:5:25 | LL | macro_rules! f { () => (n) } | ^ not found in this scope @@ -32,7 +32,7 @@ LL | println!("{}", f!()); = note: this error originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `n` in this scope - --> $DIR/issue-15167.rs:3:25 + --> $DIR/macro-hygiene-scope-15167.rs:5:25 | LL | macro_rules! f { () => (n) } | ^ not found in this scope diff --git a/tests/ui/issues/issue-9737.rs b/tests/ui/macros/macro-invocation-with-variable-in-scope-9737.rs index a8a17e58dd6..957c2e3f103 100644 --- a/tests/ui/issues/issue-9737.rs +++ b/tests/ui/macros/macro-invocation-with-variable-in-scope-9737.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9737 //@ run-pass #![allow(unused_variables)] macro_rules! f { diff --git a/tests/ui/issues/issue-25386.rs b/tests/ui/macros/private-struct-member-macro-access-25386.rs index b26cc77680d..88e5a22a699 100644 --- a/tests/ui/issues/issue-25386.rs +++ b/tests/ui/macros/private-struct-member-macro-access-25386.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/25386 mod stuff { pub struct Item { c_object: Box<CObj>, diff --git a/tests/ui/issues/issue-25386.stderr b/tests/ui/macros/private-struct-member-macro-access-25386.stderr index 720b77866a5..d02a41848f4 100644 --- a/tests/ui/issues/issue-25386.stderr +++ b/tests/ui/macros/private-struct-member-macro-access-25386.stderr @@ -1,5 +1,5 @@ error[E0616]: field `c_object` of struct `Item` is private - --> $DIR/issue-25386.rs:19:16 + --> $DIR/private-struct-member-macro-access-25386.rs:20:16 | LL | (*$var.c_object).$member.is_some() | ^^^^^^^^ private field diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index 8c22919a1c2..60ea5da761d 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -46,3 +46,58 @@ LL | #[inline = ""] error: aborting due to 5 previous errors +Future incompatibility report: Future breakage diagnostic: +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` + --> $DIR/malformed-regressions.rs:1:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + --> $DIR/malformed-regressions.rs:7:1 + | +LL | #[link] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + --> $DIR/malformed-regressions.rs:9:1 + | +LL | #[link = ""] + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` + --> $DIR/malformed-regressions.rs:3:1 + | +LL | #[ignore()] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + +Future breakage diagnostic: +error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` + --> $DIR/malformed-regressions.rs:5:1 + | +LL | #[inline = ""] + | ^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default + diff --git a/tests/ui/issues/issue-92741.fixed b/tests/ui/mismatched_types/newlines-in-diagnostic-fix-suggestions-92741.fixed index cb37d25273f..c165779e402 100644 --- a/tests/ui/issues/issue-92741.fixed +++ b/tests/ui/mismatched_types/newlines-in-diagnostic-fix-suggestions-92741.fixed @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/92741 //@ run-rustfix fn main() {} fn _foo() -> bool { diff --git a/tests/ui/issues/issue-92741.rs b/tests/ui/mismatched_types/newlines-in-diagnostic-fix-suggestions-92741.rs index 1c5d5810a57..b3fa5f77308 100644 --- a/tests/ui/issues/issue-92741.rs +++ b/tests/ui/mismatched_types/newlines-in-diagnostic-fix-suggestions-92741.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/92741 //@ run-rustfix fn main() {} fn _foo() -> bool { diff --git a/tests/ui/issues/issue-92741.stderr b/tests/ui/mismatched_types/newlines-in-diagnostic-fix-suggestions-92741.stderr index 49315e7a8bf..60917d9a63e 100644 --- a/tests/ui/issues/issue-92741.stderr +++ b/tests/ui/mismatched_types/newlines-in-diagnostic-fix-suggestions-92741.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-92741.rs:4:5 + --> $DIR/newlines-in-diagnostic-fix-suggestions-92741.rs:5:5 | LL | fn _foo() -> bool { | ---- expected `bool` because of return type @@ -15,7 +15,7 @@ LL - mut | error[E0308]: mismatched types - --> $DIR/issue-92741.rs:10:5 + --> $DIR/newlines-in-diagnostic-fix-suggestions-92741.rs:11:5 | LL | fn _bar() -> bool { | ---- expected `bool` because of return type @@ -31,7 +31,7 @@ LL + if true { true } else { false } | error[E0308]: mismatched types - --> $DIR/issue-92741.rs:15:5 + --> $DIR/newlines-in-diagnostic-fix-suggestions-92741.rs:16:5 | LL | fn _baz() -> bool { | ---- expected `bool` because of return type diff --git a/tests/ui/issues/issue-15571.rs b/tests/ui/moves/match-move-same-binding-15571.rs index cf17113a282..f6d79c6d76c 100644 --- a/tests/ui/issues/issue-15571.rs +++ b/tests/ui/moves/match-move-same-binding-15571.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15571 + //@ run-pass fn match_on_local() { diff --git a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr index 51d0f85c031..dfc983bf487 100644 --- a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr +++ b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr @@ -10,6 +10,11 @@ LL | let _f = to_fn(|| test(i)); | | | captured by this `Fn` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:3:33 + | +LL | fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f } + | ^^^^^ help: consider cloning the value if the performance cost is acceptable | LL | let _f = to_fn(|| test(i.clone())); diff --git a/tests/ui/moves/use-correct-generic-args-in-borrow-suggest.rs b/tests/ui/moves/use-correct-generic-args-in-borrow-suggest.rs new file mode 100644 index 00000000000..0fb0cee2013 --- /dev/null +++ b/tests/ui/moves/use-correct-generic-args-in-borrow-suggest.rs @@ -0,0 +1,13 @@ +//! Regression test for #145164: For normal calls, make sure the suggestion to borrow generic inputs +//! uses the generic args from the callee's type rather than those attached to the callee's HIR +//! node. In cases where the callee isn't an identifier expression, its HIR node won't have its +//! generic arguments attached, which could lead to ICE when it had other generic args. In this +//! case, the callee expression is `run.clone()`, to which `clone`'s generic arguments are attached. + +fn main() { + let value = String::new(); + run.clone()(value, ()); + run(value, ()); + //~^ ERROR use of moved value: `value` +} +fn run<F, T: Clone>(value: T, f: F) {} diff --git a/tests/ui/moves/use-correct-generic-args-in-borrow-suggest.stderr b/tests/ui/moves/use-correct-generic-args-in-borrow-suggest.stderr new file mode 100644 index 00000000000..8c29bfbd290 --- /dev/null +++ b/tests/ui/moves/use-correct-generic-args-in-borrow-suggest.stderr @@ -0,0 +1,18 @@ +error[E0382]: use of moved value: `value` + --> $DIR/use-correct-generic-args-in-borrow-suggest.rs:10:9 + | +LL | let value = String::new(); + | ----- move occurs because `value` has type `String`, which does not implement the `Copy` trait +LL | run.clone()(value, ()); + | ----- value moved here +LL | run(value, ()); + | ^^^^^ value used here after move + | +help: consider borrowing `value` + | +LL | run.clone()(&value, ()); + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/issues/issue-15207.rs b/tests/ui/never/never-type-method-call-15207.rs index 356e55ac912..69cdeeabb7c 100644 --- a/tests/ui/issues/issue-15207.rs +++ b/tests/ui/never/never-type-method-call-15207.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15207 + fn main() { loop { break.push(1) //~ ERROR no method named `push` found for type `!` diff --git a/tests/ui/issues/issue-15207.stderr b/tests/ui/never/never-type-method-call-15207.stderr index a1047e27ba2..265e7c8611d 100644 --- a/tests/ui/issues/issue-15207.stderr +++ b/tests/ui/never/never-type-method-call-15207.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `push` found for type `!` in the current scope - --> $DIR/issue-15207.rs:3:15 + --> $DIR/never-type-method-call-15207.rs:5:15 | LL | break.push(1) | ^^^^ method not found in `!` diff --git a/tests/ui/nll/issue-46589.nll.stderr b/tests/ui/nll/issue-46589.nll.stderr index dc80c1d08de..f2d08d1f4c8 100644 --- a/tests/ui/nll/issue-46589.nll.stderr +++ b/tests/ui/nll/issue-46589.nll.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `**other` as mutable more than once at a time - --> $DIR/issue-46589.rs:24:21 + --> $DIR/issue-46589.rs:25:21 | LL | *other = match (*other).get_self() { | -------- first mutable borrow occurs here diff --git a/tests/ui/nll/issue-46589.polonius.stderr b/tests/ui/nll/issue-46589.polonius.stderr new file mode 100644 index 00000000000..f2d08d1f4c8 --- /dev/null +++ b/tests/ui/nll/issue-46589.polonius.stderr @@ -0,0 +1,15 @@ +error[E0499]: cannot borrow `**other` as mutable more than once at a time + --> $DIR/issue-46589.rs:25:21 + | +LL | *other = match (*other).get_self() { + | -------- first mutable borrow occurs here +LL | Some(s) => s, +LL | None => (*other).new_self() + | ^^^^^^^^ + | | + | second mutable borrow occurs here + | first borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/issue-46589.rs b/tests/ui/nll/issue-46589.rs index 10aff0d7b4e..9a23f61b8cb 100644 --- a/tests/ui/nll/issue-46589.rs +++ b/tests/ui/nll/issue-46589.rs @@ -1,9 +1,10 @@ //@ ignore-compare-mode-polonius (explicit revisions) -//@ revisions: nll polonius_next polonius -//@ [polonius_next] check-pass -//@ [polonius_next] compile-flags: -Zpolonius=next -//@ [polonius] check-pass -//@ [polonius] compile-flags: -Zpolonius +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #46589 +//@ [polonius] known-bug: #46589 +//@ [polonius] compile-flags: -Zpolonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Zpolonius=legacy struct Foo; @@ -22,7 +23,6 @@ impl Foo { *other = match (*other).get_self() { Some(s) => s, None => (*other).new_self() - //[nll]~^ ERROR cannot borrow `**other` as mutable more than once at a time [E0499] }; let c = other; diff --git a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr index 57546037006..7f9a8e50dae 100644 --- a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr +++ b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr @@ -10,6 +10,11 @@ LL | expect_fn(|| drop(x.0)); | | | captured by this `Fn` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/issue-52663-span-decl-captured-variable.rs:1:33 + | +LL | fn expect_fn<F>(f: F) where F : Fn() { + | ^^^^ help: consider cloning the value if the performance cost is acceptable | LL | expect_fn(|| drop(x.0.clone())); diff --git a/tests/ui/nll/polonius/array-literal-index-oob-2024.rs b/tests/ui/nll/polonius/array-literal-index-oob-2024.rs new file mode 100644 index 00000000000..2054a32e535 --- /dev/null +++ b/tests/ui/nll/polonius/array-literal-index-oob-2024.rs @@ -0,0 +1,12 @@ +// This test used to ICE under `-Zpolonius=next` when computing loan liveness +// and taking kills into account during reachability traversal of the localized +// constraint graph. Originally from another test but on edition 2024, as +// seen in issue #135646. + +//@ compile-flags: -Zpolonius=next +//@ edition: 2024 +//@ check-pass + +fn main() { + &{ [1, 2, 3][4] }; +} diff --git a/tests/ui/nll/polonius/flow-sensitive-invariance.nll.stderr b/tests/ui/nll/polonius/flow-sensitive-invariance.nll.stderr new file mode 100644 index 00000000000..5756148f4eb --- /dev/null +++ b/tests/ui/nll/polonius/flow-sensitive-invariance.nll.stderr @@ -0,0 +1,36 @@ +error: lifetime may not live long enough + --> $DIR/flow-sensitive-invariance.rs:20:17 + | +LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let returned_value = create_invariant(); +LL | if choice { Ok(returned_value) } else { Err(returned_value) } + | ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Invariant<'l>` is invariant over the parameter `'l` + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: lifetime may not live long enough + --> $DIR/flow-sensitive-invariance.rs:20:45 + | +LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let returned_value = create_invariant(); +LL | if choice { Ok(returned_value) } else { Err(returned_value) } + | ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Invariant<'l>` is invariant over the parameter `'l` + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other + +error: aborting due to 2 previous errors + diff --git a/tests/ui/nll/polonius/flow-sensitive-invariance.polonius.stderr b/tests/ui/nll/polonius/flow-sensitive-invariance.polonius.stderr new file mode 100644 index 00000000000..5756148f4eb --- /dev/null +++ b/tests/ui/nll/polonius/flow-sensitive-invariance.polonius.stderr @@ -0,0 +1,36 @@ +error: lifetime may not live long enough + --> $DIR/flow-sensitive-invariance.rs:20:17 + | +LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let returned_value = create_invariant(); +LL | if choice { Ok(returned_value) } else { Err(returned_value) } + | ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Invariant<'l>` is invariant over the parameter `'l` + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: lifetime may not live long enough + --> $DIR/flow-sensitive-invariance.rs:20:45 + | +LL | fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let returned_value = create_invariant(); +LL | if choice { Ok(returned_value) } else { Err(returned_value) } + | ^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Invariant<'l>` is invariant over the parameter `'l` + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other + +error: aborting due to 2 previous errors + diff --git a/tests/ui/nll/polonius/flow-sensitive-invariance.rs b/tests/ui/nll/polonius/flow-sensitive-invariance.rs new file mode 100644 index 00000000000..c5571f131da --- /dev/null +++ b/tests/ui/nll/polonius/flow-sensitive-invariance.rs @@ -0,0 +1,34 @@ +// An example (from @steffahn) of reachability as an approximation of liveness where the polonius +// alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +use std::cell::Cell; + +struct Invariant<'l>(Cell<&'l ()>); + +fn create_invariant<'l>() -> Invariant<'l> { + Invariant(Cell::new(&())) +} + +fn use_it<'a, 'b>(choice: bool) -> Result<Invariant<'a>, Invariant<'b>> { + let returned_value = create_invariant(); + if choice { Ok(returned_value) } else { Err(returned_value) } + //[nll]~^ ERROR lifetime may not live long enough + //[nll]~| ERROR lifetime may not live long enough + //[polonius]~^^^ ERROR lifetime may not live long enough + //[polonius]~| ERROR lifetime may not live long enough +} + +fn use_it_but_its_the_same_region<'a: 'b, 'b: 'a>( + choice: bool, +) -> Result<Invariant<'a>, Invariant<'b>> { + let returned_value = create_invariant(); + if choice { Ok(returned_value) } else { Err(returned_value) } +} + +fn main() {} diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr index 7ac4e5de283..b768f60590c 100644 --- a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.nll.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `*elements` as mutable more than once at a time - --> $DIR/iterating-updating-cursor-issue-108704.rs:40:26 + --> $DIR/iterating-updating-cursor-issue-108704.rs:41:26 | LL | for (idx, el) in elements.iter_mut().enumerate() { | ^^^^^^^^ diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.polonius.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.polonius.stderr new file mode 100644 index 00000000000..b768f60590c --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.polonius.stderr @@ -0,0 +1,12 @@ +error[E0499]: cannot borrow `*elements` as mutable more than once at a time + --> $DIR/iterating-updating-cursor-issue-108704.rs:41:26 + | +LL | for (idx, el) in elements.iter_mut().enumerate() { + | ^^^^^^^^ + | | + | `*elements` was mutably borrowed here in the previous iteration of the loop + | first borrow used here, in later iteration of loop + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs index 420cb73bed2..673efa8f225 100644 --- a/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-108704.rs @@ -1,11 +1,12 @@ #![crate_type = "lib"] -// An example from #108704 of the linked-list cursor-like pattern of #46859/#48001. +// An example from #108704 of the linked-list cursor-like pattern of #46859/#48001, where the +// polonius alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation. //@ ignore-compare-mode-polonius (explicit revisions) //@ revisions: nll polonius legacy //@ [nll] known-bug: #108704 -//@ [polonius] check-pass +//@ [polonius] known-bug: #108704 //@ [polonius] compile-flags: -Z polonius=next //@ [legacy] check-pass //@ [legacy] compile-flags: -Z polonius=legacy @@ -32,7 +33,7 @@ fn merge_tree_ok(root: &mut Root, path: Vec<String>) { } } -// NLLs fail here +// NLLs and polonius alpha fail here fn merge_tree_ko(root: &mut Root, path: Vec<String>) { let mut elements = &mut root.children; diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr index 14e1726e158..34b04e707db 100644 --- a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.nll.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `p.0` as mutable more than once at a time - --> $DIR/iterating-updating-cursor-issue-57165.rs:29:20 + --> $DIR/iterating-updating-cursor-issue-57165.rs:30:20 | LL | while let Some(now) = p { | ^^^ - first borrow used here, in later iteration of loop @@ -7,7 +7,7 @@ LL | while let Some(now) = p { | `p.0` was mutably borrowed here in the previous iteration of the loop error[E0503]: cannot use `*p` because it was mutably borrowed - --> $DIR/iterating-updating-cursor-issue-57165.rs:29:27 + --> $DIR/iterating-updating-cursor-issue-57165.rs:30:27 | LL | while let Some(now) = p { | --- ^ diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.polonius.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.polonius.stderr new file mode 100644 index 00000000000..34b04e707db --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.polonius.stderr @@ -0,0 +1,22 @@ +error[E0499]: cannot borrow `p.0` as mutable more than once at a time + --> $DIR/iterating-updating-cursor-issue-57165.rs:30:20 + | +LL | while let Some(now) = p { + | ^^^ - first borrow used here, in later iteration of loop + | | + | `p.0` was mutably borrowed here in the previous iteration of the loop + +error[E0503]: cannot use `*p` because it was mutably borrowed + --> $DIR/iterating-updating-cursor-issue-57165.rs:30:27 + | +LL | while let Some(now) = p { + | --- ^ + | | | + | | use of borrowed `p.0` + | | borrow later used here + | `p.0` is borrowed here + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0499, E0503. +For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs index 63ec89146d4..9670fc77e6f 100644 --- a/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-57165.rs @@ -1,11 +1,12 @@ #![crate_type = "lib"] -// An example from #57165 of the linked-list cursor-like pattern of #46859/#48001. +// An example from #57165 of the linked-list cursor-like pattern of #46859/#48001, where the +// polonius alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation. //@ ignore-compare-mode-polonius (explicit revisions) //@ revisions: nll polonius legacy //@ [nll] known-bug: #57165 -//@ [polonius] check-pass +//@ [polonius] known-bug: #57165 //@ [polonius] compile-flags: -Z polonius=next //@ [legacy] check-pass //@ [legacy] compile-flags: -Z polonius=legacy @@ -22,7 +23,7 @@ fn no_control_flow() { } } -// NLLs fail here +// NLLs and polonius alpha fail here fn conditional() { let mut b = Some(Box::new(X { next: None })); let mut p = &mut b; diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr index bf38da566c6..b76e4ff6398 100644 --- a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.nll.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `*node_ref` because it is borrowed - --> $DIR/iterating-updating-cursor-issue-63908.rs:42:5 + --> $DIR/iterating-updating-cursor-issue-63908.rs:43:5 | LL | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) { | - let's call the lifetime of this reference `'1` diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.polonius.stderr b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.polonius.stderr new file mode 100644 index 00000000000..b76e4ff6398 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.polonius.stderr @@ -0,0 +1,18 @@ +error[E0506]: cannot assign to `*node_ref` because it is borrowed + --> $DIR/iterating-updating-cursor-issue-63908.rs:43:5 + | +LL | fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) { + | - let's call the lifetime of this reference `'1` +LL | loop { +LL | let next_ref = &mut node_ref.as_mut().unwrap().next; + | -------- `*node_ref` is borrowed here +... +LL | node_ref = next_ref; + | ------------------- assignment requires that `*node_ref` is borrowed for `'1` +... +LL | *node_ref = None; + | ^^^^^^^^^ `*node_ref` is assigned to here but it was already borrowed + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs index 00e48b65fed..6682926c523 100644 --- a/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs +++ b/tests/ui/nll/polonius/iterating-updating-cursor-issue-63908.rs @@ -1,11 +1,12 @@ #![crate_type = "lib"] -// An example from #63908 of the linked-list cursor-like pattern of #46859/#48001. +// An example from #63908 of the linked-list cursor-like pattern of #46859/#48001, where the +// polonius alpha analysis shows the same imprecision as NLLs, unlike the datalog implementation. //@ ignore-compare-mode-polonius (explicit revisions) //@ revisions: nll polonius legacy //@ [nll] known-bug: #63908 -//@ [polonius] check-pass +//@ [polonius] known-bug: #63908 //@ [polonius] compile-flags: -Z polonius=next //@ [legacy] check-pass //@ [legacy] compile-flags: -Z polonius=legacy @@ -27,7 +28,7 @@ fn remove_last_node_recursive<T>(node_ref: &mut List<T>) { } } -// NLLs fail here +// NLLs and polonius alpha fail here fn remove_last_node_iterative<T>(mut node_ref: &mut List<T>) { loop { let next_ref = &mut node_ref.as_mut().unwrap().next; diff --git a/tests/ui/nll/polonius/iterating-updating-mutref.nll.stderr b/tests/ui/nll/polonius/iterating-updating-mutref.nll.stderr new file mode 100644 index 00000000000..941c736d8d2 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-mutref.nll.stderr @@ -0,0 +1,15 @@ +error[E0499]: cannot borrow `self.buf_read` as mutable more than once at a time + --> $DIR/iterating-updating-mutref.rs:61:23 + | +LL | pub fn next<'a>(&'a mut self) -> &'a str { + | -- lifetime `'a` defined here +LL | loop { +LL | let buf = self.buf_read.fill_buf(); + | ^^^^^^^^^^^^^ `self.buf_read` was mutably borrowed here in the previous iteration of the loop +LL | if let Some(s) = decode(buf) { +LL | return s; + | - returning this value requires that `self.buf_read` is borrowed for `'a` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/iterating-updating-mutref.rs b/tests/ui/nll/polonius/iterating-updating-mutref.rs new file mode 100644 index 00000000000..a315bf66279 --- /dev/null +++ b/tests/ui/nll/polonius/iterating-updating-mutref.rs @@ -0,0 +1,87 @@ +// These are some examples of iterating through and updating a mutable ref, similar in spirit to the +// linked-list-like pattern of #46859/#48001 where the polonius alpha analysis shows imprecision, +// unlike the datalog implementation. +// +// They differ in that after the loans prior to the loop are either not live after the loop, or with +// control flow and outlives relationships that are simple enough for the reachability +// approximation. They're thus accepted by the alpha analysis, like NLLs did for the simplest cases +// of flow-sensitivity. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [nll] known-bug: #46859 +//@ [polonius] check-pass +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] check-pass +//@ [legacy] compile-flags: -Z polonius=legacy + +// The #46859 OP +struct List<T> { + value: T, + next: Option<Box<List<T>>>, +} + +fn to_refs<T>(mut list: &mut List<T>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + list = n; + } else { + return result; + } + } +} + +// A similar construction, where paths in the constraint graph are also clearly terminating, so it's +// fine even for NLLs. +fn to_refs2<T>(mut list: &mut List<T>) -> Vec<&mut T> { + let mut result = vec![]; + loop { + result.push(&mut list.value); + if let Some(n) = list.next.as_mut() { + list = n; + } else { + break; + } + } + + result +} + +// Another MCVE from the same issue, but was rejected by NLLs. +pub struct Decoder { + buf_read: BufRead, +} + +impl Decoder { + // NLLs fail here + pub fn next<'a>(&'a mut self) -> &'a str { + loop { + let buf = self.buf_read.fill_buf(); + if let Some(s) = decode(buf) { + return s; + } + // loop to get more input data + + // At this point `buf` is not used anymore. + // With NLL I would expect the borrow to end here, + // such that `self.buf_read` is not borrowed anymore + // by the time we start the next loop iteration. + } + } +} + +struct BufRead; + +impl BufRead { + fn fill_buf(&mut self) -> &[u8] { + unimplemented!() + } +} + +fn decode(_: &[u8]) -> Option<&str> { + unimplemented!() +} + +fn main() {} diff --git a/tests/ui/nll/polonius/lending-iterator-sanity-checks.legacy.stderr b/tests/ui/nll/polonius/lending-iterator-sanity-checks.legacy.stderr new file mode 100644 index 00000000000..fa201b89048 --- /dev/null +++ b/tests/ui/nll/polonius/lending-iterator-sanity-checks.legacy.stderr @@ -0,0 +1,28 @@ +error[E0499]: cannot borrow `*t` as mutable more than once at a time + --> $DIR/lending-iterator-sanity-checks.rs:19:19 + | +LL | fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> { + | - let's call the lifetime of this reference `'1` +LL | let Some(i) = t.next() else { return None }; + | - first mutable borrow occurs here +LL | let Some(j) = t.next() else { return None }; + | ^ second mutable borrow occurs here +... +LL | Some((i, j)) + | ------------ returning this value requires that `*t` is borrowed for `'1` + +error[E0499]: cannot borrow `*t` as mutable more than once at a time + --> $DIR/lending-iterator-sanity-checks.rs:31:13 + | +LL | let i = t.next(); + | - first mutable borrow occurs here +... +LL | let j = t.next(); + | ^ second mutable borrow occurs here +LL | +LL | } + | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/lending-iterator-sanity-checks.nll.stderr b/tests/ui/nll/polonius/lending-iterator-sanity-checks.nll.stderr new file mode 100644 index 00000000000..fa201b89048 --- /dev/null +++ b/tests/ui/nll/polonius/lending-iterator-sanity-checks.nll.stderr @@ -0,0 +1,28 @@ +error[E0499]: cannot borrow `*t` as mutable more than once at a time + --> $DIR/lending-iterator-sanity-checks.rs:19:19 + | +LL | fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> { + | - let's call the lifetime of this reference `'1` +LL | let Some(i) = t.next() else { return None }; + | - first mutable borrow occurs here +LL | let Some(j) = t.next() else { return None }; + | ^ second mutable borrow occurs here +... +LL | Some((i, j)) + | ------------ returning this value requires that `*t` is borrowed for `'1` + +error[E0499]: cannot borrow `*t` as mutable more than once at a time + --> $DIR/lending-iterator-sanity-checks.rs:31:13 + | +LL | let i = t.next(); + | - first mutable borrow occurs here +... +LL | let j = t.next(); + | ^ second mutable borrow occurs here +LL | +LL | } + | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr b/tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr new file mode 100644 index 00000000000..bf8546b63bf --- /dev/null +++ b/tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr @@ -0,0 +1,26 @@ +error[E0499]: cannot borrow `*t` as mutable more than once at a time + --> $DIR/lending-iterator-sanity-checks.rs:19:19 + | +LL | let Some(i) = t.next() else { return None }; + | - first mutable borrow occurs here +LL | let Some(j) = t.next() else { return None }; + | ^ second mutable borrow occurs here +... +LL | } + | - first borrow might be used here, when `i` is dropped and runs the destructor for type `<T as LendingIterator>::Item<'_>` + +error[E0499]: cannot borrow `*t` as mutable more than once at a time + --> $DIR/lending-iterator-sanity-checks.rs:31:13 + | +LL | let i = t.next(); + | - first mutable borrow occurs here +... +LL | let j = t.next(); + | ^ second mutable borrow occurs here +LL | +LL | } + | - first borrow might be used here, when `i` is dropped and runs the destructor for type `Option<<T as LendingIterator>::Item<'_>>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/lending-iterator-sanity-checks.rs b/tests/ui/nll/polonius/lending-iterator-sanity-checks.rs new file mode 100644 index 00000000000..ae8cc78957f --- /dev/null +++ b/tests/ui/nll/polonius/lending-iterator-sanity-checks.rs @@ -0,0 +1,71 @@ +// Some sanity checks for lending iterators with GATs. This is just some non-regression tests +// ensuring the polonius alpha analysis, the datalog implementation, and NLLs agree in these common +// cases of overlapping yielded items. + +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius legacy +//@ [polonius] compile-flags: -Z polonius=next +//@ [legacy] compile-flags: -Z polonius=legacy + +trait LendingIterator { + type Item<'a> + where + Self: 'a; + fn next(&mut self) -> Option<Self::Item<'_>>; +} + +fn use_live<T: LendingIterator>(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> { + let Some(i) = t.next() else { return None }; + let Some(j) = t.next() else { return None }; + //~^ ERROR cannot borrow `*t` as mutable more than once at a time + + // `i` is obviously still (use-)live here, but we called `next` again to get `j`. + Some((i, j)) +} + +fn drop_live<T: LendingIterator>(t: &mut T) { + let i = t.next(); + + // Now `i` is use-dead here, but we don't know if the iterator items have a `Drop` impl, so it's + // still drop-live. + let j = t.next(); + //~^ ERROR cannot borrow `*t` as mutable more than once at a time +} + +// But we can still manually serialize the lifetimes with scopes (or preventing the destructor from +// being called), so they're not overlapping. +fn manually_non_overlapping<T: LendingIterator>(t: &mut T) { + { + let i = t.next(); + } + + let j = t.next(); // i is dead + + drop(j); + let k = t.next(); // j is dead + + let k = std::mem::ManuallyDrop::new(k); + let l = t.next(); // we told the compiler that k is not drop-live +} + +// The cfg below is because there's a diagnostic ICE trying to explain the source of the error when +// using the datalog implementation. We're not fixing *that*, outside of removing the implementation +// in the future. +#[cfg(not(legacy))] // FIXME: remove this cfg when removing the datalog implementation +fn items_have_no_borrows<T: LendingIterator>(t: &mut T) +where + for<'a> T::Item<'a>: 'static, +{ + let i = t.next(); + let j = t.next(); +} + +fn items_are_copy<T: LendingIterator>(t: &mut T) +where + for<'a> T::Item<'a>: Copy, +{ + let i = t.next(); + let j = t.next(); +} + +fn main() {} diff --git a/tests/ui/issues/issue-99838.rs b/tests/ui/packed/misaligned-reference-drop-field-99838.rs index 687b47fbe71..58e168162cb 100644 --- a/tests/ui/issues/issue-99838.rs +++ b/tests/ui/packed/misaligned-reference-drop-field-99838.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/99838 //@ run-pass use std::hint; diff --git a/tests/ui/issues/issue-15043.rs b/tests/ui/parser/generics-rangle-eq-15043.rs index a9bb46b649b..1afc334dfd8 100644 --- a/tests/ui/issues/issue-15043.rs +++ b/tests/ui/parser/generics-rangle-eq-15043.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15043 + //@ run-pass #![allow(warnings)] diff --git a/tests/ui/issues/issue-15896.rs b/tests/ui/pattern/enum-struct-pattern-mismatch-15896.rs index d3153b516e6..9f7c5084c0e 100644 --- a/tests/ui/issues/issue-15896.rs +++ b/tests/ui/pattern/enum-struct-pattern-mismatch-15896.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15896 + // Regression test for #15896. It used to ICE rustc. fn main() { diff --git a/tests/ui/issues/issue-15896.stderr b/tests/ui/pattern/enum-struct-pattern-mismatch-15896.stderr index 381f6dc2276..8dee4c37e2f 100644 --- a/tests/ui/issues/issue-15896.stderr +++ b/tests/ui/pattern/enum-struct-pattern-mismatch-15896.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-15896.rs:11:11 + --> $DIR/enum-struct-pattern-mismatch-15896.rs:13:11 | LL | let u = match e { | - this expression has type `E` diff --git a/tests/ui/issues/issue-15381.rs b/tests/ui/pattern/refutable-pattern-for-loop-15381.rs index bd5f62ddc67..3c19612c9cc 100644 --- a/tests/ui/issues/issue-15381.rs +++ b/tests/ui/pattern/refutable-pattern-for-loop-15381.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15381 + fn main() { let values: Vec<u8> = vec![1,2,3,4,5,6,7,8]; diff --git a/tests/ui/issues/issue-15381.stderr b/tests/ui/pattern/refutable-pattern-for-loop-15381.stderr index 03a0100f1bd..3c1d5fb454c 100644 --- a/tests/ui/issues/issue-15381.stderr +++ b/tests/ui/pattern/refutable-pattern-for-loop-15381.stderr @@ -1,5 +1,5 @@ error[E0005]: refutable pattern in `for` loop binding - --> $DIR/issue-15381.rs:4:9 + --> $DIR/refutable-pattern-for-loop-15381.rs:6:9 | LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) { | ^^^^^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered diff --git a/tests/ui/issues/issue-15104.rs b/tests/ui/pattern/slice-pattern-recursion-15104.rs index e68c94c370e..24e3fe78de0 100644 --- a/tests/ui/issues/issue-15104.rs +++ b/tests/ui/pattern/slice-pattern-recursion-15104.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15104 + //@ run-pass fn main() { diff --git a/tests/ui/issues/issue-16149.rs b/tests/ui/pattern/static-binding-shadow-16149.rs index 51b60725c5a..a46f78214c7 100644 --- a/tests/ui/issues/issue-16149.rs +++ b/tests/ui/pattern/static-binding-shadow-16149.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16149 + extern "C" { static externalValue: isize; } diff --git a/tests/ui/issues/issue-16149.stderr b/tests/ui/pattern/static-binding-shadow-16149.stderr index 9ffd0e7e645..6d8c7634acd 100644 --- a/tests/ui/issues/issue-16149.stderr +++ b/tests/ui/pattern/static-binding-shadow-16149.stderr @@ -1,5 +1,5 @@ error[E0530]: match bindings cannot shadow statics - --> $DIR/issue-16149.rs:7:9 + --> $DIR/static-binding-shadow-16149.rs:9:9 | LL | static externalValue: isize; | ---------------------------- the static `externalValue` is defined here diff --git a/tests/ui/issues/issue-15260.rs b/tests/ui/pattern/struct-field-duplicate-binding-15260.rs index 64fc3df3d23..a3617798cdf 100644 --- a/tests/ui/issues/issue-15260.rs +++ b/tests/ui/pattern/struct-field-duplicate-binding-15260.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15260 + struct Foo { a: usize, } diff --git a/tests/ui/issues/issue-15260.stderr b/tests/ui/pattern/struct-field-duplicate-binding-15260.stderr index 4a3041122b2..536904fbcb3 100644 --- a/tests/ui/issues/issue-15260.stderr +++ b/tests/ui/pattern/struct-field-duplicate-binding-15260.stderr @@ -1,5 +1,5 @@ error[E0025]: field `a` bound multiple times in the pattern - --> $DIR/issue-15260.rs:8:9 + --> $DIR/struct-field-duplicate-binding-15260.rs:10:9 | LL | a: _, | ---- first use of `a` @@ -7,7 +7,7 @@ LL | a: _ | ^^^^ multiple uses of `a` in pattern error[E0025]: field `a` bound multiple times in the pattern - --> $DIR/issue-15260.rs:14:9 + --> $DIR/struct-field-duplicate-binding-15260.rs:16:9 | LL | a, | - first use of `a` @@ -15,7 +15,7 @@ LL | a: _ | ^^^^ multiple uses of `a` in pattern error[E0025]: field `a` bound multiple times in the pattern - --> $DIR/issue-15260.rs:20:9 + --> $DIR/struct-field-duplicate-binding-15260.rs:22:9 | LL | a, | - first use of `a` @@ -23,7 +23,7 @@ LL | a: _, | ^^^^ multiple uses of `a` in pattern error[E0025]: field `a` bound multiple times in the pattern - --> $DIR/issue-15260.rs:22:9 + --> $DIR/struct-field-duplicate-binding-15260.rs:24:9 | LL | a, | - first use of `a` diff --git a/tests/ui/issues/issue-15129-rpass.rs b/tests/ui/pattern/tuple-enum-match-15129.rs index e2ddb989072..1d6192c4cb3 100644 --- a/tests/ui/issues/issue-15129-rpass.rs +++ b/tests/ui/pattern/tuple-enum-match-15129.rs @@ -1,24 +1,25 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15129 + //@ run-pass pub enum T { T1(()), - T2(()) + T2(()), } pub enum V { V1(isize), - V2(bool) + V2(bool), } fn foo(x: (T, V)) -> String { match x { - (T::T1(()), V::V1(i)) => format!("T1(()), V1({})", i), - (T::T2(()), V::V2(b)) => format!("T2(()), V2({})", b), - _ => String::new() + (T::T1(()), V::V1(i)) => format!("T1(()), V1({})", i), + (T::T2(()), V::V2(b)) => format!("T2(()), V2({})", b), + _ => String::new(), } } - fn main() { assert_eq!(foo((T::T1(()), V::V1(99))), "T1(()), V1(99)".to_string()); assert_eq!(foo((T::T2(()), V::V2(true))), "T2(()), V2(true)".to_string()); diff --git a/tests/ui/issues/issue-16401.rs b/tests/ui/pattern/unit-type-struct-pattern-mismatch-16401.rs index 0985a6806d2..2eba33e177e 100644 --- a/tests/ui/issues/issue-16401.rs +++ b/tests/ui/pattern/unit-type-struct-pattern-mismatch-16401.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16401 + struct Slice<T> { data: *const T, len: usize, diff --git a/tests/ui/issues/issue-16401.stderr b/tests/ui/pattern/unit-type-struct-pattern-mismatch-16401.stderr index 6af920ca439..22c04e439c4 100644 --- a/tests/ui/issues/issue-16401.stderr +++ b/tests/ui/pattern/unit-type-struct-pattern-mismatch-16401.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-16401.rs:8:9 + --> $DIR/unit-type-struct-pattern-mismatch-16401.rs:10:9 | LL | match () { | -- this expression has type `()` diff --git a/tests/ui/issues/issue-pr29383.rs b/tests/ui/pattern/unit-variant-pattern-matching-29383.rs index 2bcc0aa2782..e339dc01f46 100644 --- a/tests/ui/issues/issue-pr29383.rs +++ b/tests/ui/pattern/unit-variant-pattern-matching-29383.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/29383 enum E { A, B, diff --git a/tests/ui/issues/issue-pr29383.stderr b/tests/ui/pattern/unit-variant-pattern-matching-29383.stderr index 57783d75ba1..e30837568a5 100644 --- a/tests/ui/issues/issue-pr29383.stderr +++ b/tests/ui/pattern/unit-variant-pattern-matching-29383.stderr @@ -1,5 +1,5 @@ error[E0532]: expected tuple struct or tuple variant, found unit variant `E::A` - --> $DIR/issue-pr29383.rs:9:14 + --> $DIR/unit-variant-pattern-matching-29383.rs:10:14 | LL | A, | - `E::A` defined here @@ -8,7 +8,7 @@ LL | Some(E::A(..)) => {} | ^^^^^^^^ help: use this syntax instead: `E::A` error[E0532]: expected tuple struct or tuple variant, found unit variant `E::B` - --> $DIR/issue-pr29383.rs:11:14 + --> $DIR/unit-variant-pattern-matching-29383.rs:12:14 | LL | B, | - `E::B` defined here diff --git a/tests/ui/proc-macro/auxiliary/match-expander.rs b/tests/ui/proc-macro/auxiliary/match-expander.rs new file mode 100644 index 00000000000..bf78df2addf --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/match-expander.rs @@ -0,0 +1,15 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn matcher(input: TokenStream) -> TokenStream { +" +struct S(()); +let s = S(()); +match s { + true => {} + _ => {} +} +".parse().unwrap() +} diff --git a/tests/ui/proc-macro/match-expander.rs b/tests/ui/proc-macro/match-expander.rs new file mode 100644 index 00000000000..23e5746c540 --- /dev/null +++ b/tests/ui/proc-macro/match-expander.rs @@ -0,0 +1,12 @@ +//@ proc-macro: match-expander.rs +// Ensure that we don't point at macro invocation when providing inference contexts. + +#[macro_use] +extern crate match_expander; + +fn main() { + match_expander::matcher!(); + //~^ ERROR: mismatched types + //~| NOTE: expected `S`, found `bool` + //~| NOTE: in this expansion of match_expander::matcher! +} diff --git a/tests/ui/proc-macro/match-expander.stderr b/tests/ui/proc-macro/match-expander.stderr new file mode 100644 index 00000000000..b77468ec60a --- /dev/null +++ b/tests/ui/proc-macro/match-expander.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/match-expander.rs:8:5 + | +LL | match_expander::matcher!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `S`, found `bool` + | + = note: this error originates in the macro `match_expander::matcher` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr index ecb12c1df3b..0bcea9b85f4 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr @@ -5,7 +5,6 @@ LL | quote!($($nonrep $nonrep)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr index 093e2ebc098..d945ab41a12 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr @@ -5,7 +5,6 @@ LL | quote!($($nonrep)*); | ^^^^^^^^^^^^^^^^^^^ | | | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/does-not-have-iter-separated.stderr b/tests/ui/proc-macro/quote/does-not-have-iter-separated.stderr index 937209e675e..2d715f293d4 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter-separated.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter-separated.stderr @@ -2,10 +2,7 @@ error[E0308]: mismatched types --> $DIR/does-not-have-iter-separated.rs:8:5 | LL | quote!($(a b),*); - | ^^^^^^^^^^^^^^^^ - | | - | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this + | ^^^^^^^^^^^^^^^^ expected `HasIterator`, found `ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/does-not-have-iter.stderr b/tests/ui/proc-macro/quote/does-not-have-iter.stderr index e74ea334899..ac8e725038a 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter.stderr @@ -2,10 +2,7 @@ error[E0308]: mismatched types --> $DIR/does-not-have-iter.rs:8:5 | LL | quote!($(a b)*); - | ^^^^^^^^^^^^^^^ - | | - | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this + | ^^^^^^^^^^^^^^^ expected `HasIterator`, found `ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr index f37dc320fa3..8081f7b3a8b 100644 --- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -44,6 +44,7 @@ LL | LL | foo(f); | ^ move occurs because `f` has type `{closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 52:58}`, which does not implement the `Copy` trait | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: consider cloning the value if the performance cost is acceptable | LL | foo(f.clone()); diff --git a/tests/ui/issues/issue-9249.rs b/tests/ui/static/static-string-slice-9249.rs index b98ba050521..da099117bd4 100644 --- a/tests/ui/issues/issue-9249.rs +++ b/tests/ui/static/static-string-slice-9249.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/9249 //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-16452.rs b/tests/ui/statics/conditional-static-declaration-16010.rs index 4ab74f09059..0bc5b0ee86f 100644 --- a/tests/ui/issues/issue-16452.rs +++ b/tests/ui/statics/conditional-static-declaration-16010.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16010 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/structs/default-field-values/auxiliary/struct_field_default.rs b/tests/ui/structs/default-field-values/auxiliary/struct_field_default.rs index b315df5dba2..a1c9645a1ae 100644 --- a/tests/ui/structs/default-field-values/auxiliary/struct_field_default.rs +++ b/tests/ui/structs/default-field-values/auxiliary/struct_field_default.rs @@ -3,3 +3,13 @@ pub struct A { pub a: isize = 42, } + +struct Priv; + +pub struct B { + pub a: Priv = Priv, +} + +pub struct C { + pub a: Priv, +} diff --git a/tests/ui/structs/default-field-values/non-exhaustive-ctor-2.rs b/tests/ui/structs/default-field-values/non-exhaustive-ctor-2.rs new file mode 100644 index 00000000000..047505c3f1c --- /dev/null +++ b/tests/ui/structs/default-field-values/non-exhaustive-ctor-2.rs @@ -0,0 +1,29 @@ +//@ aux-build:struct_field_default.rs +#![feature(default_field_values)] + +extern crate struct_field_default as xc; + +use m::S; + +mod m { + pub struct S { + pub field: () = (), + pub field1: Priv1 = Priv1 {}, + pub field2: Priv2 = Priv2, + } + struct Priv1 {} + struct Priv2; +} + +fn main() { + let _ = S { field: (), field1: m::Priv1 {} }; + //~^ ERROR missing field `field2` + //~| ERROR struct `Priv1` is private + let _ = S { field: (), field1: m::Priv1 {}, field2: m::Priv2 }; + //~^ ERROR struct `Priv1` is private + //~| ERROR unit struct `Priv2` is private + let _ = xc::B { a: xc::Priv }; + //~^ ERROR unit struct `Priv` is private + let _ = xc::C { a: xc::Priv }; + //~^ ERROR unit struct `Priv` is private +} diff --git a/tests/ui/structs/default-field-values/non-exhaustive-ctor-2.stderr b/tests/ui/structs/default-field-values/non-exhaustive-ctor-2.stderr new file mode 100644 index 00000000000..66de73561db --- /dev/null +++ b/tests/ui/structs/default-field-values/non-exhaustive-ctor-2.stderr @@ -0,0 +1,105 @@ +error[E0603]: struct `Priv1` is private + --> $DIR/non-exhaustive-ctor-2.rs:19:39 + | +LL | let _ = S { field: (), field1: m::Priv1 {} }; + | ------ ^^^^^ private struct + | | + | while setting this field + | +note: the struct `Priv1` is defined here + --> $DIR/non-exhaustive-ctor-2.rs:14:4 + | +LL | struct Priv1 {} + | ^^^^^^^^^^^^ +help: the type `Priv1` of field `field1` is private, but you can construct the default value defined for it in `S` using `..` in the struct initializer expression + | +LL - let _ = S { field: (), field1: m::Priv1 {} }; +LL + let _ = S { field: (), .. }; + | + +error[E0603]: struct `Priv1` is private + --> $DIR/non-exhaustive-ctor-2.rs:22:39 + | +LL | let _ = S { field: (), field1: m::Priv1 {}, field2: m::Priv2 }; + | ------ ^^^^^ private struct + | | + | while setting this field + | +note: the struct `Priv1` is defined here + --> $DIR/non-exhaustive-ctor-2.rs:14:4 + | +LL | struct Priv1 {} + | ^^^^^^^^^^^^ +help: the type `Priv1` of field `field1` is private, but you can construct the default value defined for it in `S` using `..` in the struct initializer expression + | +LL - let _ = S { field: (), field1: m::Priv1 {}, field2: m::Priv2 }; +LL + let _ = S { field: (), field2: m::Priv2, .. }; + | + +error[E0603]: unit struct `Priv2` is private + --> $DIR/non-exhaustive-ctor-2.rs:22:60 + | +LL | let _ = S { field: (), field1: m::Priv1 {}, field2: m::Priv2 }; + | ------ ^^^^^ private unit struct + | | + | while setting this field + | +note: the unit struct `Priv2` is defined here + --> $DIR/non-exhaustive-ctor-2.rs:15:4 + | +LL | struct Priv2; + | ^^^^^^^^^^^^^ +help: the type `Priv2` of field `field2` is private, but you can construct the default value defined for it in `S` using `..` in the struct initializer expression + | +LL - let _ = S { field: (), field1: m::Priv1 {}, field2: m::Priv2 }; +LL + let _ = S { field: (), field1: m::Priv1 {}, .. }; + | + +error[E0603]: unit struct `Priv` is private + --> $DIR/non-exhaustive-ctor-2.rs:25:28 + | +LL | let _ = xc::B { a: xc::Priv }; + | - ^^^^ private unit struct + | | + | while setting this field + | +note: the unit struct `Priv` is defined here + --> $DIR/auxiliary/struct_field_default.rs:7:1 + | +LL | struct Priv; + | ^^^^^^^^^^^ +help: the type `Priv` of field `a` is private, but you can construct the default value defined for it in `B` using `..` in the struct initializer expression + | +LL - let _ = xc::B { a: xc::Priv }; +LL + let _ = xc::B { .. }; + | + +error[E0603]: unit struct `Priv` is private + --> $DIR/non-exhaustive-ctor-2.rs:27:28 + | +LL | let _ = xc::C { a: xc::Priv }; + | - ^^^^ private unit struct + | | + | while setting this field + | +note: the unit struct `Priv` is defined here + --> $DIR/auxiliary/struct_field_default.rs:7:1 + | +LL | struct Priv; + | ^^^^^^^^^^^ + +error[E0063]: missing field `field2` in initializer of `S` + --> $DIR/non-exhaustive-ctor-2.rs:19:13 + | +LL | let _ = S { field: (), field1: m::Priv1 {} }; + | ^ missing `field2` + | +help: all remaining fields have default values, you can use those values with `..` + | +LL | let _ = S { field: (), field1: m::Priv1 {}, .. }; + | ++++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0063, E0603. +For more information about an error, try `rustc --explain E0063`. diff --git a/tests/ui/issues/issue-24365.rs b/tests/ui/structs/struct-field-access-errors-24365.rs index da195116047..13a95cd1cca 100644 --- a/tests/ui/issues/issue-24365.rs +++ b/tests/ui/structs/struct-field-access-errors-24365.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/24365 pub enum Attribute { Code {attr_name_idx: u16}, } diff --git a/tests/ui/issues/issue-24365.stderr b/tests/ui/structs/struct-field-access-errors-24365.stderr index 3f6ed0231d8..65275af4701 100644 --- a/tests/ui/issues/issue-24365.stderr +++ b/tests/ui/structs/struct-field-access-errors-24365.stderr @@ -1,17 +1,17 @@ error[E0609]: no field `b` on type `Foo` - --> $DIR/issue-24365.rs:10:22 + --> $DIR/struct-field-access-errors-24365.rs:11:22 | LL | println!("{}", a.b); | ^ unknown field error[E0609]: no field `attr_name_idx` on type `&Attribute` - --> $DIR/issue-24365.rs:17:18 + --> $DIR/struct-field-access-errors-24365.rs:18:18 | LL | let z = (&x).attr_name_idx; | ^^^^^^^^^^^^^ unknown field error[E0609]: no field `attr_name_idx` on type `Attribute` - --> $DIR/issue-24365.rs:18:15 + --> $DIR/struct-field-access-errors-24365.rs:19:15 | LL | let y = x.attr_name_idx; | ^^^^^^^^^^^^^ unknown field diff --git a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs index 44eac3691a3..34088f219b2 100644 --- a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs +++ b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.rs @@ -11,8 +11,55 @@ struct X(Y); struct Y; fn consume_fn<F: Fn()>(_f: F) { } +//~^ HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures fn consume_fnmut<F: FnMut()>(_f: F) { } +//~^ HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures +//~| HELP `Fn` and `FnMut` closures + +trait T { + fn consume_fn<F: Fn()>(_f: F) { } + //~^ HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + fn method_consume_fn<F: Fn()>(&self, _f: F) { } + //~^ HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures + //~| HELP `Fn` and `FnMut` closures +} +impl T for () {} pub fn main() { } @@ -73,6 +120,120 @@ fn move_into_fn() { }); } +fn move_into_assoc_fn() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let x = X(Y); + + // move into Fn + + <() as T>::consume_fn(|| { + let X(_t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) + | Either::Two(_t) => (), + } + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(mut _t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) + | Either::Two(mut _t) => (), + } + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + }); +} + +fn move_into_method() { + let e = Either::One(X(Y)); + let mut em = Either::One(X(Y)); + + let x = X(Y); + + // move into Fn + + ().method_consume_fn(|| { + let X(_t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(_t) = e { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) + | Either::Two(_t) => (), + } + match e { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(_t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + + let X(mut _t) = x; + //~^ ERROR cannot move + //~| HELP consider borrowing here + if let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + while let Either::One(mut _t) = em { } + //~^ ERROR cannot move + //~| HELP consider borrowing here + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) + | Either::Two(mut _t) => (), + } + match em { + //~^ ERROR cannot move + //~| HELP consider borrowing here + Either::One(mut _t) => (), + Either::Two(ref _t) => (), + // FIXME: should suggest removing `ref` too + } + }); +} + fn move_into_fnmut() { let e = Either::One(X(Y)); let mut em = Either::One(X(Y)); diff --git a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr index edda2cbc735..132a31c8f7c 100644 --- a/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr +++ b/tests/ui/suggestions/dont-suggest-ref/move-into-closure.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:28:21 + --> $DIR/move-into-closure.rs:75:21 | LL | let x = X(Y); | - captured outer variable @@ -12,13 +12,18 @@ LL | let X(_t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | let X(_t) = &x; | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:31:34 + --> $DIR/move-into-closure.rs:78:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -32,13 +37,18 @@ LL | if let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | if let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:34:37 + --> $DIR/move-into-closure.rs:81:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -52,13 +62,18 @@ LL | while let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | while let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:37:15 + --> $DIR/move-into-closure.rs:84:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -75,13 +90,18 @@ LL | Either::One(_t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:43:15 + --> $DIR/move-into-closure.rs:90:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -98,13 +118,18 @@ LL | Either::One(_t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:51:25 + --> $DIR/move-into-closure.rs:98:25 | LL | let x = X(Y); | - captured outer variable @@ -118,13 +143,18 @@ LL | let X(mut _t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | let X(mut _t) = &x; | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:54:38 + --> $DIR/move-into-closure.rs:101:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -138,13 +168,18 @@ LL | if let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | if let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:57:41 + --> $DIR/move-into-closure.rs:104:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -158,13 +193,18 @@ LL | while let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | while let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:60:15 + --> $DIR/move-into-closure.rs:107:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -181,13 +221,18 @@ LL | Either::One(mut _t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure - --> $DIR/move-into-closure.rs:66:15 + --> $DIR/move-into-closure.rs:113:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -204,13 +249,540 @@ LL | Either::One(mut _t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:13:18 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:132:21 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +LL | let X(_t) = x; + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(_t) = &x; + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:135:34 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:138:37 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:141:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:147:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) => (), + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:155:25 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | let X(mut _t) = x; + | ------ ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(mut _t) = &x; + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:158:38 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:161:41 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:164:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:170:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | <() as T>::consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) => (), + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:39:22 + | +LL | fn consume_fn<F: Fn()>(_f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:189:21 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +LL | let X(_t) = x; + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(_t) = &x; + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:192:34 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:195:37 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(_t) = e { } + | -- ^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(_t) = &e { } + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:198:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:204:15 + | +LL | let e = Either::One(X(Y)); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match e { + | ^ +... +LL | Either::One(_t) => (), + | -- + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &e { + | + + +error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:212:25 + | +LL | let x = X(Y); + | - captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | let X(mut _t) = x; + | ------ ^ + | | + | data moved here + | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | let X(mut _t) = &x; + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:215:38 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | if let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | if let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:218:41 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | while let Either::One(mut _t) = em { } + | ------ ^^ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | while let Either::One(mut _t) = &em { } + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:221:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ +help: consider borrowing here + | +LL | match &em { + | + + +error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `Fn` closure + --> $DIR/move-into-closure.rs:227:15 + | +LL | let mut em = Either::One(X(Y)); + | ------ captured outer variable +... +LL | ().method_consume_fn(|| { + | -- captured by this `Fn` closure +... +LL | match em { + | ^^ +... +LL | Either::One(mut _t) => (), + | ------ + | | + | data moved here + | move occurs because `_t` has type `X`, which does not implement the `Copy` trait + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:50:29 + | +LL | fn method_consume_fn<F: Fn()>(&self, _f: F) { } + | ^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:85:21 + --> $DIR/move-into-closure.rs:246:21 | LL | let x = X(Y); | - captured outer variable @@ -223,13 +795,18 @@ LL | let X(_t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | let X(_t) = &x; | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:88:34 + --> $DIR/move-into-closure.rs:249:34 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -243,13 +820,18 @@ LL | if let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | if let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:91:37 + --> $DIR/move-into-closure.rs:252:37 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -263,13 +845,18 @@ LL | while let Either::One(_t) = e { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | while let Either::One(_t) = &e { } | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:94:15 + --> $DIR/move-into-closure.rs:255:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -286,13 +873,18 @@ LL | Either::One(_t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `e.0`, as `e` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:100:15 + --> $DIR/move-into-closure.rs:261:15 | LL | let e = Either::One(X(Y)); | - captured outer variable @@ -309,13 +901,18 @@ LL | Either::One(_t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &e { | + error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:108:25 + --> $DIR/move-into-closure.rs:269:25 | LL | let x = X(Y); | - captured outer variable @@ -329,13 +926,18 @@ LL | let X(mut _t) = x; | data moved here | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | let X(mut _t) = &x; | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:111:38 + --> $DIR/move-into-closure.rs:272:38 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -349,13 +951,18 @@ LL | if let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | if let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:114:41 + --> $DIR/move-into-closure.rs:275:41 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -369,13 +976,18 @@ LL | while let Either::One(mut _t) = em { } | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | while let Either::One(mut _t) = &em { } | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:117:15 + --> $DIR/move-into-closure.rs:278:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -392,13 +1004,18 @@ LL | Either::One(mut _t) | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:123:15 + --> $DIR/move-into-closure.rs:284:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -415,13 +1032,18 @@ LL | Either::One(mut _t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &em { | + error[E0507]: cannot move out of `em.0`, as `em` is a captured variable in an `FnMut` closure - --> $DIR/move-into-closure.rs:130:15 + --> $DIR/move-into-closure.rs:291:15 | LL | let mut em = Either::One(X(Y)); | ------ captured outer variable @@ -438,11 +1060,16 @@ LL | Either::One(mut _t) => (), | data moved here | move occurs because `_t` has type `X`, which does not implement the `Copy` trait | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/move-into-closure.rs:25:21 + | +LL | fn consume_fnmut<F: FnMut()>(_f: F) { } + | ^^^^^^^ help: consider borrowing here | LL | match &em { | + -error: aborting due to 21 previous errors +error: aborting due to 41 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/suggestions/option-content-move2.stderr b/tests/ui/suggestions/option-content-move2.stderr index c73e874b403..c8aa6667b58 100644 --- a/tests/ui/suggestions/option-content-move2.stderr +++ b/tests/ui/suggestions/option-content-move2.stderr @@ -14,6 +14,11 @@ LL | LL | var = Some(NotCopyable); | --- variable moved due to use in closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move2.rs:5:12 + | +LL | fn func<F: FnMut() -> H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move2.rs:1:1 | @@ -38,6 +43,12 @@ LL | move || { LL | LL | var = Some(NotCopyableButCloneable); | --- variable moved due to use in closure + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move2.rs:5:12 + | +LL | fn func<F: FnMut() -> H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr index 68c52352a65..2c9a86c036b 100644 --- a/tests/ui/suggestions/option-content-move3.stderr +++ b/tests/ui/suggestions/option-content-move3.stderr @@ -9,6 +9,7 @@ LL | move || { LL | let x = var; | ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | @@ -37,6 +38,11 @@ LL | move || { LL | let x = var; | --- variable moved due to use in closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move3.rs:6:12 + | +LL | fn func<F: FnMut() -> H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ note: if `NotCopyable` implemented `Clone`, you could clone the value --> $DIR/option-content-move3.rs:2:1 | @@ -57,6 +63,7 @@ LL | move || { LL | let x = var; | ^^^ move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait | + = help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once help: consider borrowing here | LL | let x = &var; @@ -77,6 +84,11 @@ LL | move || { LL | let x = var; | --- variable moved due to use in closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/option-content-move3.rs:6:12 + | +LL | fn func<F: FnMut() -> H, H: FnMut()>(_: F) {} + | ^^^^^^^^^^^^ help: consider cloning the value before moving it into the closure | LL ~ { diff --git a/tests/ui/issues/issue-30756.rs b/tests/ui/thread-local/thread-local-with-attributes-30756.rs index d103776406c..fcf7bb813c8 100644 --- a/tests/ui/issues/issue-30756.rs +++ b/tests/ui/thread-local/thread-local-with-attributes-30756.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/30756 //@ run-pass #![forbid(unsafe_code)] diff --git a/tests/ui/trait-bounds/more_maybe_bounds.rs b/tests/ui/trait-bounds/more_maybe_bounds.rs index 47348b0a0dd..d367dd5b299 100644 --- a/tests/ui/trait-bounds/more_maybe_bounds.rs +++ b/tests/ui/trait-bounds/more_maybe_bounds.rs @@ -1,7 +1,7 @@ // FIXME(more_maybe_bounds): Even under `more_maybe_bounds` / `-Zexperimental-default-bounds`, // trying to relax non-default bounds should still be an error in all contexts! As you can see -// there are places like supertrait bounds and trait object types where we currently don't perform -// this check. +// there are places like supertrait bounds, trait object types or associated type bounds (ATB) +// where we currently don't perform this check. #![feature(auto_traits, more_maybe_bounds, negative_impls)] trait Trait1 {} @@ -13,11 +13,15 @@ trait Trait4 where Self: Trait1 {} // FIXME: `?Trait2` should be rejected, `Trait2` isn't marked `#[lang = "default_traitN"]`. fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {} + fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} //~^ ERROR bound modifier `?` can only be applied to default traits like `Sized` //~| ERROR bound modifier `?` can only be applied to default traits like `Sized` //~| ERROR bound modifier `?` can only be applied to default traits like `Sized` +// FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`. +fn baz<T>() where T: Iterator<Item: ?Trait1> {} + struct S; impl !Trait2 for S {} impl Trait1 for S {} diff --git a/tests/ui/trait-bounds/more_maybe_bounds.stderr b/tests/ui/trait-bounds/more_maybe_bounds.stderr index 09c9fc31165..8dd83fc7728 100644 --- a/tests/ui/trait-bounds/more_maybe_bounds.stderr +++ b/tests/ui/trait-bounds/more_maybe_bounds.stderr @@ -1,17 +1,17 @@ error: bound modifier `?` can only be applied to default traits like `Sized` - --> $DIR/more_maybe_bounds.rs:16:20 + --> $DIR/more_maybe_bounds.rs:17:20 | LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} | ^^^^^^^ error: bound modifier `?` can only be applied to default traits like `Sized` - --> $DIR/more_maybe_bounds.rs:16:30 + --> $DIR/more_maybe_bounds.rs:17:30 | LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} | ^^^^^^^ error: bound modifier `?` can only be applied to default traits like `Sized` - --> $DIR/more_maybe_bounds.rs:16:40 + --> $DIR/more_maybe_bounds.rs:17:40 | LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {} | ^^^^^^^ diff --git a/tests/ui/issues/issue-15444.rs b/tests/ui/traits/fn-type-trait-impl-15444.rs index 14708c7733c..ab91e88b9cd 100644 --- a/tests/ui/issues/issue-15444.rs +++ b/tests/ui/traits/fn-type-trait-impl-15444.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15444 + //@ run-pass trait MyTrait { diff --git a/tests/ui/issues/issue-15734.rs b/tests/ui/traits/index-trait-multiple-impls-15734.rs index 26fb7061664..a2d5d7c87fc 100644 --- a/tests/ui/issues/issue-15734.rs +++ b/tests/ui/traits/index-trait-multiple-impls-15734.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/15734 + //@ run-pass //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) diff --git a/tests/ui/issues/issue-16048.rs b/tests/ui/traits/lifetime-mismatch-trait-impl-16048.rs index eaf6acff26b..9c36b231403 100644 --- a/tests/ui/issues/issue-16048.rs +++ b/tests/ui/traits/lifetime-mismatch-trait-impl-16048.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/16048 + trait NoLifetime { fn get<'p, T : Test<'p>>(&self) -> T; //~^ NOTE lifetimes in impl do not match this method in trait diff --git a/tests/ui/issues/issue-16048.stderr b/tests/ui/traits/lifetime-mismatch-trait-impl-16048.stderr index f97f13152bc..08b69184b7f 100644 --- a/tests/ui/issues/issue-16048.stderr +++ b/tests/ui/traits/lifetime-mismatch-trait-impl-16048.stderr @@ -1,5 +1,5 @@ error[E0195]: lifetime parameters or bounds on method `get` do not match the trait declaration - --> $DIR/issue-16048.rs:21:11 + --> $DIR/lifetime-mismatch-trait-impl-16048.rs:23:11 | LL | fn get<'p, T : Test<'p>>(&self) -> T; | ------------------ lifetimes in impl do not match this method in trait @@ -8,7 +8,7 @@ LL | fn get<'p, T: Test<'a> + From<Foo<'a>>>(&self) -> T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait error[E0605]: non-primitive cast: `Foo<'a>` as `T` - --> $DIR/issue-16048.rs:24:16 + --> $DIR/lifetime-mismatch-trait-impl-16048.rs:26:16 | LL | return *self as T; | ^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object diff --git a/tests/ui/issues/issue-30236.rs b/tests/ui/typeck/unused-type-parameter-span-30236.rs index 08d08a54402..bcdc922a71b 100644 --- a/tests/ui/issues/issue-30236.rs +++ b/tests/ui/typeck/unused-type-parameter-span-30236.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/30236 type Foo< Unused //~ ERROR type parameter `Unused` is never used > = u8; diff --git a/tests/ui/issues/issue-30236.stderr b/tests/ui/typeck/unused-type-parameter-span-30236.stderr index bfe374a653f..038bd1ebd28 100644 --- a/tests/ui/issues/issue-30236.stderr +++ b/tests/ui/typeck/unused-type-parameter-span-30236.stderr @@ -1,5 +1,5 @@ error[E0091]: type parameter `Unused` is never used - --> $DIR/issue-30236.rs:2:5 + --> $DIR/unused-type-parameter-span-30236.rs:3:5 | LL | Unused | ^^^^^^ unused type parameter diff --git a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr index 8d9a61cb681..9d87402a15b 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr @@ -10,6 +10,11 @@ LL | let f = to_fn(|| drop(x)); | | | captured by this `Fn` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:7:33 + | +LL | fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f } + | ^^^^^ help: consider cloning the value if the performance cost is acceptable | LL | let f = to_fn(|| drop(x.clone())); @@ -27,6 +32,11 @@ LL | let f = to_fn_mut(|| drop(x)); | | | captured by this `FnMut` closure | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:8:37 + | +LL | fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f } + | ^^^^^^^^ help: consider cloning the value if the performance cost is acceptable | LL | let f = to_fn_mut(|| drop(x.clone())); @@ -43,6 +53,12 @@ LL | let f = to_fn(move || drop(x)); | ------- ^ `x` is moved here | | | captured by this `Fn` closure + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:7:33 + | +LL | fn to_fn<A:std::marker::Tuple,F:Fn<A>>(f: F) -> F { f } + | ^^^^^ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure --> $DIR/unboxed-closure-illegal-move.rs:32:40 @@ -55,6 +71,12 @@ LL | let f = to_fn_mut(move || drop(x)); | ------- ^ `x` is moved here | | | captured by this `FnMut` closure + | +help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once + --> $DIR/unboxed-closure-illegal-move.rs:8:37 + | +LL | fn to_fn_mut<A:std::marker::Tuple,F:FnMut<A>>(f: F) -> F { f } + | ^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/issues/issue-88150.rs b/tests/ui/uninhabited/uninhabited-type-layout-computation-88150.rs index 1dadba307c0..1387c5b6c10 100644 --- a/tests/ui/issues/issue-88150.rs +++ b/tests/ui/uninhabited/uninhabited-type-layout-computation-88150.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/88150 //@ run-pass //@ compile-flags:-C debuginfo=2 //@ edition:2018 diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.rs b/tests/ui/unsized/relaxed-bounds-invalid-places.rs index b8eda1e7786..4c1f242a01c 100644 --- a/tests/ui/unsized/relaxed-bounds-invalid-places.rs +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.rs @@ -22,6 +22,10 @@ impl<T> S1<T> { fn f() where T: ?Sized {} //~ ERROR this relaxed bound is not permitted here } +// Test associated type bounds (ATB). +// issue: <https://github.com/rust-lang/rust/issues/135229> +struct S6<T>(T) where T: Iterator<Item: ?Sized>; //~ ERROR this relaxed bound is not permitted here + trait Tr: ?Sized {} //~ ERROR relaxed bounds are not permitted in supertrait bounds // Test that relaxed `Sized` bounds are rejected in trait object types: diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr index 30285d62693..d3f0535e2f0 100644 --- a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr @@ -38,8 +38,16 @@ LL | fn f() where T: ?Sized {} | = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds-invalid-places.rs:27:41 + | +LL | struct S6<T>(T) where T: Iterator<Item: ?Sized>; + | ^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + error: relaxed bounds are not permitted in supertrait bounds - --> $DIR/relaxed-bounds-invalid-places.rs:25:11 + --> $DIR/relaxed-bounds-invalid-places.rs:29:11 | LL | trait Tr: ?Sized {} | ^^^^^^ @@ -47,19 +55,19 @@ LL | trait Tr: ?Sized {} = note: traits are `?Sized` by default error: relaxed bounds are not permitted in trait object types - --> $DIR/relaxed-bounds-invalid-places.rs:29:20 + --> $DIR/relaxed-bounds-invalid-places.rs:33:20 | LL | type O1 = dyn Tr + ?Sized; | ^^^^^^ error: relaxed bounds are not permitted in trait object types - --> $DIR/relaxed-bounds-invalid-places.rs:30:15 + --> $DIR/relaxed-bounds-invalid-places.rs:34:15 | LL | type O2 = dyn ?Sized + ?Sized + Tr; | ^^^^^^ error: relaxed bounds are not permitted in trait object types - --> $DIR/relaxed-bounds-invalid-places.rs:30:24 + --> $DIR/relaxed-bounds-invalid-places.rs:34:24 | LL | type O2 = dyn ?Sized + ?Sized + Tr; | ^^^^^^ @@ -76,5 +84,5 @@ error: bound modifier `?` can only be applied to `Sized` LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized; | ^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors diff --git a/tests/ui/wf/hir-wf-check-erase-regions.stderr b/tests/ui/wf/hir-wf-check-erase-regions.nll.stderr index 07304cd448e..dcade3aa367 100644 --- a/tests/ui/wf/hir-wf-check-erase-regions.stderr +++ b/tests/ui/wf/hir-wf-check-erase-regions.nll.stderr @@ -1,5 +1,5 @@ error[E0277]: `&'a T` is not an iterator - --> $DIR/hir-wf-check-erase-regions.rs:7:21 + --> $DIR/hir-wf-check-erase-regions.rs:11:21 | LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'a T` is not an iterator @@ -11,7 +11,7 @@ note: required by a bound in `std::iter::IntoIterator::IntoIter` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL error[E0277]: `&'a T` is not an iterator - --> $DIR/hir-wf-check-erase-regions.rs:7:5 + --> $DIR/hir-wf-check-erase-regions.rs:11:5 | LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>; | ^^^^^^^^^^^^^ `&'a T` is not an iterator @@ -23,7 +23,7 @@ note: required by a bound in `Flatten` --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL error[E0277]: `&'a T` is not an iterator - --> $DIR/hir-wf-check-erase-regions.rs:11:27 + --> $DIR/hir-wf-check-erase-regions.rs:15:27 | LL | fn into_iter(self) -> Self::IntoIter { | ^^^^^^^^^^^^^^ `&'a T` is not an iterator @@ -35,7 +35,7 @@ note: required by a bound in `Flatten` --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL error[E0277]: `&T` is not an iterator - --> $DIR/hir-wf-check-erase-regions.rs:11:27 + --> $DIR/hir-wf-check-erase-regions.rs:15:27 | LL | fn into_iter(self) -> Self::IntoIter { | ^^^^^^^^^^^^^^ `&T` is not an iterator diff --git a/tests/ui/wf/hir-wf-check-erase-regions.polonius.stderr b/tests/ui/wf/hir-wf-check-erase-regions.polonius.stderr new file mode 100644 index 00000000000..55728aa642b --- /dev/null +++ b/tests/ui/wf/hir-wf-check-erase-regions.polonius.stderr @@ -0,0 +1,39 @@ +error[E0277]: `&'a T` is not an iterator + --> $DIR/hir-wf-check-erase-regions.rs:11:21 + | +LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'a T` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&'a T` + = help: the trait `Iterator` is implemented for `&mut I` + = note: required for `Flatten<std::slice::Iter<'a, T>>` to implement `Iterator` +note: required by a bound in `std::iter::IntoIterator::IntoIter` + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + +error[E0277]: `&'a T` is not an iterator + --> $DIR/hir-wf-check-erase-regions.rs:11:5 + | +LL | type IntoIter = std::iter::Flatten<std::slice::Iter<'a, T>>; + | ^^^^^^^^^^^^^ `&'a T` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&'a T` + = help: the trait `Iterator` is implemented for `&mut I` + = note: required for `&'a T` to implement `IntoIterator` +note: required by a bound in `Flatten` + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + +error[E0277]: `&'a T` is not an iterator + --> $DIR/hir-wf-check-erase-regions.rs:15:27 + | +LL | fn into_iter(self) -> Self::IntoIter { + | ^^^^^^^^^^^^^^ `&'a T` is not an iterator + | + = help: the trait `Iterator` is not implemented for `&'a T` + = help: the trait `Iterator` is implemented for `&mut I` + = note: required for `&'a T` to implement `IntoIterator` +note: required by a bound in `Flatten` + --> $SRC_DIR/core/src/iter/adapters/flatten.rs:LL:COL + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/hir-wf-check-erase-regions.rs b/tests/ui/wf/hir-wf-check-erase-regions.rs index 20cc1cfe730..ef9132697ef 100644 --- a/tests/ui/wf/hir-wf-check-erase-regions.rs +++ b/tests/ui/wf/hir-wf-check-erase-regions.rs @@ -1,6 +1,10 @@ // Regression test for #87549. //@ incremental +//@ ignore-compare-mode-polonius (explicit revisions) +//@ revisions: nll polonius +//@ [polonius] compile-flags: -Zpolonius=next + pub struct Table<T, const N: usize>([Option<T>; N]); impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> { @@ -10,7 +14,7 @@ impl<'a, T, const N: usize> IntoIterator for &'a Table<T, N> { fn into_iter(self) -> Self::IntoIter { //~^ ERROR `&'a T` is not an iterator - //~| ERROR `&T` is not an iterator + //[nll]~| ERROR `&T` is not an iterator unimplemented!() } } |
