diff --git a/.github/ISSUE_TEMPLATE/tracking_issue.md b/.github/ISSUE_TEMPLATE/tracking_issue.md index 5f17f30b3b0b..598628936112 100644 --- a/.github/ISSUE_TEMPLATE/tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/tracking_issue.md @@ -28,6 +28,8 @@ Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however *not* meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. +Discussion comments will get marked as off-topic or deleted. +Repeated discussions on the tracking issue may lead to the tracking issue getting locked. ### Steps $DIR/option-content-move2.rs:11:9 + // | + // LL | let mut var = None; + // | ------- captured outer variable + // LL | func(|| { + // | -- captured by this `FnMut` closure + // LL | // Shouldn't suggest `move ||.as_ref()` here + // LL | move || { + // | ^^^^^^^ `var` is moved here + // LL | + // LL | var = Some(NotCopyable); + // | --- + // | | + // | variable moved due to use in closure + // | move occurs because `var` has type `Option`, which does not implement the `Copy` trait + // | + return; + } + + // Search for an appropriate place for the structured `.clone()` suggestion to be applied. + // If we encounter a statement before the borrow error, we insert a statement there. + for (_, node) in tcx.hir().parent_iter(closure_expr.hir_id) { + if let Node::Stmt(stmt) = node { + let padding = tcx + .sess + .source_map() + .indentation_before(stmt.span) + .unwrap_or_else(|| " ".to_string()); + err.multipart_suggestion_verbose( + "clone the value before moving it into the closure", + vec![ + ( + stmt.span.shrink_to_lo(), + format!("let value = {upvar_name}.clone();\n{padding}"), + ), + (use_span, "value".to_string()), + ], + Applicability::MachineApplicable, + ); + suggested = true; + break; + } else if let Node::Expr(expr) = node + && let ExprKind::Closure(_) = expr.kind + { + // We want to suggest cloning only on the first closure, not + // subsequent ones (like `ui/suggestions/option-content-move2.rs`). + break; + } + } + if !suggested { + // If we couldn't find a statement for us to insert a new `.clone()` statement before, + // we have a bare expression, so we suggest the creation of a new block inline to go + // from `move || val` to `{ let value = val.clone(); move || value }`. + let padding = tcx + .sess + .source_map() + .indentation_before(closure_expr.span) + .unwrap_or_else(|| " ".to_string()); + err.multipart_suggestion_verbose( + "clone the value before moving it into the closure", + vec![ + ( + closure_expr.span.shrink_to_lo(), + format!("{{\n{padding}let value = {upvar_name}.clone();\n{padding}"), + ), + (use_spans.var_or_use(), "value".to_string()), + (closure_expr.span.shrink_to_hi(), format!("\n{padding}}}")), + ], + Applicability::MachineApplicable, + ); + } + } + fn report_cannot_move_from_borrowed_content( &mut self, move_place: Place<'tcx>, @@ -310,10 +428,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { span: Span, use_spans: Option>, ) -> Diag<'tcx> { + let tcx = self.infcx.tcx; // Inspect the type of the content behind the // borrow to provide feedback about why this // was a move rather than a copy. - let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty; + let ty = deref_target_place.ty(self.body, tcx).ty; let upvar_field = self .prefixes(move_place.as_ref(), PrefixSet::All) .find_map(|p| self.is_upvar_field_projection(p)); @@ -363,8 +482,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let upvar = &self.upvars[upvar_field.unwrap().index()]; let upvar_hir_id = upvar.get_root_variable(); - let upvar_name = upvar.to_string(self.infcx.tcx); - let upvar_span = self.infcx.tcx.hir().span(upvar_hir_id); + let upvar_name = upvar.to_string(tcx); + let upvar_span = tcx.hir().span(upvar_hir_id); let place_name = self.describe_any_place(move_place.as_ref()); @@ -380,12 +499,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { closure_kind_ty, closure_kind, place_description, ); - self.cannot_move_out_of(span, &place_description) + let closure_span = tcx.def_span(def_id); + let mut err = self + .cannot_move_out_of(span, &place_description) .with_span_label(upvar_span, "captured outer variable") .with_span_label( - self.infcx.tcx.def_span(def_id), + closure_span, format!("captured by this `{closure_kind}` closure"), - ) + ); + self.suggest_clone_of_captured_var_in_move_closure( + &mut err, + upvar_hir_id, + &upvar_name, + use_spans, + ); + err } _ => { let source = self.borrowed_content_source(deref_base); @@ -415,7 +543,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ), (_, _, _) => self.cannot_move_out_of( span, - &source.describe_for_unnamed_place(self.infcx.tcx), + &source.describe_for_unnamed_place(tcx), ), } } @@ -447,7 +575,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; if let Some(expr) = self.find_expr(span) { - self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span)); + self.suggest_cloning(err, place_ty, expr, self.find_expr(other_span), None); } err.subdiagnostic( @@ -482,7 +610,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; if let Some(expr) = self.find_expr(use_span) { - self.suggest_cloning(err, place_ty, expr, self.find_expr(span)); + self.suggest_cloning( + err, + place_ty, + expr, + self.find_expr(span), + Some(use_spans), + ); } err.subdiagnostic( @@ -595,7 +729,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let place_desc = &format!("`{}`", self.local_names[*local].unwrap()); if let Some(expr) = self.find_expr(binding_span) { - self.suggest_cloning(err, bind_to.ty, expr, None); + self.suggest_cloning(err, bind_to.ty, expr, None, None); } err.subdiagnostic( diff --git a/compiler/rustc_codegen_cranelift/example/polymorphize_coroutine.rs b/compiler/rustc_codegen_cranelift/example/polymorphize_coroutine.rs index c965b34e13b9..407da94c0f09 100644 --- a/compiler/rustc_codegen_cranelift/example/polymorphize_coroutine.rs +++ b/compiler/rustc_codegen_cranelift/example/polymorphize_coroutine.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; @@ -8,7 +8,8 @@ fn main() { } fn run_coroutine() { - let mut coroutine = || { + let mut coroutine = #[coroutine] + || { yield; return; }; diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs index 0205de556228..90d4ab721dae 100644 --- a/compiler/rustc_codegen_cranelift/example/std_example.rs +++ b/compiler/rustc_codegen_cranelift/example/std_example.rs @@ -1,6 +1,7 @@ #![feature( core_intrinsics, coroutines, + stmt_expr_attributes, coroutine_trait, is_sorted, repr_simd, @@ -123,9 +124,12 @@ fn main() { test_simd(); } - Box::pin(move |mut _task_context| { - yield (); - }) + Box::pin( + #[coroutine] + move |mut _task_context| { + yield (); + }, + ) .as_mut() .resume(0); diff --git a/compiler/rustc_codegen_gcc/example/std_example.rs b/compiler/rustc_codegen_gcc/example/std_example.rs index ad69409eb659..8ab8fcc525e5 100644 --- a/compiler/rustc_codegen_gcc/example/std_example.rs +++ b/compiler/rustc_codegen_gcc/example/std_example.rs @@ -1,5 +1,5 @@ #![allow(internal_features)] -#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted)] +#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted, stmt_expr_attributes)] #[cfg(feature="master")] #[cfg(target_arch="x86_64")] @@ -103,7 +103,7 @@ fn main() { test_simd(); } - Box::pin(move |mut _task_context| { + Box::pin(#[coroutine] move |mut _task_context| { yield (); }).as_mut().resume(0); diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index d353704fb75d..23a5e5ff8730 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -898,26 +898,20 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.gcc_checked_binop(oop, typ, lhs, rhs) } - fn alloca(&mut self, ty: Type<'gcc>, align: Align) -> RValue<'gcc> { - // FIXME(antoyo): this check that we don't call get_aligned() a second time on a type. - // Ideally, we shouldn't need to do this check. - let aligned_type = if ty == self.cx.u128_type || ty == self.cx.i128_type { - ty - } else { - ty.get_aligned(align.bytes()) - }; + fn alloca(&mut self, size: Size, align: Align) -> RValue<'gcc> { + let ty = self.cx.type_array(self.cx.type_i8(), size.bytes()).get_aligned(align.bytes()); // TODO(antoyo): It might be better to return a LValue, but fixing the rustc API is non-trivial. self.stack_var_count.set(self.stack_var_count.get() + 1); self.current_func() .new_local( self.location, - aligned_type, + ty, &format!("stack_var_{}", self.stack_var_count.get()), ) .get_address(self.location) } - fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { + fn dynamic_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { unimplemented!(); } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index bee6bda007c3..b7aec97ad8c2 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -531,7 +531,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { // We instead thus allocate some scratch space... let scratch_size = cast.size(bx); let scratch_align = cast.align(bx); - let llscratch = bx.alloca(cast.gcc_type(bx), scratch_align); + let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); // ... where we first store the value... diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 6039a4aaf013..0c7cffbe7308 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -18,7 +18,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, Ty}; use rustc_span::{sym, Span, Symbol}; -use rustc_target::abi::Align; +use rustc_target::abi::{Align, Size}; use crate::builder::Builder; #[cfg(not(feature = "master"))] @@ -558,7 +558,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( let ze = bx.zext(result, bx.type_ix(expected_bytes * 8)); // Convert the integer to a byte array - let ptr = bx.alloca(bx.type_ix(expected_bytes * 8), Align::ONE); + let ptr = bx.alloca(Size::from_bytes(expected_bytes), Align::ONE); bx.store(ze, ptr, Align::ONE); let array_ty = bx.type_array(bx.type_i8(), expected_bytes); let ptr = bx.pointercast(ptr, bx.cx.type_ptr_to(array_ty)); diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index c0b43b778979..aec11e9905f3 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -227,7 +227,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { // when passed by value, making it larger. let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes()); // Allocate some scratch space... - let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align); + let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); // ...store the value... bx.store(val, llscratch, scratch_align); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 4c2bdb2f5ec2..f7546039540b 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -468,9 +468,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { val } - fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value { + fn alloca(&mut self, size: Size, align: Align) -> &'ll Value { let mut bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); + let ty = self.cx().type_array(self.cx().type_i8(), size.bytes()); unsafe { let alloca = llvm::LLVMBuildAlloca(bx.llbuilder, ty, UNNAMED); llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); @@ -478,10 +479,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn byte_array_alloca(&mut self, len: &'ll Value, align: Align) -> &'ll Value { + fn dynamic_alloca(&mut self, size: &'ll Value, align: Align) -> &'ll Value { unsafe { let alloca = - llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), len, UNNAMED); + llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), size, UNNAMED); llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); alloca } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index ab9f20fdf63c..41347333ea6f 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{sym, Span, Symbol}; -use rustc_target::abi::{self, Align, HasDataLayout, Primitive}; +use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use std::cmp::Ordering; @@ -649,8 +649,9 @@ fn codegen_msvc_try<'ll>( // } // // More information can be found in libstd's seh.rs implementation. + let ptr_size = bx.tcx().data_layout.pointer_size; let ptr_align = bx.tcx().data_layout.pointer_align.abi; - let slot = bx.alloca(bx.type_ptr(), ptr_align); + let slot = bx.alloca(ptr_size, ptr_align); let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void()); bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None); @@ -920,15 +921,14 @@ fn codegen_emcc_try<'ll>( // We need to pass two values to catch_func (ptr and is_rust_panic), so // create an alloca and pass a pointer to that. + let ptr_size = bx.tcx().data_layout.pointer_size; let ptr_align = bx.tcx().data_layout.pointer_align.abi; let i8_align = bx.tcx().data_layout.i8_align.abi; - let catch_data_type = bx.type_struct(&[bx.type_ptr(), bx.type_bool()], false); - let catch_data = bx.alloca(catch_data_type, ptr_align); - let catch_data_0 = - bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(0)]); - bx.store(ptr, catch_data_0, ptr_align); - let catch_data_1 = - bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(1)]); + // Required in order for there to be no padding between the fields. + assert!(i8_align <= ptr_align); + let catch_data = bx.alloca(2 * ptr_size, ptr_align); + bx.store(ptr, catch_data, ptr_align); + let catch_data_1 = bx.inbounds_ptradd(catch_data, bx.const_usize(ptr_size.bytes())); bx.store(is_rust_panic, catch_data_1, i8_align); let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void()); @@ -1374,7 +1374,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let ze = bx.zext(i_, bx.type_ix(expected_bytes * 8)); // Convert the integer to a byte array - let ptr = bx.alloca(bx.type_ix(expected_bytes * 8), Align::ONE); + let ptr = bx.alloca(Size::from_bytes(expected_bytes), Align::ONE); bx.store(ze, ptr, Align::ONE); let array_ty = bx.type_array(bx.type_i8(), expected_bytes); return Ok(bx.load(array_ty, ptr, Align::ONE)); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 930b9b8c0db2..ae7c0f24b40f 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -508,7 +508,7 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let ptr_size = bx.tcx().data_layout.pointer_size; let ptr_align = bx.tcx().data_layout.pointer_align.abi; let arg_argc = bx.const_int(cx.type_isize(), 2); - let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), ptr_align); + let arg_argv = bx.alloca(2 * ptr_size, ptr_align); bx.store(param_handle, arg_argv, ptr_align); let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes())); bx.store(param_system_table, arg_argv_el1, ptr_align); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 64c13fa7c1fb..d4d172c000f3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1517,7 +1517,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // when passed by value, making it larger. let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes()); // Allocate some scratch space... - let llscratch = bx.alloca(bx.cast_backend_type(cast), scratch_align); + let llscratch = bx.alloca(scratch_size, scratch_align); bx.lifetime_start(llscratch, scratch_size); // ...memcpy the value... bx.memcpy( diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 9cf64e2d6768..e5fd59657a49 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -327,7 +327,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let llfield_ty = bx.cx().backend_type(field); // Can't bitcast an aggregate, so round trip through memory. - let llptr = bx.alloca(llfield_ty, field.align.abi); + let llptr = bx.alloca(field.size, field.align.abi); bx.store(*llval, llptr, field.align.abi); *llval = bx.load(llfield_ty, llptr, field.align.abi); } @@ -470,7 +470,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { let align_minus_1 = bx.sub(align, one); let size_extra = bx.add(size, align_minus_1); let min_align = Align::ONE; - let alloca = bx.byte_array_alloca(size_extra, min_align); + let alloca = bx.dynamic_alloca(size_extra, min_align); let address = bx.ptrtoint(alloca, bx.type_isize()); let neg_address = bx.neg(address); let offset = bx.and(neg_address, align_minus_1); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 90627da579e7..b23d0894da67 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -81,7 +81,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { align: Align, ) -> Self { assert!(layout.is_sized(), "tried to statically allocate unsized place"); - let tmp = bx.alloca(bx.cx().backend_type(layout), align); + let tmp = bx.alloca(layout.size, align); Self::new_sized_aligned(tmp, layout, align) } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9191618c064b..51b22bfaf255 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -144,8 +144,8 @@ pub trait BuilderMethods<'a, 'tcx>: } fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; - fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value; - fn byte_array_alloca(&mut self, len: Self::Value, align: Align) -> Self::Value; + fn alloca(&mut self, size: Size, align: Align) -> Self::Value; + fn dynamic_alloca(&mut self, size: Self::Value, align: Align) -> Self::Value; fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value; diff --git a/compiler/rustc_error_codes/src/error_codes/E0626.md b/compiler/rustc_error_codes/src/error_codes/E0626.md index e2534415d830..28d543350ffd 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0626.md +++ b/compiler/rustc_error_codes/src/error_codes/E0626.md @@ -4,10 +4,10 @@ yield point. Erroneous code example: ```compile_fail,E0626 -# #![feature(coroutines, coroutine_trait, pin)] +# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; -let mut b = || { +let mut b = #[coroutine] || { let a = &String::new(); // <-- This borrow... yield (); // ...is still in scope here, when the yield occurs. println!("{}", a); @@ -23,10 +23,10 @@ resolve the previous example by removing the borrow and just storing the integer by value: ``` -# #![feature(coroutines, coroutine_trait, pin)] +# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; -let mut b = || { +let mut b = #[coroutine] || { let a = 3; yield (); println!("{}", a); @@ -41,10 +41,10 @@ in those cases, something like the `Rc` or `Arc` types may be useful. This error also frequently arises with iteration: ```compile_fail,E0626 -# #![feature(coroutines, coroutine_trait, pin)] +# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; -let mut b = || { +let mut b = #[coroutine] || { let v = vec![1,2,3]; for &x in &v { // <-- borrow of `v` is still in scope... yield x; // ...when this yield occurs. @@ -57,10 +57,10 @@ Such cases can sometimes be resolved by iterating "by value" (or using `into_iter()`) to avoid borrowing: ``` -# #![feature(coroutines, coroutine_trait, pin)] +# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; -let mut b = || { +let mut b = #[coroutine] || { let v = vec![1,2,3]; for x in v { // <-- Take ownership of the values instead! yield x; // <-- Now yield is OK. @@ -72,10 +72,10 @@ Pin::new(&mut b).resume(()); If taking ownership is not an option, using indices can work too: ``` -# #![feature(coroutines, coroutine_trait, pin)] +# #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] # use std::ops::Coroutine; # use std::pin::Pin; -let mut b = || { +let mut b = #[coroutine] || { let v = vec![1,2,3]; let len = v.len(); // (*) for i in 0..len { diff --git a/compiler/rustc_error_codes/src/error_codes/E0627.md b/compiler/rustc_error_codes/src/error_codes/E0627.md index 5d366f78fc57..da2e2d355a16 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0627.md +++ b/compiler/rustc_error_codes/src/error_codes/E0627.md @@ -3,7 +3,7 @@ A yield expression was used outside of the coroutine literal. Erroneous code example: ```compile_fail,E0627 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] fn fake_coroutine() -> &'static str { yield 1; @@ -19,10 +19,10 @@ The error occurs because keyword `yield` can only be used inside the coroutine literal. This can be fixed by constructing the coroutine correctly. ``` -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] fn main() { - let mut coroutine = || { + let mut coroutine = #[coroutine] || { yield 1; return "foo" }; diff --git a/compiler/rustc_error_codes/src/error_codes/E0628.md b/compiler/rustc_error_codes/src/error_codes/E0628.md index ce19bcd56cc7..d0d387cf6c7e 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0628.md +++ b/compiler/rustc_error_codes/src/error_codes/E0628.md @@ -3,10 +3,10 @@ More than one parameter was used for a coroutine. Erroneous code example: ```compile_fail,E0628 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] fn main() { - let coroutine = |a: i32, b: i32| { + let coroutine = #[coroutine] |a: i32, b: i32| { // error: too many parameters for a coroutine // Allowed only 0 or 1 parameter yield a; @@ -20,10 +20,10 @@ at most 1 parameter for the coroutine. For example, we might resolve the previous example by passing only one parameter. ``` -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] fn main() { - let coroutine = |a: i32| { + let coroutine = #[coroutine] |a: i32| { yield a; }; } diff --git a/compiler/rustc_error_codes/src/error_codes/E0727.md b/compiler/rustc_error_codes/src/error_codes/E0727.md index fde35885c920..7754186508f1 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0727.md +++ b/compiler/rustc_error_codes/src/error_codes/E0727.md @@ -3,10 +3,10 @@ A `yield` clause was used in an `async` context. Erroneous code example: ```compile_fail,E0727,edition2018 -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { - let coroutine = || { + let coroutine = #[coroutine] || { async { yield; } @@ -20,10 +20,10 @@ which is not yet supported. To fix this error, you have to move `yield` out of the `async` block: ```edition2018 -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { - let coroutine = || { + let coroutine = #[coroutine] || { yield; }; } diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 1eee11604cef..c0e664f6eeda 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -211,6 +211,8 @@ declare_features! ( (accepted, inclusive_range_syntax, "1.26.0", Some(28237)), /// Allows inferring outlives requirements (RFC 2093). (accepted, infer_outlives_requirements, "1.30.0", Some(44493)), + /// Allow anonymous constants from an inline `const` block + (accepted, inline_const, "CURRENT_RUSTC_VERSION", Some(76001)), /// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). (accepted, irrefutable_let_patterns, "1.33.0", Some(44495)), /// Allows `#[instruction_set(_)]` attribute. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 23b3f31b4370..647cd8d06f26 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -534,6 +534,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes, experimental!(cfi_encoding) ), + // `#[coroutine]` attribute to be applied to closures to make them coroutines instead + gated!( + coroutine, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::No, coroutines, experimental!(coroutines) + ), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 9641d336c3f3..2647f09c8c96 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -501,8 +501,6 @@ declare_features! ( (unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)), /// Allows associated types in inherent impls. (incomplete, inherent_associated_types, "1.52.0", Some(8995)), - /// Allow anonymous constants from an inline `const` block - (unstable, inline_const, "1.49.0", Some(76001)), /// Allow anonymous constants from an inline `const` block in pattern position (unstable, inline_const_pat, "1.58.0", Some(76001)), /// Allows using `pointer` and `reference` in intra-doc links diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs index 3359fef8c1c4..d376c24cb589 100644 --- a/compiler/rustc_fs_util/src/lib.rs +++ b/compiler/rustc_fs_util/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(absolute_path)] - use std::ffi::CString; use std::fs; use std::io; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 4a0df6cf7b86..63da27246a2a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1964,11 +1964,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { try_emit("recursive delegation"); } - let sig = self.tcx().fn_sig(sig_id).instantiate_identity(); - if sig.output().has_opaque_types() { - try_emit("delegation to a function with opaque type"); - } - let sig_generics = self.tcx().generics_of(sig_id); let parent = self.tcx().parent(self.item_def_id()); let parent_generics = self.tcx().generics_of(parent); @@ -1991,29 +1986,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { try_emit("delegation to a trait method from a free function"); } - if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes { - try_emit("delegation to async functions"); - } - - if self.tcx().constness(sig_id) == hir::Constness::Const { - try_emit("delegation to const functions"); - } - - if sig.c_variadic() { - try_emit("delegation to variadic functions"); - // variadic functions are also `unsafe` and `extern "C"`. - // Do not emit same error multiple times. - return error_occured; - } - - if let hir::Unsafety::Unsafe = sig.unsafety() { - try_emit("delegation to unsafe functions"); - } - - if abi::Abi::Rust != sig.abi() { - try_emit("delegation to non Rust ABI functions"); - } - error_occured } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 9ebb5f95f05f..4165fa7f07d1 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1139,7 +1139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // are the same function and their parameters have a LUB. match self.commit_if_ok(|_| { self.at(cause, self.param_env).lub( - DefineOpaqueTypes::No, + DefineOpaqueTypes::Yes, prev_ty, new_ty, ) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index c4ab4eb2657d..fd42c9c1faaf 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1260,30 +1260,34 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { id: DefIndex, sess: &'a Session, ) -> impl Iterator + 'a { - iter::from_coroutine(move || { - if let Some(data) = &self.root.proc_macro_data { - // If we are loading as a proc macro, we want to return - // the view of this crate as a proc macro crate. - if id == CRATE_DEF_INDEX { - for child_index in data.macros.decode(self) { + iter::from_coroutine( + #[cfg_attr(not(bootstrap), coroutine)] + move || { + if let Some(data) = &self.root.proc_macro_data { + // If we are loading as a proc macro, we want to return + // the view of this crate as a proc macro crate. + if id == CRATE_DEF_INDEX { + for child_index in data.macros.decode(self) { + yield self.get_mod_child(child_index, sess); + } + } + } else { + // Iterate over all children. + let non_reexports = + self.root.tables.module_children_non_reexports.get(self, id); + for child_index in non_reexports.unwrap().decode(self) { yield self.get_mod_child(child_index, sess); } - } - } else { - // Iterate over all children. - let non_reexports = self.root.tables.module_children_non_reexports.get(self, id); - for child_index in non_reexports.unwrap().decode(self) { - yield self.get_mod_child(child_index, sess); - } - let reexports = self.root.tables.module_children_reexports.get(self, id); - if !reexports.is_default() { - for reexport in reexports.decode((self, sess)) { - yield reexport; + let reexports = self.root.tables.module_children_reexports.get(self, id); + if !reexports.is_default() { + for reexport in reexports.decode((self, sess)) { + yield reexport; + } } } - } - }) + }, + ) } fn is_ctfe_mir_available(self, id: DefIndex) -> bool { diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index aadaca18326c..501052b7411b 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -35,8 +35,9 @@ #![feature(const_type_name)] #![feature(discriminant_kind)] #![feature(coroutines)] +#![feature(stmt_expr_attributes)] #![feature(if_let_guard)] -#![feature(inline_const)] +#![cfg_attr(bootstrap, feature(inline_const))] #![feature(iter_from_coroutine)] #![feature(negative_impls)] #![feature(never_type)] diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 11167515b7ca..b66c664e6ae1 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -422,49 +422,53 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>( child_captures: impl IntoIterator>, mut for_each: impl FnMut((usize, &'a CapturedPlace<'tcx>), (usize, &'a CapturedPlace<'tcx>)) -> T, ) -> impl Iterator + Captures<'a> + Captures<'tcx> { - std::iter::from_coroutine(move || { - let mut child_captures = child_captures.into_iter().enumerate().peekable(); + std::iter::from_coroutine( + #[cfg_attr(not(bootstrap), coroutine)] + move || { + let mut child_captures = child_captures.into_iter().enumerate().peekable(); - // One parent capture may correspond to several child captures if we end up - // refining the set of captures via edition-2021 precise captures. We want to - // match up any number of child captures with one parent capture, so we keep - // peeking off this `Peekable` until the child doesn't match anymore. - for (parent_field_idx, parent_capture) in parent_captures.into_iter().enumerate() { - // Make sure we use every field at least once, b/c why are we capturing something - // if it's not used in the inner coroutine. - let mut field_used_at_least_once = false; + // One parent capture may correspond to several child captures if we end up + // refining the set of captures via edition-2021 precise captures. We want to + // match up any number of child captures with one parent capture, so we keep + // peeking off this `Peekable` until the child doesn't match anymore. + for (parent_field_idx, parent_capture) in parent_captures.into_iter().enumerate() { + // Make sure we use every field at least once, b/c why are we capturing something + // if it's not used in the inner coroutine. + let mut field_used_at_least_once = false; - // A parent matches a child if they share the same prefix of projections. - // The child may have more, if it is capturing sub-fields out of - // something that is captured by-move in the parent closure. - while child_captures.peek().map_or(false, |(_, child_capture)| { - child_prefix_matches_parent_projections(parent_capture, child_capture) - }) { - let (child_field_idx, child_capture) = child_captures.next().unwrap(); - // This analysis only makes sense if the parent capture is a - // prefix of the child capture. - assert!( - child_capture.place.projections.len() >= parent_capture.place.projections.len(), - "parent capture ({parent_capture:#?}) expected to be prefix of \ + // A parent matches a child if they share the same prefix of projections. + // The child may have more, if it is capturing sub-fields out of + // something that is captured by-move in the parent closure. + while child_captures.peek().map_or(false, |(_, child_capture)| { + child_prefix_matches_parent_projections(parent_capture, child_capture) + }) { + let (child_field_idx, child_capture) = child_captures.next().unwrap(); + // This analysis only makes sense if the parent capture is a + // prefix of the child capture. + assert!( + child_capture.place.projections.len() + >= parent_capture.place.projections.len(), + "parent capture ({parent_capture:#?}) expected to be prefix of \ child capture ({child_capture:#?})" - ); + ); - yield for_each( - (parent_field_idx, parent_capture), - (child_field_idx, child_capture), - ); + yield for_each( + (parent_field_idx, parent_capture), + (child_field_idx, child_capture), + ); - field_used_at_least_once = true; + field_used_at_least_once = true; + } + + // Make sure the field was used at least once. + assert!( + field_used_at_least_once, + "we captured {parent_capture:#?} but it was not used in the child coroutine?" + ); } - - // Make sure the field was used at least once. - assert!( - field_used_at_least_once, - "we captured {parent_capture:#?} but it was not used in the child coroutine?" - ); - } - assert_eq!(child_captures.next(), None, "leftover child captures?"); - }) + assert_eq!(child_captures.next(), None, "leftover child captures?"); + }, + ) } fn child_prefix_matches_parent_projections( diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7dbe59e132d7..45fa5e8f7ca3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1284,20 +1284,23 @@ impl<'tcx> TyCtxt<'tcx> { self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); let definitions = &self.untracked.definitions; - std::iter::from_coroutine(|| { - let mut i = 0; + std::iter::from_coroutine( + #[cfg_attr(not(bootstrap), coroutine)] + || { + let mut i = 0; - // Recompute the number of definitions each time, because our caller may be creating - // new ones. - while i < { definitions.read().num_definitions() } { - let local_def_index = rustc_span::def_id::DefIndex::from_usize(i); - yield LocalDefId { local_def_index }; - i += 1; - } + // Recompute the number of definitions each time, because our caller may be creating + // new ones. + while i < { definitions.read().num_definitions() } { + let local_def_index = rustc_span::def_id::DefIndex::from_usize(i); + yield LocalDefId { local_def_index }; + i += 1; + } - // Freeze definitions once we finish iterating on them, to prevent adding new ones. - definitions.freeze(); - }) + // Freeze definitions once we finish iterating on them, to prevent adding new ones. + definitions.freeze(); + }, + ) } pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cc026e349d74..cda332aee564 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -45,7 +45,7 @@ use rustc_data_structures::unord::UnordMap; use rustc_errors::{Diag, ErrorGuaranteed, StashKey}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet}; +use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; use rustc_index::IndexVec; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; @@ -224,8 +224,15 @@ pub struct ResolverAstLowering { pub lint_buffer: Steal, /// Information about functions signatures for delegation items expansion - pub has_self: LocalDefIdSet, - pub fn_parameter_counts: LocalDefIdMap, + pub delegation_fn_sigs: LocalDefIdMap, +} + +#[derive(Debug)] +pub struct DelegationFnSig { + pub header: ast::FnHeader, + pub param_count: usize, + pub has_self: bool, + pub c_variadic: bool, } #[derive(Clone, Copy, Debug)] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index b308a80f7bad..e42755ca7bf2 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -4,7 +4,7 @@ #![feature(cow_is_borrowed)] #![feature(decl_macro)] #![feature(impl_trait_in_assoc_type)] -#![feature(inline_const)] +#![cfg_attr(bootstrap, feature(inline_const))] #![feature(is_sorted)] #![feature(let_chains)] #![feature(map_try_insert)] diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 84ecd0a0de54..ed51710564a4 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -686,6 +686,8 @@ impl<'a> Parser<'a> { (None, self.parse_path(PathStyle::Expr)?) }; + let rename = if self.eat_keyword(kw::As) { Some(self.parse_ident()?) } else { None }; + let body = if self.check(&token::OpenDelim(Delimiter::Brace)) { Some(self.parse_block()?) } else { @@ -695,11 +697,9 @@ impl<'a> Parser<'a> { let span = span.to(self.prev_token.span); self.psess.gated_spans.gate(sym::fn_delegation, span); - let ident = path.segments.last().map(|seg| seg.ident).unwrap_or(Ident::empty()); - Ok(( - ident, - ItemKind::Delegation(Box::new(Delegation { id: DUMMY_NODE_ID, qself, path, body })), - )) + let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident); + let deleg = Delegation { id: DUMMY_NODE_ID, qself, path, rename, body }; + Ok((ident, ItemKind::Delegation(Box::new(deleg)))) } fn parse_item_list( diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 742f4bd3c834..7486da33b217 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1252,8 +1252,6 @@ impl<'a> Parser<'a> { fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P> { if pat { self.psess.gated_spans.gate(sym::inline_const_pat, span); - } else { - self.psess.gated_spans.gate(sym::inline_const, span); } self.eat_keyword(kw::Const); let (attrs, blk) = self.parse_inner_attrs_and_block()?; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c877ae5e21f4..292af43b602e 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -21,6 +21,7 @@ use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, Par use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate}; use rustc_middle::middle::resolve_bound_vars::Set1; +use rustc_middle::ty::DelegationFnSig; use rustc_middle::{bug, span_bug}; use rustc_session::config::{CrateType, ResolveDocLinks}; use rustc_session::lint; @@ -4749,12 +4750,13 @@ struct ItemInfoCollector<'a, 'b, 'tcx> { impl ItemInfoCollector<'_, '_, '_> { fn collect_fn_info(&mut self, sig: &FnSig, id: NodeId) { - let def_id = self.r.local_def_id(id); - self.r.fn_parameter_counts.insert(def_id, sig.decl.inputs.len()); - - if sig.decl.has_self() { - self.r.has_self.insert(def_id); - } + let sig = DelegationFnSig { + header: sig.header, + param_count: sig.decl.inputs.len(), + has_self: sig.decl.has_self(), + c_variadic: sig.decl.c_variadic(), + }; + self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig); } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index d79c638fa078..64451030adf0 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2039,7 +2039,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ast::AssocItemKind::Fn(..) => AssocSuggestion::AssocFn { called }, ast::AssocItemKind::Type(..) => AssocSuggestion::AssocType, ast::AssocItemKind::Delegation(..) - if self.r.has_self.contains(&self.r.local_def_id(assoc_item.id)) => + if self.r.delegation_fn_sigs[&self.r.local_def_id(assoc_item.id)] + .has_self => { AssocSuggestion::MethodWithSelf { called } } @@ -2062,7 +2063,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if filter_fn(res) { let def_id = res.def_id(); let has_self = match def_id.as_local() { - Some(def_id) => self.r.has_self.contains(&def_id), + Some(def_id) => { + self.r.delegation_fn_sigs.get(&def_id).map_or(false, |sig| sig.has_self) + } None => self .r .tcx diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b5b6d899cc58..e07c3247d07a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -43,7 +43,7 @@ use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::NonMacroAttrKind; use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS}; -use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet}; +use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::IndexVec; @@ -52,8 +52,8 @@ use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; use rustc_middle::span_bug; -use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt, TyCtxtFeed}; -use rustc_middle::ty::{Feed, ResolverGlobalCtxt, ResolverOutputs}; +use rustc_middle::ty::{self, DelegationFnSig, Feed, MainDefinition, RegisteredTools}; +use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs, TyCtxt, TyCtxtFeed}; use rustc_query_system::ich::StableHashingContext; use rustc_session::lint::builtin::PRIVATE_MACRO_USE; use rustc_session::lint::LintBuffer; @@ -992,7 +992,6 @@ pub struct Resolver<'a, 'tcx> { extern_prelude: FxHashMap>, /// N.B., this is used only for better diagnostics, not name resolution itself. - has_self: LocalDefIdSet, field_def_ids: LocalDefIdMap<&'tcx [DefId]>, /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax. @@ -1149,8 +1148,7 @@ pub struct Resolver<'a, 'tcx> { legacy_const_generic_args: FxHashMap>>, /// Amount of lifetime parameters for each item in the crate. item_generics_num_lifetimes: FxHashMap, - /// Amount of parameters for each function in the crate. - fn_parameter_counts: LocalDefIdMap, + delegation_fn_sigs: LocalDefIdMap, main_def: Option, trait_impls: FxIndexMap>, @@ -1399,7 +1397,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { prelude: None, extern_prelude, - has_self: Default::default(), field_def_ids: Default::default(), field_visibility_spans: FxHashMap::default(), @@ -1508,7 +1505,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { doc_link_resolutions: Default::default(), doc_link_traits_in_scope: Default::default(), all_macro_rules: Default::default(), - fn_parameter_counts: Default::default(), + delegation_fn_sigs: Default::default(), }; let root_parent_scope = ParentScope::module(graph_root, &resolver); @@ -1621,8 +1618,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { trait_map: self.trait_map, lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), - has_self: self.has_self, - fn_parameter_counts: self.fn_parameter_counts, + delegation_fn_sigs: self.delegation_fn_sigs, }; ResolverOutputs { global_ctxt, ast_lowering } } diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 3e1d8f3828bb..19f4e6994acf 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -11,7 +11,7 @@ #![cfg_attr(bootstrap, feature(associated_type_bounds))] #![feature(const_option)] #![feature(core_intrinsics)] -#![feature(inline_const)] +#![cfg_attr(bootstrap, feature(inline_const))] #![feature(min_specialization)] #![feature(never_type)] #![feature(ptr_sub_ptr)] diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 07c116631737..4f259960ac3a 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1888,9 +1888,12 @@ fn collect_print_requests( let prints = PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::>(); let prints = prints.join(", "); - early_dcx.early_fatal(format!( - "unknown print request `{req}`. Valid print requests are: {prints}" - )); + + let mut diag = + early_dcx.early_struct_fatal(format!("unknown print request: `{req}`")); + #[allow(rustc::diagnostic_outside_of_impl)] + diag.help(format!("valid print requests are: {prints}")); + diag.emit() } }; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8abf42e2c139..99591b5e1440 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -192,6 +192,7 @@ symbols! { Duration, Encodable, Encoder, + Enumerate, Eq, Equal, Err, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 837b784f2725..e50edfdc656c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -50,22 +50,38 @@ pub struct FindExprBySpan<'hir> { pub span: Span, pub result: Option<&'hir hir::Expr<'hir>>, pub ty_result: Option<&'hir hir::Ty<'hir>>, + pub include_closures: bool, + pub tcx: TyCtxt<'hir>, } impl<'hir> FindExprBySpan<'hir> { - pub fn new(span: Span) -> Self { - Self { span, result: None, ty_result: None } + pub fn new(span: Span, tcx: TyCtxt<'hir>) -> Self { + Self { span, result: None, ty_result: None, tcx, include_closures: false } } } impl<'v> Visitor<'v> for FindExprBySpan<'v> { + type NestedFilter = rustc_middle::hir::nested_filter::OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.tcx.hir() + } + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { if self.span == ex.span { self.result = Some(ex); } else { + if let hir::ExprKind::Closure(..) = ex.kind + && self.include_closures + && let closure_header_sp = self.span.with_hi(ex.span.hi()) + && closure_header_sp == ex.span + { + self.result = Some(ex); + } hir::intravisit::walk_expr(self, ex); } } + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { if self.span == ty.span { self.ty_result = Some(ty); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 9d3caaa01abd..cc879c42ce95 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -901,7 +901,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Remove all the desugaring and macro contexts. span.remove_mark(); } - let mut expr_finder = FindExprBySpan::new(span); + let mut expr_finder = FindExprBySpan::new(span, self.tcx); let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return; }; @@ -1367,7 +1367,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return false; }; let body = self.tcx.hir().body(body_id); - let mut expr_finder = FindExprBySpan::new(span); + let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(body.value); let Some(expr) = expr_finder.result else { return false; @@ -1469,7 +1469,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Remove all the hir desugaring contexts while maintaining the macro contexts. span.remove_mark(); } - let mut expr_finder = super::FindExprBySpan::new(span); + let mut expr_finder = super::FindExprBySpan::new(span, self.tcx); let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; }; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 0e309689680a..1971136e54c7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -2457,7 +2457,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) { - let mut expr_finder = FindExprBySpan::new(span); + let mut expr_finder = FindExprBySpan::new(span, self.tcx); expr_finder.visit_expr(self.tcx.hir().body(body_id).value); if let Some(hir::Expr { diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 3be0be83e09e..3924b371bbce 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -183,7 +183,7 @@ pub enum TyKind { /// /// ``` /// #![feature(coroutines)] - /// static |a| { + /// #[coroutine] static |a| { /// let x = &vec![3]; /// yield a; /// yield x[0]; diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index c54f0062824a..846b9a1404d2 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -31,7 +31,7 @@ //! // instead of a max-heap. //! impl Ord for State { //! fn cmp(&self, other: &Self) -> Ordering { -//! // Notice that the we flip the ordering on costs. +//! // Notice that we flip the ordering on costs. //! // In case of a tie we compare positions - this step is necessary //! // to make implementations of `PartialEq` and `Ord` consistent. //! other.cost.cmp(&self.cost) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 88faf5a9c7d6..b417513aaa23 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -128,7 +128,6 @@ #![feature(fn_traits)] #![feature(hasher_prefixfree_extras)] #![feature(hint_assert_unchecked)] -#![feature(inline_const)] #![feature(inplace_iteration)] #![feature(iter_advance_by)] #![feature(iter_next_chunk)] @@ -169,6 +168,7 @@ // Language features: // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(associated_type_bounds))] +#![cfg_attr(bootstrap, feature(inline_const))] #![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] #![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(test, feature(panic_update_hook))] diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index ef46040f0a70..7adbabf69e49 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -15,6 +15,7 @@ use crate::ops::Try; #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "Enumerate")] pub struct Enumerate { iter: I, count: usize, diff --git a/library/core/src/iter/sources/from_coroutine.rs b/library/core/src/iter/sources/from_coroutine.rs index bf413b24d417..9bac9037a024 100644 --- a/library/core/src/iter/sources/from_coroutine.rs +++ b/library/core/src/iter/sources/from_coroutine.rs @@ -14,7 +14,7 @@ use crate::pin::Pin; /// #![feature(coroutines)] /// #![feature(iter_from_coroutine)] /// -/// let it = std::iter::from_coroutine(|| { +/// let it = std::iter::from_coroutine(#[cfg_attr(not(bootstrap), coroutine)] || { /// yield 1; /// yield 2; /// yield 3; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 154565b6fee1..6925a7d1da1f 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -201,6 +201,7 @@ // // Language features: // tidy-alphabetical-start +#![cfg_attr(bootstrap, feature(inline_const))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -231,7 +232,6 @@ #![feature(fundamental)] #![feature(generic_arg_infer)] #![feature(if_let_guard)] -#![feature(inline_const)] #![feature(intra_doc_pointers)] #![feature(intrinsics)] #![feature(lang_items)] diff --git a/library/core/src/ops/coroutine.rs b/library/core/src/ops/coroutine.rs index 6e067f95da92..5250be15fe43 100644 --- a/library/core/src/ops/coroutine.rs +++ b/library/core/src/ops/coroutine.rs @@ -40,12 +40,13 @@ pub enum CoroutineState { /// ```rust /// #![feature(coroutines)] /// #![feature(coroutine_trait)] +/// #![feature(stmt_expr_attributes)] /// /// use std::ops::{Coroutine, CoroutineState}; /// use std::pin::Pin; /// /// fn main() { -/// let mut coroutine = || { +/// let mut coroutine = #[cfg_attr(not(bootstrap), coroutine)] || { /// yield 1; /// "foo" /// }; diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index efd525aeb3b7..a11c6c742d7d 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -1809,7 +1809,7 @@ impl DispatchFromDyn> for Pin where Ptr: DispatchFromDyn /// fn coroutine_fn() -> impl Coroutine /* not Unpin */ { /// // Allow coroutine to be self-referential (not `Unpin`) /// // vvvvvv so that locals can cross yield points. -/// static || { +/// #[cfg_attr(not(bootstrap), coroutine)] static || { /// let foo = String::from("foo"); /// let foo_ref = &foo; // ------+ /// yield 0; // | <- crosses yield point! diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index c8fd997a5da6..073459fcb003 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -511,7 +511,8 @@ impl AtomicBool { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, inline_const)] + /// #![feature(atomic_from_mut)] + /// # #![cfg_attr(bootstrap, feature(inline_const))] /// use std::sync::atomic::{AtomicBool, Ordering}; /// /// let mut some_bools = [const { AtomicBool::new(false) }; 10]; @@ -1313,7 +1314,8 @@ impl AtomicPtr { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, inline_const)] + /// #![feature(atomic_from_mut)] + /// # #![cfg_attr(bootstrap, feature(inline_const))] /// use std::ptr::null_mut; /// use std::sync::atomic::{AtomicPtr, Ordering}; /// @@ -2303,7 +2305,8 @@ macro_rules! atomic_int { /// # Examples /// /// ``` - /// #![feature(atomic_from_mut, inline_const)] + /// #![feature(atomic_from_mut)] + /// # #![cfg_attr(bootstrap, feature(inline_const))] #[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")] /// #[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 7bd962fa2609..d6e705a37a71 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -46,7 +46,7 @@ #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] #![feature(try_find)] -#![feature(inline_const)] +#![cfg_attr(bootstrap, feature(inline_const))] #![feature(is_sorted)] #![feature(layout_for_ptr)] #![feature(pattern)] diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs index 48514e52587f..331b66262490 100644 --- a/library/portable-simd/crates/core_simd/src/lib.rs +++ b/library/portable-simd/crates/core_simd/src/lib.rs @@ -7,7 +7,6 @@ convert_float_to_int, core_intrinsics, decl_macro, - inline_const, intra_doc_pointers, repr_simd, simd_ffi, diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 0636f55771ee..1c58671a0cf7 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -3332,7 +3332,6 @@ impl Error for StripPrefixError { /// ## Posix paths /// /// ``` -/// #![feature(absolute_path)] /// # #[cfg(unix)] /// fn main() -> std::io::Result<()> { /// use std::path::{self, Path}; @@ -3357,7 +3356,6 @@ impl Error for StripPrefixError { /// ## Windows paths /// /// ``` -/// #![feature(absolute_path)] /// # #[cfg(windows)] /// fn main() -> std::io::Result<()> { /// use std::path::{self, Path}; @@ -3382,7 +3380,7 @@ impl Error for StripPrefixError { /// /// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 /// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew -#[unstable(feature = "absolute_path", issue = "92750")] +#[stable(feature = "absolute_path", since = "CURRENT_RUSTC_VERSION")] pub fn absolute>(path: P) -> io::Result { let path = path.as_ref(); if path.as_os_str().is_empty() { diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index b49585599cb3..ff41f6e77be7 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -201,14 +201,21 @@ pub fn to_u16s>(s: S) -> crate::io::Result> { // currently reside in the buffer. This function is an abstraction over these // functions by making them easier to call. // -// The first callback, `f1`, is yielded a (pointer, len) pair which can be +// The first callback, `f1`, is passed a (pointer, len) pair which can be // passed to a syscall. The `ptr` is valid for `len` items (u16 in this case). -// The closure is expected to return what the syscall returns which will be -// interpreted by this function to determine if the syscall needs to be invoked -// again (with more buffer space). +// The closure is expected to: +// - On success, return the actual length of the written data *without* the null terminator. +// This can be 0. In this case the last_error must be left unchanged. +// - On insufficient buffer space, +// - either return the required length *with* the null terminator, +// - or set the last-error to ERROR_INSUFFICIENT_BUFFER and return `len`. +// - On other failure, return 0 and set last_error. +// +// This is how most but not all syscalls indicate the required buffer space. +// Other syscalls may need translation to match this protocol. // // Once the syscall has completed (errors bail out early) the second closure is -// yielded the data which has been read from the syscall. The return value +// passed the data which has been read from the syscall. The return value // from this closure is then the return value of the function. pub fn fill_utf16_buf(mut f1: F1, f2: F2) -> crate::io::Result where diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index 374c9845ea4b..64d8b72aed28 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -326,6 +326,8 @@ fn home_dir_crt() -> Option { super::fill_utf16_buf( |buf, mut sz| { + // GetUserProfileDirectoryW does not quite use the usual protocol for + // negotiating the buffer size, so we have to translate. match c::GetUserProfileDirectoryW( ptr::without_provenance_mut(CURRENT_PROCESS_TOKEN), buf, diff --git a/library/std/src/sys/pal/windows/thread_local_key.rs b/library/std/src/sys/pal/windows/thread_local_key.rs index 4c00860dae38..e5ba619fc6ba 100644 --- a/library/std/src/sys/pal/windows/thread_local_key.rs +++ b/library/std/src/sys/pal/windows/thread_local_key.rs @@ -141,9 +141,15 @@ impl StaticKey { panic!("out of TLS indexes"); } - self.key.store(key + 1, Release); register_dtor(self); + // Release-storing the key needs to be the last thing we do. + // This is because in `fn key()`, other threads will do an acquire load of the key, + // and if that sees this write then it will entirely bypass the `InitOnce`. We thus + // need to establish synchronization through `key`. In particular that acquire load + // must happen-after the register_dtor above, to ensure the dtor actually runs! + self.key.store(key + 1, Release); + let r = c::InitOnceComplete(self.once.get(), 0, ptr::null_mut()); debug_assert_eq!(r, c::TRUE); @@ -313,8 +319,22 @@ unsafe fn run_dtors() { // Use acquire ordering to observe key initialization. let mut cur = DTORS.load(Acquire); while !cur.is_null() { - let key = (*cur).key.load(Relaxed) - 1; + let pre_key = (*cur).key.load(Acquire); let dtor = (*cur).dtor.unwrap(); + cur = (*cur).next.load(Relaxed); + + // In StaticKey::init, we register the dtor before setting `key`. + // So if one thread's `run_dtors` races with another thread executing `init` on the same + // `StaticKey`, we can encounter a key of 0 here. That means this key was never + // initialized in this thread so we can safely skip it. + if pre_key == 0 { + continue; + } + // If this is non-zero, then via the `Acquire` load above we synchronized with + // everything relevant for this key. (It's not clear that this is needed, since the + // release-acquire pair on DTORS also establishes synchronization, but better safe than + // sorry.) + let key = pre_key - 1; let ptr = c::TlsGetValue(key); if !ptr.is_null() { @@ -322,8 +342,6 @@ unsafe fn run_dtors() { dtor(ptr as *mut _); any_run = true; } - - cur = (*cur).next.load(Relaxed); } if !any_run { diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh index d6de992913bf..9cc508fe9288 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh @@ -5,7 +5,7 @@ set -euf -o pipefail -INTEGRATION_SHA=56310bca298872ffb5ea02e665956d9b6dc41171 +INTEGRATION_SHA=1011e3298775ee7cdf6f6dc73e808d6a86e33bd6 PICK_REFS=() checkout=fuchsia diff --git a/src/ci/docker/scripts/build-fuchsia-toolchain.sh b/src/ci/docker/scripts/build-fuchsia-toolchain.sh index beea2f522fde..7a0d4fcffc15 100755 --- a/src/ci/docker/scripts/build-fuchsia-toolchain.sh +++ b/src/ci/docker/scripts/build-fuchsia-toolchain.sh @@ -4,13 +4,13 @@ set -ex source shared.sh FUCHSIA_SDK_URL=https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/linux-amd64 -FUCHSIA_SDK_ID=MrhQwtmP8CpZre-i_PNOREcThbUcrX3bA-45d6WQr-cC -FUCHSIA_SDK_SHA256=32b850c2d98ff02a59adefa2fcf34e44471385b51cad7ddb03ee3977a590afe7 +FUCHSIA_SDK_ID=version:20.20240412.3.1 +FUCHSIA_SDK_SHA256=cc52f3497487dd813c89d9316e6967efcea89c7759edccf3e40fcf3662e53f19 FUCHSIA_SDK_USR_DIR=/usr/local/core-linux-amd64-fuchsia-sdk CLANG_DOWNLOAD_URL=\ https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64 -CLANG_DOWNLOAD_ID=Tpc85d1ZwSlZ6UKl2d96GRUBGNA5JKholOKe24sRDr0C -CLANG_DOWNLOAD_SHA256=4e973ce5dd59c12959e942a5d9df7a19150118d03924a86894e29edb8b110ebd +CLANG_DOWNLOAD_ID=git_revision:c777c011a709dffd4fa5e79cad7947b7c3405d02 +CLANG_DOWNLOAD_SHA256=779167422ad73c292f049dcea5569f84577af9292189ed2749518b966a4d0844 install_clang() { mkdir -p clang_download diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index 437b51641fc9..8ac00a8863f6 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -280,7 +280,7 @@ class TestEnvironment: # Look up the product bundle transfer manifest. self.log_info("Looking up the product bundle transfer manifest...") product_name = "minimal." + self.triple_to_arch(self.target) - fuchsia_version = "14.20230811.2.1" + fuchsia_version = "20.20240412.3.1" # FIXME: We should be able to replace this with the machine parsable # `ffx --machine json product lookup ...` once F15 is released. diff --git a/src/ci/github-actions/calculate-job-matrix.py b/src/ci/github-actions/calculate-job-matrix.py new file mode 100755 index 000000000000..c24cefa8d896 --- /dev/null +++ b/src/ci/github-actions/calculate-job-matrix.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +""" +This script serves for generating a matrix of jobs that should +be executed on CI. + +It reads job definitions from `src/ci/github-actions/jobs.yml` +and filters them based on the event that happened on CI. +""" +import dataclasses +import enum +import json +import logging +import os +from pathlib import Path +from typing import List, Dict, Any, Optional + +import yaml + +JOBS_YAML_PATH = Path(__file__).absolute().parent / "jobs.yml" + + +def name_jobs(jobs: List[Dict], prefix: str) -> List[Dict]: + """ + Add a `name` attribute to each job, based on its image and the given `prefix`. + """ + for job in jobs: + job["name"] = f"{prefix} - {job['image']}" + return jobs + + +def add_base_env(jobs: List[Dict], environment: Dict[str, str]) -> List[Dict]: + """ + Prepends `environment` to the `env` attribute of each job. + The `env` of each job has higher precedence than `environment`. + """ + for job in jobs: + env = environment.copy() + env.update(job.get("env", {})) + job["env"] = env + return jobs + + +class JobType(enum.Enum): + PR = enum.auto() + Try = enum.auto() + Auto = enum.auto() + + +@dataclasses.dataclass +class GitHubCtx: + event_name: str + ref: str + repository: str + + +def find_job_type(ctx: GitHubCtx) -> Optional[JobType]: + if ctx.event_name == "pull_request": + return JobType.PR + elif ctx.event_name == "push": + old_bors_try_build = ( + ctx.ref in ("refs/heads/try", "refs/heads/try-perf") and + ctx.repository == "rust-lang-ci/rust" + ) + new_bors_try_build = ( + ctx.ref == "refs/heads/automation/bors/try" and + ctx.repository == "rust-lang/rust" + ) + try_build = old_bors_try_build or new_bors_try_build + + if try_build: + return JobType.Try + + if ctx.ref == "refs/heads/auto" and ctx.repository == "rust-lang-ci/rust": + return JobType.Auto + + return None + + +def calculate_jobs(job_type: JobType, job_data: Dict[str, Any]) -> List[Dict[str, Any]]: + if job_type == JobType.PR: + return add_base_env(name_jobs(job_data["pr"], "PR"), job_data["envs"]["pr"]) + elif job_type == JobType.Try: + return add_base_env(name_jobs(job_data["try"], "try"), job_data["envs"]["try"]) + elif job_type == JobType.Auto: + return add_base_env(name_jobs(job_data["auto"], "auto"), job_data["envs"]["auto"]) + + return [] + + +def get_github_ctx() -> GitHubCtx: + return GitHubCtx( + event_name=os.environ["GITHUB_EVENT_NAME"], + ref=os.environ["GITHUB_REF"], + repository=os.environ["GITHUB_REPOSITORY"] + ) + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + + with open(JOBS_YAML_PATH) as f: + data = yaml.safe_load(f) + + github_ctx = get_github_ctx() + + job_type = find_job_type(github_ctx) + logging.info(f"Job type: {job_type}") + + jobs = [] + if job_type is not None: + jobs = calculate_jobs(job_type, data) + + logging.info(f"Output:\n{yaml.dump(jobs, indent=4)}") + print(f"jobs={json.dumps(jobs)}") diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index de71b9f874f8..19d6b517552f 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -342,6 +342,8 @@ concurrency: jobs: # The job matrix for `calculate_matrix` is defined in src/ci/github-actions/jobs.yml. + # It calculates which jobs should be executed, based on the data of the ${{ github }} context. + # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml. calculate_matrix: name: Calculate job matrix runs-on: ubuntu-latest @@ -351,422 +353,34 @@ jobs: - name: Checkout the source code uses: actions/checkout@v4 - name: Calculate the CI job matrix - run: python3 src/ci/scripts/calculate-job-matrix.py >> $GITHUB_OUTPUT + run: python3 src/ci/github-actions/calculate-job-matrix.py >> $GITHUB_OUTPUT id: jobs - pr: + job: <<: *base-ci-job - name: PR - ${{ matrix.name }} + name: ${{ matrix.name }} needs: [ calculate_matrix ] env: - <<: [*shared-ci-variables, *public-variables] - PR_CI_JOB: 1 - if: github.event_name == 'pull_request' - continue-on-error: ${{ matrix.name == 'mingw-check-tidy' }} + CI_JOB_NAME: ${{ matrix.image }} + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs. + HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SCCACHE_BUCKET: rust-lang-ci-sccache2 + TOOLSTATE_REPO: https://github.com/rust-lang-nursery/rust-toolstate + CACHE_DOMAIN: ci-caches.rust-lang.org + continue-on-error: ${{ matrix.continue_on_error || false }} strategy: matrix: # Check the `calculate_matrix` job to see how is the matrix defined. include: ${{ fromJSON(needs.calculate_matrix.outputs.jobs) }} - - auto: - <<: *base-ci-job - name: auto - ${{ matrix.name }} - env: - <<: [*shared-ci-variables, *prod-variables] - if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' - strategy: - matrix: - include: - ############################# - # Linux/Docker builders # - ############################# - - - name: aarch64-gnu - <<: *job-aarch64-linux - - - name: arm-android - <<: *job-linux-8c - - - name: armhf-gnu - <<: *job-linux-8c - - - name: dist-aarch64-linux - env: - CODEGEN_BACKENDS: llvm,cranelift - <<: *job-linux-8c - - - name: dist-android - <<: *job-linux-8c - - - name: dist-arm-linux - <<: *job-linux-16c - - - name: dist-armhf-linux - <<: *job-linux-8c - - - name: dist-armv7-linux - <<: *job-linux-8c - - - name: dist-i586-gnu-i586-i686-musl - <<: *job-linux-8c - - - name: dist-i686-linux - <<: *job-linux-8c - - - name: dist-loongarch64-linux - <<: *job-linux-8c - - - name: dist-ohos - <<: *job-linux-8c - - - name: dist-powerpc-linux - <<: *job-linux-8c - - - name: dist-powerpc64-linux - <<: *job-linux-8c - - - name: dist-powerpc64le-linux - <<: *job-linux-8c - - - name: dist-riscv64-linux - <<: *job-linux-8c - - - name: dist-s390x-linux - <<: *job-linux-8c - - - name: dist-various-1 - <<: *job-linux-8c - - - name: dist-various-2 - <<: *job-linux-8c - - - name: dist-x86_64-freebsd - <<: *job-linux-8c - - - name: dist-x86_64-illumos - <<: *job-linux-8c - - - &dist-x86_64-linux - name: dist-x86_64-linux - env: - CODEGEN_BACKENDS: llvm,cranelift - <<: *job-linux-16c - - - name: dist-x86_64-linux-alt - env: - IMAGE: dist-x86_64-linux - CODEGEN_BACKENDS: llvm,cranelift - <<: *job-linux-16c - - - name: dist-x86_64-musl - env: - CODEGEN_BACKENDS: llvm,cranelift - <<: *job-linux-8c - - - name: dist-x86_64-netbsd - <<: *job-linux-8c - - - name: i686-gnu - <<: *job-linux-8c - - - name: i686-gnu-nopt - <<: *job-linux-8c - - - name: mingw-check - <<: *job-linux-4c - - - name: test-various - <<: *job-linux-8c - - - name: x86_64-gnu - <<: *job-linux-4c - - # This job ensures commits landing on nightly still pass the full - # test suite on the stable channel. There are some UI tests that - # depend on the channel being built (for example if they include the - # channel name on the output), and this builder prevents landing - # changes that would result in broken builds after a promotion. - - name: x86_64-gnu-stable - env: - IMAGE: x86_64-gnu - RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable - # Only run this job on the nightly channel. Running this on beta - # could cause failures when `dev: 1` in `stage0.txt`, and running - # this on stable is useless. - CI_ONLY_WHEN_CHANNEL: nightly - <<: *job-linux-4c - - - name: x86_64-gnu-aux - <<: *job-linux-4c - - - name: x86_64-gnu-integration - env: - # Only run this job on the nightly channel. Fuchsia requires - # nightly features to compile, and this job would fail if - # executed on beta and stable. - CI_ONLY_WHEN_CHANNEL: nightly - <<: *job-linux-8c - - - name: x86_64-gnu-debug - <<: *job-linux-8c - - - name: x86_64-gnu-distcheck - <<: *job-linux-8c - - - name: x86_64-gnu-llvm-18 - env: - RUST_BACKTRACE: 1 - <<: *job-linux-8c - - - name: x86_64-gnu-llvm-17 - env: - RUST_BACKTRACE: 1 - <<: *job-linux-8c - - - name: x86_64-gnu-nopt - <<: *job-linux-4c - - - name: x86_64-gnu-tools - env: - DEPLOY_TOOLSTATES_JSON: toolstates-linux.json - <<: *job-linux-8c - - #################### - # macOS Builders # - #################### - - - name: dist-x86_64-apple - env: - SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin - RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1 - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_14.3.1.app - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - CODEGEN_BACKENDS: llvm,cranelift - <<: *job-macos-xl - - - name: dist-apple-various - env: - SCRIPT: ./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim - RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_14.3.1.app - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - <<: *job-macos-xl - - - name: x86_64-apple-1 - env: &env-x86_64-apple-tests - SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps - RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - MACOSX_DEPLOYMENT_TARGET: 10.12 - MACOSX_STD_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_14.3.1.app - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - <<: *job-macos-xl - - - name: x86_64-apple-2 - env: - SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps - <<: *env-x86_64-apple-tests - <<: *job-macos-xl - - # This target only needs to support 11.0 and up as nothing else supports the hardware - - name: dist-aarch64-apple - env: - SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin - RUST_CONFIGURE_ARGS: >- - --enable-full-tools - --enable-sanitizers - --enable-profiler - --set rust.jemalloc - --set llvm.ninja=false - --set rust.lto=thin - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - SELECT_XCODE: /Applications/Xcode_14.3.1.app - USE_XCODE_CLANG: 1 - MACOSX_DEPLOYMENT_TARGET: 11.0 - MACOSX_STD_DEPLOYMENT_TARGET: 11.0 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-macos-m1 - - # This target only needs to support 11.0 and up as nothing else supports the hardware - - name: aarch64-apple - env: - SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin - RUST_CONFIGURE_ARGS: >- - --enable-sanitizers - --enable-profiler - --set rust.jemalloc - RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - SELECT_XCODE: /Applications/Xcode_14.3.1.app - USE_XCODE_CLANG: 1 - MACOSX_DEPLOYMENT_TARGET: 11.0 - MACOSX_STD_DEPLOYMENT_TARGET: 11.0 - NO_LLVM_ASSERTIONS: 1 - NO_DEBUG_ASSERTIONS: 1 - NO_OVERFLOW_CHECKS: 1 - <<: *job-macos-m1 - - ###################### - # Windows Builders # - ###################### - - - name: x86_64-msvc - env: - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler - SCRIPT: make ci-msvc - <<: *job-windows-8c - - - name: i686-msvc - env: - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc - SCRIPT: make ci-msvc - <<: *job-windows-8c - - - name: x86_64-msvc-ext - env: - SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows - HOST_TARGET: x86_64-pc-windows-msvc - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json - DEPLOY_TOOLSTATES_JSON: toolstates-windows.json - <<: *job-windows-8c - - # 32/64-bit MinGW builds. - # - # We are using MinGW with POSIX threads since LLVM requires - # C++'s std::thread which is disabled in libstdc++ with win32 threads. - # FIXME: Libc++ doesn't have this limitation so we can avoid - # winpthreads if we switch to it. - # - # Instead of relying on the MinGW version installed on CI we download - # and install one ourselves so we won't be surprised by changes to CI's - # build image. - # - # Finally, note that the downloads below are all in the `rust-lang-ci` S3 - # bucket, but they clearly didn't originate there! The downloads originally - # came from the mingw-w64 SourceForge download site. Unfortunately - # SourceForge is notoriously flaky, so we mirror it on our own infrastructure. - - - name: i686-mingw - env: - RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu - SCRIPT: make ci-mingw - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). - NO_DOWNLOAD_CI_LLVM: 1 - CUSTOM_MINGW: 1 - <<: *job-windows-8c - - - name: x86_64-mingw - env: - SCRIPT: make ci-mingw - RUST_CONFIGURE_ARGS: >- - --build=x86_64-pc-windows-gnu - --enable-profiler - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). - NO_DOWNLOAD_CI_LLVM: 1 - CUSTOM_MINGW: 1 - <<: *job-windows-8c - - - name: dist-x86_64-msvc - env: - RUST_CONFIGURE_ARGS: >- - --build=x86_64-pc-windows-msvc - --host=x86_64-pc-windows-msvc - --target=x86_64-pc-windows-msvc - --enable-full-tools - --enable-profiler - --set rust.codegen-units=1 - SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths - DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-windows-8c - - - name: dist-i686-msvc - env: - RUST_CONFIGURE_ARGS: >- - --build=i686-pc-windows-msvc - --host=i686-pc-windows-msvc - --target=i686-pc-windows-msvc,i586-pc-windows-msvc - --enable-full-tools - --enable-profiler - SCRIPT: python x.py dist bootstrap --include-default-paths - DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-windows-8c - - - name: dist-aarch64-msvc - env: - RUST_CONFIGURE_ARGS: >- - --build=x86_64-pc-windows-msvc - --host=aarch64-pc-windows-msvc - --enable-full-tools - --enable-profiler - SCRIPT: python x.py dist bootstrap --include-default-paths - DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-windows-8c - - - name: dist-i686-mingw - env: - RUST_CONFIGURE_ARGS: >- - --build=i686-pc-windows-gnu - --enable-full-tools - --enable-profiler - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). - NO_DOWNLOAD_CI_LLVM: 1 - SCRIPT: python x.py dist bootstrap --include-default-paths - CUSTOM_MINGW: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-windows-8c - - - name: dist-x86_64-mingw - env: - SCRIPT: python x.py dist bootstrap --include-default-paths - RUST_CONFIGURE_ARGS: >- - --build=x86_64-pc-windows-gnu - --enable-full-tools - --enable-profiler - # We are intentionally allowing an old toolchain on this builder (and that's - # incompatible with LLVM downloads today). - NO_DOWNLOAD_CI_LLVM: 1 - CUSTOM_MINGW: 1 - DIST_REQUIRE_ALL_TOOLS: 1 - <<: *job-windows-8c - - - name: dist-x86_64-msvc-alt - env: - RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler - SCRIPT: python x.py dist bootstrap --include-default-paths - <<: *job-windows-8c - - try: - <<: *base-ci-job - name: try - ${{ matrix.name }} - env: - DIST_TRY_BUILD: 1 - <<: [*shared-ci-variables, *prod-variables] - if: github.event_name == 'push' && (((github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust') || ((github.ref == 'refs/heads/automation/bors/try') && github.repository == 'rust-lang/rust')) - strategy: - matrix: - include: - - &dist-x86_64-linux - name: dist-x86_64-linux - env: - CODEGEN_BACKENDS: llvm,cranelift - <<: *job-linux-16c - + # GitHub Actions fails the workflow if an empty list of jobs is provided to + # the workflow, so we need to skip this job if nothing was produced by + # the Python script. + # + # Unfortunately checking whether a list is empty is not possible in a nice + # way due to GitHub Actions expressions limits. + # This hack is taken from https://github.com/ferrocene/ferrocene/blob/d43edc6b7697cf1719ec1c17c54904ab94825763/.github/workflows/release.yml#L75-L82 + if: fromJSON(needs.calculate_matrix.outputs.jobs)[0] != null master: name: master @@ -791,18 +405,18 @@ jobs: # build completed, as there is no practical way to detect when a workflow is # successful listening to webhooks only. try-success: - needs: [try] + needs: [ job ] if: "success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" <<: *base-success-job try-failure: - needs: [try] + needs: [ job ] if: "!success() && github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust'" <<: *base-failure-job auto-success: - needs: [auto] + needs: [ job ] if: "success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" <<: *base-success-job auto-failure: - needs: [auto] + needs: [ job ] if: "!success() && github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust'" <<: *base-failure-job diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 7e89eef2670e..ec58bd0924e8 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -2,7 +2,7 @@ # dynamically in CI from ci.yml. # You *do not* need to re-run `src/tools/expand-yaml-anchors` when you # modify this file. -shared_defs: +runners: - &base-job env: { } @@ -37,14 +37,430 @@ shared_defs: - &job-aarch64-linux os: [ self-hosted, ARM64, linux ] +envs: + production: + &production + DEPLOY_BUCKET: rust-lang-ci2 + TOOLSTATE_ISSUES_API_URL: https://api.github.com/repos/rust-lang/rust/issues + TOOLSTATE_PUBLISH: 1 + # AWS_SECRET_ACCESS_KEYs are stored in GitHub's secrets storage, named + # AWS_SECRET_ACCESS_KEY_. Including the key id in the name allows to + # rotate them in a single branch while keeping the old key in another + # branch, which wouldn't be possible if the key was named with the kind + # (caches, artifacts...). + CACHES_AWS_ACCESS_KEY_ID: AKIA46X5W6CZI5DHEBFL + ARTIFACTS_AWS_ACCESS_KEY_ID: AKIA46X5W6CZN24CBO55 + AWS_REGION: us-west-1 + + try: + <<: *production + DIST_TRY_BUILD: 1 + + auto: + <<: *production + + pr: + PR_CI_JOB: 1 + +# Jobs that run on each push to a pull request (PR) +# These jobs automatically inherit envs.pr, to avoid repeating +# it in each job definition. pr: - - name: mingw-check + - image: mingw-check <<: *job-linux-4c - - name: mingw-check-tidy + - image: mingw-check-tidy + continue_on_error: true <<: *job-linux-4c - - name: x86_64-gnu-llvm-17 + - image: x86_64-gnu-llvm-17 env: ENABLE_GCC_CODEGEN: "1" <<: *job-linux-16c - - name: x86_64-gnu-tools + - image: x86_64-gnu-tools <<: *job-linux-16c + +# Jobs that run when you perform a try build (@bors try) +# These jobs automatically inherit envs.production, to avoid repeating +# it in each job definition. +try: + - image: dist-x86_64-linux + env: + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-linux-16c + +# Main CI jobs that have to be green to merge a commit into master +# These jobs automatically inherit envs.production, to avoid repeating +# it in each job definition. +auto: + ############################# + # Linux/Docker builders # + ############################# + + - image: aarch64-gnu + <<: *job-aarch64-linux + + - image: arm-android + <<: *job-linux-8c + + - image: armhf-gnu + <<: *job-linux-8c + + - image: dist-aarch64-linux + env: + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-linux-8c + + - image: dist-android + <<: *job-linux-8c + + - image: dist-arm-linux + <<: *job-linux-16c + + - image: dist-armhf-linux + <<: *job-linux-8c + + - image: dist-armv7-linux + <<: *job-linux-8c + + - image: dist-i586-gnu-i586-i686-musl + <<: *job-linux-8c + + - image: dist-i686-linux + <<: *job-linux-8c + + - image: dist-loongarch64-linux + <<: *job-linux-8c + + - image: dist-ohos + <<: *job-linux-8c + + - image: dist-powerpc-linux + <<: *job-linux-8c + + - image: dist-powerpc64-linux + <<: *job-linux-8c + + - image: dist-powerpc64le-linux + <<: *job-linux-8c + + - image: dist-riscv64-linux + <<: *job-linux-8c + + - image: dist-s390x-linux + <<: *job-linux-8c + + - image: dist-various-1 + <<: *job-linux-8c + + - image: dist-various-2 + <<: *job-linux-8c + + - image: dist-x86_64-freebsd + <<: *job-linux-8c + + - image: dist-x86_64-illumos + <<: *job-linux-8c + + - image: dist-x86_64-linux + env: + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-linux-16c + + - image: dist-x86_64-linux-alt + env: + IMAGE: dist-x86_64-linux + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-linux-16c + + - image: dist-x86_64-musl + env: + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-linux-8c + + - image: dist-x86_64-netbsd + <<: *job-linux-8c + + - image: i686-gnu + <<: *job-linux-8c + + - image: i686-gnu-nopt + <<: *job-linux-8c + + - image: mingw-check + <<: *job-linux-4c + + - image: test-various + <<: *job-linux-8c + + - image: x86_64-gnu + <<: *job-linux-4c + + # This job ensures commits landing on nightly still pass the full + # test suite on the stable channel. There are some UI tests that + # depend on the channel being built (for example if they include the + # channel name on the output), and this builder prevents landing + # changes that would result in broken builds after a promotion. + - image: x86_64-gnu-stable + env: + IMAGE: x86_64-gnu + RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable + # Only run this job on the nightly channel. Running this on beta + # could cause failures when `dev: 1` in `stage0.txt`, and running + # this on stable is useless. + CI_ONLY_WHEN_CHANNEL: nightly + <<: *job-linux-4c + + - image: x86_64-gnu-aux + <<: *job-linux-4c + + - image: x86_64-gnu-integration + env: + # Only run this job on the nightly channel. Fuchsia requires + # nightly features to compile, and this job would fail if + # executed on beta and stable. + CI_ONLY_WHEN_CHANNEL: nightly + <<: *job-linux-8c + + - image: x86_64-gnu-debug + <<: *job-linux-8c + + - image: x86_64-gnu-distcheck + <<: *job-linux-8c + + - image: x86_64-gnu-llvm-18 + env: + RUST_BACKTRACE: 1 + <<: *job-linux-8c + + - image: x86_64-gnu-llvm-17 + env: + RUST_BACKTRACE: 1 + <<: *job-linux-8c + + - image: x86_64-gnu-nopt + <<: *job-linux-4c + + - image: x86_64-gnu-tools + env: + DEPLOY_TOOLSTATES_JSON: toolstates-linux.json + <<: *job-linux-8c + + #################### + # macOS Builders # + #################### + + - image: dist-x86_64-apple + env: + SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin + RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1 + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.12 + SELECT_XCODE: /Applications/Xcode_14.3.1.app + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + NO_OVERFLOW_CHECKS: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + CODEGEN_BACKENDS: llvm,cranelift + <<: *job-macos-xl + + - image: dist-apple-various + env: + SCRIPT: ./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim + RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.12 + SELECT_XCODE: /Applications/Xcode_14.3.1.app + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + NO_OVERFLOW_CHECKS: 1 + <<: *job-macos-xl + + - image: x86_64-apple-1 + env: &env-x86_64-apple-tests + SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps + RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + MACOSX_DEPLOYMENT_TARGET: 10.12 + MACOSX_STD_DEPLOYMENT_TARGET: 10.12 + SELECT_XCODE: /Applications/Xcode_14.3.1.app + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + NO_OVERFLOW_CHECKS: 1 + <<: *job-macos-xl + + - image: x86_64-apple-2 + env: + SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps + <<: *env-x86_64-apple-tests + <<: *job-macos-xl + + # This target only needs to support 11.0 and up as nothing else supports the hardware + - image: dist-aarch64-apple + env: + SCRIPT: ./x.py dist bootstrap --include-default-paths --host=aarch64-apple-darwin --target=aarch64-apple-darwin + RUST_CONFIGURE_ARGS: >- + --enable-full-tools + --enable-sanitizers + --enable-profiler + --set rust.jemalloc + --set llvm.ninja=false + --set rust.lto=thin + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + SELECT_XCODE: /Applications/Xcode_14.3.1.app + USE_XCODE_CLANG: 1 + MACOSX_DEPLOYMENT_TARGET: 11.0 + MACOSX_STD_DEPLOYMENT_TARGET: 11.0 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + NO_OVERFLOW_CHECKS: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + <<: *job-macos-m1 + + # This target only needs to support 11.0 and up as nothing else supports the hardware + - image: aarch64-apple + env: + SCRIPT: ./x.py --stage 2 test --host=aarch64-apple-darwin --target=aarch64-apple-darwin + RUST_CONFIGURE_ARGS: >- + --enable-sanitizers + --enable-profiler + --set rust.jemalloc + RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 + SELECT_XCODE: /Applications/Xcode_14.3.1.app + USE_XCODE_CLANG: 1 + MACOSX_DEPLOYMENT_TARGET: 11.0 + MACOSX_STD_DEPLOYMENT_TARGET: 11.0 + NO_LLVM_ASSERTIONS: 1 + NO_DEBUG_ASSERTIONS: 1 + NO_OVERFLOW_CHECKS: 1 + <<: *job-macos-m1 + + ###################### + # Windows Builders # + ###################### + + - image: x86_64-msvc + env: + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler + SCRIPT: make ci-msvc + <<: *job-windows-8c + + - image: i686-msvc + env: + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc + SCRIPT: make ci-msvc + <<: *job-windows-8c + + - image: x86_64-msvc-ext + env: + SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo && src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows + HOST_TARGET: x86_64-pc-windows-msvc + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld --save-toolstates=/tmp/toolstate/toolstates.json + DEPLOY_TOOLSTATES_JSON: toolstates-windows.json + <<: *job-windows-8c + + # 32/64-bit MinGW builds. + # + # We are using MinGW with POSIX threads since LLVM requires + # C++'s std::thread which is disabled in libstdc++ with win32 threads. + # FIXME: Libc++ doesn't have this limitation so we can avoid + # winpthreads if we switch to it. + # + # Instead of relying on the MinGW version installed on CI we download + # and install one ourselves so we won't be surprised by changes to CI's + # build image. + # + # Finally, note that the downloads below are all in the `rust-lang-ci` S3 + # bucket, but they clearly didn't originate there! The downloads originally + # came from the mingw-w64 SourceForge download site. Unfortunately + # SourceForge is notoriously flaky, so we mirror it on our own infrastructure. + + - image: i686-mingw + env: + RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu + SCRIPT: make ci-mingw + # We are intentionally allowing an old toolchain on this builder (and that's + # incompatible with LLVM downloads today). + NO_DOWNLOAD_CI_LLVM: 1 + CUSTOM_MINGW: 1 + <<: *job-windows-8c + + - image: x86_64-mingw + env: + SCRIPT: make ci-mingw + RUST_CONFIGURE_ARGS: >- + --build=x86_64-pc-windows-gnu + --enable-profiler + # We are intentionally allowing an old toolchain on this builder (and that's + # incompatible with LLVM downloads today). + NO_DOWNLOAD_CI_LLVM: 1 + CUSTOM_MINGW: 1 + <<: *job-windows-8c + + - image: dist-x86_64-msvc + env: + RUST_CONFIGURE_ARGS: >- + --build=x86_64-pc-windows-msvc + --host=x86_64-pc-windows-msvc + --target=x86_64-pc-windows-msvc + --enable-full-tools + --enable-profiler + --set rust.codegen-units=1 + SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths + DIST_REQUIRE_ALL_TOOLS: 1 + <<: *job-windows-8c + + - image: dist-i686-msvc + env: + RUST_CONFIGURE_ARGS: >- + --build=i686-pc-windows-msvc + --host=i686-pc-windows-msvc + --target=i686-pc-windows-msvc,i586-pc-windows-msvc + --enable-full-tools + --enable-profiler + SCRIPT: python x.py dist bootstrap --include-default-paths + DIST_REQUIRE_ALL_TOOLS: 1 + <<: *job-windows-8c + + - image: dist-aarch64-msvc + env: + RUST_CONFIGURE_ARGS: >- + --build=x86_64-pc-windows-msvc + --host=aarch64-pc-windows-msvc + --enable-full-tools + --enable-profiler + SCRIPT: python x.py dist bootstrap --include-default-paths + DIST_REQUIRE_ALL_TOOLS: 1 + <<: *job-windows-8c + + - image: dist-i686-mingw + env: + RUST_CONFIGURE_ARGS: >- + --build=i686-pc-windows-gnu + --enable-full-tools + --enable-profiler + # We are intentionally allowing an old toolchain on this builder (and that's + # incompatible with LLVM downloads today). + NO_DOWNLOAD_CI_LLVM: 1 + SCRIPT: python x.py dist bootstrap --include-default-paths + CUSTOM_MINGW: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + <<: *job-windows-8c + + - image: dist-x86_64-mingw + env: + SCRIPT: python x.py dist bootstrap --include-default-paths + RUST_CONFIGURE_ARGS: >- + --build=x86_64-pc-windows-gnu + --enable-full-tools + --enable-profiler + # We are intentionally allowing an old toolchain on this builder (and that's + # incompatible with LLVM downloads today). + NO_DOWNLOAD_CI_LLVM: 1 + CUSTOM_MINGW: 1 + DIST_REQUIRE_ALL_TOOLS: 1 + <<: *job-windows-8c + + - image: dist-x86_64-msvc-alt + env: + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler + SCRIPT: python x.py dist bootstrap --include-default-paths + <<: *job-windows-8c diff --git a/src/ci/scripts/calculate-job-matrix.py b/src/ci/scripts/calculate-job-matrix.py deleted file mode 100755 index 9b1e74c23c32..000000000000 --- a/src/ci/scripts/calculate-job-matrix.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 - -""" -This script serves for generating a matrix of jobs that should -be executed on CI. - -It reads job definitions from `src/ci/github-actions/jobs.yml` -and filters them based on the event that happened on CI. - -Currently, it only supports PR builds. -""" - -import json -from pathlib import Path - -import yaml - -JOBS_YAML_PATH = Path(__file__).absolute().parent.parent / "github-actions" / "jobs.yml" - - -if __name__ == "__main__": - with open(JOBS_YAML_PATH) as f: - jobs = yaml.safe_load(f) - job_output = jobs["pr"] - print(f"jobs={json.dumps(job_output)}") diff --git a/src/doc/unstable-book/src/language-features/coroutines.md b/src/doc/unstable-book/src/language-features/coroutines.md index f8e5a22fbd5c..9fb07594650f 100644 --- a/src/doc/unstable-book/src/language-features/coroutines.md +++ b/src/doc/unstable-book/src/language-features/coroutines.md @@ -26,13 +26,13 @@ tweaks to the overall design. A syntactical example of a coroutine is: ```rust -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; fn main() { - let mut coroutine = || { + let mut coroutine = #[coroutine] || { yield 1; return "foo" }; @@ -48,7 +48,8 @@ fn main() { } ``` -Coroutines are closure-like literals which can contain a `yield` statement. The +Coroutines are closure-like literals which are annotated with `#[coroutine]` +and can contain a `yield` statement. The `yield` statement takes an optional expression of a value to yield out of the coroutine. All coroutine literals implement the `Coroutine` trait in the `std::ops` module. The `Coroutine` trait has one main method, `resume`, which @@ -58,13 +59,13 @@ An example of the control flow of coroutines is that the following example prints all numbers in order: ```rust -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; fn main() { - let mut coroutine = || { + let mut coroutine = #[coroutine] || { println!("2"); yield; println!("4"); @@ -78,9 +79,9 @@ fn main() { } ``` -At this time the main intended use case of coroutines is an implementation -primitive for async/await syntax, but coroutines will likely be extended to -ergonomic implementations of iterators and other primitives in the future. +At this time the main use case of coroutines is an implementation +primitive for `async`/`await` and `gen` syntax, but coroutines +will likely be extended to other primitives in the future. Feedback on the design and usage is always appreciated! ### The `Coroutine` trait @@ -163,14 +164,14 @@ which point all state is saved off in the coroutine and a value is returned. Let's take a look at an example to see what's going on here: ```rust -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; fn main() { let ret = "foo"; - let mut coroutine = move || { + let mut coroutine = #[coroutine] move || { yield 1; return ret }; @@ -183,7 +184,7 @@ fn main() { This coroutine literal will compile down to something similar to: ```rust -#![feature(arbitrary_self_types, coroutines, coroutine_trait)] +#![feature(arbitrary_self_types, coroutine_trait)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; diff --git a/src/doc/unstable-book/src/language-features/inline-const-pat.md b/src/doc/unstable-book/src/language-features/inline-const-pat.md index 5f0f7547a0a8..c6f54d79cfce 100644 --- a/src/doc/unstable-book/src/language-features/inline-const-pat.md +++ b/src/doc/unstable-book/src/language-features/inline-const-pat.md @@ -2,8 +2,6 @@ The tracking issue for this feature is: [#76001] -See also [`inline_const`](inline-const.md) - ------ This feature allows you to use inline constant expressions in pattern position: diff --git a/src/doc/unstable-book/src/language-features/inline-const.md b/src/doc/unstable-book/src/language-features/inline-const.md deleted file mode 100644 index 7be70eed6ced..000000000000 --- a/src/doc/unstable-book/src/language-features/inline-const.md +++ /dev/null @@ -1,32 +0,0 @@ -# `inline_const` - -The tracking issue for this feature is: [#76001] - -See also [`inline_const_pat`](inline-const-pat.md) - ------- - -This feature allows you to use inline constant expressions. For example, you can -turn this code: - -```rust -# fn add_one(x: i32) -> i32 { x + 1 } -const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4; - -fn main() { - let x = add_one(MY_COMPUTATION); -} -``` - -into this code: - -```rust -#![feature(inline_const)] - -# fn add_one(x: i32) -> i32 { x + 1 } -fn main() { - let x = add_one(const { 1 + 2 * 3 / 4 }); -} -``` - -[#76001]: https://github.com/rust-lang/rust/issues/76001 diff --git a/src/doc/unstable-book/src/the-unstable-book.md b/src/doc/unstable-book/src/the-unstable-book.md index 0f4fb405669a..63134f7ae28c 100644 --- a/src/doc/unstable-book/src/the-unstable-book.md +++ b/src/doc/unstable-book/src/the-unstable-book.md @@ -5,13 +5,13 @@ each one organized by a "feature flag." That is, when using an unstable feature of Rust, you must use a flag, like this: ```rust -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; fn main() { - let mut coroutine = || { + let mut coroutine = #[coroutine] || { yield 1; return "foo" }; diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs index 4ae75544c60c..232bccf6a154 100644 --- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs +++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs @@ -1,4 +1,3 @@ -#![feature(inline_const)] #![warn(clippy::indexing_slicing)] // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr index 120f5c35cb03..5ce2ed2ffaee 100644 --- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr +++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr @@ -1,5 +1,5 @@ error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:27:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:26:5 | LL | x[index]; | ^^^^^^^^ @@ -9,7 +9,7 @@ LL | x[index]; = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:41:5 | LL | v[0]; | ^^^^ @@ -17,7 +17,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5 | LL | v[10]; | ^^^^^ @@ -25,7 +25,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:44:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -33,7 +33,7 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:49:5 | LL | v[N]; | ^^^^ @@ -41,7 +41,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui-toml/suppress_lint_in_const/test.rs:51:5 + --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5 | LL | v[M]; | ^^^^ diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs index b454c29aef4d..fdec14a1528f 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs @@ -10,7 +10,7 @@ arithmetic_overflow, unconditional_panic )] -#![feature(const_mut_refs, inline_const)] +#![feature(const_mut_refs)] #![warn(clippy::arithmetic_side_effects)] extern crate proc_macro_derive; diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed index 167263d31df8..f7dad28b0369 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed @@ -1,4 +1,4 @@ -#![feature(let_chains, inline_const)] +#![feature(let_chains)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs index f3f055eb7f06..d22871d2c8f2 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs @@ -1,4 +1,4 @@ -#![feature(let_chains, inline_const)] +#![feature(let_chains)] #![warn(clippy::bool_to_int_with_if)] #![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)] diff --git a/src/tools/clippy/tests/ui/const_is_empty.rs b/src/tools/clippy/tests/ui/const_is_empty.rs index ae37a82e4f93..04e0de91ecfb 100644 --- a/src/tools/clippy/tests/ui/const_is_empty.rs +++ b/src/tools/clippy/tests/ui/const_is_empty.rs @@ -1,4 +1,3 @@ -#![feature(inline_const)] #![warn(clippy::const_is_empty)] #![allow(clippy::needless_late_init, unused_must_use)] diff --git a/src/tools/clippy/tests/ui/const_is_empty.stderr b/src/tools/clippy/tests/ui/const_is_empty.stderr index 0e09da77bb46..7f80b520b1a4 100644 --- a/src/tools/clippy/tests/ui/const_is_empty.stderr +++ b/src/tools/clippy/tests/ui/const_is_empty.stderr @@ -1,5 +1,5 @@ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:6:8 + --> tests/ui/const_is_empty.rs:5:8 | LL | if "".is_empty() { | ^^^^^^^^^^^^^ @@ -8,151 +8,151 @@ LL | if "".is_empty() { = help: to override `-D warnings` add `#[allow(clippy::const_is_empty)]` error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:9:8 + --> tests/ui/const_is_empty.rs:8:8 | LL | if "foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:15:8 + --> tests/ui/const_is_empty.rs:14:8 | LL | if b"".is_empty() { | ^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:18:8 + --> tests/ui/const_is_empty.rs:17:8 | LL | if b"foobar".is_empty() { | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:35:8 + --> tests/ui/const_is_empty.rs:34:8 | LL | if empty2.is_empty() { | ^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:38:8 + --> tests/ui/const_is_empty.rs:37:8 | LL | if non_empty2.is_empty() { | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:60:13 + --> tests/ui/const_is_empty.rs:59:13 | LL | let _ = EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:62:13 + --> tests/ui/const_is_empty.rs:61:13 | LL | let _ = NON_EMPTY_STR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:64:13 + --> tests/ui/const_is_empty.rs:63:13 | LL | let _ = EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:66:13 + --> tests/ui/const_is_empty.rs:65:13 | LL | let _ = NON_EMPTY_BSTR.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:68:13 + --> tests/ui/const_is_empty.rs:67:13 | LL | let _ = EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:70:13 + --> tests/ui/const_is_empty.rs:69:13 | LL | let _ = EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:72:13 + --> tests/ui/const_is_empty.rs:71:13 | LL | let _ = EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:74:13 + --> tests/ui/const_is_empty.rs:73:13 | LL | let _ = NON_EMPTY_U8_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:76:13 + --> tests/ui/const_is_empty.rs:75:13 | LL | let _ = NON_EMPTY_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:78:13 + --> tests/ui/const_is_empty.rs:77:13 | LL | let _ = NON_EMPTY_ARRAY_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:80:13 + --> tests/ui/const_is_empty.rs:79:13 | LL | let _ = EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:82:13 + --> tests/ui/const_is_empty.rs:81:13 | LL | let _ = NON_EMPTY_REF_ARRAY.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:84:13 + --> tests/ui/const_is_empty.rs:83:13 | LL | let _ = EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:86:13 + --> tests/ui/const_is_empty.rs:85:13 | LL | let _ = NON_EMPTY_SLICE.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:88:13 + --> tests/ui/const_is_empty.rs:87:13 | LL | let _ = NON_EMPTY_SLICE_REPEAT.is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:94:13 + --> tests/ui/const_is_empty.rs:93:13 | LL | let _ = value.is_empty(); | ^^^^^^^^^^^^^^^^ error: this expression always evaluates to false - --> tests/ui/const_is_empty.rs:97:13 + --> tests/ui/const_is_empty.rs:96:13 | LL | let _ = x.is_empty(); | ^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:99:13 + --> tests/ui/const_is_empty.rs:98:13 | LL | let _ = "".is_empty(); | ^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:101:13 + --> tests/ui/const_is_empty.rs:100:13 | LL | let _ = b"".is_empty(); | ^^^^^^^^^^^^^^ error: this expression always evaluates to true - --> tests/ui/const_is_empty.rs:155:13 + --> tests/ui/const_is_empty.rs:154:13 | LL | let _ = val.is_empty(); | ^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/crashes/ice-5238.rs b/src/tools/clippy/tests/ui/crashes/ice-5238.rs index b1fc3fb9d251..fe03a39ad1ba 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5238.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-5238.rs @@ -1,9 +1,9 @@ // Regression test for #5238 / https://github.com/rust-lang/rust/pull/69562 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] fn main() { - let _ = || { + let _ = #[coroutine] || { yield; }; } diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs index 27ee2f91594b..2e726141649e 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs +++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs @@ -1,6 +1,5 @@ //@compile-flags: -Zdeduplicate-diagnostics=yes -#![feature(inline_const)] #![warn(clippy::indexing_slicing)] // We also check the out_of_bounds_indexing lint here, because it lints similar things and // we want to avoid false positives. diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr index 5f62ec9b5565..386f91becf14 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr +++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr @@ -1,5 +1,5 @@ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:16:20 + --> tests/ui/indexing_slicing_index.rs:15:20 | LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false. | ^^^^^^^^^^ @@ -10,19 +10,19 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]` error[E0080]: evaluation of `main::{constant#3}` failed - --> tests/ui/indexing_slicing_index.rs:48:14 + --> tests/ui/indexing_slicing_index.rs:47:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4 note: erroneous constant encountered - --> tests/ui/indexing_slicing_index.rs:48:5 + --> tests/ui/indexing_slicing_index.rs:47:5 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^^^^^^^^^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:29:5 + --> tests/ui/indexing_slicing_index.rs:28:5 | LL | x[index]; | ^^^^^^^^ @@ -30,7 +30,7 @@ LL | x[index]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:32:5 + --> tests/ui/indexing_slicing_index.rs:31:5 | LL | x[4]; | ^^^^ @@ -39,13 +39,13 @@ LL | x[4]; = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]` error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:34:5 + --> tests/ui/indexing_slicing_index.rs:33:5 | LL | x[1 << 3]; | ^^^^^^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:45:14 + --> tests/ui/indexing_slicing_index.rs:44:14 | LL | const { &ARR[idx()] }; | ^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | const { &ARR[idx()] }; = note: the suggestion might not be applicable in constant blocks error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:48:14 + --> tests/ui/indexing_slicing_index.rs:47:14 | LL | const { &ARR[idx4()] }; | ^^^^^^^^^^^ @@ -63,13 +63,13 @@ LL | const { &ARR[idx4()] }; = note: the suggestion might not be applicable in constant blocks error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:55:5 + --> tests/ui/indexing_slicing_index.rs:54:5 | LL | y[4]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:58:5 + --> tests/ui/indexing_slicing_index.rs:57:5 | LL | v[0]; | ^^^^ @@ -77,7 +77,7 @@ LL | v[0]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:60:5 + --> tests/ui/indexing_slicing_index.rs:59:5 | LL | v[10]; | ^^^^^ @@ -85,7 +85,7 @@ LL | v[10]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:62:5 + --> tests/ui/indexing_slicing_index.rs:61:5 | LL | v[1 << 3]; | ^^^^^^^^^ @@ -93,13 +93,13 @@ LL | v[1 << 3]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:70:5 + --> tests/ui/indexing_slicing_index.rs:69:5 | LL | x[N]; | ^^^^ error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:73:5 + --> tests/ui/indexing_slicing_index.rs:72:5 | LL | v[N]; | ^^^^ @@ -107,7 +107,7 @@ LL | v[N]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: indexing may panic - --> tests/ui/indexing_slicing_index.rs:75:5 + --> tests/ui/indexing_slicing_index.rs:74:5 | LL | v[M]; | ^^^^ @@ -115,7 +115,7 @@ LL | v[M]; = help: consider using `.get(n)` or `.get_mut(n)` instead error: index is out of bounds - --> tests/ui/indexing_slicing_index.rs:79:13 + --> tests/ui/indexing_slicing_index.rs:78:13 | LL | let _ = x[4]; | ^^^^ diff --git a/src/tools/clippy/tests/ui/large_futures.fixed b/src/tools/clippy/tests/ui/large_futures.fixed index aa8c3021b970..1e87859f4526 100644 --- a/src/tools/clippy/tests/ui/large_futures.fixed +++ b/src/tools/clippy/tests/ui/large_futures.fixed @@ -1,4 +1,3 @@ -#![feature(coroutines)] #![warn(clippy::large_futures)] #![allow(clippy::never_loop)] #![allow(clippy::future_not_send)] diff --git a/src/tools/clippy/tests/ui/large_futures.rs b/src/tools/clippy/tests/ui/large_futures.rs index fc6ea458d3db..3f4ea2ebf8bb 100644 --- a/src/tools/clippy/tests/ui/large_futures.rs +++ b/src/tools/clippy/tests/ui/large_futures.rs @@ -1,4 +1,3 @@ -#![feature(coroutines)] #![warn(clippy::large_futures)] #![allow(clippy::never_loop)] #![allow(clippy::future_not_send)] diff --git a/src/tools/clippy/tests/ui/large_futures.stderr b/src/tools/clippy/tests/ui/large_futures.stderr index 5709c7b77a0a..00082e579c59 100644 --- a/src/tools/clippy/tests/ui/large_futures.stderr +++ b/src/tools/clippy/tests/ui/large_futures.stderr @@ -1,5 +1,5 @@ error: large future with a size of 16385 bytes - --> tests/ui/large_futures.rs:11:9 + --> tests/ui/large_futures.rs:10:9 | LL | big_fut([0u8; 1024 * 16]).await; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(big_fut([0u8; 1024 * 16]))` @@ -8,37 +8,37 @@ LL | big_fut([0u8; 1024 * 16]).await; = help: to override `-D warnings` add `#[allow(clippy::large_futures)]` error: large future with a size of 16386 bytes - --> tests/ui/large_futures.rs:15:5 + --> tests/ui/large_futures.rs:14:5 | LL | f.await | ^ help: consider `Box::pin` on it: `Box::pin(f)` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:20:9 + --> tests/ui/large_futures.rs:19:9 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 16387 bytes - --> tests/ui/large_futures.rs:25:13 + --> tests/ui/large_futures.rs:24:13 | LL | wait().await; | ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:33:5 + --> tests/ui/large_futures.rs:32:5 | LL | foo().await; | ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())` error: large future with a size of 49159 bytes - --> tests/ui/large_futures.rs:35:5 + --> tests/ui/large_futures.rs:34:5 | LL | calls_fut(fut).await; | ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))` error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:48:5 + --> tests/ui/large_futures.rs:47:5 | LL | / async { LL | | @@ -59,7 +59,7 @@ LL + }) | error: large future with a size of 65540 bytes - --> tests/ui/large_futures.rs:60:13 + --> tests/ui/large_futures.rs:59:13 | LL | / async { LL | | let x = [0i32; 1024 * 16]; diff --git a/src/tools/clippy/tests/ui/manual_float_methods.rs b/src/tools/clippy/tests/ui/manual_float_methods.rs index f3e95d6807d3..80781ecda721 100644 --- a/src/tools/clippy/tests/ui/manual_float_methods.rs +++ b/src/tools/clippy/tests/ui/manual_float_methods.rs @@ -2,7 +2,6 @@ //@aux-build:proc_macros.rs #![allow(clippy::needless_if, unused)] #![warn(clippy::manual_is_infinite, clippy::manual_is_finite)] -#![feature(inline_const)] #[macro_use] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/manual_float_methods.stderr b/src/tools/clippy/tests/ui/manual_float_methods.stderr index dae96839262d..930df0b97cb3 100644 --- a/src/tools/clippy/tests/ui/manual_float_methods.stderr +++ b/src/tools/clippy/tests/ui/manual_float_methods.stderr @@ -1,5 +1,5 @@ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:23:8 + --> tests/ui/manual_float_methods.rs:22:8 | LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` @@ -8,7 +8,7 @@ LL | if x == f32::INFINITY || x == f32::NEG_INFINITY {} = help: to override `-D warnings` add `#[allow(clippy::manual_is_infinite)]` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:24:8 + --> tests/ui/manual_float_methods.rs:23:8 | LL | if x != f32::INFINITY && x != f32::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:25:8 + --> tests/ui/manual_float_methods.rs:24:8 | LL | if x == INFINITE || x == NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:26:8 + --> tests/ui/manual_float_methods.rs:25:8 | LL | if x != INFINITE && x != NEG_INFINITE {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,13 +54,13 @@ LL | if !x.is_infinite() {} | ~~~~~~~~~~~~~~~~ error: manually checking if a float is infinite - --> tests/ui/manual_float_methods.rs:28:8 + --> tests/ui/manual_float_methods.rs:27:8 | LL | if x == f64::INFINITY || x == f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()` error: manually checking if a float is finite - --> tests/ui/manual_float_methods.rs:29:8 + --> tests/ui/manual_float_methods.rs:28:8 | LL | if x != f64::INFINITY && x != f64::NEG_INFINITY {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs index 92f173d9db4a..93c69209c698 100644 --- a/src/tools/clippy/tests/ui/never_loop.rs +++ b/src/tools/clippy/tests/ui/never_loop.rs @@ -1,4 +1,4 @@ -#![feature(inline_const, try_blocks)] +#![feature(try_blocks)] #![allow( clippy::eq_op, clippy::single_match, diff --git a/src/tools/clippy/tests/ui/panicking_macros.rs b/src/tools/clippy/tests/ui/panicking_macros.rs index dccfbd409e50..2bbf5792ec4c 100644 --- a/src/tools/clippy/tests/ui/panicking_macros.rs +++ b/src/tools/clippy/tests/ui/panicking_macros.rs @@ -1,5 +1,4 @@ #![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::let_unit_value)] -#![feature(inline_const)] #![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)] extern crate core; diff --git a/src/tools/clippy/tests/ui/panicking_macros.stderr b/src/tools/clippy/tests/ui/panicking_macros.stderr index 06025859c0c6..7c0f0a7d3764 100644 --- a/src/tools/clippy/tests/ui/panicking_macros.stderr +++ b/src/tools/clippy/tests/ui/panicking_macros.stderr @@ -1,5 +1,5 @@ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:23:5 + --> tests/ui/panicking_macros.rs:22:5 | LL | panic!(); | ^^^^^^^^ @@ -8,19 +8,19 @@ LL | panic!(); = help: to override `-D warnings` add `#[allow(clippy::panic)]` error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:26:5 + --> tests/ui/panicking_macros.rs:25:5 | LL | panic!("message"); | ^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:28:5 + --> tests/ui/panicking_macros.rs:27:5 | LL | panic!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:35:5 + --> tests/ui/panicking_macros.rs:34:5 | LL | todo!(); | ^^^^^^^ @@ -29,19 +29,19 @@ LL | todo!(); = help: to override `-D warnings` add `#[allow(clippy::todo)]` error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:38:5 + --> tests/ui/panicking_macros.rs:37:5 | LL | todo!("message"); | ^^^^^^^^^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:40:5 + --> tests/ui/panicking_macros.rs:39:5 | LL | todo!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:47:5 + --> tests/ui/panicking_macros.rs:46:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ @@ -50,19 +50,19 @@ LL | unimplemented!(); = help: to override `-D warnings` add `#[allow(clippy::unimplemented)]` error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:50:5 + --> tests/ui/panicking_macros.rs:49:5 | LL | unimplemented!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:52:5 + --> tests/ui/panicking_macros.rs:51:5 | LL | unimplemented!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:59:5 + --> tests/ui/panicking_macros.rs:58:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ @@ -71,37 +71,37 @@ LL | unreachable!(); = help: to override `-D warnings` add `#[allow(clippy::unreachable)]` error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:62:5 + --> tests/ui/panicking_macros.rs:61:5 | LL | unreachable!("message"); | ^^^^^^^^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:64:5 + --> tests/ui/panicking_macros.rs:63:5 | LL | unreachable!("{} {}", "panic with", "multiple arguments"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `panic` should not be present in production code - --> tests/ui/panicking_macros.rs:71:5 + --> tests/ui/panicking_macros.rs:70:5 | LL | panic!(); | ^^^^^^^^ error: `todo` should not be present in production code - --> tests/ui/panicking_macros.rs:73:5 + --> tests/ui/panicking_macros.rs:72:5 | LL | todo!(); | ^^^^^^^ error: `unimplemented` should not be present in production code - --> tests/ui/panicking_macros.rs:75:5 + --> tests/ui/panicking_macros.rs:74:5 | LL | unimplemented!(); | ^^^^^^^^^^^^^^^^ error: usage of the `unreachable!` macro - --> tests/ui/panicking_macros.rs:77:5 + --> tests/ui/panicking_macros.rs:76:5 | LL | unreachable!(); | ^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs index f6909828aa9a..e9d77182a919 100644 --- a/src/tools/clippy/tests/ui/redundant_locals.rs +++ b/src/tools/clippy/tests/ui/redundant_locals.rs @@ -1,7 +1,7 @@ //@aux-build:proc_macros.rs #![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)] #![warn(clippy::redundant_locals)] -#![feature(async_closure, coroutines)] +#![feature(async_closure, coroutines, stmt_expr_attributes)] extern crate proc_macros; use proc_macros::{external, with_span}; @@ -191,11 +191,11 @@ fn issue12225() { let v4 = v4; dbg!(&v4); }); - assert_static(static || { + assert_static(#[coroutine] static || { let v5 = v5; yield; }); - assert_static(|| { + assert_static(#[coroutine] || { let v6 = v6; yield; }); diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index e1c0da9118d3..44727e01ea22 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -12,7 +12,6 @@ #![feature(let_chains)] #![feature(lint_reasons)] #![feature(trait_upcasting)] -#![feature(absolute_path)] // Configure clippy and other lints #![allow( clippy::collapsible_else_if, diff --git a/src/tools/miri/tests/fail/coroutine-pinned-moved.rs b/src/tools/miri/tests/fail/coroutine-pinned-moved.rs index 005ae7e91323..8648be2a2641 100644 --- a/src/tools/miri/tests/fail/coroutine-pinned-moved.rs +++ b/src/tools/miri/tests/fail/coroutine-pinned-moved.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::{ ops::{Coroutine, CoroutineState}, @@ -7,7 +7,7 @@ use std::{ }; fn firstn() -> impl Coroutine { - static move || { + #[coroutine] static move || { let mut num = 0; let num = &mut num; *num += 0; diff --git a/src/tools/miri/tests/pass/coroutine.rs b/src/tools/miri/tests/pass/coroutine.rs index 7e1f64df04d4..e76abfc4185d 100644 --- a/src/tools/miri/tests/pass/coroutine.rs +++ b/src/tools/miri/tests/pass/coroutine.rs @@ -1,6 +1,6 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows -#![feature(coroutines, coroutine_trait, never_type)] +#![feature(coroutines, coroutine_trait, never_type, stmt_expr_attributes)] use std::fmt::Debug; use std::mem::ManuallyDrop; @@ -43,9 +43,9 @@ fn basic() { panic!() } - finish(1, false, || yield 1); + finish(1, false, #[coroutine] || yield 1); - finish(3, false, || { + finish(3, false, #[coroutine] || { let mut x = 0; yield 1; x += 1; @@ -55,27 +55,27 @@ fn basic() { assert_eq!(x, 2); }); - finish(7 * 8 / 2, false, || { + finish(7 * 8 / 2, false, #[coroutine] || { for i in 0..8 { yield i; } }); - finish(1, false, || { + finish(1, false, #[coroutine] || { if true { yield 1; } else { } }); - finish(1, false, || { + finish(1, false, #[coroutine] || { if false { } else { yield 1; } }); - finish(2, false, || { + finish(2, false, #[coroutine] || { if { yield 1; false @@ -88,7 +88,7 @@ fn basic() { // also test self-referential coroutines assert_eq!( - finish(5, true, static || { + finish(5, true, #[coroutine] static || { let mut x = 5; let y = &mut x; *y = 5; @@ -99,7 +99,7 @@ fn basic() { 10 ); assert_eq!( - finish(5, true, || { + finish(5, true, #[coroutine] || { let mut x = Box::new(5); let y = &mut *x; *y = 5; @@ -111,7 +111,7 @@ fn basic() { ); let b = true; - finish(1, false, || { + finish(1, false, #[coroutine] || { yield 1; if b { return; @@ -123,7 +123,7 @@ fn basic() { drop(x); }); - finish(3, false, || { + finish(3, false, #[coroutine] || { yield 1; #[allow(unreachable_code)] let _x: (String, !) = (String::new(), { @@ -172,7 +172,7 @@ fn smoke_resume_arg() { } drain( - &mut |mut b| { + &mut #[coroutine] |mut b| { while b != 0 { b = yield (b + 1); } @@ -181,21 +181,21 @@ fn smoke_resume_arg() { vec![(1, Yielded(2)), (-45, Yielded(-44)), (500, Yielded(501)), (0, Complete(-1))], ); - expect_drops(2, || drain(&mut |a| yield a, vec![(DropMe, Yielded(DropMe))])); + expect_drops(2, || drain(&mut #[coroutine] |a| yield a, vec![(DropMe, Yielded(DropMe))])); expect_drops(6, || { drain( - &mut |a| yield yield a, + &mut #[coroutine] |a| yield yield a, vec![(DropMe, Yielded(DropMe)), (DropMe, Yielded(DropMe)), (DropMe, Complete(DropMe))], ) }); #[allow(unreachable_code)] - expect_drops(2, || drain(&mut |a| yield return a, vec![(DropMe, Complete(DropMe))])); + expect_drops(2, || drain(&mut #[coroutine] |a| yield return a, vec![(DropMe, Complete(DropMe))])); expect_drops(2, || { drain( - &mut |a: DropMe| { + &mut #[coroutine] |a: DropMe| { if false { yield () } else { a } }, vec![(DropMe, Complete(DropMe))], @@ -205,7 +205,7 @@ fn smoke_resume_arg() { expect_drops(4, || { drain( #[allow(unused_assignments, unused_variables)] - &mut |mut a: DropMe| { + &mut #[coroutine] |mut a: DropMe| { a = yield; a = yield; a = yield; @@ -228,7 +228,7 @@ fn uninit_fields() { } fn run(x: bool, y: bool) { - let mut c = || { + let mut c = #[coroutine] || { if x { let _a: T; if y { diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/portable-simd.rs index cdb441b450b3..1fc713d48dcc 100644 --- a/src/tools/miri/tests/pass/portable-simd.rs +++ b/src/tools/miri/tests/pass/portable-simd.rs @@ -1,5 +1,5 @@ //@compile-flags: -Zmiri-strict-provenance -#![feature(portable_simd, adt_const_params, inline_const, core_intrinsics)] +#![feature(portable_simd, adt_const_params, core_intrinsics)] #![allow(incomplete_features, internal_features)] use std::intrinsics::simd as intrinsics; use std::ptr; diff --git a/src/tools/miri/tests/pass/shims/path.rs b/src/tools/miri/tests/pass/shims/path.rs index 9fc6e7faefbd..cadbeb476bdf 100644 --- a/src/tools/miri/tests/pass/shims/path.rs +++ b/src/tools/miri/tests/pass/shims/path.rs @@ -1,5 +1,4 @@ //@compile-flags: -Zmiri-disable-isolation -#![feature(absolute_path)] use std::path::{absolute, Path}; #[track_caller] diff --git a/src/tools/miri/tests/pass/stacked-borrows/coroutine-self-referential.rs b/src/tools/miri/tests/pass/stacked-borrows/coroutine-self-referential.rs index c4b15c8758be..bb98e024a0a1 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/coroutine-self-referential.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/coroutine-self-referential.rs @@ -1,6 +1,6 @@ // See https://github.com/rust-lang/unsafe-code-guidelines/issues/148: // this fails when Stacked Borrows is strictly applied even to `!Unpin` types. -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::{ ops::{Coroutine, CoroutineState}, @@ -8,7 +8,7 @@ use std::{ }; fn firstn() -> impl Coroutine { - static move || { + #[coroutine] static move || { let mut num = 0; let num = &mut num; diff --git a/src/tools/miri/tests/pass/track-caller-attribute.rs b/src/tools/miri/tests/pass/track-caller-attribute.rs index d88bcc98858f..c3803af3cc8e 100644 --- a/src/tools/miri/tests/pass/track-caller-attribute.rs +++ b/src/tools/miri/tests/pass/track-caller-attribute.rs @@ -232,7 +232,7 @@ fn test_coroutine() { } #[rustfmt::skip] - let coroutine = #[track_caller] |arg: String| { + let coroutine = #[track_caller] #[coroutine] |arg: String| { yield ("first", arg.clone(), Location::caller()); yield ("second", arg.clone(), Location::caller()); }; @@ -255,7 +255,7 @@ fn test_coroutine() { assert_eq!(mono_loc.column(), 42); #[rustfmt::skip] - let non_tracked_coroutine = || { yield Location::caller(); }; + let non_tracked_coroutine = #[coroutine] || { yield Location::caller(); }; let non_tracked_line = line!() - 1; // This is the line of the coroutine, not its caller let non_tracked_loc = match Box::pin(non_tracked_coroutine).as_mut().resume(()) { CoroutineState::Yielded(val) => val, @@ -263,7 +263,7 @@ fn test_coroutine() { }; assert_eq!(non_tracked_loc.file(), file!()); assert_eq!(non_tracked_loc.line(), non_tracked_line); - assert_eq!(non_tracked_loc.column(), 44); + assert_eq!(non_tracked_loc.column(), 57); } fn main() { diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs index d50088e6cf1d..c92d4e78ffa7 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs @@ -3869,7 +3869,7 @@ use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; fn main() { - let mut coroutine = || { + let mut coroutine = #[coroutine] || { yield 1; return "foo" }; @@ -3901,7 +3901,7 @@ use std::ops::Coroutine; use std::pin::Pin; fn main() { - let mut coroutine = || { + let mut coroutine = #[coroutine] || { println!("2"); yield; println!("4"); @@ -4007,7 +4007,7 @@ use std::pin::Pin; fn main() { let ret = "foo"; - let mut coroutine = move || { + let mut coroutine = #[coroutine] move || { yield 1; return ret }; diff --git a/src/tools/rustfmt/tests/source/immovable_coroutines.rs b/src/tools/rustfmt/tests/source/immovable_coroutines.rs index 3b94af0c96ce..539049577a00 100644 --- a/src/tools/rustfmt/tests/source/immovable_coroutines.rs +++ b/src/tools/rustfmt/tests/source/immovable_coroutines.rs @@ -1,7 +1,8 @@ #![feature(coroutines)] unsafe fn foo() { - let mut ga = static || { + let mut ga = #[coroutine] + static || { yield 1; }; } diff --git a/src/tools/rustfmt/tests/target/immovable_coroutines.rs b/src/tools/rustfmt/tests/target/immovable_coroutines.rs index f52cfa00f978..539049577a00 100644 --- a/src/tools/rustfmt/tests/target/immovable_coroutines.rs +++ b/src/tools/rustfmt/tests/target/immovable_coroutines.rs @@ -1,7 +1,8 @@ #![feature(coroutines)] unsafe fn foo() { - let mut ga = static || { + let mut ga = #[coroutine] + static || { yield 1; }; } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f0ed0ae806fd..93188b4fbaeb 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -317,7 +317,6 @@ run-make/unstable-flag-required/Makefile run-make/use-suggestions-rust-2018/Makefile run-make/used-cdylib-macos/Makefile run-make/used/Makefile -run-make/valid-print-requests/Makefile run-make/volatile-intrinsics/Makefile run-make/wasm-exceptions-nostd/Makefile run-make/wasm-override-linker/Makefile diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs index 12339cb4415c..51b4dc4e1699 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-32bit.rs @@ -37,23 +37,9 @@ pub fn array_char(f: fn(*const char)) { f(&b as *const _); f(&c as *const _); - // Any type of local array variable leads to stack protection with the - // "strong" heuristic. The 'basic' heuristic only adds stack protection to - // functions with local array variables of a byte-sized type, however. Since - // 'char' is 4 bytes in Rust, this function is not protected by the 'basic' - // heuristic - // - // (This test *also* takes the address of the local stack variables. We - // cannot know that this isn't what triggers the `strong` heuristic. - // However, the test strategy of passing the address of a stack array to an - // external function is sufficient to trigger the `basic` heuristic (see - // test `array_u8_large()`). Since the `basic` heuristic only checks for the - // presence of stack-local array variables, we can be confident that this - // test also captures this part of the `strong` heuristic specification.) - // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -231,8 +217,8 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // Even though the local variable conceptually doesn't have its address // taken, it's so large that the "move" is implemented with a reference to a // stack-local variable in the ABI. Consequently, this function *is* - // protected by the `strong` heuristic. This is also the case for - // rvalue-references in C++, regardless of struct size: + // protected. This is also the case for rvalue-references in C++, + // regardless of struct size: // ``` // cat < @@ -246,7 +232,7 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -259,9 +245,9 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // A new instance of `Gigastruct` is passed to `f()`, without any apparent // connection to this stack frame. Still, since instances of `Gigastruct` // are sufficiently large, it is allocated in the caller stack frame and - // passed as a pointer. As such, this function is *also* protected by the - // `strong` heuristic, just like `local_large_var_moved`. This is also the - // case for pass-by-value of sufficiently large structs in C++: + // passed as a pointer. As such, this function is *also* protected, just + // like `local_large_var_moved`. This is also the case for pass-by-value + // of sufficiently large structs in C++: // ``` // cat < @@ -276,7 +262,7 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs index 46c775112519..c5915262c093 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect-windows-64bit.rs @@ -37,23 +37,9 @@ pub fn array_char(f: fn(*const char)) { f(&b as *const _); f(&c as *const _); - // Any type of local array variable leads to stack protection with the - // "strong" heuristic. The 'basic' heuristic only adds stack protection to - // functions with local array variables of a byte-sized type, however. Since - // 'char' is 4 bytes in Rust, this function is not protected by the 'basic' - // heuristic - // - // (This test *also* takes the address of the local stack variables. We - // cannot know that this isn't what triggers the `strong` heuristic. - // However, the test strategy of passing the address of a stack array to an - // external function is sufficient to trigger the `basic` heuristic (see - // test `array_u8_large()`). Since the `basic` heuristic only checks for the - // presence of stack-local array variables, we can be confident that this - // test also captures this part of the `strong` heuristic specification.) - // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -239,8 +225,8 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // Even though the local variable conceptually doesn't have its address // taken, it's so large that the "move" is implemented with a reference to a // stack-local variable in the ABI. Consequently, this function *is* - // protected by the `strong` heuristic. This is also the case for - // rvalue-references in C++, regardless of struct size: + // protected. This is also the case for rvalue-references in C++, + // regardless of struct size: // ``` // cat < @@ -254,7 +240,7 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } @@ -267,9 +253,9 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // A new instance of `Gigastruct` is passed to `f()`, without any apparent // connection to this stack frame. Still, since instances of `Gigastruct` // are sufficiently large, it is allocated in the caller stack frame and - // passed as a pointer. As such, this function is *also* protected by the - // `strong` heuristic, just like `local_large_var_moved`. This is also the - // case for pass-by-value of sufficiently large structs in C++: + // passed as a pointer. As such, this function is *also* protected, just + // like `local_large_var_moved`. This is also the case for pass-by-value + // of sufficiently large structs in C++: // ``` // cat < @@ -284,7 +270,7 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // all: __security_check_cookie // strong: __security_check_cookie - // basic-NOT: __security_check_cookie + // basic: __security_check_cookie // none-NOT: __security_check_cookie // missing-NOT: __security_check_cookie } diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs index e63adc88ff50..8e32d170244a 100644 --- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs +++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs @@ -11,6 +11,11 @@ //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled //@ min-llvm-version: 17.0.2 +// NOTE: the heuristics for stack smash protection inappropriately rely on types in LLVM IR, +// despite those types having no semantic meaning. This means that the `basic` and `strong` +// settings do not behave in a coherent way. This is a known issue in LLVM. +// See comments on https://github.com/rust-lang/rust/issues/114903. + #![crate_type = "lib"] #![allow(incomplete_features)] @@ -39,23 +44,9 @@ pub fn array_char(f: fn(*const char)) { f(&b as *const _); f(&c as *const _); - // Any type of local array variable leads to stack protection with the - // "strong" heuristic. The 'basic' heuristic only adds stack protection to - // functions with local array variables of a byte-sized type, however. Since - // 'char' is 4 bytes in Rust, this function is not protected by the 'basic' - // heuristic - // - // (This test *also* takes the address of the local stack variables. We - // cannot know that this isn't what triggers the `strong` heuristic. - // However, the test strategy of passing the address of a stack array to an - // external function is sufficient to trigger the `basic` heuristic (see - // test `array_u8_large()`). Since the `basic` heuristic only checks for the - // presence of stack-local array variables, we can be confident that this - // test also captures this part of the `strong` heuristic specification.) - // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail + // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -163,26 +154,11 @@ pub fn local_string_addr_taken(f: fn(&String)) { f(&x); // Taking the address of the local variable `x` leads to stack smash - // protection with the `strong` heuristic, but not with the `basic` - // heuristic. It does not matter that the reference is not mut. - // - // An interesting note is that a similar function in C++ *would* be - // protected by the `basic` heuristic, because `std::string` has a char - // array internally as a small object optimization: - // ``` - // cat < - // void f(void (*g)(const std::string&)) { - // std::string x; - // g(x); - // } - // EOF - // ``` - // + // protection. It does not matter that the reference is not mut. // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail + // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -233,8 +209,8 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // Even though the local variable conceptually doesn't have its address // taken, it's so large that the "move" is implemented with a reference to a // stack-local variable in the ABI. Consequently, this function *is* - // protected by the `strong` heuristic. This is also the case for - // rvalue-references in C++, regardless of struct size: + // protected. This is also the case for rvalue-references in C++, + // regardless of struct size: // ``` // cat < @@ -248,7 +224,7 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) { // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail + // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } @@ -261,9 +237,9 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // A new instance of `Gigastruct` is passed to `f()`, without any apparent // connection to this stack frame. Still, since instances of `Gigastruct` // are sufficiently large, it is allocated in the caller stack frame and - // passed as a pointer. As such, this function is *also* protected by the - // `strong` heuristic, just like `local_large_var_moved`. This is also the - // case for pass-by-value of sufficiently large structs in C++: + // passed as a pointer. As such, this function is *also* protected, just + // like `local_large_var_moved`. This is also the case for pass-by-value + // of sufficiently large structs in C++: // ``` // cat < @@ -275,10 +251,9 @@ pub fn local_large_var_cloned(f: fn(Gigastruct)) { // EOF // ``` - // all: __stack_chk_fail // strong: __stack_chk_fail - // basic-NOT: __stack_chk_fail + // basic: __stack_chk_fail // none-NOT: __stack_chk_fail // missing-NOT: __stack_chk_fail } diff --git a/tests/codegen/align-byval-alignment-mismatch.rs b/tests/codegen/align-byval-alignment-mismatch.rs index 306e3ce1358a..71f2dd42ec22 100644 --- a/tests/codegen/align-byval-alignment-mismatch.rs +++ b/tests/codegen/align-byval-alignment-mismatch.rs @@ -56,7 +56,7 @@ extern "C" { #[no_mangle] pub unsafe fn rust_to_c_increases_alignment(x: Align1) { // i686-linux: start: - // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align1, align 4 + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca [48 x i8], align 4 // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 4 {{.*}}[[ALLOCA]], ptr {{.*}}align 1 {{.*}}%x // i686-linux-NEXT: call void @extern_c_align1({{.+}} [[ALLOCA]]) @@ -90,7 +90,7 @@ pub unsafe extern "C" fn c_to_rust_decreases_alignment(x: Align1) { #[no_mangle] pub unsafe extern "C" fn c_to_rust_increases_alignment(x: Align16) { // i686-linux: start: - // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align16, align 16 + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca [48 x i8], align 16 // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 16 {{.*}}[[ALLOCA]], ptr {{.*}}align 4 {{.*}}%0 // i686-linux-NEXT: call void @extern_rust_align16({{.+}} [[ALLOCA]]) @@ -116,7 +116,7 @@ pub unsafe extern "C" fn c_to_rust_ref_decreases_alignment(x: Align1) { #[no_mangle] pub unsafe extern "C" fn c_to_rust_ref_increases_alignment(x: Align16) { // i686-linux: start: - // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca %Align16, align 16 + // i686-linux-NEXT: [[ALLOCA:%[0-9a-z]+]] = alloca [48 x i8], align 16 // i686-linux-NEXT: call void @llvm.memcpy.{{.+}}(ptr {{.*}}align 16 {{.*}}[[ALLOCA]], ptr {{.*}}align 4 {{.*}}%0 // i686-linux-NEXT: call void @extern_rust_ref_align16({{.+}} [[ALLOCA]]) diff --git a/tests/codegen/align-byval.rs b/tests/codegen/align-byval.rs index c74e236f29d3..3a2be2b2b9c3 100644 --- a/tests/codegen/align-byval.rs +++ b/tests/codegen/align-byval.rs @@ -106,20 +106,20 @@ pub struct ForceAlign16 { pub unsafe fn call_na1(x: NaturalAlign1) { // CHECK: start: - // m68k: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 1 + // m68k: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 1 // m68k: call void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}} [[ALLOCA]]) - // wasm: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 1 + // wasm: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 1 // wasm: call void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}} [[ALLOCA]]) // x86_64-linux: call void @natural_align_1(i16 // x86_64-windows: call void @natural_align_1(i16 - // i686-linux: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 4 + // i686-linux: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 4 // i686-linux: call void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}} [[ALLOCA]]) - // i686-windows: [[ALLOCA:%[a-z0-9+]]] = alloca %NaturalAlign1, align 4 + // i686-windows: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 4 // i686-windows: call void @natural_align_1({{.*}}byval([2 x i8]) align 4{{.*}} [[ALLOCA]]) natural_align_1(x); } @@ -134,10 +134,10 @@ pub unsafe fn call_na2(x: NaturalAlign2) { // x86_64-linux-NEXT: call void @natural_align_2 // x86_64-windows-NEXT: call void @natural_align_2 - // i686-linux: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4 + // i686-linux: [[ALLOCA:%[0-9]+]] = alloca [34 x i8], align 4 // i686-linux: call void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}} [[ALLOCA]]) - // i686-windows: [[ALLOCA:%[0-9]+]] = alloca %NaturalAlign2, align 4 + // i686-windows: [[ALLOCA:%[0-9]+]] = alloca [34 x i8], align 4 // i686-windows: call void @natural_align_2({{.*}}byval([34 x i8]) align 4{{.*}} [[ALLOCA]]) natural_align_2(x); } diff --git a/tests/codegen/align-enum.rs b/tests/codegen/align-enum.rs index b40168d77a47..93d5a87fb309 100644 --- a/tests/codegen/align-enum.rs +++ b/tests/codegen/align-enum.rs @@ -18,7 +18,7 @@ pub struct Nested64 { // CHECK-LABEL: @align64 #[no_mangle] pub fn align64(a: u32) -> Align64 { -// CHECK: %a64 = alloca %Align64, align 64 +// CHECK: %a64 = alloca [64 x i8], align 64 // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) let a64 = Align64::A(a); a64 @@ -27,7 +27,7 @@ pub fn align64(a: u32) -> Align64 { // CHECK-LABEL: @nested64 #[no_mangle] pub fn nested64(a: u8, b: u32, c: u16) -> Nested64 { -// CHECK: %n64 = alloca %Nested64, align 64 +// CHECK: %n64 = alloca [128 x i8], align 64 let n64 = Nested64 { a, b: Align64::B(b), c }; n64 } diff --git a/tests/codegen/align-struct.rs b/tests/codegen/align-struct.rs index dbbb85bee6f3..e70b42b47db8 100644 --- a/tests/codegen/align-struct.rs +++ b/tests/codegen/align-struct.rs @@ -26,7 +26,7 @@ pub enum Enum64 { // CHECK-LABEL: @align64 #[no_mangle] pub fn align64(i : i32) -> Align64 { -// CHECK: %a64 = alloca %Align64, align 64 +// CHECK: %a64 = alloca [64 x i8], align 64 // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 64 %{{.*}}, ptr align 64 %{{.*}}, i{{[0-9]+}} 64, i1 false) let a64 = Align64(i); a64 @@ -44,7 +44,7 @@ pub fn align64_load(a: Align64) -> i32 { // CHECK-LABEL: @nested64 #[no_mangle] pub fn nested64(a: Align64, b: i32, c: i32, d: i8) -> Nested64 { -// CHECK: %n64 = alloca %Nested64, align 64 +// CHECK: %n64 = alloca [128 x i8], align 64 let n64 = Nested64 { a, b, c, d }; n64 } @@ -52,7 +52,7 @@ pub fn nested64(a: Align64, b: i32, c: i32, d: i8) -> Nested64 { // CHECK-LABEL: @enum4 #[no_mangle] pub fn enum4(a: i32) -> Enum4 { -// CHECK: %e4 = alloca %Enum4, align 4 +// CHECK: %e4 = alloca [8 x i8], align 4 let e4 = Enum4::A(a); e4 } @@ -60,7 +60,7 @@ pub fn enum4(a: i32) -> Enum4 { // CHECK-LABEL: @enum64 #[no_mangle] pub fn enum64(a: Align64) -> Enum64 { -// CHECK: %e64 = alloca %Enum64, align 64 +// CHECK: %e64 = alloca [128 x i8], align 64 let e64 = Enum64::A(a); e64 } diff --git a/tests/codegen/array-codegen.rs b/tests/codegen/array-codegen.rs index 1310e61c41d0..fc272f2556cb 100644 --- a/tests/codegen/array-codegen.rs +++ b/tests/codegen/array-codegen.rs @@ -18,7 +18,7 @@ pub fn array_load(a: &[u8; 4]) -> [u8; 4] { #[no_mangle] pub fn array_store(a: [u8; 4], p: &mut [u8; 4]) { // CHECK-NOT: alloca - // CHECK: %[[TEMP:.+]] = alloca i32, [[TEMPALIGN:align [0-9]+]] + // CHECK: %[[TEMP:.+]] = alloca [4 x i8], [[TEMPALIGN:align [0-9]+]] // CHECK-NOT: alloca // CHECK: %a = alloca [4 x i8] // CHECK-NOT: alloca diff --git a/tests/codegen/array-map.rs b/tests/codegen/array-map.rs index 743a15989f78..f49dddcfc207 100644 --- a/tests/codegen/array-map.rs +++ b/tests/codegen/array-map.rs @@ -27,7 +27,7 @@ pub fn short_integer_map(x: [u32; 8]) -> [u32; 8] { #[no_mangle] pub fn long_integer_map(x: [u32; 512]) -> [u32; 512] { // CHECK: start: - // CHECK-NEXT: alloca [512 x i32] + // CHECK-NEXT: alloca [2048 x i8] // CHECK-NOT: alloca // CHECK: mul <{{[0-9]+}} x i32> // CHECK: add <{{[0-9]+}} x i32> diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs index e6024f03425f..9c31acc9bb7c 100644 --- a/tests/codegen/cast-target-abi.rs +++ b/tests/codegen/cast-target-abi.rs @@ -77,15 +77,20 @@ extern "C" { // CHECK-LABEL: @call_twou16s #[no_mangle] pub unsafe fn call_twou16s() { - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]] - // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i32]], align [[ABI_ALIGN:4]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [4 x i8], align [[ABI_ALIGN:4]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] - // CHECK: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]] + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 4, i1 false) - // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i32]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:i64]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // CHECK: call void @receives_twou16s([[ABI_TYPE]] [[ABI_VALUE]]) let x = TwoU16s { a: 1, b: 2 }; receives_twou16s(x); @@ -96,23 +101,23 @@ pub unsafe fn call_twou16s() { pub unsafe fn return_twou16s() -> TwoU16s { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. - // powerpc64: [[RETVAL:%.+]] = alloca %TwoU16s, align 2 + // powerpc64: [[RETVAL:%.+]] = alloca [4 x i8], align 2 // powerpc64: call void @returns_twou16s(ptr {{.+}} [[RETVAL]]) // The other targets copy the cast ABI type to an alloca. - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [8 x i8], align [[ABI_ALIGN:8]] - // aarch64: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]] - // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]] - // sparc64: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]] + // aarch64: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] + // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] + // sparc64: [[RUST_ALLOCA:%.+]] = alloca [4 x i8], align [[RUST_ALIGN:2]] - // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s() - // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s() - // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s() + // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:i64]] @returns_twou16s() + // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:i64]] @returns_twou16s() + // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:i64]] @returns_twou16s() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] @@ -127,12 +132,12 @@ pub unsafe fn return_twou16s() -> TwoU16s { // CHECK-LABEL: @call_fiveu16s #[no_mangle] pub unsafe fn call_fiveu16s() { - // CHECK: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] + // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // CHECK: [[RUST_ALLOCA:%.+]] = alloca %FiveU16s, align 2 + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [10 x i8], align 2 // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 10, i1 false) - // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // CHECK: call void @receives_fiveu16s([[ABI_TYPE]] [[ABI_VALUE]]) let x = FiveU16s { a: 1, b: 2, c: 3, d: 4, e: 5 }; receives_fiveu16s(x); @@ -149,13 +154,13 @@ pub unsafe fn return_fiveu16s() -> FiveU16s { // The other targets copy the cast ABI type to the sret pointer. - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s() - // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s() - // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s() + // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() + // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() + // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_fiveu16s() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] @@ -170,15 +175,17 @@ pub unsafe fn return_fiveu16s() -> FiveU16s { // CHECK-LABEL: @call_doubledouble #[no_mangle] pub unsafe fn call_doubledouble() { - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x double\]]], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]] - // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]] + // CHECK: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // CHECK: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]] + // CHECK: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false) - // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x double\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // sparc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, double }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // CHECK: call void @receives_doubledouble([[ABI_TYPE]] [[ABI_VALUE]]) let x = DoubleDouble { f: 1., g: 2. }; receives_doubledouble(x); @@ -189,23 +196,23 @@ pub unsafe fn call_doubledouble() { pub unsafe fn return_doubledouble() -> DoubleDouble { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. - // powerpc64: [[RETVAL:%.+]] = alloca %DoubleDouble, align 8 + // powerpc64: [[RETVAL:%.+]] = alloca [16 x i8], align 8 // powerpc64: call void @returns_doubledouble(ptr {{.+}} [[RETVAL]]) // The other targets copy the cast ABI type to an alloca. - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x double\]]], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]] - // sparc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // sparc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // aarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]] - // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]] - // sparc64: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]] + // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // sparc64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] - // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble() - // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble() - // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble() + // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x double\]]] @returns_doubledouble() + // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, double }]] @returns_doubledouble() + // sparc64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, double }]] @returns_doubledouble() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] @@ -224,21 +231,21 @@ pub unsafe fn return_doubledouble() -> DoubleDouble { // powerpc64-LABEL: @call_doublefloat #[no_mangle] pub unsafe fn call_doublefloat() { - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, float }]], align [[ABI_ALIGN:8]] - // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] + // powerpc64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] - // aarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]] - // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]] - // powerpc64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]] + // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // powerpc64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] // aarch64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false) // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 12, i1 false) // powerpc64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false) - // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] - // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] - // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // aarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:{ double, float }]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] + // powerpc64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE:\[2 x i64\]]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // aarch64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]]) // loongarch64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]]) @@ -256,20 +263,20 @@ pub unsafe fn call_doublefloat() { pub unsafe fn return_doublefloat() -> DoubleFloat { // powerpc returns this struct via sret pointer, it doesn't use the cast ABI. - // powerpc64: [[RETVAL:%.+]] = alloca %DoubleFloat, align 8 + // powerpc64: [[RETVAL:%.+]] = alloca [16 x i8], align 8 // powerpc64: call void @returns_doublefloat(ptr {{.+}} [[RETVAL]]) // The other targets copy the cast ABI type to an alloca. - // aarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]] - // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, float }]], align [[ABI_ALIGN:8]] + // aarch64: [[ABI_ALLOCA:%.+]] = alloca [16 x i8], align [[ABI_ALIGN:8]] + // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [12 x i8], align [[ABI_ALIGN:8]] - // aarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]] - // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]] + // aarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] + // loongarch64: [[RUST_ALLOCA:%.+]] = alloca [16 x i8], align [[RUST_ALIGN:8]] - // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doublefloat() - // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doublefloat() + // aarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:\[2 x i64\]]] @returns_doublefloat() + // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE:{ double, float }]] @returns_doublefloat() // aarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]] diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs index 8b32e902b3f5..35bf00f8f3c3 100644 --- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs +++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs @@ -33,7 +33,7 @@ extern "C" { pub fn test() { let s = S { f1: 1, f2: 2, f3: 3 }; unsafe { - // CHECK: [[ALLOCA:%.+]] = alloca { i64, i32 }, align 8 + // CHECK: [[ALLOCA:%.+]] = alloca [12 x i8], align 8 // CHECK: [[LOAD:%.+]] = load { i64, i32 }, ptr [[ALLOCA]], align 8 // CHECK: call void @foo({ i64, i32 } [[LOAD]]) foo(s); diff --git a/tests/codegen/const_scalar_pair.rs b/tests/codegen/const_scalar_pair.rs index 0aa430a8efa0..f142896c31f1 100644 --- a/tests/codegen/const_scalar_pair.rs +++ b/tests/codegen/const_scalar_pair.rs @@ -1,7 +1,5 @@ //@ compile-flags: --crate-type=lib -Copt-level=0 -Zmir-opt-level=0 -C debuginfo=2 -#![feature(inline_const)] - // Test that we don't generate a memory allocation for the constant // and read the fields from that, but instead just create the value pair directly. pub fn foo() -> (i32, i32) { diff --git a/tests/codegen/coroutine-debug-msvc.rs b/tests/codegen/coroutine-debug-msvc.rs index fb1b46fe497f..e2296db1d594 100644 --- a/tests/codegen/coroutine-debug-msvc.rs +++ b/tests/codegen/coroutine-debug-msvc.rs @@ -11,7 +11,7 @@ use std::ops::Coroutine; fn coroutine_test() -> impl Coroutine { - || { + #[coroutine] || { yield 0; let s = String::from("foo"); yield 1; diff --git a/tests/codegen/coroutine-debug.rs b/tests/codegen/coroutine-debug.rs index 7eaee669559e..914515f58b85 100644 --- a/tests/codegen/coroutine-debug.rs +++ b/tests/codegen/coroutine-debug.rs @@ -11,7 +11,7 @@ use std::ops::Coroutine; fn coroutine_test() -> impl Coroutine { - || { + #[coroutine] || { yield 0; let s = String::from("foo"); yield 1; diff --git a/tests/codegen/debug-fndef-size.rs b/tests/codegen/debug-fndef-size.rs index b3cc45614bc5..5551d2cc39cf 100644 --- a/tests/codegen/debug-fndef-size.rs +++ b/tests/codegen/debug-fndef-size.rs @@ -12,7 +12,7 @@ pub fn main() { foo(0, 1, i32::cmp); } -// CHECK: %compare.dbg.spill = alloca {}, align 1 +// CHECK: %compare.dbg.spill = alloca [0 x i8], align 1 // CHECK: call void @llvm.dbg.declare(metadata ptr %compare.dbg.spill, metadata ![[VAR:.*]], metadata !DIExpression()), !dbg !{{.*}} // CHECK: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 1, dwarfAddressSpace: {{.*}}) // CHECK: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 1) diff --git a/tests/codegen/emcripten-catch-unwind.rs b/tests/codegen/emcripten-catch-unwind.rs new file mode 100644 index 000000000000..7de7bd81b5c0 --- /dev/null +++ b/tests/codegen/emcripten-catch-unwind.rs @@ -0,0 +1,59 @@ +//@ compile-flags: -O --target wasm32-unknown-emscripten +//@ needs-llvm-components: webassembly + +// Emscripten has its own unique implementation of catch_unwind (in `codegen_emcc_try`), +// make sure it generates something reasonable. + +#![feature(no_core, lang_items, intrinsics, rustc_attrs)] +#![crate_type = "lib"] +#![no_std] +#![no_core] + +#[lang="sized"] trait Sized { } +#[lang="freeze"] trait Freeze { } +#[lang="copy"] trait Copy { } + +#[rustc_intrinsic] +fn size_of() -> usize { loop {} } + +extern "rust-intrinsic" { + fn catch_unwind( + try_fn: fn(_: *mut u8), + data: *mut u8, + catch_fn: fn(_: *mut u8, _: *mut u8) + ) -> i32; +} + +// CHECK-LABEL: @ptr_size +#[no_mangle] +pub fn ptr_size() -> usize { + // CHECK: ret [[PTR_SIZE:.*]] + size_of::<*mut u8>() +} + +// CHECK-LABEL: @test_catch_unwind +#[no_mangle] +pub unsafe fn test_catch_unwind( + try_fn: fn(_: *mut u8), + data: *mut u8, + catch_fn: fn(_: *mut u8, _: *mut u8) +) -> i32 { + // CHECK: start: + // CHECK: [[ALLOCA:%.*]] = alloca + + // CHECK: catch.i: + // CHECK: [[LANDINGPAD:%.*]] = landingpad + // CHECK: [[EXCEPTION:%.*]] = extractvalue {{.*}} [[LANDINGPAD]], 0 + // CHECK: [[SELECTOR:%.*]] = extractvalue {{.*}} [[LANDINGPAD]], 1 + + // CHECK: [[IS_RUST_EXN:%.*]] = icmp eq {{.*}}[[SELECTOR]] + // CHECK: [[IS_RUST_EXN_I8:%.*]] = zext i1 [[IS_RUST_EXN]] to i8 + + // CHECK: store ptr [[EXCEPTION]], ptr [[ALLOCA]] + // CHECK: [[IS_RUST_SLOT:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], [[PTR_SIZE]] + // CHECK: store i8 [[IS_RUST_EXN_I8]], ptr [[IS_RUST_SLOT]] + + // CHECK: call void %catch_fn(ptr %data, ptr nonnull [[ALLOCA]]) + + catch_unwind(try_fn, data, catch_fn) +} diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs index 2e6dad8791b2..f1c40f6695be 100644 --- a/tests/codegen/enum/enum-match.rs +++ b/tests/codegen/enum/enum-match.rs @@ -15,7 +15,7 @@ pub enum Enum0 { // CHECK-NEXT: start: // CHECK-NEXT: %1 = icmp eq i8 %0, 2 // CHECK-NEXT: %2 = and i8 %0, 1 -// CHECK-NEXT: %_0.0 = select i1 %1, i8 13, i8 %2 +// CHECK-NEXT: %{{.+}} = select i1 %1, i8 13, i8 %2 #[no_mangle] pub fn match0(e: Enum0) -> u8 { use Enum0::*; diff --git a/tests/codegen/i128-x86-align.rs b/tests/codegen/i128-x86-align.rs index b2e0c294c39d..3e6ed2b8e16a 100644 --- a/tests/codegen/i128-x86-align.rs +++ b/tests/codegen/i128-x86-align.rs @@ -6,7 +6,6 @@ // correctly. // CHECK: %ScalarPair = type { i32, [3 x i32], i128 } -// CHECK: %Struct = type { i32, i32, [2 x i32], i128 } #![feature(core_intrinsics)] @@ -43,7 +42,7 @@ pub fn store(x: &mut ScalarPair) { #[no_mangle] pub fn alloca() { // CHECK-LABEL: @alloca( - // CHECK: [[X:%.*]] = alloca %ScalarPair, align 16 + // CHECK: [[X:%.*]] = alloca [32 x i8], align 16 // CHECK: store i32 1, ptr %x, align 16 // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr %x, i64 16 // CHECK-NEXT: store i128 2, ptr [[GEP]], align 16 @@ -55,7 +54,7 @@ pub fn alloca() { pub fn load_volatile(x: &ScalarPair) -> ScalarPair { // CHECK-LABEL: @load_volatile( // CHECK-SAME: align 16 dereferenceable(32) %x - // CHECK: [[TMP:%.*]] = alloca %ScalarPair, align 16 + // CHECK: [[TMP:%.*]] = alloca [32 x i8], align 16 // CHECK: [[LOAD:%.*]] = load volatile %ScalarPair, ptr %x, align 16 // CHECK-NEXT: store %ScalarPair [[LOAD]], ptr [[TMP]], align 16 // CHECK-NEXT: [[A:%.*]] = load i32, ptr [[TMP]], align 16 @@ -67,7 +66,7 @@ pub fn load_volatile(x: &ScalarPair) -> ScalarPair { #[no_mangle] pub fn transmute(x: ScalarPair) -> (std::mem::MaybeUninit, i128) { // CHECK-LABEL: define { i128, i128 } @transmute(i32 noundef %x.0, i128 noundef %x.1) - // CHECK: [[TMP:%.*]] = alloca { i128, i128 }, align 16 + // CHECK: [[TMP:%.*]] = alloca [32 x i8], align 16 // CHECK-NEXT: store i32 %x.0, ptr [[TMP]], align 16 // CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 16 // CHECK-NEXT: store i128 %x.1, ptr [[GEP]], align 16 @@ -92,7 +91,7 @@ pub struct Struct { pub fn store_struct(x: &mut Struct) { // CHECK-LABEL: @store_struct( // CHECK-SAME: align 16 dereferenceable(32) %x - // CHECK: [[TMP:%.*]] = alloca %Struct, align 16 + // CHECK: [[TMP:%.*]] = alloca [32 x i8], align 16 // CHECK: store i32 1, ptr [[TMP]], align 16 // CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 4 // CHECK-NEXT: store i32 2, ptr [[GEP1]], align 4 diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index f858562b5f11..04a91bb87f7c 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -4,7 +4,6 @@ #![crate_type = "lib"] #![feature(core_intrinsics)] #![feature(custom_mir)] -#![feature(inline_const)] #![allow(unreachable_code)] use std::intrinsics::{transmute, transmute_unchecked}; @@ -153,7 +152,7 @@ pub unsafe fn check_from_newtype(x: Scalar64) -> u64 { // CHECK-LABEL: @check_aggregate_to_bool( #[no_mangle] pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool { - // CHECK: %x = alloca %Aggregate8, align 1 + // CHECK: %x = alloca [1 x i8], align 1 // CHECK: %[[BYTE:.+]] = load i8, ptr %x, align 1 // CHECK: %[[BOOL:.+]] = trunc i8 %[[BYTE]] to i1 // CHECK: ret i1 %[[BOOL]] @@ -163,7 +162,7 @@ pub unsafe fn check_aggregate_to_bool(x: Aggregate8) -> bool { // CHECK-LABEL: @check_aggregate_from_bool( #[no_mangle] pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 { - // CHECK: %_0 = alloca %Aggregate8, align 1 + // CHECK: %_0 = alloca [1 x i8], align 1 // CHECK: %[[BYTE:.+]] = zext i1 %x to i8 // CHECK: store i8 %[[BYTE]], ptr %_0, align 1 transmute(x) @@ -190,7 +189,7 @@ pub unsafe fn check_byte_from_bool(x: bool) -> u8 { // CHECK-LABEL: @check_to_pair( #[no_mangle] pub unsafe fn check_to_pair(x: u64) -> Option { - // CHECK: %_0 = alloca %"core::option::Option", align 4 + // CHECK: %_0 = alloca [8 x i8], align 4 // CHECK: store i64 %x, ptr %_0, align 4 transmute(x) } @@ -202,7 +201,7 @@ pub unsafe fn check_from_pair(x: Option) -> u64 { // immediates so we can write using the destination alloca's alignment. const { assert!(std::mem::align_of::>() == 4) }; - // CHECK: %_0 = alloca i64, align 8 + // CHECK: %_0 = alloca [8 x i8], align 8 // CHECK: store i32 %x.0, ptr %_0, align 8 // CHECK: store i32 %x.1, ptr %0, align 4 // CHECK: %[[R:.+]] = load i64, ptr %_0, align 8 @@ -248,7 +247,7 @@ pub unsafe fn check_from_bytes(x: [u8; 4]) -> u32 { // CHECK-LABEL: @check_to_aggregate( #[no_mangle] pub unsafe fn check_to_aggregate(x: u64) -> Aggregate64 { - // CHECK: %_0 = alloca %Aggregate64, align 4 + // CHECK: %_0 = alloca [8 x i8], align 4 // CHECK: store i64 %x, ptr %_0, align 4 // CHECK: %0 = load i64, ptr %_0, align 4 // CHECK: ret i64 %0 @@ -258,7 +257,7 @@ pub unsafe fn check_to_aggregate(x: u64) -> Aggregate64 { // CHECK-LABEL: @check_from_aggregate( #[no_mangle] pub unsafe fn check_from_aggregate(x: Aggregate64) -> u64 { - // CHECK: %x = alloca %Aggregate64, align 4 + // CHECK: %x = alloca [8 x i8], align 4 // CHECK: %[[VAL:.+]] = load i64, ptr %x, align 4 // CHECK: ret i64 %[[VAL]] transmute(x) @@ -452,7 +451,7 @@ pub struct HighAlignScalar(u8); // CHECK-LABEL: @check_to_overalign( #[no_mangle] pub unsafe fn check_to_overalign(x: u64) -> HighAlignScalar { - // CHECK: %_0 = alloca %HighAlignScalar, align 8 + // CHECK: %_0 = alloca [8 x i8], align 8 // CHECK: store i64 %x, ptr %_0, align 8 // CHECK: %0 = load i64, ptr %_0, align 8 // CHECK: ret i64 %0 @@ -462,7 +461,7 @@ pub unsafe fn check_to_overalign(x: u64) -> HighAlignScalar { // CHECK-LABEL: @check_from_overalign( #[no_mangle] pub unsafe fn check_from_overalign(x: HighAlignScalar) -> u64 { - // CHECK: %x = alloca %HighAlignScalar, align 8 + // CHECK: %x = alloca [8 x i8], align 8 // CHECK: %[[VAL:.+]] = load i64, ptr %x, align 8 // CHECK: ret i64 %[[VAL]] transmute(x) diff --git a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs index 0bd43dc50b21..56b4330b1a6c 100644 --- a/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs +++ b/tests/codegen/issues/issue-105386-ub-in-debuginfo.rs @@ -15,7 +15,7 @@ pub fn outer_function(x: S, y: S) -> usize { // Check that we do not attempt to load from the spilled arg before it is assigned to // when generating debuginfo. // CHECK-LABEL: @outer_function -// CHECK: [[spill:%.*]] = alloca %"{closure@{{.*.rs}}:9:23: 9:25}" +// CHECK: [[spill:%.*]] = alloca // CHECK-NOT: [[ptr_tmp:%.*]] = getelementptr inbounds i8, ptr [[spill]] // CHECK-NOT: [[load:%.*]] = load ptr, ptr // CHECK: call void @llvm.lifetime.start{{.*}}({{.*}}, ptr [[spill]]) diff --git a/tests/codegen/issues/issue-111603.rs b/tests/codegen/issues/issue-111603.rs index 3f4c7e7d5423..41bfb493ff58 100644 --- a/tests/codegen/issues/issue-111603.rs +++ b/tests/codegen/issues/issue-111603.rs @@ -11,7 +11,7 @@ pub fn new_from_array(x: u64) -> Arc<[u64]> { // Ensure that we only generate one alloca for the array. // CHECK: alloca - // CHECK-SAME: [1000 x i64] + // CHECK-SAME: [8000 x i8] // CHECK-NOT: alloca let array = [x; 1000]; Arc::new(array) diff --git a/tests/codegen/issues/issue-96274.rs b/tests/codegen/issues/issue-96274.rs index d278796dd02a..ffefd5f43f8c 100644 --- a/tests/codegen/issues/issue-96274.rs +++ b/tests/codegen/issues/issue-96274.rs @@ -1,7 +1,6 @@ //@ compile-flags: -O #![crate_type = "lib"] -#![feature(inline_const)] use std::mem::MaybeUninit; diff --git a/tests/codegen/overaligned-constant.rs b/tests/codegen/overaligned-constant.rs index 9e5b69ff2670..7cd8d19c2113 100644 --- a/tests/codegen/overaligned-constant.rs +++ b/tests/codegen/overaligned-constant.rs @@ -2,7 +2,7 @@ // do not ICE during codegen, and that the LLVM constant has the higher alignment. // //@ compile-flags: -Zmir-opt-level=0 -Zmir-enable-passes=+GVN -//@ compile-flags: -Cno-prepopulate-passes +//@ compile-flags: -Cno-prepopulate-passes --crate-type=lib //@ only-64bit struct S(i32); @@ -12,9 +12,10 @@ struct SmallStruct(f32, Option, &'static [f32]); // CHECK: @0 = private unnamed_addr constant // CHECK-SAME: , align 8 -fn main() { - // CHECK-LABEL: @_ZN20overaligned_constant4main - // CHECK: [[full:%_.*]] = alloca %SmallStruct, align 8 +#[no_mangle] +pub fn overaligned_constant() { + // CHECK-LABEL: @overaligned_constant + // CHECK: [[full:%_.*]] = alloca [32 x i8], align 8 // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[full]], ptr align 8 @0, i64 32, i1 false) // CHECK: %b.0 = load i32, ptr @0, align 4 // CHECK: %b.1 = load i32, ptr getelementptr inbounds ({{.*}}), align 4 diff --git a/tests/codegen/packed.rs b/tests/codegen/packed.rs index 764476b0aa13..5142df9c4881 100644 --- a/tests/codegen/packed.rs +++ b/tests/codegen/packed.rs @@ -51,7 +51,7 @@ pub struct BigPacked2 { // CHECK-LABEL: @call_pkd1 #[no_mangle] pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { -// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array +// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct @@ -63,7 +63,7 @@ pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 { // CHECK-LABEL: @call_pkd2 #[no_mangle] pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 { -// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array +// CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca [32 x i8] // CHECK: call void %{{.*}}(ptr noalias nocapture noundef sret{{.*}} dereferenceable(32) [[ALLOCA]]) // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 2 %{{.*}}, ptr align 4 %{{.*}}, i{{[0-9]+}} 32, i1 false) // check that calls whose destination is a field of a packed struct diff --git a/tests/codegen/personality_lifetimes.rs b/tests/codegen/personality_lifetimes.rs index f2ab9c3bb82b..0ef4aa424d83 100644 --- a/tests/codegen/personality_lifetimes.rs +++ b/tests/codegen/personality_lifetimes.rs @@ -23,7 +23,7 @@ pub fn test() { let _s = S; // Check that the personality slot alloca gets a lifetime start in each cleanup block, not just // in the first one. - // CHECK: [[SLOT:%[0-9]+]] = alloca { ptr, i32{{.*}} } + // CHECK: [[SLOT:%[0-9]+]] = alloca [{{[0-9]+}} x i8] // CHECK-LABEL: cleanup: // CHECK: call void @llvm.lifetime.start.{{.*}}({{.*}}) // CHECK-LABEL: cleanup1: diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs index ca781a99296b..6c3d991af9f1 100644 --- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs +++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs @@ -5,7 +5,7 @@ //@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static #![crate_type="lib"] -#![feature(inline_const, type_alias_impl_trait)] +#![feature(type_alias_impl_trait)] extern crate core; diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs index 488be2a8629d..c416f4d28bb5 100644 --- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs +++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs @@ -4,7 +4,6 @@ #![crate_type = "lib"] #![allow(non_camel_case_types)] #![feature(repr_simd, intrinsics)] -#![feature(inline_const)] #[repr(simd)] #[derive(Copy, Clone)] diff --git a/tests/codegen/sroa-fragment-debuginfo.rs b/tests/codegen/sroa-fragment-debuginfo.rs index d8c2d2c6f9ef..32786d2a76a4 100644 --- a/tests/codegen/sroa-fragment-debuginfo.rs +++ b/tests/codegen/sroa-fragment-debuginfo.rs @@ -14,9 +14,9 @@ pub struct ExtraSlice<'input> { #[no_mangle] pub fn extra(s: &[u8]) { // CHECK: void @extra( -// CHECK: %slice.dbg.spill1 = alloca i32, -// CHECK: %slice.dbg.spill = alloca { ptr, i64 }, -// CHECK: %s.dbg.spill = alloca { ptr, i64 }, +// CHECK: %slice.dbg.spill1 = alloca [4 x i8], +// CHECK: %slice.dbg.spill = alloca [16 x i8], +// CHECK: %s.dbg.spill = alloca [16 x i8], // CHECK: call void @llvm.dbg.declare(metadata ptr %s.dbg.spill, metadata ![[S_EXTRA:.*]], metadata !DIExpression()), // CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata ![[SLICE_EXTRA:.*]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 128)), // CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill1, metadata ![[SLICE_EXTRA]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 32)), diff --git a/tests/codegen/stores.rs b/tests/codegen/stores.rs index 3fda5aa47eaf..86ec52fa1015 100644 --- a/tests/codegen/stores.rs +++ b/tests/codegen/stores.rs @@ -15,8 +15,8 @@ pub struct Bytes { // dependent alignment #[no_mangle] pub fn small_array_alignment(x: &mut [i8; 4], y: [i8; 4]) { -// CHECK: [[TMP:%.+]] = alloca i32 -// CHECK: %y = alloca [4 x i8] +// CHECK: [[TMP:%.+]] = alloca [4 x i8], align 4 +// CHECK: %y = alloca [4 x i8], align 1 // CHECK: store i32 %0, ptr [[TMP]] // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) *x = y; @@ -27,8 +27,8 @@ pub fn small_array_alignment(x: &mut [i8; 4], y: [i8; 4]) { // dependent alignment #[no_mangle] pub fn small_struct_alignment(x: &mut Bytes, y: Bytes) { -// CHECK: [[TMP:%.+]] = alloca i32 -// CHECK: %y = alloca %Bytes +// CHECK: [[TMP:%.+]] = alloca [4 x i8], align 4 +// CHECK: %y = alloca [4 x i8], align 1 // CHECK: store i32 %0, ptr [[TMP]] // CHECK: call void @llvm.memcpy.{{.*}}(ptr align 1 {{.+}}, ptr align 4 {{.+}}, i{{[0-9]+}} 4, i1 false) *x = y; diff --git a/tests/codegen/swap-large-types.rs b/tests/codegen/swap-large-types.rs index b182f3ed9479..b976f6fe207b 100644 --- a/tests/codegen/swap-large-types.rs +++ b/tests/codegen/swap-large-types.rs @@ -15,7 +15,7 @@ type KeccakBuffer = [[u64; 5]; 5]; // CHECK-LABEL: @swap_basic #[no_mangle] pub fn swap_basic(x: &mut KeccakBuffer, y: &mut KeccakBuffer) { -// CHECK: alloca [5 x [5 x i64]] +// CHECK: alloca [200 x i8] // SAFETY: exclusive references are always valid to read/write, // are non-overlapping, and nothing here panics so it's drop-safe. diff --git a/tests/codegen/swap-small-types.rs b/tests/codegen/swap-small-types.rs index 4dcfed2a53af..1a48c63d8139 100644 --- a/tests/codegen/swap-small-types.rs +++ b/tests/codegen/swap-small-types.rs @@ -12,7 +12,7 @@ type RGB48 = [u16; 3]; pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) { // FIXME: See #115212 for why this has an alloca again - // CHECK: alloca [3 x i16], align 2 + // CHECK: alloca [6 x i8], align 2 // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) diff --git a/tests/coverage/coroutine.cov-map b/tests/coverage/coroutine.cov-map index ef9faab590b3..255708d365ee 100644 --- a/tests/coverage/coroutine.cov-map +++ b/tests/coverage/coroutine.cov-map @@ -43,11 +43,11 @@ Number of file 0 mappings: 9 = ((c4 - c5) - c6) Function name: coroutine::main::{closure#0} -Raw bytes (14): 0x[01, 01, 00, 02, 01, 15, 1c, 01, 1f, 05, 02, 10, 01, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 15, 29, 01, 1f, 05, 02, 10, 01, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 21, 28) to (start + 1, 31) +- Code(Counter(0)) at (prev + 21, 41) to (start + 1, 31) - Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6) diff --git a/tests/coverage/coroutine.coverage b/tests/coverage/coroutine.coverage index bd3d4e468801..68b52d198316 100644 --- a/tests/coverage/coroutine.coverage +++ b/tests/coverage/coroutine.coverage @@ -1,4 +1,4 @@ - LL| |#![feature(coroutines, coroutine_trait)] + LL| |#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] LL| | LL| |use std::ops::{Coroutine, CoroutineState}; LL| |use std::pin::Pin; @@ -18,7 +18,7 @@ LL| | LL| 1|fn main() { LL| 1| let is_true = std::env::args().len() == 1; - LL| 1| let mut coroutine = || { + LL| 1| let mut coroutine = #[coroutine] || { LL| 1| yield get_u32(is_true); LL| 1| return "foo"; LL| 1| }; diff --git a/tests/coverage/coroutine.rs b/tests/coverage/coroutine.rs index 2aa689466fc3..7f72e0d8bd42 100644 --- a/tests/coverage/coroutine.rs +++ b/tests/coverage/coroutine.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; @@ -18,7 +18,7 @@ fn get_u32(val: bool) -> Result { fn main() { let is_true = std::env::args().len() == 1; - let mut coroutine = || { + let mut coroutine = #[coroutine] || { yield get_u32(is_true); return "foo"; }; diff --git a/tests/coverage/yield.cov-map b/tests/coverage/yield.cov-map index 9cc67dfe88ac..0347aaaa3676 100644 --- a/tests/coverage/yield.cov-map +++ b/tests/coverage/yield.cov-map @@ -41,21 +41,21 @@ Number of file 0 mappings: 16 - Code(Counter(11)) at (prev + 2, 1) to (start + 0, 2) Function name: yield::main::{closure#0} -Raw bytes (14): 0x[01, 01, 00, 02, 01, 08, 1c, 01, 10, 05, 02, 10, 01, 06] +Raw bytes (14): 0x[01, 01, 00, 02, 01, 08, 29, 01, 10, 05, 02, 10, 01, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 2 -- Code(Counter(0)) at (prev + 8, 28) to (start + 1, 16) +- Code(Counter(0)) at (prev + 8, 41) to (start + 1, 16) - Code(Counter(1)) at (prev + 2, 16) to (start + 1, 6) Function name: yield::main::{closure#1} -Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 1c, 01, 10, 05, 02, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 01, 06] +Raw bytes (24): 0x[01, 01, 00, 04, 01, 16, 29, 01, 10, 05, 02, 09, 00, 10, 09, 01, 09, 00, 10, 0d, 01, 10, 01, 06] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 16) +- Code(Counter(0)) at (prev + 22, 41) to (start + 1, 16) - Code(Counter(1)) at (prev + 2, 9) to (start + 0, 16) - Code(Counter(2)) at (prev + 1, 9) to (start + 0, 16) - Code(Counter(3)) at (prev + 1, 16) to (start + 1, 6) diff --git a/tests/coverage/yield.coverage b/tests/coverage/yield.coverage index d7e455f211e4..e2fc9196d244 100644 --- a/tests/coverage/yield.coverage +++ b/tests/coverage/yield.coverage @@ -1,11 +1,11 @@ - LL| |#![feature(coroutines, coroutine_trait)] + LL| |#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] LL| |#![allow(unused_assignments)] LL| | LL| |use std::ops::{Coroutine, CoroutineState}; LL| |use std::pin::Pin; LL| | LL| 1|fn main() { - LL| 1| let mut coroutine = || { + LL| 1| let mut coroutine = #[coroutine] || { LL| 1| yield 1; LL| 1| return "foo"; LL| 1| }; @@ -19,7 +19,7 @@ LL| 0| _ => panic!("unexpected value from resume"), LL| | } LL| | - LL| 1| let mut coroutine = || { + LL| 1| let mut coroutine = #[coroutine] || { LL| 1| yield 1; LL| 1| yield 2; LL| 0| yield 3; diff --git a/tests/coverage/yield.rs b/tests/coverage/yield.rs index b7e2ba31b59c..64ea27066047 100644 --- a/tests/coverage/yield.rs +++ b/tests/coverage/yield.rs @@ -1,11 +1,11 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] #![allow(unused_assignments)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; fn main() { - let mut coroutine = || { + let mut coroutine = #[coroutine] || { yield 1; return "foo"; }; @@ -19,7 +19,7 @@ fn main() { _ => panic!("unexpected value from resume"), } - let mut coroutine = || { + let mut coroutine = #[coroutine] || { yield 1; yield 2; yield 3; diff --git a/tests/debuginfo/coroutine-locals.rs b/tests/debuginfo/coroutine-locals.rs index 54b5cd577c8b..c019998040b9 100644 --- a/tests/debuginfo/coroutine-locals.rs +++ b/tests/debuginfo/coroutine-locals.rs @@ -46,7 +46,7 @@ // lldb-command:v c // lldb-check:(int) c = 6 -#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait)] +#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)] #![omit_gdb_pretty_printer_section] use std::ops::Coroutine; @@ -54,7 +54,8 @@ use std::pin::Pin; fn main() { let mut a = 5; - let mut b = || { + let mut b = #[coroutine] + || { let c = 6; // Live across multiple yield points let d = 7; // Live across only one yield point @@ -76,4 +77,6 @@ fn main() { _zzz(); // #break } -fn _zzz() {()} +fn _zzz() { + () +} diff --git a/tests/debuginfo/coroutine-objects.rs b/tests/debuginfo/coroutine-objects.rs index 9e1bd5d62e7a..e13f20455a86 100644 --- a/tests/debuginfo/coroutine-objects.rs +++ b/tests/debuginfo/coroutine-objects.rs @@ -63,7 +63,7 @@ // cdb-check: b : Returned [Type: enum2$] // cdb-check: [+0x[...]] _ref__a : 0x[...] : 6 [Type: int *] -#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait)] +#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)] #![omit_gdb_pretty_printer_section] use std::ops::Coroutine; @@ -71,7 +71,8 @@ use std::pin::Pin; fn main() { let mut a = 5; - let mut b = || { + let mut b = #[coroutine] + || { let mut c = 6; let mut d = 7; diff --git a/tests/debuginfo/function-names.rs b/tests/debuginfo/function-names.rs index 1e4be4324455..2b0c2593676b 100644 --- a/tests/debuginfo/function-names.rs +++ b/tests/debuginfo/function-names.rs @@ -83,7 +83,7 @@ #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] -#![feature(adt_const_params, coroutines, coroutine_trait)] +#![feature(adt_const_params, coroutines, coroutine_trait, stmt_expr_attributes)] #![allow(incomplete_features)] use std::ops::Coroutine; @@ -111,7 +111,8 @@ fn main() { closure(); // Coroutine - let mut coroutine = || { + let mut coroutine = #[coroutine] + || { yield; return; }; diff --git a/tests/debuginfo/issue-57822.rs b/tests/debuginfo/issue-57822.rs index 93e1a2558f69..995779a6a9ca 100644 --- a/tests/debuginfo/issue-57822.rs +++ b/tests/debuginfo/issue-57822.rs @@ -26,7 +26,7 @@ // lldb-command:v b // lldbg-check:(issue_57822::main::{coroutine_env#3}) b = -#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait)] +#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)] #![omit_gdb_pretty_printer_section] use std::ops::Coroutine; @@ -38,11 +38,13 @@ fn main() { let g = move || f(); let mut y = 2; - let mut a = move || { + let mut a = #[coroutine] + move || { y += 1; yield; }; - let mut b = move || { + let mut b = #[coroutine] + move || { Pin::new(&mut a).resume(()); yield; }; diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs index fe6abc546879..e9a53b7aacb7 100644 --- a/tests/mir-opt/building/custom/arrays.rs +++ b/tests/mir-opt/building/custom/arrays.rs @@ -1,5 +1,5 @@ // skip-filecheck -#![feature(custom_mir, core_intrinsics, inline_const)] +#![feature(custom_mir, core_intrinsics)] extern crate core; use core::intrinsics::mir::*; diff --git a/tests/mir-opt/building/custom/consts.rs b/tests/mir-opt/building/custom/consts.rs index 42abf5019e55..1a410177fa54 100644 --- a/tests/mir-opt/building/custom/consts.rs +++ b/tests/mir-opt/building/custom/consts.rs @@ -1,5 +1,5 @@ // skip-filecheck -#![feature(custom_mir, core_intrinsics, inline_const)] +#![feature(custom_mir, core_intrinsics)] extern crate core; use core::intrinsics::mir::*; diff --git a/tests/mir-opt/building/custom/operators.rs b/tests/mir-opt/building/custom/operators.rs index bc72ed8dfe39..eb97bcc73b7e 100644 --- a/tests/mir-opt/building/custom/operators.rs +++ b/tests/mir-opt/building/custom/operators.rs @@ -1,6 +1,6 @@ // skip-filecheck //@ compile-flags: --crate-type=lib -#![feature(custom_mir, core_intrinsics, inline_const)] +#![feature(custom_mir, core_intrinsics)] use std::intrinsics::mir::*; // EMIT_MIR operators.f.built.after.mir diff --git a/tests/mir-opt/const_prop/invalid_constant.rs b/tests/mir-opt/const_prop/invalid_constant.rs index afd8746af5fb..2b7271f63ff2 100644 --- a/tests/mir-opt/const_prop/invalid_constant.rs +++ b/tests/mir-opt/const_prop/invalid_constant.rs @@ -4,7 +4,6 @@ // Verify that we can pretty print invalid constants. #![feature(adt_const_params)] -#![feature(inline_const)] #![allow(incomplete_features)] #[derive(Copy, Clone)] diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir index 7214b01c6016..7e033916fd34 100644 --- a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir +++ b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}` 0 coroutine_drop -fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:11:15: 11:17}) -> () { +fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12:7}) -> () { let mut _0: (); let mut _2: (); let _3: std::string::String; diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir index 00769a493b5a..613ef2909b5e 100644 --- a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir +++ b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}` 0 coroutine_drop -fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:11:15: 11:17}) -> () { +fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12:7}) -> () { let mut _0: (); let mut _2: (); let _3: std::string::String; diff --git a/tests/mir-opt/coroutine_drop_cleanup.rs b/tests/mir-opt/coroutine_drop_cleanup.rs index 69984c737fed..33fdd2dd0d9c 100644 --- a/tests/mir-opt/coroutine_drop_cleanup.rs +++ b/tests/mir-opt/coroutine_drop_cleanup.rs @@ -1,5 +1,5 @@ // skip-filecheck -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] // EMIT_MIR_FOR_EACH_PANIC_STRATEGY @@ -8,7 +8,8 @@ // EMIT_MIR coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.mir fn main() { - let gen = || { + let gen = #[coroutine] + || { let _s = String::new(); yield; }; diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir index 8369a3e60dd9..4731aed335d9 100644 --- a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir +++ b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-abort.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}` before StateTransform -fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:23:16: 23:18}, _2: ()) -> () +fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}, _2: ()) -> () yields () { let mut _0: (); diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir index 1773db1abffe..14e1782b8601 100644 --- a/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir +++ b/tests/mir-opt/coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.panic-unwind.mir @@ -1,6 +1,6 @@ // MIR for `main::{closure#0}` before StateTransform -fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:23:16: 23:18}, _2: ()) -> () +fn main::{closure#0}(_1: {coroutine@$DIR/coroutine_storage_dead_unwind.rs:24:5: 24:7}, _2: ()) -> () yields () { let mut _0: (); diff --git a/tests/mir-opt/coroutine_storage_dead_unwind.rs b/tests/mir-opt/coroutine_storage_dead_unwind.rs index 253be1ff698d..ce9bad483af8 100644 --- a/tests/mir-opt/coroutine_storage_dead_unwind.rs +++ b/tests/mir-opt/coroutine_storage_dead_unwind.rs @@ -6,7 +6,7 @@ // Basic block and local names can safely change, but the StorageDead statements // should not go away. -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] struct Foo(i32); @@ -20,7 +20,8 @@ fn take(_x: T) {} // EMIT_MIR coroutine_storage_dead_unwind.main-{closure#0}.StateTransform.before.mir fn main() { - let _gen = || { + let _gen = #[coroutine] + || { let a = Foo(5); let b = Bar(6); yield; diff --git a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir index 165aa3a05cb7..f8b3f68d21e6 100644 --- a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir @@ -4,7 +4,7 @@ _0: CoroutineSavedTy { ty: HasDrop, source_info: SourceInfo { - span: $DIR/coroutine_tiny.rs:21:13: 21:15 (#0), + span: $DIR/coroutine_tiny.rs:22:13: 22:15 (#0), scope: scope[0], }, ignore_for_traits: false, @@ -21,7 +21,7 @@ }, } */ -fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24}>, _2: u8) -> CoroutineState<(), ()> { +fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}>, _2: u8) -> CoroutineState<(), ()> { debug _x => _10; let mut _0: std::ops::CoroutineState<(), ()>; let _3: HasDrop; @@ -34,18 +34,18 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24 let _10: u8; let mut _11: u32; scope 1 { - debug _d => (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24})) as variant#3).0: HasDrop); + debug _d => (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop); } bb0: { - _11 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24}))); + _11 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))); switchInt(move _11) -> [0: bb1, 3: bb5, otherwise: bb6]; } bb1: { _10 = move _2; nop; - (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24})) as variant#3).0: HasDrop) = HasDrop; + (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop) = HasDrop; StorageLive(_4); goto -> bb2; } @@ -58,7 +58,7 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24 StorageDead(_4); StorageDead(_6); StorageDead(_7); - discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24}))) = 3; + discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))) = 3; return; } diff --git a/tests/mir-opt/coroutine_tiny.rs b/tests/mir-opt/coroutine_tiny.rs index 9728425f2326..81e9940541ba 100644 --- a/tests/mir-opt/coroutine_tiny.rs +++ b/tests/mir-opt/coroutine_tiny.rs @@ -5,7 +5,7 @@ //@ compile-flags: -C panic=abort //@ no-prefer-dynamic -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] struct HasDrop; @@ -17,7 +17,8 @@ fn callee() {} // EMIT_MIR coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir fn main() { - let _gen = |_x: u8| { + let _gen = #[coroutine] + |_x: u8| { let _d = HasDrop; loop { yield; diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff index 859082c31119..07031a298bc3 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff @@ -4,24 +4,24 @@ fn main() -> () { let mut _0: (); let _1: std::ops::CoroutineState; - let mut _2: std::pin::Pin<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>; - let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; - let mut _4: {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; + let mut _2: std::pin::Pin<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>; + let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _4: {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _5: bool; scope 1 { debug _r => _1; } + scope 2 (inlined g) { + } -+ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) { ++ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new) { + debug pointer => _3; -+ scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) { ++ scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new_unchecked) { + debug pointer => _3; + } + } + scope 5 (inlined g::{closure#0}) { + debug a => _5; -+ let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; ++ let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _7: u32; + let mut _8: i32; + } @@ -32,22 +32,22 @@ StorageLive(_3); StorageLive(_4); - _4 = g() -> [return: bb1, unwind unreachable]; -+ _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; ++ _4 = {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> { __pointer: _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; + StorageLive(_6); + StorageLive(_7); -+ _6 = (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}); ++ _6 = (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); + _7 = discriminant((*_6)); + switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9]; } bb1: { - _3 = &mut _4; -- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind unreachable]; +- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new(move _3) -> [return: bb2, unwind unreachable]; + StorageDead(_4); + _0 = const (); + StorageDead(_1); @@ -56,7 +56,7 @@ bb2: { - StorageDead(_3); -- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind unreachable]; +- _1 = <{coroutine@$DIR/inline_coroutine.rs:20:5: 20:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind unreachable]; + StorageDead(_7); + StorageDead(_6); + StorageDead(_5); diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff index 44b06c34972a..ab6c62b0baf5 100644 --- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff @@ -4,24 +4,24 @@ fn main() -> () { let mut _0: (); let _1: std::ops::CoroutineState; - let mut _2: std::pin::Pin<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>; - let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; - let mut _4: {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; + let mut _2: std::pin::Pin<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>; + let mut _3: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _4: {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _5: bool; scope 1 { debug _r => _1; } + scope 2 (inlined g) { + } -+ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) { ++ scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new) { + debug pointer => _3; -+ scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) { ++ scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new_unchecked) { + debug pointer => _3; + } + } + scope 5 (inlined g::{closure#0}) { + debug a => _5; -+ let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}; ++ let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}; + let mut _7: u32; + let mut _8: i32; + } @@ -32,22 +32,22 @@ StorageLive(_3); StorageLive(_4); - _4 = g() -> [return: bb1, unwind continue]; -+ _4 = {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8 (#0)}; ++ _4 = {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8 (#0)}; + _3 = &mut _4; -+ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}> { __pointer: _3 }; ++ _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}> { __pointer: _3 }; + StorageDead(_3); + StorageLive(_5); + _5 = const false; + StorageLive(_6); + StorageLive(_7); -+ _6 = (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}); ++ _6 = (_2.0: &mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}); + _7 = discriminant((*_6)); + switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11]; } bb1: { - _3 = &mut _4; -- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new(move _3) -> [return: bb2, unwind: bb5]; +- _2 = Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:20:5: 20:8}>::new(move _3) -> [return: bb2, unwind: bb5]; + StorageDead(_4); + _0 = const (); + StorageDead(_1); @@ -56,7 +56,7 @@ - bb2: { - StorageDead(_3); -- _1 = <{coroutine@$DIR/inline_coroutine.rs:19:5: 19:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; +- _1 = <{coroutine@$DIR/inline_coroutine.rs:20:5: 20:8} as Coroutine>::resume(move _2, const false) -> [return: bb3, unwind: bb5]; + bb2 (cleanup): { + drop(_4) -> [return: bb3, unwind terminate(cleanup)]; } diff --git a/tests/mir-opt/inline/inline_coroutine.rs b/tests/mir-opt/inline/inline_coroutine.rs index 180f9d4a6fdd..07f8fb20f7ea 100644 --- a/tests/mir-opt/inline/inline_coroutine.rs +++ b/tests/mir-opt/inline/inline_coroutine.rs @@ -16,5 +16,6 @@ fn main() { #[inline] pub fn g() -> impl Coroutine { #[inline] - |a| { yield if a { 7 } else { 13 } } + #[coroutine] + |a| yield if a { 7 } else { 13 } } diff --git a/tests/pretty/stmt_expr_attributes.rs b/tests/pretty/stmt_expr_attributes.rs index 5076adf5aa47..5eb7d2fcae36 100644 --- a/tests/pretty/stmt_expr_attributes.rs +++ b/tests/pretty/stmt_expr_attributes.rs @@ -1,6 +1,5 @@ //@ pp-exact -#![feature(inline_const)] #![feature(inline_const_pat)] #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/tests/run-make/valid-print-requests/Makefile b/tests/run-make/valid-print-requests/Makefile deleted file mode 100644 index 99430e98d1c2..000000000000 --- a/tests/run-make/valid-print-requests/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) --print uwu 2>&1 | diff - valid-print-requests.stderr diff --git a/tests/run-make/valid-print-requests/valid-print-requests.stderr b/tests/run-make/valid-print-requests/valid-print-requests.stderr deleted file mode 100644 index 22bb102f9c98..000000000000 --- a/tests/run-make/valid-print-requests/valid-print-requests.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: unknown print request `uwu`. Valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` - diff --git a/tests/ui/associated-types/issue-25700.stderr b/tests/ui/associated-types/issue-25700.stderr index fb0e63c207a5..8d40e6905e07 100644 --- a/tests/ui/associated-types/issue-25700.stderr +++ b/tests/ui/associated-types/issue-25700.stderr @@ -12,7 +12,10 @@ note: if `S<()>` implemented `Clone`, you could clone the value --> $DIR/issue-25700.rs:1:1 | LL | struct S(#[allow(dead_code)] Option<&'static T>); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | drop(t); + | - you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-outside-of-await-issue-121096.stderr b/tests/ui/async-await/async-outside-of-await-issue-121096.stderr index b0677a83864e..d7caf6b3c0d2 100644 --- a/tests/ui/async-await/async-outside-of-await-issue-121096.stderr +++ b/tests/ui/async-await/async-outside-of-await-issue-121096.stderr @@ -2,7 +2,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/async-outside-of-await-issue-121096.rs:7:7 | LL | fn main() { - | ---- this is not `async` + | --------- this is not `async` ... LL | }.await | ^^^^^ only allowed inside `async` functions and blocks diff --git a/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr index 928eb0b821db..a98bb0764c0e 100644 --- a/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr +++ b/tests/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr @@ -141,7 +141,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:68:19 | LL | fn foo13() -> Result<(), ()> { - | ----- this is not `async` + | ---------------------------- this is not `async` LL | let _ = bar().await(); | ^^^^^ only allowed inside `async` functions and blocks @@ -149,7 +149,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:73:19 | LL | fn foo14() -> Result<(), ()> { - | ----- this is not `async` + | ---------------------------- this is not `async` LL | let _ = bar().await()?; | ^^^^^ only allowed inside `async` functions and blocks @@ -157,7 +157,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:78:19 | LL | fn foo15() -> Result<(), ()> { - | ----- this is not `async` + | ---------------------------- this is not `async` LL | let _ = bar().await; | ^^^^^ only allowed inside `async` functions and blocks @@ -165,7 +165,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:82:19 | LL | fn foo16() -> Result<(), ()> { - | ----- this is not `async` + | ---------------------------- this is not `async` LL | let _ = bar().await?; | ^^^^^ only allowed inside `async` functions and blocks @@ -173,7 +173,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/incorrect-syntax-suggestions.rs:87:23 | LL | fn foo() -> Result<(), ()> { - | --- this is not `async` + | -------------------------- this is not `async` LL | let _ = bar().await?; | ^^^^^ only allowed inside `async` functions and blocks diff --git a/tests/ui/async-await/coroutine-not-future.rs b/tests/ui/async-await/coroutine-not-future.rs index 2993f58378a4..452274355078 100644 --- a/tests/ui/async-await/coroutine-not-future.rs +++ b/tests/ui/async-await/coroutine-not-future.rs @@ -1,5 +1,5 @@ //@ edition:2018 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::future::Future; use std::ops::Coroutine; @@ -9,6 +9,7 @@ fn returns_async_block() -> impl Future { async {} } fn returns_coroutine() -> impl Coroutine<(), Yield = (), Return = ()> { + #[coroutine] || { let _: () = yield (); } @@ -23,9 +24,12 @@ fn main() { takes_future(returns_async_block()); takes_future(async {}); takes_coroutine(returns_coroutine()); - takes_coroutine(|| { - let _: () = yield (); - }); + takes_coroutine( + #[coroutine] + || { + let _: () = yield (); + }, + ); // async futures are not coroutines: takes_coroutine(async_fn()); @@ -38,8 +42,11 @@ fn main() { // coroutines are not futures: takes_future(returns_coroutine()); //~^ ERROR is not a future - takes_future(|ctx| { - //~^ ERROR is not a future - ctx = yield (); - }); + takes_future( + #[coroutine] + |ctx| { + //~^ ERROR is not a future + ctx = yield (); + }, + ); } diff --git a/tests/ui/async-await/coroutine-not-future.stderr b/tests/ui/async-await/coroutine-not-future.stderr index 580217fb4f82..403e547a7538 100644 --- a/tests/ui/async-await/coroutine-not-future.stderr +++ b/tests/ui/async-await/coroutine-not-future.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `impl Future: Coroutine<_>` is not satisfied - --> $DIR/coroutine-not-future.rs:31:21 + --> $DIR/coroutine-not-future.rs:35:21 | LL | takes_coroutine(async_fn()); | --------------- ^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future` @@ -7,13 +7,13 @@ LL | takes_coroutine(async_fn()); | required by a bound introduced by this call | note: required by a bound in `takes_coroutine` - --> $DIR/coroutine-not-future.rs:18:39 + --> $DIR/coroutine-not-future.rs:19:39 | LL | fn takes_coroutine(_g: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine` error[E0277]: the trait bound `impl Future: Coroutine<_>` is not satisfied - --> $DIR/coroutine-not-future.rs:33:21 + --> $DIR/coroutine-not-future.rs:37:21 | LL | takes_coroutine(returns_async_block()); | --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future` @@ -21,27 +21,27 @@ LL | takes_coroutine(returns_async_block()); | required by a bound introduced by this call | note: required by a bound in `takes_coroutine` - --> $DIR/coroutine-not-future.rs:18:39 + --> $DIR/coroutine-not-future.rs:19:39 | LL | fn takes_coroutine(_g: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine` -error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:35:21: 35:29}: Coroutine<_>` is not satisfied - --> $DIR/coroutine-not-future.rs:35:21 +error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:39:21: 39:29}: Coroutine<_>` is not satisfied + --> $DIR/coroutine-not-future.rs:39:21 | LL | takes_coroutine(async {}); - | --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:35:21: 35:29}` + | --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:39:21: 39:29}` | | | required by a bound introduced by this call | note: required by a bound in `takes_coroutine` - --> $DIR/coroutine-not-future.rs:18:39 + --> $DIR/coroutine-not-future.rs:19:39 | LL | fn takes_coroutine(_g: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine` error[E0277]: `impl Coroutine` is not a future - --> $DIR/coroutine-not-future.rs:39:18 + --> $DIR/coroutine-not-future.rs:43:18 | LL | takes_future(returns_coroutine()); | ------------ ^^^^^^^^^^^^^^^^^^^ `impl Coroutine` is not a future @@ -50,26 +50,26 @@ LL | takes_future(returns_coroutine()); | = help: the trait `Future` is not implemented for `impl Coroutine` note: required by a bound in `takes_future` - --> $DIR/coroutine-not-future.rs:17:26 + --> $DIR/coroutine-not-future.rs:18:26 | LL | fn takes_future(_f: impl Future) {} | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future` -error[E0277]: `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}` is not a future - --> $DIR/coroutine-not-future.rs:41:18 +error[E0277]: `{coroutine@$DIR/coroutine-not-future.rs:47:9: 47:14}` is not a future + --> $DIR/coroutine-not-future.rs:47:9 | -LL | takes_future(|ctx| { - | _____------------_^ - | | | - | | required by a bound introduced by this call +LL | takes_future( + | ------------ required by a bound introduced by this call +LL | #[coroutine] +LL | / |ctx| { LL | | -LL | | ctx = yield (); -LL | | }); - | |_____^ `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}` is not a future +LL | | ctx = yield (); +LL | | }, + | |_________^ `{coroutine@$DIR/coroutine-not-future.rs:47:9: 47:14}` is not a future | - = help: the trait `Future` is not implemented for `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}` + = help: the trait `Future` is not implemented for `{coroutine@$DIR/coroutine-not-future.rs:47:9: 47:14}` note: required by a bound in `takes_future` - --> $DIR/coroutine-not-future.rs:17:26 + --> $DIR/coroutine-not-future.rs:18:26 | LL | fn takes_future(_f: impl Future) {} | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future` diff --git a/tests/ui/async-await/issues/issue-51751.stderr b/tests/ui/async-await/issues/issue-51751.stderr index ba256b19948c..ab12e0427b47 100644 --- a/tests/ui/async-await/issues/issue-51751.stderr +++ b/tests/ui/async-await/issues/issue-51751.stderr @@ -2,7 +2,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-51751.rs:9:27 | LL | fn main() { - | ---- this is not `async` + | --------- this is not `async` LL | let result = inc(10000); LL | let finished = result.await; | ^^^^^ only allowed inside `async` functions and blocks diff --git a/tests/ui/async-await/issues/issue-62009-1.stderr b/tests/ui/async-await/issues/issue-62009-1.stderr index 02933f4f2f23..f8a4b5d9af8b 100644 --- a/tests/ui/async-await/issues/issue-62009-1.stderr +++ b/tests/ui/async-await/issues/issue-62009-1.stderr @@ -2,7 +2,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-62009-1.rs:6:23 | LL | fn main() { - | ---- this is not `async` + | --------- this is not `async` LL | async { let (); }.await; | ^^^^^ only allowed inside `async` functions and blocks @@ -10,7 +10,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-62009-1.rs:10:7 | LL | fn main() { - | ---- this is not `async` + | --------- this is not `async` ... LL | }.await; | ^^^^^ only allowed inside `async` functions and blocks @@ -19,7 +19,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-62009-1.rs:12:16 | LL | fn main() { - | ---- this is not `async` + | --------- this is not `async` ... LL | (|_| 2333).await; | ^^^^^ only allowed inside `async` functions and blocks diff --git a/tests/ui/async-await/issues/issue-62009-2.stderr b/tests/ui/async-await/issues/issue-62009-2.stderr index 80a831cc5475..0004f99f9018 100644 --- a/tests/ui/async-await/issues/issue-62009-2.stderr +++ b/tests/ui/async-await/issues/issue-62009-2.stderr @@ -2,7 +2,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/issue-62009-2.rs:8:23 | LL | fn main() { - | ---- this is not `async` + | --------- this is not `async` LL | (async || 2333)().await; | ^^^^^ only allowed inside `async` functions and blocks diff --git a/tests/ui/async-await/issues/issue-65419/issue-65419-coroutine-resume-after-completion.rs b/tests/ui/async-await/issues/issue-65419/issue-65419-coroutine-resume-after-completion.rs index f937311a5a0f..6b7dfc1235e8 100644 --- a/tests/ui/async-await/issues/issue-65419/issue-65419-coroutine-resume-after-completion.rs +++ b/tests/ui/async-await/issues/issue-65419/issue-65419-coroutine-resume-after-completion.rs @@ -6,15 +6,13 @@ //@ error-pattern:coroutine resumed after completion //@ edition:2018 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] -use std::{ - ops::Coroutine, - pin::Pin, -}; +use std::{ops::Coroutine, pin::Pin}; fn main() { - let mut g = || { + let mut g = #[coroutine] + || { yield; }; Pin::new(&mut g).resume(()); // Yields once. diff --git a/tests/ui/async-await/issues/non-async-enclosing-span.stderr b/tests/ui/async-await/issues/non-async-enclosing-span.stderr index 91a9e5aa6cab..9c26de1c5047 100644 --- a/tests/ui/async-await/issues/non-async-enclosing-span.stderr +++ b/tests/ui/async-await/issues/non-async-enclosing-span.stderr @@ -2,7 +2,7 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks --> $DIR/non-async-enclosing-span.rs:9:28 | LL | fn main() { - | ---- this is not `async` + | --------- this is not `async` LL | let x = move || {}; LL | let y = do_the_thing().await; | ^^^^^ only allowed inside `async` functions and blocks diff --git a/tests/ui/async-await/non-trivial-drop.rs b/tests/ui/async-await/non-trivial-drop.rs index 71b881242197..95de3c5b0054 100644 --- a/tests/ui/async-await/non-trivial-drop.rs +++ b/tests/ui/async-await/non-trivial-drop.rs @@ -8,7 +8,7 @@ fn main() { } fn foo() { - || { + #[coroutine] || { yield drop(Config { nickname: NonCopy, b: NonCopy2, diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs b/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs new file mode 100644 index 000000000000..7f95fa7ebbec --- /dev/null +++ b/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_dfl.rs @@ -0,0 +1,8 @@ +//@ aux-crate: sigpipe_utils=sigpipe-utils.rs + +#![feature(unix_sigpipe)] + +#[unix_sigpipe = "inherit"] +fn main() { + sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); +} diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs b/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs new file mode 100644 index 000000000000..d96e8b8ef843 --- /dev/null +++ b/tests/ui/attributes/unix_sigpipe/auxiliary/assert-inherit-sig_ign.rs @@ -0,0 +1,8 @@ +//@ aux-crate: sigpipe_utils=sigpipe-utils.rs + +#![feature(unix_sigpipe)] + +#[unix_sigpipe = "inherit"] +fn main() { + sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Ignore); +} diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs index db3407a7d55f..694fa460e9bb 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs +++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs @@ -1,14 +1,29 @@ +//@ ignore-cross-compile because aux-bin does not yet support it +//@ only-unix because SIGPIPE is a unix thing +//@ aux-bin: assert-inherit-sig_dfl.rs +//@ aux-bin: assert-inherit-sig_ign.rs //@ run-pass -//@ aux-build:sigpipe-utils.rs -#![feature(unix_sigpipe)] +#![feature(rustc_private, unix_sigpipe)] -#[unix_sigpipe = "inherit"] +extern crate libc; + +// By default the Rust runtime resets SIGPIPE to SIG_DFL before exec:ing child +// processes so opt-out of that with `#[unix_sigpipe = "sig_dfl"]`. See +// https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L359-L384 +#[unix_sigpipe = "sig_dfl"] fn main() { - extern crate sigpipe_utils; + // First expect SIG_DFL in a child process with #[unix_sigpipe = "inherit"]. + assert_inherit_sigpipe_disposition("auxiliary/bin/assert-inherit-sig_dfl"); - // #[unix_sigpipe = "inherit"] is active, so SIGPIPE shall NOT be ignored, - // instead the default handler shall be installed. (We assume that the - // process that runs these tests have the default handler.) - sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); + // With SIG_IGN we expect #[unix_sigpipe = "inherit"] to also get SIG_IGN. + unsafe { + libc::signal(libc::SIGPIPE, libc::SIG_IGN); + } + assert_inherit_sigpipe_disposition("auxiliary/bin/assert-inherit-sig_ign"); +} + +fn assert_inherit_sigpipe_disposition(aux_bin: &str) { + let mut cmd = std::process::Command::new(aux_bin); + assert!(cmd.status().unwrap().success()); } diff --git a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr index dcf1c02bceef..4c1de72798c4 100644 --- a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr +++ b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr @@ -23,6 +23,13 @@ LL | fn copy(x: T) -> (T, T) { (x, x) } | | value moved here | move occurs because `x` has type `T`, which does not implement the `Copy` trait | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/typeck-auto-trait-no-supertraits-2.rs:8:9 + | +LL | fn copy(x: T) -> (T, T) { (x, x) } + | ^ - you could clone this value + | | + | consider constraining this type parameter with `Clone` help: consider further restricting this bound | LL | fn copy(x: T) -> (T, T) { (x, x) } diff --git a/tests/ui/binop/binop-consume-args.stderr b/tests/ui/binop/binop-consume-args.stderr index 6fbbb55437eb..1b59216b3c76 100644 --- a/tests/ui/binop/binop-consume-args.stderr +++ b/tests/ui/binop/binop-consume-args.stderr @@ -8,6 +8,13 @@ LL | lhs + rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:5:8 + | +LL | fn add, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs + rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: consider further restricting this bound @@ -26,6 +33,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:5:30 + | +LL | fn add, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs + rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn add, B: Copy>(lhs: A, rhs: B) { @@ -41,6 +55,13 @@ LL | lhs - rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:11:8 + | +LL | fn sub, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs - rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: consider further restricting this bound @@ -59,6 +80,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:11:30 + | +LL | fn sub, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs - rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn sub, B: Copy>(lhs: A, rhs: B) { @@ -74,6 +102,13 @@ LL | lhs * rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:17:8 + | +LL | fn mul, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs * rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: consider further restricting this bound @@ -92,6 +127,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:17:30 + | +LL | fn mul, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs * rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn mul, B: Copy>(lhs: A, rhs: B) { @@ -107,6 +149,13 @@ LL | lhs / rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:23:8 + | +LL | fn div, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs / rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: consider further restricting this bound @@ -125,6 +174,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:23:30 + | +LL | fn div, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs / rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn div, B: Copy>(lhs: A, rhs: B) { @@ -140,6 +196,13 @@ LL | lhs % rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:29:8 + | +LL | fn rem, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs % rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: consider further restricting this bound @@ -158,6 +221,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:29:30 + | +LL | fn rem, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs % rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn rem, B: Copy>(lhs: A, rhs: B) { @@ -173,6 +243,13 @@ LL | lhs & rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:35:11 + | +LL | fn bitand, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs & rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider further restricting this bound @@ -191,6 +268,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:35:36 + | +LL | fn bitand, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs & rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn bitand, B: Copy>(lhs: A, rhs: B) { @@ -206,6 +290,13 @@ LL | lhs | rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:41:10 + | +LL | fn bitor, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs | rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider further restricting this bound @@ -224,6 +315,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:41:34 + | +LL | fn bitor, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs | rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn bitor, B: Copy>(lhs: A, rhs: B) { @@ -239,6 +337,13 @@ LL | lhs ^ rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:47:11 + | +LL | fn bitxor, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs ^ rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider further restricting this bound @@ -257,6 +362,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:47:36 + | +LL | fn bitxor, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs ^ rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn bitxor, B: Copy>(lhs: A, rhs: B) { @@ -272,6 +384,13 @@ LL | lhs << rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:53:8 + | +LL | fn shl, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs << rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider further restricting this bound @@ -290,6 +409,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:53:30 + | +LL | fn shl, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs << rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn shl, B: Copy>(lhs: A, rhs: B) { @@ -305,6 +431,13 @@ LL | lhs >> rhs; LL | drop(lhs); | ^^^ value used here after move | +help: if `A` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:59:8 + | +LL | fn shr, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs >> rhs; + | --- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider further restricting this bound @@ -323,6 +456,13 @@ LL | drop(lhs); LL | drop(rhs); | ^^^ value used here after move | +help: if `B` implemented `Clone`, you could clone the value + --> $DIR/binop-consume-args.rs:59:30 + | +LL | fn shr, B>(lhs: A, rhs: B) { + | ^ consider constraining this type parameter with `Clone` +LL | lhs >> rhs; + | --- you could clone this value help: consider restricting type parameter `B` | LL | fn shr, B: Copy>(lhs: A, rhs: B) { diff --git a/tests/ui/binop/binop-move-semantics.stderr b/tests/ui/binop/binop-move-semantics.stderr index 1dd8c9a87d47..83c27590e901 100644 --- a/tests/ui/binop/binop-move-semantics.stderr +++ b/tests/ui/binop/binop-move-semantics.stderr @@ -11,6 +11,13 @@ LL | | x; | |_____value used here after move | `x` moved due to usage in operator | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/binop-move-semantics.rs:5:16 + | +LL | fn double_move>(x: T) { + | ^ consider constraining this type parameter with `Clone` +LL | x + | - you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: consider further restricting this bound @@ -51,6 +58,14 @@ LL | x ... LL | use_mut(n); use_imm(m); | - borrow later used here + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/binop-move-semantics.rs:17:18 + | +LL | fn move_borrowed>(x: T, mut y: T) { + | ^ consider constraining this type parameter with `Clone` +LL | let m = &x; + | -- you could clone this value error[E0505]: cannot move out of `y` because it is borrowed --> $DIR/binop-move-semantics.rs:23:5 @@ -65,6 +80,15 @@ LL | y; | ^ move out of `y` occurs here LL | use_mut(n); use_imm(m); | - borrow later used here + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/binop-move-semantics.rs:17:18 + | +LL | fn move_borrowed>(x: T, mut y: T) { + | ^ consider constraining this type parameter with `Clone` +LL | let m = &x; +LL | let n = &mut y; + | ------ you could clone this value error[E0507]: cannot move out of `*m` which is behind a mutable reference --> $DIR/binop-move-semantics.rs:30:5 @@ -80,12 +104,29 @@ LL | | *n; | note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/binop-move-semantics.rs:26:24 + | +LL | fn illegal_dereference>(mut x: T, y: T) { + | ^ consider constraining this type parameter with `Clone` +... +LL | *m + | -- you could clone this value error[E0507]: cannot move out of `*n` which is behind a shared reference --> $DIR/binop-move-semantics.rs:32:5 | LL | *n; | ^^ move occurs because `*n` has type `T`, which does not implement the `Copy` trait + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/binop-move-semantics.rs:26:24 + | +LL | fn illegal_dereference>(mut x: T, y: T) { + | ^ consider constraining this type parameter with `Clone` +... +LL | *n; + | -- you could clone this value error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable --> $DIR/binop-move-semantics.rs:54:5 diff --git a/tests/ui/borrowck/borrowck-move-by-capture.stderr b/tests/ui/borrowck/borrowck-move-by-capture.stderr index 01647011207f..9915acfe0653 100644 --- a/tests/ui/borrowck/borrowck-move-by-capture.stderr +++ b/tests/ui/borrowck/borrowck-move-by-capture.stderr @@ -11,6 +11,12 @@ LL | let _h = to_fn_once(move || -> isize { *bar }); | | variable moved due to use in closure | | move occurs because `bar` has type `Box`, which does not implement the `Copy` trait | `bar` is moved here + | +help: clone the value before moving it into the closure + | +LL ~ let value = bar.clone(); +LL ~ let _h = to_fn_once(move || -> isize { value }); + | error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr b/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr index 86bddacbdc72..b4b60d40d914 100644 --- a/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr +++ b/tests/ui/borrowck/borrowck-move-out-of-static-item.stderr @@ -8,7 +8,10 @@ note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/borrowck-move-out-of-static-item.rs:3:1 | LL | struct Foo { - | ^^^^^^^^^^ + | ^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | test(BAR); + | --- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-move-subcomponent.stderr b/tests/ui/borrowck/borrowck-move-subcomponent.stderr index 4d9477f85811..cc6c3bdeb102 100644 --- a/tests/ui/borrowck/borrowck-move-subcomponent.stderr +++ b/tests/ui/borrowck/borrowck-move-subcomponent.stderr @@ -14,7 +14,10 @@ note: if `S` implemented `Clone`, you could clone the value --> $DIR/borrowck-move-subcomponent.rs:6:1 | LL | struct S { - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let pb = &a; + | -- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-overloaded-call.stderr b/tests/ui/borrowck/borrowck-overloaded-call.stderr index 1602058c183f..c3b7b0b6080c 100644 --- a/tests/ui/borrowck/borrowck-overloaded-call.stderr +++ b/tests/ui/borrowck/borrowck-overloaded-call.stderr @@ -34,7 +34,10 @@ note: if `SFnOnce` implemented `Clone`, you could clone the value --> $DIR/borrowck-overloaded-call.rs:41:1 | LL | struct SFnOnce { - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | s(" world".to_string()); + | - you could clone this value error: aborting due to 3 previous errors diff --git a/tests/ui/borrowck/clone-on-ref.stderr b/tests/ui/borrowck/clone-on-ref.stderr index f0eaf4bac7df..19f040556f8a 100644 --- a/tests/ui/borrowck/clone-on-ref.stderr +++ b/tests/ui/borrowck/clone-on-ref.stderr @@ -32,6 +32,13 @@ LL | LL | println!("{b}"); | --- borrow later used here | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/clone-on-ref.rs:11:8 + | +LL | fn bar(x: T) { + | ^ consider constraining this type parameter with `Clone` +LL | let a = &x; + | -- you could clone this value help: consider further restricting this bound | LL | fn bar(x: T) { @@ -56,7 +63,10 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/clone-on-ref.rs:19:1 | LL | struct A; - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +LL | fn qux(x: A) { +LL | let a = &x; + | -- you could clone this value help: consider annotating `A` with `#[derive(Clone)]` | LL + #[derive(Clone)] diff --git a/tests/ui/borrowck/issue-101119.stderr b/tests/ui/borrowck/issue-101119.stderr index b4775496f4f4..a894fa63ace2 100644 --- a/tests/ui/borrowck/issue-101119.stderr +++ b/tests/ui/borrowck/issue-101119.stderr @@ -22,7 +22,10 @@ note: if `State` implemented `Clone`, you could clone the value --> $DIR/issue-101119.rs:1:1 | LL | struct State; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | fill_segment(state); + | ----- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index 94421c35c65d..603055beadce 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -13,8 +13,11 @@ LL | self.b; note: if `StructB` implemented `Clone`, you could clone the value --> $DIR/issue-103624.rs:23:1 | +LL | self.b; + | ------ you could clone this value +... LL | struct StructB {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type error[E0521]: borrowed data escapes outside of method --> $DIR/issue-103624.rs:14:9 diff --git a/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr b/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr index 701f00d079d3..dde17d1f6523 100644 --- a/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr +++ b/tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr @@ -15,7 +15,10 @@ note: if `Example` implemented `Clone`, you could clone the value --> $DIR/issue-119915-bad-clone-suggestion.rs:3:1 | LL | struct Example(PhantomData<(fn(E), fn(FakeParam))>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | unsafe { self.change() } + | ---- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-17718-static-move.stderr b/tests/ui/borrowck/issue-17718-static-move.stderr index e2c3a9d5a266..057ac6d7e3df 100644 --- a/tests/ui/borrowck/issue-17718-static-move.stderr +++ b/tests/ui/borrowck/issue-17718-static-move.stderr @@ -8,7 +8,10 @@ note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/issue-17718-static-move.rs:1:1 | LL | struct Foo; - | ^^^^^^^^^^ + | ^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _a = FOO; + | --- you could clone this value help: consider borrowing here | LL | let _a = &FOO; diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr index 1da6f0bef023..20a4bd4e4237 100644 --- a/tests/ui/borrowck/issue-20801.stderr +++ b/tests/ui/borrowck/issue-20801.stderr @@ -23,7 +23,10 @@ note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let a = unsafe { *mut_ref() }; + | ---------- you could clone this value help: consider removing the dereference here | LL - let a = unsafe { *mut_ref() }; @@ -40,7 +43,10 @@ note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let b = unsafe { *imm_ref() }; + | ---------- you could clone this value help: consider removing the dereference here | LL - let b = unsafe { *imm_ref() }; @@ -57,7 +63,10 @@ note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let c = unsafe { *mut_ptr() }; + | ---------- you could clone this value help: consider removing the dereference here | LL - let c = unsafe { *mut_ptr() }; @@ -74,7 +83,10 @@ note: if `T` implemented `Clone`, you could clone the value --> $DIR/issue-20801.rs:3:1 | LL | struct T(u8); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let d = unsafe { *const_ptr() }; + | ------------ you could clone this value help: consider removing the dereference here | LL - let d = unsafe { *const_ptr() }; diff --git a/tests/ui/borrowck/move-error-in-promoted-2.stderr b/tests/ui/borrowck/move-error-in-promoted-2.stderr index 43f4e820857a..1e9b1d5209cb 100644 --- a/tests/ui/borrowck/move-error-in-promoted-2.stderr +++ b/tests/ui/borrowck/move-error-in-promoted-2.stderr @@ -11,7 +11,10 @@ note: if `S` implemented `Clone`, you could clone the value --> $DIR/move-error-in-promoted-2.rs:3:1 | LL | struct S; - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | &([S][0],); + | ------ you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/move-error-snippets.stderr b/tests/ui/borrowck/move-error-snippets.stderr index 40b64398aef6..97d140515184 100644 --- a/tests/ui/borrowck/move-error-snippets.stderr +++ b/tests/ui/borrowck/move-error-snippets.stderr @@ -13,7 +13,12 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-error-snippets.rs:9:1 | LL | struct A; - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type + | + ::: $DIR/move-error-snippets-ext.rs:5:17 + | +LL | let a = $c; + | -- you could clone this value = note: this error originates in the macro `aaa` which comes from the expansion of the macro `sss` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider borrowing here | diff --git a/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr b/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr index a4e70b506462..009e85a8031e 100644 --- a/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr +++ b/tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr @@ -8,7 +8,10 @@ note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-in-static-initializer-issue-38520.rs:5:1 | LL | struct Foo(usize); - | ^^^^^^^^^^ + | ^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | static Y: usize = get(*&X); + | --- you could clone this value error[E0507]: cannot move out of a shared reference --> $DIR/move-in-static-initializer-issue-38520.rs:13:22 @@ -20,7 +23,10 @@ note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-in-static-initializer-issue-38520.rs:5:1 | LL | struct Foo(usize); - | ^^^^^^^^^^ + | ^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | const Z: usize = get(*&X); + | --- you could clone this value error: aborting due to 2 previous errors diff --git a/tests/ui/box/leak-alloc.stderr b/tests/ui/box/leak-alloc.stderr index 53ff5f0107df..bdaa9449f913 100644 --- a/tests/ui/box/leak-alloc.stderr +++ b/tests/ui/box/leak-alloc.stderr @@ -16,7 +16,10 @@ note: if `Alloc` implemented `Clone`, you could clone the value --> $DIR/leak-alloc.rs:8:1 | LL | struct Alloc {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let boxed = Box::new_in(10, alloc.by_ref()); + | ----- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/coherence/coherence-with-coroutine.rs b/tests/ui/coherence/coherence-with-coroutine.rs index 1ba983446726..6b0617e950b7 100644 --- a/tests/ui/coherence/coherence-with-coroutine.rs +++ b/tests/ui/coherence/coherence-with-coroutine.rs @@ -8,6 +8,7 @@ type OpaqueCoroutine = impl Sized; fn defining_use() -> OpaqueCoroutine { + #[coroutine] || { for i in 0..10 { yield i; diff --git a/tests/ui/coherence/coherence-with-coroutine.stock.stderr b/tests/ui/coherence/coherence-with-coroutine.stock.stderr index 9cf20ea49364..5f58b3088f14 100644 --- a/tests/ui/coherence/coherence-with-coroutine.stock.stderr +++ b/tests/ui/coherence/coherence-with-coroutine.stock.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper` - --> $DIR/coherence-with-coroutine.rs:21:1 + --> $DIR/coherence-with-coroutine.rs:22:1 | LL | impl Trait for Wrapper {} | --------------------------------------- first implementation here diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs index 7332a8f03c05..f1305202ad45 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs @@ -1,4 +1,4 @@ -#![feature(inline_const, generic_const_exprs)] +#![feature(generic_const_exprs)] //~^ WARN the feature `generic_const_exprs` is incomplete fn foo() { diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr index a85e0cbcf7e9..03b0004bf0bd 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr @@ -1,8 +1,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/const-block-is-poly.rs:1:26 + --> $DIR/const-block-is-poly.rs:1:12 | -LL | #![feature(inline_const, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ | = note: see issue #76560 for more information = note: `#[warn(incomplete_features)]` on by default diff --git a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_ty_with_infer_2.rs b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_ty_with_infer_2.rs index 4333ec9f5522..f9cf8210d651 100644 --- a/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_ty_with_infer_2.rs +++ b/tests/ui/const-generics/generic_const_exprs/const_kind_expr/relate_ty_with_infer_2.rs @@ -1,5 +1,5 @@ //@ check-pass -#![feature(inline_const, generic_const_exprs)] +#![feature(generic_const_exprs)] #![allow(incomplete_features)] use std::marker::PhantomData; diff --git a/tests/ui/const-generics/generic_const_exprs/inline-const-in-const-generic-defaults.rs b/tests/ui/const-generics/generic_const_exprs/inline-const-in-const-generic-defaults.rs index 3bc02f4c6bbf..073e0fe0a7fd 100644 --- a/tests/ui/const-generics/generic_const_exprs/inline-const-in-const-generic-defaults.rs +++ b/tests/ui/const-generics/generic_const_exprs/inline-const-in-const-generic-defaults.rs @@ -1,7 +1,6 @@ //@ check-pass #![feature(generic_const_exprs)] -#![feature(inline_const)] #![allow(incomplete_features)] pub struct ConstDefaultUnstable; diff --git a/tests/ui/const_prop/dont-propagate-generic-instance-2.rs b/tests/ui/const_prop/dont-propagate-generic-instance-2.rs index 768c9b3171a8..08064bc65899 100644 --- a/tests/ui/const_prop/dont-propagate-generic-instance-2.rs +++ b/tests/ui/const_prop/dont-propagate-generic-instance-2.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(inline_const)] - // Makes sure we don't propagate generic instances of `Self: ?Sized` blanket impls. // This is relevant when we have an overlapping impl and builtin dyn instance. // See for more context. diff --git a/tests/ui/consts/closure-structural-match-issue-90013.rs b/tests/ui/consts/closure-structural-match-issue-90013.rs index 7a5d9b69ee4a..454341a77843 100644 --- a/tests/ui/consts/closure-structural-match-issue-90013.rs +++ b/tests/ui/consts/closure-structural-match-issue-90013.rs @@ -1,6 +1,5 @@ // Regression test for issue 90013. //@ check-pass -#![feature(inline_const)] fn main() { const { || {} }; diff --git a/tests/ui/consts/const-block-const-bound.rs b/tests/ui/consts/const-block-const-bound.rs index b0d5e19ad554..933eb6cfc0af 100644 --- a/tests/ui/consts/const-block-const-bound.rs +++ b/tests/ui/consts/const-block-const-bound.rs @@ -1,7 +1,7 @@ //@ known-bug: #103507 #![allow(unused)] -#![feature(const_trait_impl, inline_const, negative_impls)] +#![feature(const_trait_impl, negative_impls)] use std::marker::Destruct; diff --git a/tests/ui/consts/const-blocks/fn-call-in-const.rs b/tests/ui/consts/const-blocks/fn-call-in-const.rs index 9bf267b7de9a..a3e24ddae7d1 100644 --- a/tests/ui/consts/const-blocks/fn-call-in-const.rs +++ b/tests/ui/consts/const-blocks/fn-call-in-const.rs @@ -1,6 +1,5 @@ //@ run-pass -#![feature(inline_const)] #![allow(unused)] // Some type that is not copyable. diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs index 6c4fca356260..2517560c2c34 100644 --- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs +++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs @@ -1,7 +1,6 @@ //@ run-pass #![feature(core_intrinsics)] #![feature(const_heap)] -#![feature(inline_const)] use std::intrinsics; diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs index 146a87862e8c..c53bb36f4a2c 100644 --- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs +++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs @@ -1,7 +1,6 @@ //@ run-pass #![feature(core_intrinsics)] #![feature(const_heap)] -#![feature(inline_const)] use std::intrinsics; diff --git a/tests/ui/consts/issue-102117.rs b/tests/ui/consts/issue-102117.rs index 3ed90aed2350..6cb9832bcd81 100644 --- a/tests/ui/consts/issue-102117.rs +++ b/tests/ui/consts/issue-102117.rs @@ -1,4 +1,4 @@ -#![feature(inline_const, const_type_id)] +#![feature(const_type_id)] use std::alloc::Layout; use std::any::TypeId; diff --git a/tests/ui/coroutine/addassign-yield.rs b/tests/ui/coroutine/addassign-yield.rs index 8718e73512f7..8329b53d715e 100644 --- a/tests/ui/coroutine/addassign-yield.rs +++ b/tests/ui/coroutine/addassign-yield.rs @@ -5,21 +5,21 @@ // is being used), we were failing to account for all types that might // possibly be live across a yield point. -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn foo() { - let _x = static || { + let _x = #[coroutine] static || { let mut s = String::new(); s += { yield; "" }; }; - let _y = static || { + let _y = #[coroutine] static || { let x = &mut 0; *{ yield; x } += match String::new() { _ => 0 }; }; // Please don't ever actually write something like this - let _z = static || { + let _z = #[coroutine] static || { let x = &mut 0; *{ let inner = &mut 1; diff --git a/tests/ui/coroutine/auto-trait-regions.rs b/tests/ui/coroutine/auto-trait-regions.rs index 5fce70e8e54d..4c239f9ee76c 100644 --- a/tests/ui/coroutine/auto-trait-regions.rs +++ b/tests/ui/coroutine/auto-trait-regions.rs @@ -1,4 +1,4 @@ -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![feature(auto_traits)] #![feature(negative_impls)] @@ -23,7 +23,7 @@ fn assert_foo(f: T) {} fn main() { // Make sure 'static is erased for coroutine interiors so we can't match it in trait selection let x: &'static _ = &OnlyFooIfStaticRef(No); - let gen = move || { + let gen = #[coroutine] move || { let x = x; yield; assert_foo(x); @@ -33,7 +33,7 @@ fn main() { // Allow impls which matches any lifetime let x = &OnlyFooIfRef(No); - let gen = move || { + let gen = #[coroutine] move || { let x = x; yield; assert_foo(x); @@ -41,7 +41,7 @@ fn main() { assert_foo(gen); // ok // Disallow impls which relates lifetimes in the coroutine interior - let gen = move || { + let gen = #[coroutine] move || { let a = A(&mut true, &mut true, No); //~^ temporary value dropped while borrowed //~| temporary value dropped while borrowed diff --git a/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs b/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs index 8af6973134a6..8ecb8c0c0979 100644 --- a/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs +++ b/tests/ui/coroutine/auxiliary/metadata-sufficient-for-layout.rs @@ -5,6 +5,7 @@ use std::marker::Unpin; use std::ops::Coroutine; pub fn g() -> impl Coroutine<(), Yield = (), Return = ()> { + #[coroutine] || { yield; } diff --git a/tests/ui/coroutine/auxiliary/unwind-aux.rs b/tests/ui/coroutine/auxiliary/unwind-aux.rs index ff1e8ed32cd4..5d5e5c2218d3 100644 --- a/tests/ui/coroutine/auxiliary/unwind-aux.rs +++ b/tests/ui/coroutine/auxiliary/unwind-aux.rs @@ -2,9 +2,10 @@ //@ no-prefer-dynamic //@ edition:2021 -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] pub fn run(a: T) { - let _ = move || { + let _ = #[coroutine] + move || { drop(a); yield; }; diff --git a/tests/ui/coroutine/auxiliary/xcrate-reachable.rs b/tests/ui/coroutine/auxiliary/xcrate-reachable.rs index 673153f0619e..0b5d18823004 100644 --- a/tests/ui/coroutine/auxiliary/xcrate-reachable.rs +++ b/tests/ui/coroutine/auxiliary/xcrate-reachable.rs @@ -7,6 +7,7 @@ fn msg() -> u32 { } pub fn foo() -> impl Coroutine<(), Yield = (), Return = u32> { + #[coroutine] || { yield; return msg(); diff --git a/tests/ui/coroutine/auxiliary/xcrate.rs b/tests/ui/coroutine/auxiliary/xcrate.rs index f749a95ad35a..52f188135bd1 100644 --- a/tests/ui/coroutine/auxiliary/xcrate.rs +++ b/tests/ui/coroutine/auxiliary/xcrate.rs @@ -1,9 +1,10 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::marker::Unpin; use std::ops::Coroutine; pub fn foo() -> impl Coroutine<(), Yield = (), Return = ()> { + #[coroutine] || { if false { yield; @@ -12,7 +13,10 @@ pub fn foo() -> impl Coroutine<(), Yield = (), Return = ()> { } pub fn bar(t: T) -> Box + Unpin> { - Box::new(|| { - yield t; - }) + Box::new( + #[coroutine] + || { + yield t; + }, + ) } diff --git a/tests/ui/coroutine/borrow-in-tail-expr.rs b/tests/ui/coroutine/borrow-in-tail-expr.rs index 2f0aa62019e8..380e95cfc776 100644 --- a/tests/ui/coroutine/borrow-in-tail-expr.rs +++ b/tests/ui/coroutine/borrow-in-tail-expr.rs @@ -1,9 +1,9 @@ //@ run-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { - let _a = || { + let _a = #[coroutine] || { yield; let a = String::new(); a.len() diff --git a/tests/ui/coroutine/borrowing.rs b/tests/ui/coroutine/borrowing.rs index 778eed8bd0d9..a6628766c1ba 100644 --- a/tests/ui/coroutine/borrowing.rs +++ b/tests/ui/coroutine/borrowing.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; @@ -6,13 +6,13 @@ use std::pin::Pin; fn main() { let _b = { let a = 3; - Pin::new(&mut || yield &a).resume(()) + Pin::new(&mut #[coroutine] || yield &a).resume(()) //~^ ERROR: `a` does not live long enough }; let _b = { let a = 3; - || { + #[coroutine] || { yield &a //~^ ERROR: `a` does not live long enough } diff --git a/tests/ui/coroutine/borrowing.stderr b/tests/ui/coroutine/borrowing.stderr index acd4cdafdfdf..4f8b97377777 100644 --- a/tests/ui/coroutine/borrowing.stderr +++ b/tests/ui/coroutine/borrowing.stderr @@ -1,13 +1,14 @@ error[E0597]: `a` does not live long enough - --> $DIR/borrowing.rs:9:33 + --> $DIR/borrowing.rs:9:46 | LL | let _b = { | -- borrow later stored here LL | let a = 3; -LL | Pin::new(&mut || yield &a).resume(()) - | -- ^ borrowed value does not live long enough - | | - | value captured here by coroutine + | - binding `a` declared here +LL | Pin::new(&mut #[coroutine] || yield &a).resume(()) + | -- ^ borrowed value does not live long enough + | | + | value captured here by coroutine LL | LL | }; | - `a` dropped here while still borrowed @@ -18,8 +19,9 @@ error[E0597]: `a` does not live long enough LL | let _b = { | -- borrow later stored here LL | let a = 3; -LL | || { - | -- value captured here by coroutine + | - binding `a` declared here +LL | #[coroutine] || { + | -- value captured here by coroutine LL | yield &a | ^ borrowed value does not live long enough ... diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs b/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs index a316c50e8673..327756ebe660 100644 --- a/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs +++ b/tests/ui/coroutine/check-resume-ty-lifetimes-2.rs @@ -7,27 +7,27 @@ struct Contravariant<'a>(fn(&'a ())); struct Covariant<'a>(fn() -> &'a ()); fn bad1<'short, 'long: 'short>() -> impl Coroutine> { - |_: Covariant<'short>| { + #[coroutine] |_: Covariant<'short>| { let a: Covariant<'long> = yield (); //~^ ERROR lifetime may not live long enough } } fn bad2<'short, 'long: 'short>() -> impl Coroutine> { - |_: Contravariant<'long>| { + #[coroutine] |_: Contravariant<'long>| { let a: Contravariant<'short> = yield (); //~^ ERROR lifetime may not live long enough } } fn good1<'short, 'long: 'short>() -> impl Coroutine> { - |_: Covariant<'long>| { + #[coroutine] |_: Covariant<'long>| { let a: Covariant<'short> = yield (); } } fn good2<'short, 'long: 'short>() -> impl Coroutine> { - |_: Contravariant<'short>| { + #[coroutine] |_: Contravariant<'short>| { let a: Contravariant<'long> = yield (); } } diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr b/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr index e0cbca2dd526..8eb7ab3501b3 100644 --- a/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr +++ b/tests/ui/coroutine/check-resume-ty-lifetimes-2.stderr @@ -5,15 +5,15 @@ LL | fn bad1<'short, 'long: 'short>() -> impl Coroutine> { | ------ ----- lifetime `'long` defined here | | | lifetime `'short` defined here -LL | |_: Covariant<'short>| { +LL | #[coroutine] |_: Covariant<'short>| { LL | let a: Covariant<'long> = yield (); | ^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long` | = help: consider adding the following bound: `'short: 'long` help: consider adding 'move' keyword before the nested closure | -LL | move |_: Covariant<'short>| { - | ++++ +LL | #[coroutine] move |_: Covariant<'short>| { + | ++++ error: lifetime may not live long enough --> $DIR/check-resume-ty-lifetimes-2.rs:18:40 @@ -22,15 +22,15 @@ LL | fn bad2<'short, 'long: 'short>() -> impl Coroutine> { | ------ ----- lifetime `'long` defined here | | | lifetime `'short` defined here -LL | |_: Contravariant<'long>| { +LL | #[coroutine] |_: Contravariant<'long>| { LL | let a: Contravariant<'short> = yield (); | ^^^^^^^^ yielding this value requires that `'short` must outlive `'long` | = help: consider adding the following bound: `'short: 'long` help: consider adding 'move' keyword before the nested closure | -LL | move |_: Contravariant<'long>| { - | ++++ +LL | #[coroutine] move |_: Contravariant<'long>| { + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes.rs b/tests/ui/coroutine/check-resume-ty-lifetimes.rs index add0b5080a8a..b75e46c541cc 100644 --- a/tests/ui/coroutine/check-resume-ty-lifetimes.rs +++ b/tests/ui/coroutine/check-resume-ty-lifetimes.rs @@ -1,5 +1,5 @@ #![feature(coroutine_trait)] -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![allow(unused)] use std::ops::Coroutine; @@ -9,11 +9,14 @@ use std::pin::pin; fn mk_static(s: &str) -> &'static str { let mut storage: Option<&'static str> = None; - let mut coroutine = pin!(|_: &str| { - let x: &'static str = yield (); - //~^ ERROR lifetime may not live long enough - storage = Some(x); - }); + let mut coroutine = pin!( + #[coroutine] + |_: &str| { + let x: &'static str = yield (); + //~^ ERROR lifetime may not live long enough + storage = Some(x); + } + ); coroutine.as_mut().resume(s); coroutine.as_mut().resume(s); diff --git a/tests/ui/coroutine/check-resume-ty-lifetimes.stderr b/tests/ui/coroutine/check-resume-ty-lifetimes.stderr index f373aa778a82..1fbaeb9f7fa4 100644 --- a/tests/ui/coroutine/check-resume-ty-lifetimes.stderr +++ b/tests/ui/coroutine/check-resume-ty-lifetimes.stderr @@ -1,11 +1,11 @@ error: lifetime may not live long enough - --> $DIR/check-resume-ty-lifetimes.rs:13:16 + --> $DIR/check-resume-ty-lifetimes.rs:15:20 | LL | fn mk_static(s: &str) -> &'static str { | - let's call the lifetime of this reference `'1` ... -LL | let x: &'static str = yield (); - | ^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` +LL | let x: &'static str = yield (); + | ^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/clone-impl-static.rs b/tests/ui/coroutine/clone-impl-static.rs index 9a165cf4672e..56d1ccac7035 100644 --- a/tests/ui/coroutine/clone-impl-static.rs +++ b/tests/ui/coroutine/clone-impl-static.rs @@ -1,10 +1,11 @@ // gate-test-coroutine_clone // Verifies that static coroutines cannot be cloned/copied. -#![feature(coroutines, coroutine_clone)] +#![feature(coroutines, coroutine_clone, stmt_expr_attributes)] fn main() { - let gen = static move || { + let gen = #[coroutine] + static move || { yield; }; check_copy(&gen); diff --git a/tests/ui/coroutine/clone-impl-static.stderr b/tests/ui/coroutine/clone-impl-static.stderr index 8fa9fb12bf68..43920326d5df 100644 --- a/tests/ui/coroutine/clone-impl-static.stderr +++ b/tests/ui/coroutine/clone-impl-static.stderr @@ -1,27 +1,27 @@ -error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}: Copy` is not satisfied - --> $DIR/clone-impl-static.rs:10:16 +error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}: Copy` is not satisfied + --> $DIR/clone-impl-static.rs:11:16 | LL | check_copy(&gen); - | ---------- ^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}` + | ---------- ^^^^ the trait `Copy` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}` | | | required by a bound introduced by this call | note: required by a bound in `check_copy` - --> $DIR/clone-impl-static.rs:16:18 + --> $DIR/clone-impl-static.rs:17:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}: Clone` is not satisfied - --> $DIR/clone-impl-static.rs:12:17 +error[E0277]: the trait bound `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}: Clone` is not satisfied + --> $DIR/clone-impl-static.rs:13:17 | LL | check_clone(&gen); - | ----------- ^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:7:15: 7:29}` + | ----------- ^^^^ the trait `Clone` is not implemented for `{static coroutine@$DIR/clone-impl-static.rs:8:5: 8:19}` | | | required by a bound introduced by this call | note: required by a bound in `check_clone` - --> $DIR/clone-impl-static.rs:17:19 + --> $DIR/clone-impl-static.rs:18:19 | LL | fn check_clone(_x: &T) {} | ^^^^^ required by this bound in `check_clone` diff --git a/tests/ui/coroutine/clone-impl.rs b/tests/ui/coroutine/clone-impl.rs index fffdae632ef7..94420e56a226 100644 --- a/tests/ui/coroutine/clone-impl.rs +++ b/tests/ui/coroutine/clone-impl.rs @@ -2,13 +2,14 @@ // Verifies that non-static coroutines can be cloned/copied if all their upvars and locals held // across awaits can be cloned/copied. -#![feature(coroutines, coroutine_clone)] +#![feature(coroutines, coroutine_clone, stmt_expr_attributes)] struct NonClone; fn test1() { let copyable: u32 = 123; - let gen_copy_0 = move || { + let gen_copy_0 = #[coroutine] + move || { yield; drop(copyable); }; @@ -18,7 +19,8 @@ fn test1() { fn test2() { let copyable: u32 = 123; - let gen_copy_1 = move || { + let gen_copy_1 = #[coroutine] + move || { /* let v = vec!['a']; let n = NonClone; @@ -37,7 +39,8 @@ fn test2() { fn test3() { let clonable_0: Vec = Vec::new(); - let gen_clone_0 = move || { + let gen_clone_0 = #[coroutine] + move || { let v = vec!['a']; yield; drop(v); @@ -51,7 +54,8 @@ fn test3() { fn test4() { let clonable_1: Vec = Vec::new(); - let gen_clone_1 = move || { + let gen_clone_1 = #[coroutine] + move || { let v = vec!['a']; /* let n = NonClone; @@ -71,7 +75,8 @@ fn test4() { fn test5() { let non_clonable: NonClone = NonClone; - let gen_non_clone = move || { + let gen_non_clone = #[coroutine] + move || { yield; drop(non_clonable); }; diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr index b454846faac9..5330d3bbd39d 100644 --- a/tests/ui/coroutine/clone-impl.stderr +++ b/tests/ui/coroutine/clone-impl.stderr @@ -1,76 +1,76 @@ -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` - --> $DIR/clone-impl.rs:46:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` + --> $DIR/clone-impl.rs:49:5 | -LL | let gen_clone_0 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` +LL | move || { + | ------- within this `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` ... LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}: Copy` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:44:14 + --> $DIR/clone-impl.rs:47:14 | LL | drop(clonable_0); | ^^^^^^^^^^ has type `Vec` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:84:18 + --> $DIR/clone-impl.rs:89:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` - --> $DIR/clone-impl.rs:46:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` + --> $DIR/clone-impl.rs:49:5 | -LL | let gen_clone_0 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` +LL | move || { + | ------- within this `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` ... LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}: Copy` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:42:9 + --> $DIR/clone-impl.rs:45:9 | LL | let v = vec!['a']; | - has type `Vec` which does not implement `Copy` LL | yield; | ^^^^^ yield occurs here, with `v` maybe used later note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:84:18 + --> $DIR/clone-impl.rs:89:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` - --> $DIR/clone-impl.rs:66:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` + --> $DIR/clone-impl.rs:70:5 | -LL | let gen_clone_1 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` +LL | move || { + | ------- within this `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` ... LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}: Copy` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:64:14 + --> $DIR/clone-impl.rs:68:14 | LL | drop(clonable_1); | ^^^^^^^^^^ has type `Vec` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:84:18 + --> $DIR/clone-impl.rs:89:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` - --> $DIR/clone-impl.rs:66:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` + --> $DIR/clone-impl.rs:70:5 | -LL | let gen_clone_1 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` +LL | move || { + | ------- within this `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` ... LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}: Copy` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:60:9 + --> $DIR/clone-impl.rs:64:9 | LL | let v = vec!['a']; | - has type `Vec` which does not implement `Copy` @@ -78,27 +78,27 @@ LL | let v = vec!['a']; LL | yield; | ^^^^^ yield occurs here, with `v` maybe used later note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:84:18 + --> $DIR/clone-impl.rs:89:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` - --> $DIR/clone-impl.rs:78:5 +error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` + --> $DIR/clone-impl.rs:83:5 | -LL | let gen_non_clone = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` +LL | move || { + | ------- within this `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` ... LL | check_copy(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}: Copy` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:76:14 + --> $DIR/clone-impl.rs:81:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:84:18 + --> $DIR/clone-impl.rs:89:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` @@ -108,22 +108,22 @@ LL + #[derive(Copy)] LL | struct NonClone; | -error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` - --> $DIR/clone-impl.rs:80:5 +error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` + --> $DIR/clone-impl.rs:85:5 | -LL | let gen_non_clone = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` +LL | move || { + | ------- within this `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` ... LL | check_clone(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Clone` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}: Clone` | note: captured value does not implement `Clone` - --> $DIR/clone-impl.rs:76:14 + --> $DIR/clone-impl.rs:81:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone` note: required by a bound in `check_clone` - --> $DIR/clone-impl.rs:85:19 + --> $DIR/clone-impl.rs:90:19 | LL | fn check_clone(_x: &T) {} | ^^^^^ required by this bound in `check_clone` diff --git a/tests/ui/coroutine/clone-rpit.next.stderr b/tests/ui/coroutine/clone-rpit.next.stderr index 41aa2d63af01..c223f1f211ac 100644 --- a/tests/ui/coroutine/clone-rpit.next.stderr +++ b/tests/ui/coroutine/clone-rpit.next.stderr @@ -5,32 +5,32 @@ LL | pub fn foo<'a, 'b>() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires coroutine witness types for `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:14:5 + --> $DIR/clone-rpit.rs:15:5 | LL | move |_: ()| { | ^^^^^^^^^^^^ note: ...which requires promoting constants in MIR for `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:14:5 + --> $DIR/clone-rpit.rs:15:5 | LL | move |_: ()| { | ^^^^^^^^^^^^ note: ...which requires checking if `foo::{closure#0}` contains FFI-unwind calls... - --> $DIR/clone-rpit.rs:14:5 + --> $DIR/clone-rpit.rs:15:5 | LL | move |_: ()| { | ^^^^^^^^^^^^ note: ...which requires building MIR for `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:14:5 + --> $DIR/clone-rpit.rs:15:5 | LL | move |_: ()| { | ^^^^^^^^^^^^ note: ...which requires match-checking `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:14:5 + --> $DIR/clone-rpit.rs:15:5 | LL | move |_: ()| { | ^^^^^^^^^^^^ note: ...which requires type-checking `foo::{closure#0}`... - --> $DIR/clone-rpit.rs:14:5 + --> $DIR/clone-rpit.rs:15:5 | LL | move |_: ()| { | ^^^^^^^^^^^^ diff --git a/tests/ui/coroutine/clone-rpit.rs b/tests/ui/coroutine/clone-rpit.rs index 0df9bf616018..66569b4f4274 100644 --- a/tests/ui/coroutine/clone-rpit.rs +++ b/tests/ui/coroutine/clone-rpit.rs @@ -11,6 +11,7 @@ // witness types, which we don't know until after borrowck. When we later check // the goal for correctness, we want to be able to bind the `impl Clone` opaque. pub fn foo<'a, 'b>() -> impl Clone { + #[coroutine] move |_: ()| { let () = yield (); } diff --git a/tests/ui/coroutine/conditional-drop.rs b/tests/ui/coroutine/conditional-drop.rs index 65d3a9e701ee..52e1b561946c 100644 --- a/tests/ui/coroutine/conditional-drop.rs +++ b/tests/ui/coroutine/conditional-drop.rs @@ -3,7 +3,7 @@ //@ revisions: default nomiropt //@[nomiropt]compile-flags: -Z mir-opt-level=0 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; @@ -29,7 +29,7 @@ fn main() { } fn t1() { - let mut a = || { + let mut a = #[coroutine] || { let b = B; if test() { drop(b); @@ -45,7 +45,7 @@ fn t1() { } fn t2() { - let mut a = || { + let mut a = #[coroutine] || { let b = B; if test2() { drop(b); diff --git a/tests/ui/coroutine/control-flow.rs b/tests/ui/coroutine/control-flow.rs index 9070ba17856c..f64b6f738836 100644 --- a/tests/ui/coroutine/control-flow.rs +++ b/tests/ui/coroutine/control-flow.rs @@ -3,7 +3,7 @@ //@ revisions: default nomiropt //@[nomiropt]compile-flags: -Z mir-opt-level=0 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{CoroutineState, Coroutine}; use std::pin::Pin; @@ -24,25 +24,25 @@ fn finish(mut amt: usize, mut t: T) -> T::Return } fn main() { - finish(1, || yield); - finish(8, || { + finish(1, #[coroutine] || yield); + finish(8, #[coroutine] || { for _ in 0..8 { yield; } }); - finish(1, || { + finish(1, #[coroutine] || { if true { yield; } else { } }); - finish(1, || { + finish(1, #[coroutine] || { if false { } else { yield; } }); - finish(2, || { + finish(2, #[coroutine] || { if { yield; false } { yield; panic!() diff --git a/tests/ui/coroutine/coroutine-region-requirements.rs b/tests/ui/coroutine/coroutine-region-requirements.rs index 8bc34fdd2f05..ab6f16995e27 100644 --- a/tests/ui/coroutine/coroutine-region-requirements.rs +++ b/tests/ui/coroutine/coroutine-region-requirements.rs @@ -1,9 +1,9 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; fn dangle(x: &mut i32) -> &'static mut i32 { - let mut g = || { + let mut g = #[coroutine] || { yield; x }; diff --git a/tests/ui/coroutine/coroutine-resume-after-panic.rs b/tests/ui/coroutine/coroutine-resume-after-panic.rs index 8445bf7e6352..2745ebc61326 100644 --- a/tests/ui/coroutine/coroutine-resume-after-panic.rs +++ b/tests/ui/coroutine/coroutine-resume-after-panic.rs @@ -5,7 +5,7 @@ // Test that we get the correct message for resuming a panicked coroutine. -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::{ ops::Coroutine, @@ -14,7 +14,7 @@ use std::{ }; fn main() { - let mut g = || { + let mut g = #[coroutine] || { panic!(); yield; }; diff --git a/tests/ui/coroutine/coroutine-with-nll.rs b/tests/ui/coroutine/coroutine-with-nll.rs index 28a3643fbc9c..fa77ab4e0495 100644 --- a/tests/ui/coroutine/coroutine-with-nll.rs +++ b/tests/ui/coroutine/coroutine-with-nll.rs @@ -1,6 +1,7 @@ #![feature(coroutines)] fn main() { + #[coroutine] || { // The reference in `_a` is a Legal with NLL since it ends before the yield let _a = &mut true; diff --git a/tests/ui/coroutine/coroutine-with-nll.stderr b/tests/ui/coroutine/coroutine-with-nll.stderr index 77e8bb1f92ee..3f3d51da3118 100644 --- a/tests/ui/coroutine/coroutine-with-nll.stderr +++ b/tests/ui/coroutine/coroutine-with-nll.stderr @@ -1,5 +1,5 @@ error[E0626]: borrow may still be in use when coroutine yields - --> $DIR/coroutine-with-nll.rs:7:17 + --> $DIR/coroutine-with-nll.rs:8:17 | LL | let b = &mut true; | ^^^^^^^^^ diff --git a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs index 3c91b3c93295..f3110d71d0d7 100644 --- a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs +++ b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.rs @@ -1,5 +1,5 @@ #![feature(coroutine_trait)] -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] // Test that we cannot create a coroutine that returns a value of its // own type. @@ -12,7 +12,7 @@ pub fn want_cyclic_coroutine_return(_: T) } fn supply_cyclic_coroutine_return() { - want_cyclic_coroutine_return(|| { + want_cyclic_coroutine_return(#[coroutine] || { //~^ ERROR type mismatch if false { yield None.unwrap(); } None.unwrap() @@ -25,7 +25,7 @@ pub fn want_cyclic_coroutine_yield(_: T) } fn supply_cyclic_coroutine_yield() { - want_cyclic_coroutine_yield(|| { + want_cyclic_coroutine_yield(#[coroutine] || { //~^ ERROR type mismatch if false { yield None.unwrap(); } None.unwrap() diff --git a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr index 325030524ba8..32799148ae1d 100644 --- a/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr +++ b/tests/ui/coroutine/coroutine-yielding-or-returning-itself.stderr @@ -1,8 +1,8 @@ -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:34: 15:36} as Coroutine>::Return == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:34: 15:36}` - --> $DIR/coroutine-yielding-or-returning-itself.rs:15:34 +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:47: 15:49} as Coroutine>::Return == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:15:47: 15:49}` + --> $DIR/coroutine-yielding-or-returning-itself.rs:15:47 | -LL | want_cyclic_coroutine_return(|| { - | _____----------------------------_^ +LL | want_cyclic_coroutine_return(#[coroutine] || { + | _____----------------------------______________^ | | | | | required by a bound introduced by this call LL | | @@ -23,11 +23,11 @@ LL | pub fn want_cyclic_coroutine_return(_: T) LL | where T: Coroutine | ^^^^^^^^^^ required by this bound in `want_cyclic_coroutine_return` -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:33: 28:35} as Coroutine>::Yield == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:33: 28:35}` - --> $DIR/coroutine-yielding-or-returning-itself.rs:28:33 +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:46: 28:48} as Coroutine>::Yield == {coroutine@$DIR/coroutine-yielding-or-returning-itself.rs:28:46: 28:48}` + --> $DIR/coroutine-yielding-or-returning-itself.rs:28:46 | -LL | want_cyclic_coroutine_yield(|| { - | _____---------------------------_^ +LL | want_cyclic_coroutine_yield(#[coroutine] || { + | _____---------------------------______________^ | | | | | required by a bound introduced by this call LL | | diff --git a/tests/ui/coroutine/derived-drop-parent-expr.rs b/tests/ui/coroutine/derived-drop-parent-expr.rs index f70a732c90f0..cc217e4960e9 100644 --- a/tests/ui/coroutine/derived-drop-parent-expr.rs +++ b/tests/ui/coroutine/derived-drop-parent-expr.rs @@ -1,7 +1,7 @@ //@ build-pass //! Like drop-tracking-parent-expression, but also tests that this doesn't ICE when building MIR -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn assert_send(_thing: T) {} @@ -9,8 +9,8 @@ fn assert_send(_thing: T) {} pub struct Client { pub nickname: String } fn main() { - let g = move || match drop(Client { ..Client::default() }) { - _status => yield, - }; + let g = #[coroutine] move || match drop(Client { ..Client::default() }) { + _status => yield, + }; assert_send(g); } diff --git a/tests/ui/coroutine/discriminant.rs b/tests/ui/coroutine/discriminant.rs index a44d8f74746b..d6879e218255 100644 --- a/tests/ui/coroutine/discriminant.rs +++ b/tests/ui/coroutine/discriminant.rs @@ -86,7 +86,7 @@ fn cycle( fn main() { // Has only one invalid discr. value. let gen_u8_tiny_niche = || { - || { + #[coroutine] || { // 3 reserved variants yield250!(); // 253 variants @@ -98,7 +98,7 @@ fn main() { // Uses all values in the u8 discriminant. let gen_u8_full = || { - || { + #[coroutine] || { // 3 reserved variants yield250!(); // 253 variants @@ -111,7 +111,7 @@ fn main() { // Barely needs a u16 discriminant. let gen_u16 = || { - || { + #[coroutine] || { // 3 reserved variants yield250!(); // 253 variants diff --git a/tests/ui/coroutine/drop-and-replace.rs b/tests/ui/coroutine/drop-and-replace.rs index 6e30d76512b7..d3d7e000020a 100644 --- a/tests/ui/coroutine/drop-and-replace.rs +++ b/tests/ui/coroutine/drop-and-replace.rs @@ -4,7 +4,7 @@ // #60187, this produced incorrect code for coroutines when a saved local was // re-assigned. -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; @@ -17,7 +17,8 @@ impl Drop for Foo { } fn main() { - let mut a = || { + let mut a = #[coroutine] + || { let mut x = Foo(4); yield; assert_eq!(x.0, 4); diff --git a/tests/ui/coroutine/drop-control-flow.rs b/tests/ui/coroutine/drop-control-flow.rs index f4e8eed4f8dc..f576b1b75944 100644 --- a/tests/ui/coroutine/drop-control-flow.rs +++ b/tests/ui/coroutine/drop-control-flow.rs @@ -4,7 +4,7 @@ // and also that values that are dropped along all paths to a yield do not get // included in the coroutine type. -#![feature(coroutines, negative_impls)] +#![feature(coroutines, negative_impls, stmt_expr_attributes)] #![allow(unused_assignments, dead_code)] struct Ptr; @@ -19,7 +19,7 @@ fn assert_send(_: T) {} // This test case is reduced from tests/ui/drop/dynamic-drop-async.rs fn one_armed_if(arg: bool) { - let _ = || { + let _ = #[coroutine] || { let arr = [Ptr]; if arg { drop(arr); @@ -29,7 +29,7 @@ fn one_armed_if(arg: bool) { } fn two_armed_if(arg: bool) { - assert_send(|| { + assert_send(#[coroutine] || { let arr = [Ptr]; if arg { drop(arr); @@ -41,7 +41,7 @@ fn two_armed_if(arg: bool) { } fn if_let(arg: Option) { - let _ = || { + let _ = #[coroutine] || { let arr = [Ptr]; if let Some(_) = arg { drop(arr); @@ -51,7 +51,7 @@ fn if_let(arg: Option) { } fn init_in_if(arg: bool) { - assert_send(|| { + assert_send(#[coroutine] || { let mut x = NonSend; drop(x); if arg { @@ -63,7 +63,7 @@ fn init_in_if(arg: bool) { } fn init_in_match_arm(arg: Option) { - assert_send(|| { + assert_send(#[coroutine] || { let mut x = NonSend; drop(x); match arg { @@ -74,7 +74,7 @@ fn init_in_match_arm(arg: Option) { } fn reinit() { - let _ = || { + let _ = #[coroutine] || { let mut arr = [Ptr]; drop(arr); arr = [Ptr]; @@ -83,7 +83,7 @@ fn reinit() { } fn loop_uninit() { - let _ = || { + let _ = #[coroutine] || { let mut arr = [Ptr]; let mut count = 0; drop(arr); @@ -96,7 +96,7 @@ fn loop_uninit() { } fn nested_loop() { - let _ = || { + let _ = #[coroutine] || { let mut arr = [Ptr]; let mut count = 0; drop(arr); @@ -111,7 +111,7 @@ fn nested_loop() { } fn loop_continue(b: bool) { - let _ = || { + let _ = #[coroutine] || { let mut arr = [Ptr]; let mut count = 0; drop(arr); diff --git a/tests/ui/coroutine/drop-env.rs b/tests/ui/coroutine/drop-env.rs index b189ab814995..d36228dc8490 100644 --- a/tests/ui/coroutine/drop-env.rs +++ b/tests/ui/coroutine/drop-env.rs @@ -3,7 +3,7 @@ //@ revisions: default nomiropt //@[nomiropt]compile-flags: -Z mir-opt-level=0 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] #![allow(dropping_copy_types)] use std::ops::Coroutine; @@ -28,7 +28,7 @@ fn main() { fn t1() { let b = B; - let mut foo = || { + let mut foo = #[coroutine] || { yield; drop(b); }; @@ -42,7 +42,7 @@ fn t1() { fn t2() { let b = B; - let mut foo = || { + let mut foo = #[coroutine] || { yield b; }; @@ -55,7 +55,7 @@ fn t2() { fn t3() { let b = B; - let foo = || { + let foo = #[coroutine] || { yield; drop(b); }; diff --git a/tests/ui/coroutine/drop-track-addassign-yield.rs b/tests/ui/coroutine/drop-track-addassign-yield.rs index b1a4bd79f31c..537e66c41b20 100644 --- a/tests/ui/coroutine/drop-track-addassign-yield.rs +++ b/tests/ui/coroutine/drop-track-addassign-yield.rs @@ -3,10 +3,10 @@ // Based on addassign-yield.rs, but with drop tracking enabled. Originally we did not implement // the fake_read callback on ExprUseVisitor which caused this case to break. -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn foo() { - let _y = static || { + let _y = #[coroutine] static || { let x = &mut 0; *{ yield; @@ -17,7 +17,7 @@ fn foo() { }; // Please don't ever actually write something like this - let _z = static || { + let _z = #[coroutine] static || { let x = &mut 0; *{ let inner = &mut 1; diff --git a/tests/ui/coroutine/drop-tracking-parent-expression.rs b/tests/ui/coroutine/drop-tracking-parent-expression.rs index 4d40192c07a2..0f4d99c89364 100644 --- a/tests/ui/coroutine/drop-tracking-parent-expression.rs +++ b/tests/ui/coroutine/drop-tracking-parent-expression.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, negative_impls, rustc_attrs)] +#![feature(coroutines, negative_impls, rustc_attrs, stmt_expr_attributes)] macro_rules! type_combinations { ( @@ -14,7 +14,7 @@ macro_rules! type_combinations { // Struct update syntax. This fails because the Client used in the update is considered // dropped *after* the yield. { - let g = move || match drop($name::Client { ..$name::Client::default() }) { + let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { //~^ `significant_drop::Client` which is not `Send` //~| `insignificant_dtor::Client` which is not `Send` //~| `derived_drop::Client` which is not `Send` @@ -29,7 +29,7 @@ macro_rules! type_combinations { // Simple owned value. This works because the Client is considered moved into `drop`, // even though the temporary expression doesn't end until after the yield. { - let g = move || match drop($name::Client::default()) { + let g = #[coroutine] move || match drop($name::Client::default()) { _ => yield, }; assert_send(g); diff --git a/tests/ui/coroutine/drop-tracking-parent-expression.stderr b/tests/ui/coroutine/drop-tracking-parent-expression.stderr index 21aa35b9579b..5f8d8495e4f1 100644 --- a/tests/ui/coroutine/drop-tracking-parent-expression.stderr +++ b/tests/ui/coroutine/drop-tracking-parent-expression.stderr @@ -13,12 +13,12 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}: Send` + = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:21:22 | -LL | let g = move || match drop($name::Client { ..$name::Client::default() }) { - | ------------------------ has type `derived_drop::Client` which is not `Send` +LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { + | ------------------------ has type `derived_drop::Client` which is not `Send` ... LL | _ => yield, | ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later @@ -53,12 +53,12 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}: Send` + = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:21:22 | -LL | let g = move || match drop($name::Client { ..$name::Client::default() }) { - | ------------------------ has type `significant_drop::Client` which is not `Send` +LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { + | ------------------------ has type `significant_drop::Client` which is not `Send` ... LL | _ => yield, | ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later @@ -93,12 +93,12 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}: Send` + = help: within `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/drop-tracking-parent-expression.rs:17:34: 17:41}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/drop-tracking-parent-expression.rs:21:22 | -LL | let g = move || match drop($name::Client { ..$name::Client::default() }) { - | ------------------------ has type `insignificant_dtor::Client` which is not `Send` +LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { + | ------------------------ has type `insignificant_dtor::Client` which is not `Send` ... LL | _ => yield, | ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later diff --git a/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs b/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs index 0f94016f11b8..43e42fa85f7f 100644 --- a/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs +++ b/tests/ui/coroutine/drop-tracking-yielding-in-match-guards.rs @@ -1,10 +1,10 @@ //@ build-pass //@ edition:2018 -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { - let _ = static |x: u8| match x { + let _ = #[coroutine] static |x: u8| match x { y if { yield } == y + 1 => (), _ => (), }; diff --git a/tests/ui/coroutine/drop-yield-twice.rs b/tests/ui/coroutine/drop-yield-twice.rs index 015343a27762..7ac1345b2ff2 100644 --- a/tests/ui/coroutine/drop-yield-twice.rs +++ b/tests/ui/coroutine/drop-yield-twice.rs @@ -1,10 +1,10 @@ -#![feature(negative_impls, coroutines)] +#![feature(negative_impls, coroutines, stmt_expr_attributes)] struct Foo(i32); impl !Send for Foo {} fn main() { - assert_send(|| { //~ ERROR coroutine cannot be sent between threads safely + assert_send(#[coroutine] || { //~ ERROR coroutine cannot be sent between threads safely let guard = Foo(42); yield; drop(guard); diff --git a/tests/ui/coroutine/drop-yield-twice.stderr b/tests/ui/coroutine/drop-yield-twice.stderr index c6a9e20b8b51..362c6e943ade 100644 --- a/tests/ui/coroutine/drop-yield-twice.stderr +++ b/tests/ui/coroutine/drop-yield-twice.stderr @@ -1,7 +1,7 @@ error: coroutine cannot be sent between threads safely --> $DIR/drop-yield-twice.rs:7:5 | -LL | / assert_send(|| { +LL | / assert_send(#[coroutine] || { LL | | let guard = Foo(42); LL | | yield; LL | | drop(guard); @@ -9,7 +9,7 @@ LL | | yield; LL | | }) | |______^ coroutine is not `Send` | - = help: within `{coroutine@$DIR/drop-yield-twice.rs:7:17: 7:19}`, the trait `Send` is not implemented for `Foo`, which is required by `{coroutine@$DIR/drop-yield-twice.rs:7:17: 7:19}: Send` + = help: within `{coroutine@$DIR/drop-yield-twice.rs:7:30: 7:32}`, the trait `Send` is not implemented for `Foo`, which is required by `{coroutine@$DIR/drop-yield-twice.rs:7:30: 7:32}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/drop-yield-twice.rs:9:9 | diff --git a/tests/ui/coroutine/dropck-resume.rs b/tests/ui/coroutine/dropck-resume.rs index 07ca4d37aba6..df014400f00f 100644 --- a/tests/ui/coroutine/dropck-resume.rs +++ b/tests/ui/coroutine/dropck-resume.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; @@ -16,7 +16,8 @@ fn drop_using_coroutine() -> i32 { let z = &mut y; let r; { - let mut g = move |r| { + let mut g = #[coroutine] + move |r| { let _s = SetToNone(r); yield; }; diff --git a/tests/ui/coroutine/dropck-resume.stderr b/tests/ui/coroutine/dropck-resume.stderr index aa6e423c7604..e9243ffa41e5 100644 --- a/tests/ui/coroutine/dropck-resume.stderr +++ b/tests/ui/coroutine/dropck-resume.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable - --> $DIR/dropck-resume.rs:25:13 + --> $DIR/dropck-resume.rs:26:13 | LL | let z = &mut y; | ------ mutable borrow occurs here diff --git a/tests/ui/coroutine/dropck.rs b/tests/ui/coroutine/dropck.rs index 450361c8dd03..9331c1fa1d58 100644 --- a/tests/ui/coroutine/dropck.rs +++ b/tests/ui/coroutine/dropck.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::cell::RefCell; use std::ops::Coroutine; @@ -10,7 +10,8 @@ fn main() { let ref_ = Box::leak(Box::new(Some(cell.borrow_mut()))); //~^ ERROR `*cell` does not live long enough [E0597] // the upvar is the non-dropck `&mut Option>`. - gen = || { + gen = #[coroutine] + || { // but the coroutine can use it to drop a `Ref<'a, i32>`. let _d = ref_.take(); //~ ERROR `ref_` does not live long enough yield; diff --git a/tests/ui/coroutine/dropck.stderr b/tests/ui/coroutine/dropck.stderr index 241d6dfe0a16..78fdeec972f7 100644 --- a/tests/ui/coroutine/dropck.stderr +++ b/tests/ui/coroutine/dropck.stderr @@ -16,10 +16,13 @@ LL | } = note: values in a scope are dropped in the opposite order they are defined error[E0597]: `ref_` does not live long enough - --> $DIR/dropck.rs:15:18 + --> $DIR/dropck.rs:16:18 | -LL | gen = || { - | -- value captured here by coroutine +LL | let ref_ = Box::leak(Box::new(Some(cell.borrow_mut()))); + | ---- binding `ref_` declared here +... +LL | || { + | -- value captured here by coroutine LL | // but the coroutine can use it to drop a `Ref<'a, i32>`. LL | let _d = ref_.take(); | ^^^^ borrowed value does not live long enough diff --git a/tests/ui/coroutine/gen_block.e2024.stderr b/tests/ui/coroutine/gen_block.e2024.stderr index 2b9eb4a820b6..322259cf2f84 100644 --- a/tests/ui/coroutine/gen_block.e2024.stderr +++ b/tests/ui/coroutine/gen_block.e2024.stderr @@ -1,5 +1,25 @@ +error[E0658]: the `#[coroutines]` attribute is an experimental feature + --> $DIR/gen_block.rs:20:13 + | +LL | let _ = #[coroutine] || yield true; + | ^^^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[coroutines]` attribute is an experimental feature + --> $DIR/gen_block.rs:24:13 + | +LL | let _ = #[coroutine] || {}; + | ^^^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: yield syntax is experimental - --> $DIR/gen_block.rs:15:16 + --> $DIR/gen_block.rs:16:16 | LL | let _ = || yield true; | ^^^^^^^^^^ @@ -8,13 +28,34 @@ LL | let _ = || yield true; = help: add `#![feature(coroutines)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/gen_block.rs:16:16 + | +LL | let _ = || yield true; + | ^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | let _ = #[coroutine] || yield true; + | ++++++++++++ + +error[E0658]: yield syntax is experimental + --> $DIR/gen_block.rs:20:29 + | +LL | let _ = #[coroutine] || yield true; + | ^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0282]: type annotations needed - --> $DIR/gen_block.rs:6:13 + --> $DIR/gen_block.rs:7:13 | LL | let x = gen {}; | ^^^^^^ cannot infer type -error: aborting due to 2 previous errors +error: aborting due to 6 previous errors Some errors have detailed explanations: E0282, E0658. For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/coroutine/gen_block.none.stderr b/tests/ui/coroutine/gen_block.none.stderr index 78a8c5e798ad..64fa2be003de 100644 --- a/tests/ui/coroutine/gen_block.none.stderr +++ b/tests/ui/coroutine/gen_block.none.stderr @@ -1,5 +1,5 @@ error: expected identifier, found reserved keyword `yield` - --> $DIR/gen_block.rs:9:19 + --> $DIR/gen_block.rs:10:19 | LL | let y = gen { yield 42 }; | --- ^^^^^ expected identifier, found reserved keyword @@ -7,25 +7,25 @@ LL | let y = gen { yield 42 }; | while parsing this struct error[E0422]: cannot find struct, variant or union type `gen` in this scope - --> $DIR/gen_block.rs:6:13 + --> $DIR/gen_block.rs:7:13 | LL | let x = gen {}; | ^^^ not found in this scope error[E0422]: cannot find struct, variant or union type `gen` in this scope - --> $DIR/gen_block.rs:9:13 + --> $DIR/gen_block.rs:10:13 | LL | let y = gen { yield 42 }; | ^^^ not found in this scope error[E0422]: cannot find struct, variant or union type `gen` in this scope - --> $DIR/gen_block.rs:12:5 + --> $DIR/gen_block.rs:13:5 | LL | gen {}; | ^^^ not found in this scope error[E0658]: yield syntax is experimental - --> $DIR/gen_block.rs:15:16 + --> $DIR/gen_block.rs:16:16 | LL | let _ = || yield true; | ^^^^^^^^^^ @@ -35,7 +35,37 @@ LL | let _ = || yield true; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: yield syntax is experimental - --> $DIR/gen_block.rs:15:16 + --> $DIR/gen_block.rs:20:29 + | +LL | let _ = #[coroutine] || yield true; + | ^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[coroutines]` attribute is an experimental feature + --> $DIR/gen_block.rs:20:13 + | +LL | let _ = #[coroutine] || yield true; + | ^^^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the `#[coroutines]` attribute is an experimental feature + --> $DIR/gen_block.rs:24:13 + | +LL | let _ = #[coroutine] || {}; + | ^^^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: yield syntax is experimental + --> $DIR/gen_block.rs:16:16 | LL | let _ = || yield true; | ^^^^^^^^^^ @@ -45,7 +75,29 @@ LL | let _ = || yield true; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 6 previous errors +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/gen_block.rs:16:16 + | +LL | let _ = || yield true; + | ^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | let _ = #[coroutine] || yield true; + | ++++++++++++ + +error[E0658]: yield syntax is experimental + --> $DIR/gen_block.rs:20:29 + | +LL | let _ = #[coroutine] || yield true; + | ^^^^^^^^^^ + | + = note: see issue #43122 for more information + = help: add `#![feature(coroutines)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 11 previous errors Some errors have detailed explanations: E0422, E0658. For more information about an error, try `rustc --explain E0422`. diff --git a/tests/ui/coroutine/gen_block.rs b/tests/ui/coroutine/gen_block.rs index f6a775aa6619..7e87a572b909 100644 --- a/tests/ui/coroutine/gen_block.rs +++ b/tests/ui/coroutine/gen_block.rs @@ -1,6 +1,7 @@ //@ revisions: e2024 none //@[e2024] compile-flags: --edition 2024 -Zunstable-options #![cfg_attr(e2024, feature(gen_blocks))] +#![feature(stmt_expr_attributes)] fn main() { let x = gen {}; @@ -14,4 +15,12 @@ fn main() { let _ = || yield true; //[none]~ ERROR yield syntax is experimental //~^ ERROR yield syntax is experimental + //~^^ ERROR `yield` can only be used in + + let _ = #[coroutine] || yield true; //[none]~ ERROR yield syntax is experimental + //~^ ERROR `#[coroutines]` attribute is an experimental feature + //~^^ ERROR yield syntax is experimental + + let _ = #[coroutine] || {}; + //~^ ERROR `#[coroutines]` attribute is an experimental feature } diff --git a/tests/ui/coroutine/issue-102645.rs b/tests/ui/coroutine/issue-102645.rs index a0263510e136..ccf82c3606ac 100644 --- a/tests/ui/coroutine/issue-102645.rs +++ b/tests/ui/coroutine/issue-102645.rs @@ -1,11 +1,12 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; fn main() { let mut a = 5; - let mut b = || { + let mut b = #[coroutine] + || { let d = 6; yield; _zzz(); // #break diff --git a/tests/ui/coroutine/issue-102645.stderr b/tests/ui/coroutine/issue-102645.stderr index 7a3b7f2b04c3..ab5e4a8459f4 100644 --- a/tests/ui/coroutine/issue-102645.stderr +++ b/tests/ui/coroutine/issue-102645.stderr @@ -1,5 +1,5 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied - --> $DIR/issue-102645.rs:14:22 + --> $DIR/issue-102645.rs:15:22 | LL | Pin::new(&mut b).resume(); | ^^^^^^-- an argument of type `()` is missing diff --git a/tests/ui/coroutine/issue-105084.rs b/tests/ui/coroutine/issue-105084.rs index 7801f1bcea0d..4e40bc127d78 100644 --- a/tests/ui/coroutine/issue-105084.rs +++ b/tests/ui/coroutine/issue-105084.rs @@ -11,7 +11,8 @@ fn copy(x: T) -> T { } fn main() { - let mut g = || { + let mut g = #[coroutine] + || { // This is desuraged as 4 stages: // - allocate a `*mut u8` with `exchange_malloc`; // - create a Box that is ignored for trait computations; diff --git a/tests/ui/coroutine/issue-105084.stderr b/tests/ui/coroutine/issue-105084.stderr index c8a6522dbd93..6b1701f0c2ab 100644 --- a/tests/ui/coroutine/issue-105084.stderr +++ b/tests/ui/coroutine/issue-105084.stderr @@ -1,8 +1,8 @@ error[E0382]: borrow of moved value: `g` - --> $DIR/issue-105084.rs:37:14 + --> $DIR/issue-105084.rs:38:14 | -LL | let mut g = || { - | ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`, which does not implement the `Copy` trait +LL | let mut g = #[coroutine] + | ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`, which does not implement the `Copy` trait ... LL | let mut h = copy(g); | - value moved here @@ -22,17 +22,17 @@ help: consider cloning the value if the performance cost is acceptable LL | let mut h = copy(g.clone()); | ++++++++ -error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}` - --> $DIR/issue-105084.rs:31:17 +error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}` + --> $DIR/issue-105084.rs:32:17 | -LL | let mut g = || { - | -- within this `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}` +LL | || { + | -- within this `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}` ... LL | let mut h = copy(g); - | ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}`, the trait `Copy` is not implemented for `Box<(i32, ())>`, which is required by `{coroutine@$DIR/issue-105084.rs:14:17: 14:19}: Copy` + | ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>`, which is required by `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}: Copy` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/issue-105084.rs:21:22 + --> $DIR/issue-105084.rs:22:22 | LL | Box::new((5, yield)); | -------------^^^^^-- diff --git a/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs b/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs index 3d372ac9110c..300c8fe6d461 100644 --- a/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs +++ b/tests/ui/coroutine/issue-110929-coroutine-conflict-error-ice.rs @@ -1,11 +1,12 @@ //@ edition:2021 //@ check-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { let x = &mut (); || { - let _c = || yield *&mut *x; + let _c = #[coroutine] + || yield *&mut *x; || _ = &mut *x; }; } diff --git a/tests/ui/coroutine/issue-113279.rs b/tests/ui/coroutine/issue-113279.rs index f251c924c133..98617af105c3 100644 --- a/tests/ui/coroutine/issue-113279.rs +++ b/tests/ui/coroutine/issue-113279.rs @@ -1,4 +1,4 @@ -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] // `foo` attempts to dereference `""`, which results in an error being reported. Later, the // coroutine transform for `foo` then produces a union which contains a `str` type - unions should @@ -9,7 +9,8 @@ // makes sure that doesn't happen again. fn foo() { - let _y = static || { + let _y = #[coroutine] + static || { let x = &mut 0; *{ yield; diff --git a/tests/ui/coroutine/issue-113279.stderr b/tests/ui/coroutine/issue-113279.stderr index cc9b64ef9ac2..a80fe670188d 100644 --- a/tests/ui/coroutine/issue-113279.stderr +++ b/tests/ui/coroutine/issue-113279.stderr @@ -1,11 +1,11 @@ error[E0161]: cannot move a value of type `str` - --> $DIR/issue-113279.rs:17:20 + --> $DIR/issue-113279.rs:18:20 | LL | } += match { *"" }.len() { | ^^^^^^^ the size of `str` cannot be statically determined error[E0507]: cannot move out of a shared reference - --> $DIR/issue-113279.rs:17:22 + --> $DIR/issue-113279.rs:18:22 | LL | } += match { *"" }.len() { | ^^^ move occurs because value has type `str`, which does not implement the `Copy` trait diff --git a/tests/ui/coroutine/issue-44197.rs b/tests/ui/coroutine/issue-44197.rs index e18bcc2c996f..0240f7a7eaac 100644 --- a/tests/ui/coroutine/issue-44197.rs +++ b/tests/ui/coroutine/issue-44197.rs @@ -10,7 +10,7 @@ fn foo(_: &str) -> String { } fn bar(baz: String) -> impl Coroutine<(), Yield = String, Return = ()> { - move || { + #[coroutine] move || { yield foo(&baz); } } @@ -20,7 +20,7 @@ fn foo2(_: &str) -> Result { } fn bar2(baz: String) -> impl Coroutine<(), Yield = String, Return = ()> { - move || { + #[coroutine] move || { if let Ok(quux) = foo2(&baz) { yield quux; } diff --git a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs index dab9c81bc8fe..d90886b6b1d6 100644 --- a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs +++ b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.rs @@ -1,7 +1,8 @@ -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { - let _ = || { + let _ = #[coroutine] + || { *(1 as *mut u32) = 42; //~^ ERROR dereference of raw pointer is unsafe yield; diff --git a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr index 19949b429396..f99c295bb9eb 100644 --- a/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr +++ b/tests/ui/coroutine/issue-45729-unsafe-in-coroutine.stderr @@ -1,5 +1,5 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/issue-45729-unsafe-in-coroutine.rs:5:9 + --> $DIR/issue-45729-unsafe-in-coroutine.rs:6:9 | LL | *(1 as *mut u32) = 42; | ^^^^^^^^^^^^^^^^ dereference of raw pointer diff --git a/tests/ui/coroutine/issue-48048.rs b/tests/ui/coroutine/issue-48048.rs index b61b7c770723..75664f20198b 100644 --- a/tests/ui/coroutine/issue-48048.rs +++ b/tests/ui/coroutine/issue-48048.rs @@ -3,7 +3,7 @@ fn main() { let x = (|_| {},); - || { + #[coroutine] || { let x = x; x.0({ //~ ERROR borrow may still be in use when coroutine yields diff --git a/tests/ui/coroutine/issue-52304.rs b/tests/ui/coroutine/issue-52304.rs index 01ed181ab1dc..552bc0028ee0 100644 --- a/tests/ui/coroutine/issue-52304.rs +++ b/tests/ui/coroutine/issue-52304.rs @@ -5,6 +5,7 @@ use std::ops::Coroutine; pub fn example() -> impl Coroutine { + #[coroutine] || yield &1 } diff --git a/tests/ui/coroutine/issue-52398.rs b/tests/ui/coroutine/issue-52398.rs index 826ce6b9d9b3..f8b2faf4eabf 100644 --- a/tests/ui/coroutine/issue-52398.rs +++ b/tests/ui/coroutine/issue-52398.rs @@ -14,14 +14,14 @@ impl A { fn main() { // Test that the MIR local with type &A created for the auto-borrow adjustment // is caught by typeck - move || { //~ WARN unused coroutine that must be used + #[coroutine] move || { //~ WARN unused coroutine that must be used A.test(yield); }; // Test that the std::cell::Ref temporary returned from the `borrow` call // is caught by typeck let y = RefCell::new(true); - static move || { //~ WARN unused coroutine that must be used + #[coroutine] static move || { //~ WARN unused coroutine that must be used yield *y.borrow(); return "Done"; }; diff --git a/tests/ui/coroutine/issue-52398.stderr b/tests/ui/coroutine/issue-52398.stderr index 18d816da4c61..806690cc3327 100644 --- a/tests/ui/coroutine/issue-52398.stderr +++ b/tests/ui/coroutine/issue-52398.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/issue-52398.rs:17:5 + --> $DIR/issue-52398.rs:17:18 | -LL | / move || { +LL | #[coroutine] move || { + | __________________^ LL | | A.test(yield); LL | | }; | |_____^ @@ -10,9 +11,10 @@ LL | | }; = note: `#[warn(unused_must_use)]` on by default warning: unused coroutine that must be used - --> $DIR/issue-52398.rs:24:5 + --> $DIR/issue-52398.rs:24:18 | -LL | / static move || { +LL | #[coroutine] static move || { + | __________________^ LL | | yield *y.borrow(); LL | | return "Done"; LL | | }; diff --git a/tests/ui/coroutine/issue-53548.rs b/tests/ui/coroutine/issue-53548.rs index 6d55994137ff..3b8dff2be28c 100644 --- a/tests/ui/coroutine/issue-53548.rs +++ b/tests/ui/coroutine/issue-53548.rs @@ -17,7 +17,7 @@ // //@ check-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] use std::cell::RefCell; use std::rc::Rc; @@ -29,7 +29,7 @@ struct Store { } fn main() { - Box::new(static move || { + Box::new(#[coroutine] static move || { let store = Store::> { inner: Default::default(), }; diff --git a/tests/ui/coroutine/issue-57017.rs b/tests/ui/coroutine/issue-57017.rs index b83d916932ab..19cd80ab4a65 100644 --- a/tests/ui/coroutine/issue-57017.rs +++ b/tests/ui/coroutine/issue-57017.rs @@ -1,5 +1,5 @@ //@ build-pass -#![feature(coroutines, negative_impls)] +#![feature(coroutines, negative_impls, stmt_expr_attributes)] #![allow(dropping_references, dropping_copy_types)] macro_rules! type_combinations { @@ -21,7 +21,7 @@ macro_rules! type_combinations { // This is the same bug as issue 57017, but using yield instead of await { - let g = move || match drop(&$name::unsync::Client::default()) { + let g = #[coroutine] move || match drop(&$name::unsync::Client::default()) { _status => yield, }; assert_send(g); @@ -30,7 +30,7 @@ macro_rules! type_combinations { // This tests that `Client` is properly considered to be dropped after moving it into the // function. { - let g = move || match drop($name::unsend::Client::default()) { + let g = #[coroutine] move || match drop($name::unsend::Client::default()) { _status => yield, }; assert_send(g); diff --git a/tests/ui/coroutine/issue-57084.rs b/tests/ui/coroutine/issue-57084.rs index 51b0c8e1de96..2df60550e037 100644 --- a/tests/ui/coroutine/issue-57084.rs +++ b/tests/ui/coroutine/issue-57084.rs @@ -8,7 +8,7 @@ use std::ops::Coroutine; fn with(f: F) -> impl Coroutine where F: Fn() -> () { - move || { + #[coroutine] move || { loop { match f() { _ => yield, @@ -19,7 +19,7 @@ where F: Fn() -> () fn main() { let data = &vec![1]; - || { //~ WARN unused coroutine that must be used + #[coroutine] || { //~ WARN unused coroutine that must be used let _to_pin = with(move || println!("{:p}", data)); loop { yield diff --git a/tests/ui/coroutine/issue-57084.stderr b/tests/ui/coroutine/issue-57084.stderr index 9f5b79a6ae8a..81bd27da9190 100644 --- a/tests/ui/coroutine/issue-57084.stderr +++ b/tests/ui/coroutine/issue-57084.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/issue-57084.rs:22:5 + --> $DIR/issue-57084.rs:22:18 | -LL | / || { +LL | #[coroutine] || { + | __________________^ LL | | let _to_pin = with(move || println!("{:p}", data)); LL | | loop { LL | | yield diff --git a/tests/ui/coroutine/issue-57478.rs b/tests/ui/coroutine/issue-57478.rs index 5e479aaa9c1b..494c2ee9843e 100644 --- a/tests/ui/coroutine/issue-57478.rs +++ b/tests/ui/coroutine/issue-57478.rs @@ -1,16 +1,19 @@ //@ check-pass -#![feature(negative_impls, coroutines)] +#![feature(negative_impls, coroutines, stmt_expr_attributes)] struct Foo; impl !Send for Foo {} fn main() { - assert_send(|| { - let guard = Foo; - drop(guard); - yield; - }) + assert_send( + #[coroutine] + || { + let guard = Foo; + drop(guard); + yield; + }, + ) } fn assert_send(_: T) {} diff --git a/tests/ui/coroutine/issue-58888.rs b/tests/ui/coroutine/issue-58888.rs index ce45f22dd6ef..6266f97ce8c4 100644 --- a/tests/ui/coroutine/issue-58888.rs +++ b/tests/ui/coroutine/issue-58888.rs @@ -13,7 +13,7 @@ impl Database { } fn check_connection(&self) -> impl Coroutine + '_ { - move || { + #[coroutine] move || { let iter = self.get_connection(); for i in iter { yield i diff --git a/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs b/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs index 6280b777201f..6f513c250a55 100644 --- a/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs +++ b/tests/ui/coroutine/issue-61442-stmt-expr-with-drop.rs @@ -4,7 +4,7 @@ //@ check-pass //@ edition:2018 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; @@ -14,12 +14,14 @@ async fn drop_and_await() { } fn drop_and_yield() { - let x = || { + let x = #[coroutine] + || { String::new(); yield; }; Box::pin(x).as_mut().resume(()); - let y = static || { + let y = #[coroutine] + static || { String::new(); yield; }; diff --git a/tests/ui/coroutine/issue-64620-yield-array-element.rs b/tests/ui/coroutine/issue-64620-yield-array-element.rs index a9307d306a61..0d898d014e80 100644 --- a/tests/ui/coroutine/issue-64620-yield-array-element.rs +++ b/tests/ui/coroutine/issue-64620-yield-array-element.rs @@ -4,6 +4,7 @@ pub fn crash(arr: [usize; 1]) { yield arr[0]; //~ ERROR: yield expression outside of coroutine literal + //~^ ERROR: `yield` can only be used in } fn main() {} diff --git a/tests/ui/coroutine/issue-64620-yield-array-element.stderr b/tests/ui/coroutine/issue-64620-yield-array-element.stderr index 347532fb7193..1c030c5248e1 100644 --- a/tests/ui/coroutine/issue-64620-yield-array-element.stderr +++ b/tests/ui/coroutine/issue-64620-yield-array-element.stderr @@ -1,9 +1,20 @@ +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/issue-64620-yield-array-element.rs:6:5 + | +LL | yield arr[0]; + | ^^^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] pub fn crash(arr: [usize; 1]) { + | ++++++++++++ + error[E0627]: yield expression outside of coroutine literal --> $DIR/issue-64620-yield-array-element.rs:6:5 | LL | yield arr[0]; | ^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0627`. diff --git a/tests/ui/coroutine/issue-68112.rs b/tests/ui/coroutine/issue-68112.rs index ccec2acc9762..b296772c9057 100644 --- a/tests/ui/coroutine/issue-68112.rs +++ b/tests/ui/coroutine/issue-68112.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::{ cell::RefCell, @@ -30,7 +30,7 @@ fn make_non_send_coroutine() -> impl Coroutine>> { } fn test1() { - let send_gen = || { + let send_gen = #[coroutine] || { let _non_send_gen = make_non_send_coroutine(); //~^ NOTE not `Send` yield; @@ -46,7 +46,7 @@ fn test1() { pub fn make_gen2(t: T) -> impl Coroutine { //~^ NOTE appears within the type //~| NOTE expansion of desugaring - || { //~ NOTE used within this coroutine + #[coroutine] || { //~ NOTE used within this coroutine yield; t } @@ -57,7 +57,7 @@ fn make_non_send_coroutine2() -> impl Coroutine>> { // } fn test2() { - let send_gen = || { //~ NOTE used within this coroutine + let send_gen = #[coroutine] || { //~ NOTE used within this coroutine let _non_send_gen = make_non_send_coroutine2(); yield; }; diff --git a/tests/ui/coroutine/issue-68112.stderr b/tests/ui/coroutine/issue-68112.stderr index 443195d36a30..bcfcb5ec6e60 100644 --- a/tests/ui/coroutine/issue-68112.stderr +++ b/tests/ui/coroutine/issue-68112.stderr @@ -4,7 +4,7 @@ error: coroutine cannot be sent between threads safely LL | require_send(send_gen); | ^^^^^^^^^^^^^^^^^^^^^^ coroutine is not `Send` | - = help: the trait `Sync` is not implemented for `RefCell`, which is required by `{coroutine@$DIR/issue-68112.rs:33:20: 33:22}: Send` + = help: the trait `Sync` is not implemented for `RefCell`, which is required by `{coroutine@$DIR/issue-68112.rs:33:33: 33:35}: Send` = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: coroutine is not `Send` as this value is used across a yield --> $DIR/issue-68112.rs:36:9 @@ -26,14 +26,14 @@ error[E0277]: `RefCell` cannot be shared between threads safely LL | require_send(send_gen); | ^^^^^^^^^^^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely | - = help: the trait `Sync` is not implemented for `RefCell`, which is required by `{coroutine@$DIR/issue-68112.rs:60:20: 60:22}: Send` + = help: the trait `Sync` is not implemented for `RefCell`, which is required by `{coroutine@$DIR/issue-68112.rs:60:33: 60:35}: Send` = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Arc>` to implement `Send` note: required because it's used within this coroutine - --> $DIR/issue-68112.rs:49:5 + --> $DIR/issue-68112.rs:49:18 | -LL | || { - | ^^ +LL | #[coroutine] || { + | ^^ note: required because it appears within the type `impl Coroutine>>` --> $DIR/issue-68112.rs:46:30 | @@ -45,10 +45,10 @@ note: required because it appears within the type `impl Coroutine impl Coroutine>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required because it's used within this coroutine - --> $DIR/issue-68112.rs:60:20 + --> $DIR/issue-68112.rs:60:33 | -LL | let send_gen = || { - | ^^ +LL | let send_gen = #[coroutine] || { + | ^^ note: required by a bound in `require_send` --> $DIR/issue-68112.rs:22:25 | diff --git a/tests/ui/coroutine/issue-69017.rs b/tests/ui/coroutine/issue-69017.rs index 09bbf63a986e..bf69e1dfdb13 100644 --- a/tests/ui/coroutine/issue-69017.rs +++ b/tests/ui/coroutine/issue-69017.rs @@ -10,6 +10,7 @@ use std::ops::Coroutine; fn gen() -> impl Coroutine { + #[coroutine] |_: usize| { println!("-> {}", yield); } diff --git a/tests/ui/coroutine/issue-69039.rs b/tests/ui/coroutine/issue-69039.rs index fd12414c3d85..13cb50e58281 100644 --- a/tests/ui/coroutine/issue-69039.rs +++ b/tests/ui/coroutine/issue-69039.rs @@ -9,6 +9,7 @@ fn mkstr(my_name: String, my_mood: String) -> String { } fn my_scenario() -> impl Coroutine { + #[coroutine] |_arg: String| { let my_name = yield "What is your name?"; let my_mood = yield "How are you feeling?"; diff --git a/tests/ui/coroutine/issue-87142.rs b/tests/ui/coroutine/issue-87142.rs index f5c3805842c5..6c22ba3dd756 100644 --- a/tests/ui/coroutine/issue-87142.rs +++ b/tests/ui/coroutine/issue-87142.rs @@ -22,6 +22,7 @@ pub struct Context { impl CoroutineProviderAlt for () { type Coro = impl Coroutine<(), Return = (), Yield = ()>; fn start(ctx: Context) -> Self::Coro { + #[coroutine] move || { match ctx { _ => (), diff --git a/tests/ui/coroutine/issue-88653.rs b/tests/ui/coroutine/issue-88653.rs index ec4c20547587..3afd12a20937 100644 --- a/tests/ui/coroutine/issue-88653.rs +++ b/tests/ui/coroutine/issue-88653.rs @@ -11,6 +11,7 @@ fn foo(bar: bool) -> impl Coroutine<(bool,)> { //~| NOTE: expected coroutine signature `fn((bool,)) -> _` //~| NOTE: in this expansion of desugaring of `impl Trait` //~| NOTE: in this expansion of desugaring of `impl Trait` + #[coroutine] |bar| { //~^ NOTE: found signature defined here if bar { diff --git a/tests/ui/coroutine/issue-91477.rs b/tests/ui/coroutine/issue-91477.rs index c98546f7971c..c215fd7948f3 100644 --- a/tests/ui/coroutine/issue-91477.rs +++ b/tests/ui/coroutine/issue-91477.rs @@ -2,6 +2,7 @@ fn foo() -> impl Sized { yield 1; //~ ERROR E0627 + //~^ ERROR: `yield` can only be used in } fn main() {} diff --git a/tests/ui/coroutine/issue-91477.stderr b/tests/ui/coroutine/issue-91477.stderr index ca8e43d8a26d..5e2151c4c35f 100644 --- a/tests/ui/coroutine/issue-91477.stderr +++ b/tests/ui/coroutine/issue-91477.stderr @@ -1,9 +1,20 @@ +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/issue-91477.rs:4:5 + | +LL | yield 1; + | ^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] fn foo() -> impl Sized { + | ++++++++++++ + error[E0627]: yield expression outside of coroutine literal --> $DIR/issue-91477.rs:4:5 | LL | yield 1; | ^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0627`. diff --git a/tests/ui/coroutine/iterator-count.rs b/tests/ui/coroutine/iterator-count.rs index bb202ab2d33e..1ca8ceaed2a9 100644 --- a/tests/ui/coroutine/iterator-count.rs +++ b/tests/ui/coroutine/iterator-count.rs @@ -21,6 +21,7 @@ impl + Unpin> Iterator for W { } fn test() -> impl Coroutine<(), Return = (), Yield = u8> + Unpin { + #[coroutine] || { for i in 1..6 { yield i @@ -32,6 +33,7 @@ fn main() { let end = 11; let closure_test = |start| { + #[coroutine] move || { for i in start..end { yield i diff --git a/tests/ui/coroutine/live-upvar-across-yield.rs b/tests/ui/coroutine/live-upvar-across-yield.rs index 86c4716c9516..d13d480dcdcc 100644 --- a/tests/ui/coroutine/live-upvar-across-yield.rs +++ b/tests/ui/coroutine/live-upvar-across-yield.rs @@ -1,13 +1,13 @@ //@ run-pass -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; fn main() { let b = |_| 3; - let mut a = || { + let mut a = #[coroutine] || { b(yield); }; Pin::new(&mut a).resume(()); diff --git a/tests/ui/coroutine/match-bindings.rs b/tests/ui/coroutine/match-bindings.rs index 9ea1deaab362..2a0cd9af9f38 100644 --- a/tests/ui/coroutine/match-bindings.rs +++ b/tests/ui/coroutine/match-bindings.rs @@ -9,7 +9,7 @@ enum Enum { } fn main() { - || { //~ WARN unused coroutine that must be used + #[coroutine] || { //~ WARN unused coroutine that must be used loop { if let true = true { match Enum::A(String::new()) { diff --git a/tests/ui/coroutine/match-bindings.stderr b/tests/ui/coroutine/match-bindings.stderr index a7aa6eadb95f..5525bfed1165 100644 --- a/tests/ui/coroutine/match-bindings.stderr +++ b/tests/ui/coroutine/match-bindings.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/match-bindings.rs:12:5 + --> $DIR/match-bindings.rs:12:18 | -LL | / || { +LL | #[coroutine] || { + | __________________^ LL | | loop { LL | | if let true = true { LL | | match Enum::A(String::new()) { diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed b/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed new file mode 100644 index 000000000000..128f09a11843 --- /dev/null +++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.fixed @@ -0,0 +1,8 @@ +//@ run-rustfix + +#![feature(coroutines, gen_blocks, stmt_expr_attributes)] + +fn main() { + let _ = #[coroutine] || yield; + //~^ ERROR `yield` can only be used +} diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs b/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs new file mode 100644 index 000000000000..dc9525914960 --- /dev/null +++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.rs @@ -0,0 +1,8 @@ +//@ run-rustfix + +#![feature(coroutines, gen_blocks, stmt_expr_attributes)] + +fn main() { + let _ = || yield; + //~^ ERROR `yield` can only be used +} diff --git a/tests/ui/coroutine/missing_coroutine_attr_suggestion.stderr b/tests/ui/coroutine/missing_coroutine_attr_suggestion.stderr new file mode 100644 index 000000000000..8d92471a361c --- /dev/null +++ b/tests/ui/coroutine/missing_coroutine_attr_suggestion.stderr @@ -0,0 +1,13 @@ +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/missing_coroutine_attr_suggestion.rs:6:16 + | +LL | let _ = || yield; + | ^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | let _ = #[coroutine] || yield; + | ++++++++++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/coroutine/nested_coroutine.rs b/tests/ui/coroutine/nested_coroutine.rs index 7ff97abf4bb1..2c12ab2adad4 100644 --- a/tests/ui/coroutine/nested_coroutine.rs +++ b/tests/ui/coroutine/nested_coroutine.rs @@ -1,13 +1,15 @@ //@ run-pass -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; fn main() { - let _coroutine = || { - let mut sub_coroutine = || { + let _coroutine = #[coroutine] + || { + let mut sub_coroutine = #[coroutine] + || { yield 2; }; diff --git a/tests/ui/coroutine/niche-in-coroutine.rs b/tests/ui/coroutine/niche-in-coroutine.rs index 45b920ab9273..117ee9e6f038 100644 --- a/tests/ui/coroutine/niche-in-coroutine.rs +++ b/tests/ui/coroutine/niche-in-coroutine.rs @@ -2,7 +2,7 @@ //@ run-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] use std::mem::size_of_val; @@ -10,7 +10,7 @@ fn take(_: T) {} fn main() { let x = false; - let gen1 = || { + let gen1 = #[coroutine] || { yield; take(x); }; diff --git a/tests/ui/coroutine/non-static-is-unpin.rs b/tests/ui/coroutine/non-static-is-unpin.rs index 616a78d5fe2a..b28bf1977145 100644 --- a/tests/ui/coroutine/non-static-is-unpin.rs +++ b/tests/ui/coroutine/non-static-is-unpin.rs @@ -3,7 +3,7 @@ //@[next] compile-flags: -Znext-solver //@ run-pass -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] #![allow(dropping_copy_types)] use std::marker::PhantomPinned; @@ -14,7 +14,7 @@ fn assert_unpin(_: G) { fn main() { // Even though this coroutine holds a `PhantomPinned` in its environment, it // remains `Unpin`. - assert_unpin(|| { + assert_unpin(#[coroutine] || { let pinned = PhantomPinned; yield; drop(pinned); diff --git a/tests/ui/coroutine/not-send-sync.rs b/tests/ui/coroutine/not-send-sync.rs index dd6182c10de0..a46dcd14e882 100644 --- a/tests/ui/coroutine/not-send-sync.rs +++ b/tests/ui/coroutine/not-send-sync.rs @@ -1,4 +1,4 @@ -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![feature(negative_impls)] struct NotSend; @@ -11,14 +11,14 @@ fn main() { fn assert_sync(_: T) {} fn assert_send(_: T) {} - assert_sync(|| { + assert_sync(#[coroutine] || { //~^ ERROR: coroutine cannot be shared between threads safely let a = NotSync; yield; drop(a); }); - assert_send(|| { + assert_send(#[coroutine] || { //~^ ERROR: coroutine cannot be sent between threads safely let a = NotSend; yield; diff --git a/tests/ui/coroutine/not-send-sync.stderr b/tests/ui/coroutine/not-send-sync.stderr index 9228340c710d..0f9cbdec1300 100644 --- a/tests/ui/coroutine/not-send-sync.stderr +++ b/tests/ui/coroutine/not-send-sync.stderr @@ -1,7 +1,7 @@ error: coroutine cannot be shared between threads safely --> $DIR/not-send-sync.rs:14:5 | -LL | / assert_sync(|| { +LL | / assert_sync(#[coroutine] || { LL | | LL | | let a = NotSync; LL | | yield; @@ -9,7 +9,7 @@ LL | | drop(a); LL | | }); | |______^ coroutine is not `Sync` | - = help: within `{coroutine@$DIR/not-send-sync.rs:14:17: 14:19}`, the trait `Sync` is not implemented for `NotSync`, which is required by `{coroutine@$DIR/not-send-sync.rs:14:17: 14:19}: Sync` + = help: within `{coroutine@$DIR/not-send-sync.rs:14:30: 14:32}`, the trait `Sync` is not implemented for `NotSync`, which is required by `{coroutine@$DIR/not-send-sync.rs:14:30: 14:32}: Sync` note: coroutine is not `Sync` as this value is used across a yield --> $DIR/not-send-sync.rs:17:9 | @@ -26,7 +26,7 @@ LL | fn assert_sync(_: T) {} error: coroutine cannot be sent between threads safely --> $DIR/not-send-sync.rs:21:5 | -LL | / assert_send(|| { +LL | / assert_send(#[coroutine] || { LL | | LL | | let a = NotSend; LL | | yield; @@ -34,7 +34,7 @@ LL | | drop(a); LL | | }); | |______^ coroutine is not `Send` | - = help: within `{coroutine@$DIR/not-send-sync.rs:21:17: 21:19}`, the trait `Send` is not implemented for `NotSend`, which is required by `{coroutine@$DIR/not-send-sync.rs:21:17: 21:19}: Send` + = help: within `{coroutine@$DIR/not-send-sync.rs:21:30: 21:32}`, the trait `Send` is not implemented for `NotSend`, which is required by `{coroutine@$DIR/not-send-sync.rs:21:30: 21:32}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/not-send-sync.rs:24:9 | diff --git a/tests/ui/coroutine/overlap-locals.rs b/tests/ui/coroutine/overlap-locals.rs index eea8595ed06f..9cfa6e2a76dd 100644 --- a/tests/ui/coroutine/overlap-locals.rs +++ b/tests/ui/coroutine/overlap-locals.rs @@ -1,9 +1,10 @@ //@ run-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { - let a = || { + let a = #[coroutine] + || { { let w: i32 = 4; yield; diff --git a/tests/ui/coroutine/panic-drops-resume.rs b/tests/ui/coroutine/panic-drops-resume.rs index 6d026e6edc8a..b23666b7885f 100644 --- a/tests/ui/coroutine/panic-drops-resume.rs +++ b/tests/ui/coroutine/panic-drops-resume.rs @@ -3,7 +3,7 @@ //@ run-pass //@ needs-unwind -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::panic::{catch_unwind, AssertUnwindSafe}; @@ -21,7 +21,7 @@ impl Drop for Dropper { } fn main() { - let mut gen = |_arg| { + let mut gen = #[coroutine] |_arg| { if true { panic!(); } diff --git a/tests/ui/coroutine/panic-drops.rs b/tests/ui/coroutine/panic-drops.rs index c99abdc72461..8c2cf560f2ac 100644 --- a/tests/ui/coroutine/panic-drops.rs +++ b/tests/ui/coroutine/panic-drops.rs @@ -1,8 +1,7 @@ //@ run-pass //@ needs-unwind - -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::panic; @@ -25,7 +24,8 @@ fn bool_true() -> bool { fn main() { let b = B; - let mut foo = || { + let mut foo = #[coroutine] + || { if bool_true() { panic!(); } @@ -34,13 +34,12 @@ fn main() { }; assert_eq!(A.load(Ordering::SeqCst), 0); - let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - Pin::new(&mut foo).resume(()) - })); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| Pin::new(&mut foo).resume(()))); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); - let mut foo = || { + let mut foo = #[coroutine] + || { if bool_true() { panic!(); } @@ -49,9 +48,7 @@ fn main() { }; assert_eq!(A.load(Ordering::SeqCst), 1); - let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - Pin::new(&mut foo).resume(()) - })); + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| Pin::new(&mut foo).resume(()))); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); } diff --git a/tests/ui/coroutine/panic-safe.rs b/tests/ui/coroutine/panic-safe.rs index 89dd09bf5203..6b9b4cb33c32 100644 --- a/tests/ui/coroutine/panic-safe.rs +++ b/tests/ui/coroutine/panic-safe.rs @@ -2,14 +2,14 @@ //@ needs-unwind -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; use std::panic; fn main() { - let mut foo = || { + let mut foo = #[coroutine] || { if true { panic!(); } diff --git a/tests/ui/coroutine/parent-expression.rs b/tests/ui/coroutine/parent-expression.rs index 4d40192c07a2..0f4d99c89364 100644 --- a/tests/ui/coroutine/parent-expression.rs +++ b/tests/ui/coroutine/parent-expression.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, negative_impls, rustc_attrs)] +#![feature(coroutines, negative_impls, rustc_attrs, stmt_expr_attributes)] macro_rules! type_combinations { ( @@ -14,7 +14,7 @@ macro_rules! type_combinations { // Struct update syntax. This fails because the Client used in the update is considered // dropped *after* the yield. { - let g = move || match drop($name::Client { ..$name::Client::default() }) { + let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { //~^ `significant_drop::Client` which is not `Send` //~| `insignificant_dtor::Client` which is not `Send` //~| `derived_drop::Client` which is not `Send` @@ -29,7 +29,7 @@ macro_rules! type_combinations { // Simple owned value. This works because the Client is considered moved into `drop`, // even though the temporary expression doesn't end until after the yield. { - let g = move || match drop($name::Client::default()) { + let g = #[coroutine] move || match drop($name::Client::default()) { _ => yield, }; assert_send(g); diff --git a/tests/ui/coroutine/parent-expression.stderr b/tests/ui/coroutine/parent-expression.stderr index 5b3737069e6c..2d817f1bfd9c 100644 --- a/tests/ui/coroutine/parent-expression.stderr +++ b/tests/ui/coroutine/parent-expression.stderr @@ -13,12 +13,12 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}: Send` + = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `derived_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:21:22 | -LL | let g = move || match drop($name::Client { ..$name::Client::default() }) { - | ------------------------ has type `derived_drop::Client` which is not `Send` +LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { + | ------------------------ has type `derived_drop::Client` which is not `Send` ... LL | _ => yield, | ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later @@ -53,12 +53,12 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}: Send` + = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `significant_drop::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:21:22 | -LL | let g = move || match drop($name::Client { ..$name::Client::default() }) { - | ------------------------ has type `significant_drop::Client` which is not `Send` +LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { + | ------------------------ has type `significant_drop::Client` which is not `Send` ... LL | _ => yield, | ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later @@ -93,12 +93,12 @@ LL | | }; LL | | ); | |_____- in this macro invocation | - = help: within `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:21: 17:28}: Send` + = help: within `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}`, the trait `Send` is not implemented for `insignificant_dtor::Client`, which is required by `{coroutine@$DIR/parent-expression.rs:17:34: 17:41}: Send` note: coroutine is not `Send` as this value is used across a yield --> $DIR/parent-expression.rs:21:22 | -LL | let g = move || match drop($name::Client { ..$name::Client::default() }) { - | ------------------------ has type `insignificant_dtor::Client` which is not `Send` +LL | let g = #[coroutine] move || match drop($name::Client { ..$name::Client::default() }) { + | ------------------------ has type `insignificant_dtor::Client` which is not `Send` ... LL | _ => yield, | ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later diff --git a/tests/ui/coroutine/partial-drop.rs b/tests/ui/coroutine/partial-drop.rs index ba13544712f1..9efb551c9c18 100644 --- a/tests/ui/coroutine/partial-drop.rs +++ b/tests/ui/coroutine/partial-drop.rs @@ -1,5 +1,5 @@ //@ check-pass -#![feature(negative_impls, coroutines)] +#![feature(negative_impls, coroutines, stmt_expr_attributes)] struct Foo; impl !Send for Foo {} @@ -10,25 +10,34 @@ struct Bar { } fn main() { - assert_send(|| { - let guard = Bar { foo: Foo, x: 42 }; - drop(guard.foo); - yield; - }); + assert_send( + #[coroutine] + || { + let guard = Bar { foo: Foo, x: 42 }; + drop(guard.foo); + yield; + }, + ); - assert_send(|| { - let mut guard = Bar { foo: Foo, x: 42 }; - drop(guard); - guard = Bar { foo: Foo, x: 23 }; - yield; - }); + assert_send( + #[coroutine] + || { + let mut guard = Bar { foo: Foo, x: 42 }; + drop(guard); + guard = Bar { foo: Foo, x: 23 }; + yield; + }, + ); - assert_send(|| { - let guard = Bar { foo: Foo, x: 42 }; - let Bar { foo, x } = guard; - drop(foo); - yield; - }); + assert_send( + #[coroutine] + || { + let guard = Bar { foo: Foo, x: 42 }; + let Bar { foo, x } = guard; + drop(foo); + yield; + }, + ); } fn assert_send(_: T) {} diff --git a/tests/ui/coroutine/partial-initialization-across-yield.rs b/tests/ui/coroutine/partial-initialization-across-yield.rs index 75ad5a228040..ab6f9c5b1e98 100644 --- a/tests/ui/coroutine/partial-initialization-across-yield.rs +++ b/tests/ui/coroutine/partial-initialization-across-yield.rs @@ -1,13 +1,13 @@ // Test that we don't allow yielding from a coroutine while a local is partially // initialized. -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] struct S { x: i32, y: i32 } struct T(i32, i32); fn test_tuple() { - let _ = || { + let _ = #[coroutine] || { let mut t: (i32, i32); t.0 = 42; //~ ERROR E0381 yield; @@ -17,7 +17,7 @@ fn test_tuple() { } fn test_tuple_struct() { - let _ = || { + let _ = #[coroutine] || { let mut t: T; t.0 = 42; //~ ERROR E0381 yield; @@ -27,7 +27,7 @@ fn test_tuple_struct() { } fn test_struct() { - let _ = || { + let _ = #[coroutine] || { let mut t: S; t.x = 42; //~ ERROR E0381 yield; diff --git a/tests/ui/coroutine/pattern-borrow.rs b/tests/ui/coroutine/pattern-borrow.rs index 76084433d470..46547504abc9 100644 --- a/tests/ui/coroutine/pattern-borrow.rs +++ b/tests/ui/coroutine/pattern-borrow.rs @@ -5,7 +5,7 @@ enum Test { A(i32), B, } fn main() { } fn fun(test: Test) { - move || { + #[coroutine] move || { if let Test::A(ref _a) = test { //~ ERROR borrow may still be in use when coroutine yields yield (); _a.use_ref(); diff --git a/tests/ui/coroutine/pin-box-coroutine.rs b/tests/ui/coroutine/pin-box-coroutine.rs index 1ee6393d1d83..d030f3ef214d 100644 --- a/tests/ui/coroutine/pin-box-coroutine.rs +++ b/tests/ui/coroutine/pin-box-coroutine.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; @@ -8,6 +8,6 @@ fn assert_coroutine(_: G) { } fn main() { - assert_coroutine(static || yield); - assert_coroutine(Box::pin(static || yield)); + assert_coroutine(#[coroutine] static || yield); + assert_coroutine(Box::pin(#[coroutine] static || yield)); } diff --git a/tests/ui/coroutine/polymorphize-args.rs b/tests/ui/coroutine/polymorphize-args.rs index 21aa3c7aafd8..5123bf412b55 100644 --- a/tests/ui/coroutine/polymorphize-args.rs +++ b/tests/ui/coroutine/polymorphize-args.rs @@ -1,14 +1,15 @@ //@ compile-flags: -Zpolymorphize=on //@ build-pass -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; use std::thread; fn main() { - let mut foo = || yield; + let mut foo = #[coroutine] + || yield; thread::spawn(move || match Pin::new(&mut foo).resume(()) { s => panic!("bad state: {:?}", s), }) diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-1.rs b/tests/ui/coroutine/print/coroutine-print-verbose-1.rs index 73106328618e..dc0165c9194d 100644 --- a/tests/ui/coroutine/print/coroutine-print-verbose-1.rs +++ b/tests/ui/coroutine/print/coroutine-print-verbose-1.rs @@ -2,7 +2,7 @@ // Same as: tests/ui/coroutine/issue-68112.stderr -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::{ cell::RefCell, @@ -30,7 +30,7 @@ fn make_non_send_coroutine() -> impl Coroutine>> { } fn test1() { - let send_gen = || { + let send_gen = #[coroutine] || { let _non_send_gen = make_non_send_coroutine(); yield; }; @@ -39,7 +39,7 @@ fn test1() { } pub fn make_gen2(t: T) -> impl Coroutine { - || { + #[coroutine] || { yield; t } @@ -49,7 +49,7 @@ fn make_non_send_coroutine2() -> impl Coroutine>> { } fn test2() { - let send_gen = || { + let send_gen = #[coroutine] || { let _non_send_gen = make_non_send_coroutine2(); yield; }; diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr index 37db83d57f75..934ab08cf178 100644 --- a/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr +++ b/tests/ui/coroutine/print/coroutine-print-verbose-1.stderr @@ -29,10 +29,10 @@ LL | require_send(send_gen); = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead = note: required for `Arc>` to implement `Send` note: required because it's used within this coroutine - --> $DIR/coroutine-print-verbose-1.rs:42:5 + --> $DIR/coroutine-print-verbose-1.rs:42:18 | -LL | || { - | ^^ +LL | #[coroutine] || { + | ^^ note: required because it appears within the type `Opaque(DefId(0:35 ~ coroutine_print_verbose_1[75fb]::make_gen2::{opaque#0}), [Arc>])` --> $DIR/coroutine-print-verbose-1.rs:41:30 | @@ -44,10 +44,10 @@ note: required because it appears within the type `Opaque(DefId(0:36 ~ coroutine LL | fn make_non_send_coroutine2() -> impl Coroutine>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required because it's used within this coroutine - --> $DIR/coroutine-print-verbose-1.rs:52:20 + --> $DIR/coroutine-print-verbose-1.rs:52:33 | -LL | let send_gen = || { - | ^^ +LL | let send_gen = #[coroutine] || { + | ^^ note: required by a bound in `require_send` --> $DIR/coroutine-print-verbose-1.rs:26:25 | diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-2.rs b/tests/ui/coroutine/print/coroutine-print-verbose-2.rs index f9ea68a8cd94..ef7199cafdde 100644 --- a/tests/ui/coroutine/print/coroutine-print-verbose-2.rs +++ b/tests/ui/coroutine/print/coroutine-print-verbose-2.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Zverbose-internals // Same as test/ui/coroutine/not-send-sync.rs -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![feature(negative_impls)] struct NotSend; @@ -14,14 +14,14 @@ fn main() { fn assert_sync(_: T) {} fn assert_send(_: T) {} - assert_sync(|| { + assert_sync(#[coroutine] || { //~^ ERROR: coroutine cannot be shared between threads safely let a = NotSync; yield; drop(a); }); - assert_send(|| { + assert_send(#[coroutine] || { //~^ ERROR: coroutine cannot be sent between threads safely let a = NotSend; yield; diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr index 26c9c27743c0..0de53d9e1d7d 100644 --- a/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr +++ b/tests/ui/coroutine/print/coroutine-print-verbose-2.stderr @@ -1,7 +1,7 @@ error: coroutine cannot be shared between threads safely --> $DIR/coroutine-print-verbose-2.rs:17:5 | -LL | / assert_sync(|| { +LL | / assert_sync(#[coroutine] || { LL | | LL | | let a = NotSync; LL | | yield; @@ -26,7 +26,7 @@ LL | fn assert_sync(_: T) {} error: coroutine cannot be sent between threads safely --> $DIR/coroutine-print-verbose-2.rs:24:5 | -LL | / assert_send(|| { +LL | / assert_send(#[coroutine] || { LL | | LL | | let a = NotSend; LL | | yield; diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-3.rs b/tests/ui/coroutine/print/coroutine-print-verbose-3.rs index be6dbad9e1c2..5dd15fc1b951 100644 --- a/tests/ui/coroutine/print/coroutine-print-verbose-3.rs +++ b/tests/ui/coroutine/print/coroutine-print-verbose-3.rs @@ -1,12 +1,13 @@ //@ compile-flags: -Zverbose-internals -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] fn main() { let x = "Type mismatch test"; - let coroutine :() = || { - //~^ ERROR mismatched types + let coroutine: () = #[coroutine] + || { + //~^ ERROR mismatched types yield 1i32; - return x + return x; }; } diff --git a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr index e2973cde6d3c..dce45aeae56a 100644 --- a/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr +++ b/tests/ui/coroutine/print/coroutine-print-verbose-3.stderr @@ -1,13 +1,12 @@ error[E0308]: mismatched types - --> $DIR/coroutine-print-verbose-3.rs:7:25 + --> $DIR/coroutine-print-verbose-3.rs:8:5 | -LL | let coroutine :() = || { - | ____________________--___^ - | | | - | | expected due to this +LL | let coroutine: () = #[coroutine] + | -- expected due to this +LL | / || { LL | | LL | | yield 1i32; -LL | | return x +LL | | return x; LL | | }; | |_____^ expected `()`, found coroutine | diff --git a/tests/ui/coroutine/reborrow-mut-upvar.rs b/tests/ui/coroutine/reborrow-mut-upvar.rs index e1f6211baebd..716781e365c5 100644 --- a/tests/ui/coroutine/reborrow-mut-upvar.rs +++ b/tests/ui/coroutine/reborrow-mut-upvar.rs @@ -3,7 +3,7 @@ #![feature(coroutines)] fn _run(bar: &mut i32) { - || { //~ WARN unused coroutine that must be used + #[coroutine] || { //~ WARN unused coroutine that must be used { let _baz = &*bar; yield; diff --git a/tests/ui/coroutine/reborrow-mut-upvar.stderr b/tests/ui/coroutine/reborrow-mut-upvar.stderr index 5b614ac4be8b..a05e84c5f3ef 100644 --- a/tests/ui/coroutine/reborrow-mut-upvar.stderr +++ b/tests/ui/coroutine/reborrow-mut-upvar.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/reborrow-mut-upvar.rs:6:5 + --> $DIR/reborrow-mut-upvar.rs:6:18 | -LL | / || { +LL | #[coroutine] || { + | __________________^ LL | | { LL | | let _baz = &*bar; LL | | yield; diff --git a/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs b/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs index a9c13188ff38..0f9c56786da0 100644 --- a/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs +++ b/tests/ui/coroutine/ref-escapes-but-not-over-yield.rs @@ -1,16 +1,17 @@ -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn foo(x: &i32) { // In this case, a reference to `b` escapes the coroutine, but not // because of a yield. We see that there is no yield in the scope of // `b` and give the more generic error message. let mut a = &3; - let mut b = move || { - yield(); + let mut b = #[coroutine] + move || { + yield (); let b = 5; a = &b; //~^ ERROR borrowed data escapes outside of coroutine }; } -fn main() { } +fn main() {} diff --git a/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr b/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr index 8811faf2fade..6fa7082c0b8b 100644 --- a/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr +++ b/tests/ui/coroutine/ref-escapes-but-not-over-yield.stderr @@ -1,5 +1,5 @@ error[E0521]: borrowed data escapes outside of coroutine - --> $DIR/ref-escapes-but-not-over-yield.rs:11:9 + --> $DIR/ref-escapes-but-not-over-yield.rs:12:9 | LL | let mut a = &3; | ----- `a` declared here, outside of the coroutine body diff --git a/tests/ui/coroutine/ref-upvar-not-send.rs b/tests/ui/coroutine/ref-upvar-not-send.rs index 487fdeea2dae..89bb5e5495f4 100644 --- a/tests/ui/coroutine/ref-upvar-not-send.rs +++ b/tests/ui/coroutine/ref-upvar-not-send.rs @@ -1,7 +1,7 @@ // For `Send` coroutines, suggest a `T: Sync` requirement for `&T` upvars, // and suggest a `T: Send` requirement for `&mut T` upvars. -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn assert_send(_: T) {} //~^ NOTE required by a bound in `assert_send` @@ -12,7 +12,7 @@ fn assert_send(_: T) {} fn main() { let x: &*mut () = &std::ptr::null_mut(); let y: &mut *mut () = &mut std::ptr::null_mut(); - assert_send(move || { + assert_send(#[coroutine] move || { //~^ ERROR coroutine cannot be sent between threads safely //~| NOTE coroutine is not `Send` yield; @@ -20,7 +20,7 @@ fn main() { }); //~^^ NOTE captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` //~| NOTE has type `&*mut ()` which is not `Send`, because `*mut ()` is not `Sync` - assert_send(move || { + assert_send(#[coroutine] move || { //~^ ERROR coroutine cannot be sent between threads safely //~| NOTE coroutine is not `Send` yield; diff --git a/tests/ui/coroutine/ref-upvar-not-send.stderr b/tests/ui/coroutine/ref-upvar-not-send.stderr index 0f91bcf40533..4c7deab3f4c4 100644 --- a/tests/ui/coroutine/ref-upvar-not-send.stderr +++ b/tests/ui/coroutine/ref-upvar-not-send.stderr @@ -1,8 +1,8 @@ error: coroutine cannot be sent between threads safely - --> $DIR/ref-upvar-not-send.rs:15:17 + --> $DIR/ref-upvar-not-send.rs:15:30 | -LL | assert_send(move || { - | _________________^ +LL | assert_send(#[coroutine] move || { + | ______________________________^ LL | | LL | | LL | | yield; @@ -10,7 +10,7 @@ LL | | let _x = x; LL | | }); | |_____^ coroutine is not `Send` | - = help: the trait `Sync` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:15:17: 15:24}: Send` + = help: the trait `Sync` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:15:30: 15:37}: Send` note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync` --> $DIR/ref-upvar-not-send.rs:19:18 | @@ -23,10 +23,10 @@ LL | fn assert_send(_: T) {} | ^^^^ required by this bound in `assert_send` error: coroutine cannot be sent between threads safely - --> $DIR/ref-upvar-not-send.rs:23:17 + --> $DIR/ref-upvar-not-send.rs:23:30 | -LL | assert_send(move || { - | _________________^ +LL | assert_send(#[coroutine] move || { + | ______________________________^ LL | | LL | | LL | | yield; @@ -34,7 +34,7 @@ LL | | let _y = y; LL | | }); | |_____^ coroutine is not `Send` | - = help: within `{coroutine@$DIR/ref-upvar-not-send.rs:23:17: 23:24}`, the trait `Send` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:23:17: 23:24}: Send` + = help: within `{coroutine@$DIR/ref-upvar-not-send.rs:23:30: 23:37}`, the trait `Send` is not implemented for `*mut ()`, which is required by `{coroutine@$DIR/ref-upvar-not-send.rs:23:30: 23:37}: Send` note: captured value is not `Send` because `&mut` references cannot be sent unless their referent is `Send` --> $DIR/ref-upvar-not-send.rs:27:18 | diff --git a/tests/ui/coroutine/reinit-in-match-guard.rs b/tests/ui/coroutine/reinit-in-match-guard.rs index 4a5842047731..0a97d9fbcb2f 100644 --- a/tests/ui/coroutine/reinit-in-match-guard.rs +++ b/tests/ui/coroutine/reinit-in-match-guard.rs @@ -1,11 +1,11 @@ //@ build-pass -#![feature(coroutines)] - +#![feature(coroutines, stmt_expr_attributes)] #![allow(unused_assignments, dead_code)] fn main() { - let _ = || { + let _ = #[coroutine] + || { let mut x = vec![22_usize]; std::mem::drop(x); match y() { diff --git a/tests/ui/coroutine/resume-after-return.rs b/tests/ui/coroutine/resume-after-return.rs index 81f86de641f2..7028e1e81e55 100644 --- a/tests/ui/coroutine/resume-after-return.rs +++ b/tests/ui/coroutine/resume-after-return.rs @@ -1,17 +1,17 @@ //@ run-pass //@ needs-unwind +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] -#![feature(coroutines, coroutine_trait)] - -use std::ops::{CoroutineState, Coroutine}; -use std::pin::Pin; +use std::ops::{Coroutine, CoroutineState}; use std::panic; +use std::pin::Pin; fn main() { - let mut foo = || { + let mut foo = #[coroutine] + || { if true { - return + return; } yield; }; diff --git a/tests/ui/coroutine/resume-arg-late-bound.rs b/tests/ui/coroutine/resume-arg-late-bound.rs index 3c2ab41047e3..e84184da631b 100644 --- a/tests/ui/coroutine/resume-arg-late-bound.rs +++ b/tests/ui/coroutine/resume-arg-late-bound.rs @@ -1,14 +1,14 @@ //! Tests that we cannot produce a coroutine that accepts a resume argument //! with any lifetime and then stores it across a `yield`. -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; fn test(a: impl for<'a> Coroutine<&'a mut bool>) {} fn main() { - let gen = |arg: &mut bool| { + let gen = #[coroutine] |arg: &mut bool| { yield (); *arg = true; }; diff --git a/tests/ui/coroutine/resume-arg-late-bound.stderr b/tests/ui/coroutine/resume-arg-late-bound.stderr index 4a4ee08c529e..646abaf4f7bd 100644 --- a/tests/ui/coroutine/resume-arg-late-bound.stderr +++ b/tests/ui/coroutine/resume-arg-late-bound.stderr @@ -4,7 +4,7 @@ error: implementation of `Coroutine` is not general enough LL | test(gen); | ^^^^^^^^^ implementation of `Coroutine` is not general enough | - = note: `{coroutine@$DIR/resume-arg-late-bound.rs:11:15: 11:31}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`... + = note: `{coroutine@$DIR/resume-arg-late-bound.rs:11:28: 11:44}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`... = note: ...but it actually implements `Coroutine<&'2 mut bool>`, for some specific lifetime `'2` error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/resume-arg-size.rs b/tests/ui/coroutine/resume-arg-size.rs index 81e96975c98f..59740a28f428 100644 --- a/tests/ui/coroutine/resume-arg-size.rs +++ b/tests/ui/coroutine/resume-arg-size.rs @@ -1,4 +1,4 @@ -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![allow(dropping_copy_types)] //@ run-pass @@ -7,7 +7,8 @@ use std::mem::size_of_val; fn main() { // Coroutine taking a `Copy`able resume arg. - let gen_copy = |mut x: usize| { + let gen_copy = #[coroutine] + |mut x: usize| { loop { drop(x); x = yield; @@ -15,7 +16,8 @@ fn main() { }; // Coroutine taking a non-`Copy` resume arg. - let gen_move = |mut x: Box| { + let gen_move = #[coroutine] + |mut x: Box| { loop { drop(x); x = yield; diff --git a/tests/ui/coroutine/resume-live-across-yield.rs b/tests/ui/coroutine/resume-live-across-yield.rs index 45851411daaa..b67619ee70fb 100644 --- a/tests/ui/coroutine/resume-live-across-yield.rs +++ b/tests/ui/coroutine/resume-live-across-yield.rs @@ -1,6 +1,6 @@ //@ run-pass -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; @@ -18,7 +18,8 @@ impl Drop for Dropper { } fn main() { - let mut g = |mut _d| { + let mut g = #[coroutine] + |mut _d| { _d = yield; _d }; diff --git a/tests/ui/coroutine/retain-resume-ref.rs b/tests/ui/coroutine/retain-resume-ref.rs index c9f995ab0cf3..6e688c33979a 100644 --- a/tests/ui/coroutine/retain-resume-ref.rs +++ b/tests/ui/coroutine/retain-resume-ref.rs @@ -1,6 +1,6 @@ //! This test ensures that a mutable reference cannot be passed as a resume argument twice. -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::marker::Unpin; use std::ops::{ @@ -12,7 +12,8 @@ use std::pin::Pin; fn main() { let mut thing = String::from("hello"); - let mut gen = |r| { + let mut gen = #[coroutine] + |r| { if false { yield r; } diff --git a/tests/ui/coroutine/retain-resume-ref.stderr b/tests/ui/coroutine/retain-resume-ref.stderr index eb8b78df6c99..e23023c6e23f 100644 --- a/tests/ui/coroutine/retain-resume-ref.stderr +++ b/tests/ui/coroutine/retain-resume-ref.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `thing` as mutable more than once at a time - --> $DIR/retain-resume-ref.rs:23:25 + --> $DIR/retain-resume-ref.rs:24:25 | LL | gen.as_mut().resume(&mut thing); | ---------- first mutable borrow occurs here diff --git a/tests/ui/coroutine/size-moved-locals.rs b/tests/ui/coroutine/size-moved-locals.rs index eb5210087a0e..0f800de84544 100644 --- a/tests/ui/coroutine/size-moved-locals.rs +++ b/tests/ui/coroutine/size-moved-locals.rs @@ -24,6 +24,7 @@ impl Drop for Foo { } fn move_before_yield() -> impl Coroutine { + #[coroutine] static || { let first = Foo([0; FOO_SIZE]); let _second = first; @@ -35,6 +36,7 @@ fn move_before_yield() -> impl Coroutine { fn noop() {} fn move_before_yield_with_noop() -> impl Coroutine { + #[coroutine] static || { let first = Foo([0; FOO_SIZE]); noop(); @@ -47,6 +49,7 @@ fn move_before_yield_with_noop() -> impl Coroutine { // Today we don't have NRVO (we allocate space for both `first` and `second`,) // but we can overlap `first` with `_third`. fn overlap_move_points() -> impl Coroutine { + #[coroutine] static || { let first = Foo([0; FOO_SIZE]); yield; @@ -58,6 +61,7 @@ fn overlap_move_points() -> impl Coroutine { } fn overlap_x_and_y() -> impl Coroutine { + #[coroutine] static || { let x = Foo([0; FOO_SIZE]); yield; diff --git a/tests/ui/coroutine/sized-yield.rs b/tests/ui/coroutine/sized-yield.rs index 1368c88b5227..a4c91fafe6ca 100644 --- a/tests/ui/coroutine/sized-yield.rs +++ b/tests/ui/coroutine/sized-yield.rs @@ -1,11 +1,12 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; use std::pin::Pin; fn main() { let s = String::from("foo"); - let mut gen = move || { + let mut gen = #[coroutine] + move || { //~^ ERROR the size for values of type yield s[..]; }; diff --git a/tests/ui/coroutine/sized-yield.stderr b/tests/ui/coroutine/sized-yield.stderr index 4e8dc13201de..5d5dd6803c89 100644 --- a/tests/ui/coroutine/sized-yield.stderr +++ b/tests/ui/coroutine/sized-yield.stderr @@ -1,8 +1,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/sized-yield.rs:8:19 + --> $DIR/sized-yield.rs:9:5 | -LL | let mut gen = move || { - | ___________________^ +LL | / move || { LL | | LL | | yield s[..]; LL | | }; @@ -12,7 +11,7 @@ LL | | }; = note: the yield type of a coroutine must have a statically known size error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/sized-yield.rs:12:24 + --> $DIR/sized-yield.rs:13:24 | LL | Pin::new(&mut gen).resume(()); | ^^^^^^ doesn't have a size known at compile-time diff --git a/tests/ui/coroutine/smoke-resume-args.rs b/tests/ui/coroutine/smoke-resume-args.rs index 7d20cd2293d6..209c48140018 100644 --- a/tests/ui/coroutine/smoke-resume-args.rs +++ b/tests/ui/coroutine/smoke-resume-args.rs @@ -3,7 +3,7 @@ //@ revisions: default nomiropt //@[nomiropt]compile-flags: -Z mir-opt-level=0 -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::fmt::Debug; use std::ops::{ @@ -50,7 +50,7 @@ fn expect_drops(expected_drops: usize, f: impl FnOnce() -> T) -> T { fn main() { drain( - &mut |mut b| { + &mut #[coroutine] |mut b| { while b != 0 { b = yield (b + 1); } @@ -59,21 +59,24 @@ fn main() { vec![(1, Yielded(2)), (-45, Yielded(-44)), (500, Yielded(501)), (0, Complete(-1))], ); - expect_drops(2, || drain(&mut |a| yield a, vec![(DropMe, Yielded(DropMe))])); + expect_drops(2, || drain(&mut #[coroutine] |a| yield a, vec![(DropMe, Yielded(DropMe))])); expect_drops(6, || { drain( - &mut |a| yield yield a, + &mut #[coroutine] |a| yield yield a, vec![(DropMe, Yielded(DropMe)), (DropMe, Yielded(DropMe)), (DropMe, Complete(DropMe))], ) }); #[allow(unreachable_code)] - expect_drops(2, || drain(&mut |a| yield return a, vec![(DropMe, Complete(DropMe))])); + expect_drops(2, || drain( + &mut #[coroutine] |a| yield return a, + vec![(DropMe, Complete(DropMe))] + )); expect_drops(2, || { drain( - &mut |a: DropMe| { + &mut #[coroutine] |a: DropMe| { if false { yield () } else { a } }, vec![(DropMe, Complete(DropMe))], @@ -83,7 +86,7 @@ fn main() { expect_drops(4, || { drain( #[allow(unused_assignments, unused_variables)] - &mut |mut a: DropMe| { + &mut #[coroutine] |mut a: DropMe| { a = yield; a = yield; a = yield; diff --git a/tests/ui/coroutine/smoke.rs b/tests/ui/coroutine/smoke.rs index 17d98a52a1c4..bfb183fde936 100644 --- a/tests/ui/coroutine/smoke.rs +++ b/tests/ui/coroutine/smoke.rs @@ -6,7 +6,7 @@ //@ needs-threads //@ compile-flags: --test -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{CoroutineState, Coroutine}; use std::pin::Pin; @@ -14,7 +14,7 @@ use std::thread; #[test] fn simple() { - let mut foo = || { + let mut foo = #[coroutine] || { if false { yield; } @@ -29,7 +29,7 @@ fn simple() { #[test] fn return_capture() { let a = String::from("foo"); - let mut foo = || { + let mut foo = #[coroutine] || { if false { yield; } @@ -44,7 +44,7 @@ fn return_capture() { #[test] fn simple_yield() { - let mut foo = || { + let mut foo = #[coroutine] || { yield; }; @@ -61,7 +61,7 @@ fn simple_yield() { #[test] fn yield_capture() { let b = String::from("foo"); - let mut foo = || { + let mut foo = #[coroutine] || { yield b; }; @@ -77,7 +77,7 @@ fn yield_capture() { #[test] fn simple_yield_value() { - let mut foo = || { + let mut foo = #[coroutine] || { yield String::from("bar"); return String::from("foo") }; @@ -95,7 +95,7 @@ fn simple_yield_value() { #[test] fn return_after_yield() { let a = String::from("foo"); - let mut foo = || { + let mut foo = #[coroutine] || { yield; return a }; @@ -112,34 +112,34 @@ fn return_after_yield() { #[test] fn send_and_sync() { - assert_send_sync(|| { + assert_send_sync(#[coroutine] || { yield }); - assert_send_sync(|| { + assert_send_sync(#[coroutine] || { yield String::from("foo"); }); - assert_send_sync(|| { + assert_send_sync(#[coroutine] || { yield; return String::from("foo"); }); let a = 3; - assert_send_sync(|| { + assert_send_sync(#[coroutine] || { yield a; return }); let a = 3; - assert_send_sync(move || { + assert_send_sync(#[coroutine] move || { yield a; return }); let a = String::from("a"); - assert_send_sync(|| { + assert_send_sync(#[coroutine] || { yield ; drop(a); return }); let a = String::from("a"); - assert_send_sync(move || { + assert_send_sync(#[coroutine] move || { yield ; drop(a); return @@ -150,7 +150,7 @@ fn send_and_sync() { #[test] fn send_over_threads() { - let mut foo = || { yield }; + let mut foo = #[coroutine] || { yield }; thread::spawn(move || { match Pin::new(&mut foo).resume(()) { CoroutineState::Yielded(()) => {} @@ -163,7 +163,7 @@ fn send_over_threads() { }).join().unwrap(); let a = String::from("a"); - let mut foo = || { yield a }; + let mut foo = #[coroutine] || { yield a }; thread::spawn(move || { match Pin::new(&mut foo).resume(()) { CoroutineState::Yielded(ref s) if *s == "a" => {} diff --git a/tests/ui/coroutine/static-coroutine.rs b/tests/ui/coroutine/static-coroutine.rs index 9beaef3e4de3..eba6336d342f 100644 --- a/tests/ui/coroutine/static-coroutine.rs +++ b/tests/ui/coroutine/static-coroutine.rs @@ -1,12 +1,13 @@ //@ run-pass -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] -use std::pin::Pin; use std::ops::{Coroutine, CoroutineState}; +use std::pin::Pin; fn main() { - let mut coroutine = static || { + let mut coroutine = #[coroutine] + static || { let a = true; let b = &a; yield; diff --git a/tests/ui/coroutine/static-mut-reference-across-yield.rs b/tests/ui/coroutine/static-mut-reference-across-yield.rs index 0d8042ed8526..40d5fdf2d573 100644 --- a/tests/ui/coroutine/static-mut-reference-across-yield.rs +++ b/tests/ui/coroutine/static-mut-reference-across-yield.rs @@ -1,6 +1,6 @@ //@ build-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] static mut A: [i32; 5] = [1, 2, 3, 4, 5]; @@ -8,13 +8,15 @@ fn is_send_sync(_: T) {} fn main() { unsafe { - let gen_index = static || { + let gen_index = #[coroutine] + static || { let u = A[{ yield; 1 }]; }; - let gen_match = static || match A { + let gen_match = #[coroutine] + static || match A { i if { yield; true diff --git a/tests/ui/coroutine/static-not-unpin.current.stderr b/tests/ui/coroutine/static-not-unpin.current.stderr index 518abdd62c79..7d6260ac569e 100644 --- a/tests/ui/coroutine/static-not-unpin.current.stderr +++ b/tests/ui/coroutine/static-not-unpin.current.stderr @@ -1,8 +1,8 @@ -error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}` cannot be unpinned +error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` cannot be unpinned --> $DIR/static-not-unpin.rs:18:18 | LL | assert_unpin(coroutine); - | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}` + | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` | | | required by a bound introduced by this call | @@ -11,7 +11,7 @@ LL | assert_unpin(coroutine); note: required by a bound in `assert_unpin` --> $DIR/static-not-unpin.rs:11:20 | -LL | fn assert_unpin(_: T) { +LL | fn assert_unpin(_: T) {} | ^^^^^ required by this bound in `assert_unpin` error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/static-not-unpin.next.stderr b/tests/ui/coroutine/static-not-unpin.next.stderr index 518abdd62c79..7d6260ac569e 100644 --- a/tests/ui/coroutine/static-not-unpin.next.stderr +++ b/tests/ui/coroutine/static-not-unpin.next.stderr @@ -1,8 +1,8 @@ -error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}` cannot be unpinned +error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` cannot be unpinned --> $DIR/static-not-unpin.rs:18:18 | LL | assert_unpin(coroutine); - | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:25: 15:34}` + | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` | | | required by a bound introduced by this call | @@ -11,7 +11,7 @@ LL | assert_unpin(coroutine); note: required by a bound in `assert_unpin` --> $DIR/static-not-unpin.rs:11:20 | -LL | fn assert_unpin(_: T) { +LL | fn assert_unpin(_: T) {} | ^^^^^ required by this bound in `assert_unpin` error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs index 3704cca77297..2bc25e3796d4 100644 --- a/tests/ui/coroutine/static-not-unpin.rs +++ b/tests/ui/coroutine/static-not-unpin.rs @@ -2,17 +2,17 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] //@ normalize-stderr-test "std::pin::Unpin" -> "std::marker::Unpin" use std::marker::Unpin; -fn assert_unpin(_: T) { -} +fn assert_unpin(_: T) {} fn main() { - let mut coroutine = static || { + let mut coroutine = #[coroutine] + static || { yield; }; assert_unpin(coroutine); //~ ERROR E0277 diff --git a/tests/ui/coroutine/static-reference-across-yield.rs b/tests/ui/coroutine/static-reference-across-yield.rs index cf19ccb54d53..e7ff658ebf64 100644 --- a/tests/ui/coroutine/static-reference-across-yield.rs +++ b/tests/ui/coroutine/static-reference-across-yield.rs @@ -4,10 +4,10 @@ static A: [i32; 5] = [1, 2, 3, 4, 5]; fn main() { - static || { + #[coroutine] static || { let u = A[{yield; 1}]; }; - static || { + #[coroutine] static || { match A { i if { yield; true } => (), _ => (), diff --git a/tests/ui/coroutine/too-live-local-in-immovable-gen.rs b/tests/ui/coroutine/too-live-local-in-immovable-gen.rs index 382e7ff38143..1c689ef7cefc 100644 --- a/tests/ui/coroutine/too-live-local-in-immovable-gen.rs +++ b/tests/ui/coroutine/too-live-local-in-immovable-gen.rs @@ -5,7 +5,7 @@ fn main() { unsafe { - static move || { //~ WARN unused coroutine that must be used + #[coroutine] static move || { //~ WARN unused coroutine that must be used // Tests that the coroutine transformation finds out that `a` is not live // during the yield expression. Type checking will also compute liveness // and it should also find out that `a` is not live. diff --git a/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr b/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr index 4a67dbe71e19..48df5c5beacd 100644 --- a/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr +++ b/tests/ui/coroutine/too-live-local-in-immovable-gen.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/too-live-local-in-immovable-gen.rs:8:9 + --> $DIR/too-live-local-in-immovable-gen.rs:8:22 | -LL | / static move || { +LL | #[coroutine] static move || { + | ______________________^ LL | | // Tests that the coroutine transformation finds out that `a` is not live LL | | // during the yield expression. Type checking will also compute liveness LL | | // and it should also find out that `a` is not live. diff --git a/tests/ui/coroutine/too-many-parameters.rs b/tests/ui/coroutine/too-many-parameters.rs index 377d80c7b22e..3baaf0623479 100644 --- a/tests/ui/coroutine/too-many-parameters.rs +++ b/tests/ui/coroutine/too-many-parameters.rs @@ -1,6 +1,7 @@ #![feature(coroutines)] fn main() { + #[coroutine] |(), ()| { //~^ error: too many parameters for a coroutine yield; diff --git a/tests/ui/coroutine/too-many-parameters.stderr b/tests/ui/coroutine/too-many-parameters.stderr index c0917c7225ba..45dad8e349e2 100644 --- a/tests/ui/coroutine/too-many-parameters.stderr +++ b/tests/ui/coroutine/too-many-parameters.stderr @@ -1,5 +1,5 @@ error[E0628]: too many parameters for a coroutine (expected 0 or 1 parameters) - --> $DIR/too-many-parameters.rs:4:5 + --> $DIR/too-many-parameters.rs:5:5 | LL | |(), ()| { | ^^^^^^^^ diff --git a/tests/ui/coroutine/type-mismatch-error.rs b/tests/ui/coroutine/type-mismatch-error.rs index 0d04c21484cb..ee4e27c20da1 100644 --- a/tests/ui/coroutine/type-mismatch-error.rs +++ b/tests/ui/coroutine/type-mismatch-error.rs @@ -1,7 +1,7 @@ //! Test that we get the expected type mismatch error instead of "closure is expected to take 0 //! arguments" (which got introduced after implementing resume arguments). -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::Coroutine; @@ -9,6 +9,7 @@ fn f(_: G, _: G::Return) {} fn main() { f( + #[coroutine] |a: u8| { if false { yield (); diff --git a/tests/ui/coroutine/type-mismatch-error.stderr b/tests/ui/coroutine/type-mismatch-error.stderr index 737d9afdd79a..f10c30e25907 100644 --- a/tests/ui/coroutine/type-mismatch-error.stderr +++ b/tests/ui/coroutine/type-mismatch-error.stderr @@ -1,5 +1,5 @@ error[E0308]: `if` and `else` have incompatible types - --> $DIR/type-mismatch-error.rs:16:17 + --> $DIR/type-mismatch-error.rs:17:17 | LL | / if false { LL | | yield (); diff --git a/tests/ui/coroutine/type-mismatch-signature-deduction.rs b/tests/ui/coroutine/type-mismatch-signature-deduction.rs index d4ca622e80f5..5b04b3efaaa4 100644 --- a/tests/ui/coroutine/type-mismatch-signature-deduction.rs +++ b/tests/ui/coroutine/type-mismatch-signature-deduction.rs @@ -4,6 +4,7 @@ use std::ops::Coroutine; fn foo() -> impl Coroutine { //~^ ERROR type mismatch + #[coroutine] || { if false { return Ok(6); diff --git a/tests/ui/coroutine/type-mismatch-signature-deduction.stderr b/tests/ui/coroutine/type-mismatch-signature-deduction.stderr index f26e30a8e743..089271960375 100644 --- a/tests/ui/coroutine/type-mismatch-signature-deduction.stderr +++ b/tests/ui/coroutine/type-mismatch-signature-deduction.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-mismatch-signature-deduction.rs:14:9 + --> $DIR/type-mismatch-signature-deduction.rs:15:9 | LL | 5 | ^ expected `Result<{integer}, _>`, found integer @@ -7,7 +7,7 @@ LL | 5 = note: expected enum `Result<{integer}, _>` found type `{integer}` note: return type inferred to be `Result<{integer}, _>` here - --> $DIR/type-mismatch-signature-deduction.rs:9:20 + --> $DIR/type-mismatch-signature-deduction.rs:10:20 | LL | return Ok(6); | ^^^^^ @@ -18,7 +18,7 @@ LL | Ok(5) LL | Err(5) | ++++ + -error[E0271]: type mismatch resolving `<{coroutine@$DIR/type-mismatch-signature-deduction.rs:7:5: 7:7} as Coroutine>::Return == i32` +error[E0271]: type mismatch resolving `<{coroutine@$DIR/type-mismatch-signature-deduction.rs:8:5: 8:7} as Coroutine>::Return == i32` --> $DIR/type-mismatch-signature-deduction.rs:5:13 | LL | fn foo() -> impl Coroutine { diff --git a/tests/ui/coroutine/uninhabited-field.rs b/tests/ui/coroutine/uninhabited-field.rs index 79776d653b1f..d6ada07ce0cb 100644 --- a/tests/ui/coroutine/uninhabited-field.rs +++ b/tests/ui/coroutine/uninhabited-field.rs @@ -3,7 +3,7 @@ #![allow(unused)] #![feature(assert_matches)] #![feature(coroutine_trait)] -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![feature(never_type)] use std::assert_matches::assert_matches; use std::ops::Coroutine; @@ -13,7 +13,7 @@ use std::pin::Pin; fn conjure() -> T { loop {} } fn run(x: bool, y: bool) { - let mut c = || { + let mut c = #[coroutine] || { if x { let a : T; if y { diff --git a/tests/ui/coroutine/unsized-capture-across-yield.rs b/tests/ui/coroutine/unsized-capture-across-yield.rs index ef9cbc1d677d..c86b1823aaff 100644 --- a/tests/ui/coroutine/unsized-capture-across-yield.rs +++ b/tests/ui/coroutine/unsized-capture-across-yield.rs @@ -7,6 +7,7 @@ use std::ops::Coroutine; fn capture() -> impl Coroutine { let b: [u8] = *(Box::new([]) as Box<[u8]>); + #[coroutine] move || { println!("{:?}", &b); //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time diff --git a/tests/ui/coroutine/unsized-capture-across-yield.stderr b/tests/ui/coroutine/unsized-capture-across-yield.stderr index 436f0901a977..03551f1bbff5 100644 --- a/tests/ui/coroutine/unsized-capture-across-yield.stderr +++ b/tests/ui/coroutine/unsized-capture-across-yield.stderr @@ -8,7 +8,7 @@ LL | #![feature(unsized_locals)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-capture-across-yield.rs:11:27 + --> $DIR/unsized-capture-across-yield.rs:12:27 | LL | move || { | -- this closure captures all values by move diff --git a/tests/ui/coroutine/unsized-local-across-yield.rs b/tests/ui/coroutine/unsized-local-across-yield.rs index 7a8ed60e46ae..cb8ced13a111 100644 --- a/tests/ui/coroutine/unsized-local-across-yield.rs +++ b/tests/ui/coroutine/unsized-local-across-yield.rs @@ -6,6 +6,7 @@ use std::ops::Coroutine; fn across() -> impl Coroutine { + #[coroutine] move || { let b: [u8] = *(Box::new([]) as Box<[u8]>); //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time diff --git a/tests/ui/coroutine/unsized-local-across-yield.stderr b/tests/ui/coroutine/unsized-local-across-yield.stderr index c4c3be77ac2b..4fe0f135a9d6 100644 --- a/tests/ui/coroutine/unsized-local-across-yield.stderr +++ b/tests/ui/coroutine/unsized-local-across-yield.stderr @@ -8,7 +8,7 @@ LL | #![feature(unsized_locals)] = note: `#[warn(incomplete_features)]` on by default error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/unsized-local-across-yield.rs:10:13 + --> $DIR/unsized-local-across-yield.rs:11:13 | LL | let b: [u8] = *(Box::new([]) as Box<[u8]>); | ^ doesn't have a size known at compile-time diff --git a/tests/ui/coroutine/yield-in-args-rev.rs b/tests/ui/coroutine/yield-in-args-rev.rs index b074e2bc9398..29d79df25fba 100644 --- a/tests/ui/coroutine/yield-in-args-rev.rs +++ b/tests/ui/coroutine/yield-in-args-rev.rs @@ -10,7 +10,7 @@ fn foo(_a: (), _b: &bool) {} fn bar() { - || { //~ WARN unused coroutine that must be used + #[coroutine] || { //~ WARN unused coroutine that must be used let b = true; foo(yield, &b); }; diff --git a/tests/ui/coroutine/yield-in-args-rev.stderr b/tests/ui/coroutine/yield-in-args-rev.stderr index dbf46739e8bf..10829d661854 100644 --- a/tests/ui/coroutine/yield-in-args-rev.stderr +++ b/tests/ui/coroutine/yield-in-args-rev.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/yield-in-args-rev.rs:13:5 + --> $DIR/yield-in-args-rev.rs:13:18 | -LL | / || { +LL | #[coroutine] || { + | __________________^ LL | | let b = true; LL | | foo(yield, &b); LL | | }; diff --git a/tests/ui/coroutine/yield-in-args.rs b/tests/ui/coroutine/yield-in-args.rs index b2827148d771..bc9909b310c3 100644 --- a/tests/ui/coroutine/yield-in-args.rs +++ b/tests/ui/coroutine/yield-in-args.rs @@ -3,6 +3,7 @@ fn foo(_b: &bool, _a: ()) {} fn main() { + #[coroutine] || { let b = true; foo(&b, yield); //~ ERROR diff --git a/tests/ui/coroutine/yield-in-args.stderr b/tests/ui/coroutine/yield-in-args.stderr index 7233f47884b7..1d2c54f9bdbf 100644 --- a/tests/ui/coroutine/yield-in-args.stderr +++ b/tests/ui/coroutine/yield-in-args.stderr @@ -1,5 +1,5 @@ error[E0626]: borrow may still be in use when coroutine yields - --> $DIR/yield-in-args.rs:8:13 + --> $DIR/yield-in-args.rs:9:13 | LL | foo(&b, yield); | ^^ ----- possible yield occurs here diff --git a/tests/ui/coroutine/yield-in-const.rs b/tests/ui/coroutine/yield-in-const.rs index 22651f32cf85..dc1b30155b9f 100644 --- a/tests/ui/coroutine/yield-in-const.rs +++ b/tests/ui/coroutine/yield-in-const.rs @@ -2,5 +2,6 @@ const A: u8 = { yield 3u8; 3u8}; //~^ ERROR yield expression outside +//~| ERROR `yield` can only be used in fn main() {} diff --git a/tests/ui/coroutine/yield-in-const.stderr b/tests/ui/coroutine/yield-in-const.stderr index d5748b053375..f02729412ccd 100644 --- a/tests/ui/coroutine/yield-in-const.stderr +++ b/tests/ui/coroutine/yield-in-const.stderr @@ -1,9 +1,15 @@ +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/yield-in-const.rs:3:17 + | +LL | const A: u8 = { yield 3u8; 3u8}; + | ^^^^^^^^^ + error[E0627]: yield expression outside of coroutine literal --> $DIR/yield-in-const.rs:3:17 | LL | const A: u8 = { yield 3u8; 3u8}; | ^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0627`. diff --git a/tests/ui/coroutine/yield-in-function.rs b/tests/ui/coroutine/yield-in-function.rs index a99312043bdb..427c5d0e7f5e 100644 --- a/tests/ui/coroutine/yield-in-function.rs +++ b/tests/ui/coroutine/yield-in-function.rs @@ -2,3 +2,4 @@ fn main() { yield; } //~^ ERROR yield expression outside +//~| ERROR `yield` can only be used in diff --git a/tests/ui/coroutine/yield-in-function.stderr b/tests/ui/coroutine/yield-in-function.stderr index b9d4708bb8d8..dbebf310b04f 100644 --- a/tests/ui/coroutine/yield-in-function.stderr +++ b/tests/ui/coroutine/yield-in-function.stderr @@ -1,9 +1,20 @@ +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/yield-in-function.rs:3:13 + | +LL | fn main() { yield; } + | ^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] fn main() { yield; } + | ++++++++++++ + error[E0627]: yield expression outside of coroutine literal --> $DIR/yield-in-function.rs:3:13 | LL | fn main() { yield; } | ^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0627`. diff --git a/tests/ui/coroutine/yield-in-initializer.rs b/tests/ui/coroutine/yield-in-initializer.rs index 19218926b8a0..3caefac013ef 100644 --- a/tests/ui/coroutine/yield-in-initializer.rs +++ b/tests/ui/coroutine/yield-in-initializer.rs @@ -3,7 +3,7 @@ #![feature(coroutines)] fn main() { - static || { //~ WARN unused coroutine that must be used + #[coroutine] static || { //~ WARN unused coroutine that must be used loop { // Test that `opt` is not live across the yield, even when borrowed in a loop // See https://github.com/rust-lang/rust/issues/52792 diff --git a/tests/ui/coroutine/yield-in-initializer.stderr b/tests/ui/coroutine/yield-in-initializer.stderr index 614df43f2f58..1e22b7876687 100644 --- a/tests/ui/coroutine/yield-in-initializer.stderr +++ b/tests/ui/coroutine/yield-in-initializer.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/yield-in-initializer.rs:6:5 + --> $DIR/yield-in-initializer.rs:6:18 | -LL | / static || { +LL | #[coroutine] static || { + | __________________^ LL | | loop { LL | | // Test that `opt` is not live across the yield, even when borrowed in a loop LL | | // See https://github.com/rust-lang/rust/issues/52792 diff --git a/tests/ui/coroutine/yield-in-static.rs b/tests/ui/coroutine/yield-in-static.rs index 45e0380d46d9..99d08913e64c 100644 --- a/tests/ui/coroutine/yield-in-static.rs +++ b/tests/ui/coroutine/yield-in-static.rs @@ -2,5 +2,6 @@ static B: u8 = { yield 3u8; 3u8}; //~^ ERROR yield expression outside +//~| ERROR `yield` can only be used in fn main() {} diff --git a/tests/ui/coroutine/yield-in-static.stderr b/tests/ui/coroutine/yield-in-static.stderr index b56283cab669..d1fd4eab0fc3 100644 --- a/tests/ui/coroutine/yield-in-static.stderr +++ b/tests/ui/coroutine/yield-in-static.stderr @@ -1,9 +1,15 @@ +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/yield-in-static.rs:3:18 + | +LL | static B: u8 = { yield 3u8; 3u8}; + | ^^^^^^^^^ + error[E0627]: yield expression outside of coroutine literal --> $DIR/yield-in-static.rs:3:18 | LL | static B: u8 = { yield 3u8; 3u8}; | ^^^^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0627`. diff --git a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs index 31025c33b1a2..6833bc990121 100644 --- a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs +++ b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.rs @@ -4,4 +4,5 @@ fn main() { yield || for i in 0 { } //~^ ERROR yield expression outside of coroutine literal //~| ERROR `{integer}` is not an iterator + //~| ERROR `yield` can only be used in } diff --git a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr index 8f8bec994584..921e8d5d47a0 100644 --- a/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr +++ b/tests/ui/coroutine/yield-outside-coroutine-issue-78653.stderr @@ -1,3 +1,14 @@ +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/yield-outside-coroutine-issue-78653.rs:4:5 + | +LL | yield || for i in 0 { } + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] fn main() { + | ++++++++++++ + error[E0627]: yield expression outside of coroutine literal --> $DIR/yield-outside-coroutine-issue-78653.rs:4:5 | @@ -14,7 +25,7 @@ LL | yield || for i in 0 { } = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` = note: required for `{integer}` to implement `IntoIterator` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0627. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/yield-subtype.rs b/tests/ui/coroutine/yield-subtype.rs index 271f8362f17e..adee5075e832 100644 --- a/tests/ui/coroutine/yield-subtype.rs +++ b/tests/ui/coroutine/yield-subtype.rs @@ -8,7 +8,7 @@ fn bar<'a>() { let a: &'static str = "hi"; let b: &'a str = a; - || { //~ WARN unused coroutine that must be used + #[coroutine] || { //~ WARN unused coroutine that must be used yield a; yield b; }; diff --git a/tests/ui/coroutine/yield-subtype.stderr b/tests/ui/coroutine/yield-subtype.stderr index 5e7ae9f581eb..973415327a5d 100644 --- a/tests/ui/coroutine/yield-subtype.stderr +++ b/tests/ui/coroutine/yield-subtype.stderr @@ -1,7 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/yield-subtype.rs:11:5 + --> $DIR/yield-subtype.rs:11:18 | -LL | / || { +LL | #[coroutine] || { + | __________________^ LL | | yield a; LL | | yield b; LL | | }; diff --git a/tests/ui/coroutine/yield-while-iterating.rs b/tests/ui/coroutine/yield-while-iterating.rs index 66ac6d3922a9..77f601e4f2c5 100644 --- a/tests/ui/coroutine/yield-while-iterating.rs +++ b/tests/ui/coroutine/yield-while-iterating.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::ops::{CoroutineState, Coroutine}; use std::cell::Cell; @@ -9,7 +9,7 @@ fn yield_during_iter_owned_data(x: Vec) { // reference to it. This winds up becoming a rather confusing // regionck error -- in particular, we would freeze with the // reference in scope, and it doesn't live long enough. - let _b = move || { + let _b =#[coroutine] move || { for p in &x { //~ ERROR yield(); } @@ -17,7 +17,7 @@ fn yield_during_iter_owned_data(x: Vec) { } fn yield_during_iter_borrowed_slice(x: &[i32]) { - let _b = move || { + let _b = #[coroutine] move || { for p in x { yield(); } @@ -26,7 +26,7 @@ fn yield_during_iter_borrowed_slice(x: &[i32]) { fn yield_during_iter_borrowed_slice_2() { let mut x = vec![22_i32]; - let _b = || { + let _b = #[coroutine] || { for p in &x { yield(); } @@ -38,7 +38,7 @@ fn yield_during_iter_borrowed_slice_3() { // OK to take a mutable ref to `x` and yield // up pointers from it: let mut x = vec![22_i32]; - let mut b = || { + let mut b = #[coroutine] || { for p in &mut x { yield p; } @@ -50,7 +50,7 @@ fn yield_during_iter_borrowed_slice_4() { // ...but not OK to do that while reading // from `x` too let mut x = vec![22_i32]; - let mut b = || { + let mut b = #[coroutine] || { for p in &mut x { yield p; } @@ -61,7 +61,7 @@ fn yield_during_iter_borrowed_slice_4() { fn yield_during_range_iter() { // Should be OK. - let mut b = || { + let mut b = #[coroutine] || { let v = vec![1,2,3]; let len = v.len(); for i in 0..len { diff --git a/tests/ui/coroutine/yield-while-iterating.stderr b/tests/ui/coroutine/yield-while-iterating.stderr index 5330121f3728..f81c914c4bd4 100644 --- a/tests/ui/coroutine/yield-while-iterating.stderr +++ b/tests/ui/coroutine/yield-while-iterating.stderr @@ -9,8 +9,8 @@ LL | yield(); error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable --> $DIR/yield-while-iterating.rs:58:20 | -LL | let mut b = || { - | -- mutable borrow occurs here +LL | let mut b = #[coroutine] || { + | -- mutable borrow occurs here LL | for p in &mut x { | - first borrow occurs due to use of `x` in coroutine ... diff --git a/tests/ui/coroutine/yield-while-local-borrowed.rs b/tests/ui/coroutine/yield-while-local-borrowed.rs index 7f8d1d4543d8..3db30c36712f 100644 --- a/tests/ui/coroutine/yield-while-local-borrowed.rs +++ b/tests/ui/coroutine/yield-while-local-borrowed.rs @@ -1,4 +1,4 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::cell::Cell; use std::ops::{Coroutine, CoroutineState}; @@ -9,7 +9,7 @@ fn borrow_local_inline() { // // (This error occurs because the region shows up in the type of // `b` and gets extended by region inference.) - let mut b = move || { + let mut b = #[coroutine] move || { let a = &mut 3; //~^ ERROR borrow may still be in use when coroutine yields yield (); @@ -20,7 +20,7 @@ fn borrow_local_inline() { fn borrow_local_inline_done() { // No error here -- `a` is not in scope at the point of `yield`. - let mut b = move || { + let mut b = #[coroutine] move || { { let a = &mut 3; } @@ -34,7 +34,7 @@ fn borrow_local() { // // (This error occurs because the region shows up in the type of // `b` and gets extended by region inference.) - let mut b = move || { + let mut b = #[coroutine] move || { let a = 3; { let b = &a; diff --git a/tests/ui/coroutine/yield-while-ref-reborrowed.rs b/tests/ui/coroutine/yield-while-ref-reborrowed.rs index 07c591758586..2600d0b4124b 100644 --- a/tests/ui/coroutine/yield-while-ref-reborrowed.rs +++ b/tests/ui/coroutine/yield-while-ref-reborrowed.rs @@ -1,15 +1,16 @@ -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] -use std::ops::{CoroutineState, Coroutine}; use std::cell::Cell; +use std::ops::{Coroutine, CoroutineState}; use std::pin::Pin; fn reborrow_shared_ref(x: &i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the coroutine. - let mut b = move || { + let mut b = #[coroutine] + move || { let a = &*x; - yield(); + yield (); println!("{}", a); }; Pin::new(&mut b).resume(()); @@ -18,9 +19,10 @@ fn reborrow_shared_ref(x: &i32) { fn reborrow_mutable_ref(x: &mut i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the coroutine. - let mut b = move || { + let mut b = #[coroutine] + move || { let a = &mut *x; - yield(); + yield (); println!("{}", a); }; Pin::new(&mut b).resume(()); @@ -28,13 +30,14 @@ fn reborrow_mutable_ref(x: &mut i32) { fn reborrow_mutable_ref_2(x: &mut i32) { // ...but not OK to go on using `x`. - let mut b = || { + let mut b = #[coroutine] + || { let a = &mut *x; - yield(); + yield (); println!("{}", a); }; println!("{}", x); //~ ERROR Pin::new(&mut b).resume(()); } -fn main() { } +fn main() {} diff --git a/tests/ui/coroutine/yield-while-ref-reborrowed.stderr b/tests/ui/coroutine/yield-while-ref-reborrowed.stderr index 62ac02653112..7c9b766457db 100644 --- a/tests/ui/coroutine/yield-while-ref-reborrowed.stderr +++ b/tests/ui/coroutine/yield-while-ref-reborrowed.stderr @@ -1,8 +1,8 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/yield-while-ref-reborrowed.rs:36:20 + --> $DIR/yield-while-ref-reborrowed.rs:39:20 | -LL | let mut b = || { - | -- coroutine construction occurs here +LL | || { + | -- coroutine construction occurs here LL | let a = &mut *x; | -- first borrow occurs due to use of `x` in coroutine ... diff --git a/tests/ui/delegation/auxiliary/fn-header-aux.rs b/tests/ui/delegation/auxiliary/fn-header-aux.rs new file mode 100644 index 000000000000..d26209a4f789 --- /dev/null +++ b/tests/ui/delegation/auxiliary/fn-header-aux.rs @@ -0,0 +1,9 @@ +//@ edition:2018 + +#![feature(c_variadic)] + +pub unsafe fn unsafe_fn_extern() {} +pub extern "C" fn extern_fn_extern() {} +pub unsafe extern "C" fn variadic_fn_extern(n: usize, mut args: ...) {} +pub const fn const_fn_extern() {} +pub async fn async_fn_extern() {} diff --git a/tests/ui/delegation/fn-header.rs b/tests/ui/delegation/fn-header.rs new file mode 100644 index 000000000000..db20e1058e06 --- /dev/null +++ b/tests/ui/delegation/fn-header.rs @@ -0,0 +1,57 @@ +//@ check-pass +//@ edition:2018 +//@ aux-crate:fn_header_aux=fn-header-aux.rs + +#![feature(c_variadic)] +#![feature(fn_delegation)] +#![allow(incomplete_features)] +#![deny(unused_unsafe)] + +mod to_reuse { + pub unsafe fn unsafe_fn() {} + pub extern "C" fn extern_fn() {} + pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} + pub const fn const_fn() {} + pub async fn async_fn() {} +} + +reuse to_reuse::unsafe_fn; +reuse to_reuse::extern_fn; +reuse to_reuse::variadic_fn; +reuse to_reuse::const_fn; +reuse to_reuse::async_fn; + +reuse fn_header_aux::unsafe_fn_extern; +reuse fn_header_aux::extern_fn_extern; +reuse fn_header_aux::variadic_fn_extern; +reuse fn_header_aux::const_fn_extern; +reuse fn_header_aux::async_fn_extern; + +const fn const_check() { + const_fn(); + const_fn_extern(); +} + +async fn async_check() { + async_fn().await; + async_fn_extern().await; +} + +fn main() { + unsafe { + unsafe_fn(); + unsafe_fn_extern(); + } + extern_fn(); + extern_fn_extern(); + let _: extern "C" fn() = extern_fn; + let _: extern "C" fn() = extern_fn_extern; + unsafe { + variadic_fn(0); + variadic_fn(0, 1); + variadic_fn_extern(0); + variadic_fn_extern(0, 1); + } + let _: unsafe extern "C" fn(usize, ...) = variadic_fn; + let _: unsafe extern "C" fn(usize, ...) = variadic_fn_extern; +} diff --git a/tests/ui/delegation/impl-trait.rs b/tests/ui/delegation/impl-trait.rs new file mode 100644 index 000000000000..13df0155485c --- /dev/null +++ b/tests/ui/delegation/impl-trait.rs @@ -0,0 +1,27 @@ +//@ check-pass + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub fn foo() -> impl Clone { 0 } +} + +reuse to_reuse::foo; + +trait Trait { + fn bar() -> impl Clone { 1 } +} + +struct S; +impl Trait for S {} + +impl S { + reuse to_reuse::foo; + reuse ::bar; +} + +fn main() { + foo().clone(); + ::bar().clone(); +} diff --git a/tests/ui/delegation/not-supported.rs b/tests/ui/delegation/not-supported.rs index 9dccb12b57ad..5f78de97638b 100644 --- a/tests/ui/delegation/not-supported.rs +++ b/tests/ui/delegation/not-supported.rs @@ -14,9 +14,9 @@ mod generics { fn foo3<'a: 'a>(_: &'a u32) {} reuse GenericTrait::bar; - //~^ delegation with early bound generics is not supported yet + //~^ ERROR delegation with early bound generics is not supported yet reuse GenericTrait::bar1; - //~^ delegation with early bound generics is not supported yet + //~^ ERROR delegation with early bound generics is not supported yet } struct F; @@ -73,26 +73,18 @@ mod opaque { } reuse to_reuse::opaque_arg; //~^ ERROR delegation with early bound generics is not supported yet - reuse to_reuse::opaque_ret; - //~^ ERROR delegation to a function with opaque type is not supported yet -} -mod fn_header { - mod to_reuse { - pub unsafe fn unsafe_fn() {} - pub extern "C" fn extern_fn() {} - pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} - pub const fn const_fn() {} + trait ToReuse { + fn opaque_ret() -> impl Trait { unimplemented!() } } - reuse to_reuse::unsafe_fn; - //~^ ERROR delegation to unsafe functions is not supported yet - reuse to_reuse::extern_fn; - //~^ ERROR delegation to non Rust ABI functions is not supported yet - reuse to_reuse::variadic_fn; - //~^ ERROR delegation to variadic functions is not supported yet - reuse to_reuse::const_fn; - //~^ ERROR delegation to const functions is not supported yet + // FIXME: Inherited `impl Trait`s create query cycles when used inside trait impls. + impl ToReuse for u8 { + reuse to_reuse::opaque_ret; //~ ERROR cycle detected when computing type + } + impl ToReuse for u16 { + reuse ToReuse::opaque_ret; //~ ERROR cycle detected when computing type + } } mod recursive { diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr index f6c49366899c..e2cb04f977b1 100644 --- a/tests/ui/delegation/not-supported.stderr +++ b/tests/ui/delegation/not-supported.stderr @@ -115,53 +115,46 @@ LL | pub fn opaque_arg(_: impl Trait) -> i32 { 0 } LL | reuse to_reuse::opaque_arg; | ^^^^^^^^^^ -error: delegation to a function with opaque type is not supported yet - --> $DIR/not-supported.rs:76:21 +error[E0391]: cycle detected when computing type of `opaque::::{synthetic#0}` + --> $DIR/not-supported.rs:83:25 | -LL | pub fn opaque_ret() -> impl Trait { unimplemented!() } - | --------------------------------- callee defined here -... -LL | reuse to_reuse::opaque_ret; - | ^^^^^^^^^^ +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ + | +note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... + --> $DIR/not-supported.rs:83:25 + | +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ + = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle +note: cycle used when checking that `opaque::` is well-formed + --> $DIR/not-supported.rs:82:5 + | +LL | impl ToReuse for u8 { + | ^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: delegation to unsafe functions is not supported yet - --> $DIR/not-supported.rs:88:21 +error[E0391]: cycle detected when computing type of `opaque::::{synthetic#0}` + --> $DIR/not-supported.rs:86:24 | -LL | pub unsafe fn unsafe_fn() {} - | ------------------------- callee defined here -... -LL | reuse to_reuse::unsafe_fn; - | ^^^^^^^^^ - -error: delegation to non Rust ABI functions is not supported yet - --> $DIR/not-supported.rs:90:21 +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ | -LL | pub extern "C" fn extern_fn() {} - | ----------------------------- callee defined here -... -LL | reuse to_reuse::extern_fn; - | ^^^^^^^^^ - -error: delegation to variadic functions is not supported yet - --> $DIR/not-supported.rs:92:21 +note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... + --> $DIR/not-supported.rs:86:24 | -LL | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} - | ------------------------------------------------------------- callee defined here -... -LL | reuse to_reuse::variadic_fn; - | ^^^^^^^^^^^ - -error: delegation to const functions is not supported yet - --> $DIR/not-supported.rs:94:21 +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ + = note: ...which again requires computing type of `opaque::::{synthetic#0}`, completing the cycle +note: cycle used when checking that `opaque::` is well-formed + --> $DIR/not-supported.rs:85:5 | -LL | pub const fn const_fn() {} - | ----------------------- callee defined here -... -LL | reuse to_reuse::const_fn; - | ^^^^^^^^ +LL | impl ToReuse for u16 { + | ^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: recursive delegation is not supported yet - --> $DIR/not-supported.rs:107:22 + --> $DIR/not-supported.rs:99:22 | LL | pub reuse to_reuse2::foo; | --- callee defined here @@ -169,7 +162,7 @@ LL | pub reuse to_reuse2::foo; LL | reuse to_reuse1::foo; | ^^^ -error: aborting due to 19 previous errors +error: aborting due to 16 previous errors -Some errors have detailed explanations: E0049, E0195. +Some errors have detailed explanations: E0049, E0195, E0391. For more information about an error, try `rustc --explain E0049`. diff --git a/tests/ui/delegation/rename.rs b/tests/ui/delegation/rename.rs new file mode 100644 index 000000000000..f4b3da76c56c --- /dev/null +++ b/tests/ui/delegation/rename.rs @@ -0,0 +1,20 @@ +//@ check-pass + +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub fn a() {} +} + +reuse to_reuse::a as b; + +struct S; +impl S { + reuse to_reuse::a as b; +} + +fn main() { + b(); + S::b(); +} diff --git a/tests/ui/derives/deriving-with-repr-packed.stderr b/tests/ui/derives/deriving-with-repr-packed.stderr index 26ac532263fd..a8523d25cab9 100644 --- a/tests/ui/derives/deriving-with-repr-packed.stderr +++ b/tests/ui/derives/deriving-with-repr-packed.stderr @@ -40,7 +40,10 @@ note: if `Y` implemented `Clone`, you could clone the value --> $DIR/deriving-with-repr-packed.rs:16:1 | LL | struct Y(usize); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | struct X(Y); + | - you could clone this value = note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/drop/dynamic-drop.rs b/tests/ui/drop/dynamic-drop.rs index f848a1a340b2..b695b5702d94 100644 --- a/tests/ui/drop/dynamic-drop.rs +++ b/tests/ui/drop/dynamic-drop.rs @@ -1,7 +1,7 @@ //@ run-pass //@ needs-unwind -#![feature(coroutines, coroutine_trait)] +#![feature(coroutines, coroutine_trait, stmt_expr_attributes)] #![feature(if_let_guard)] #![allow(unused_assignments)] @@ -176,7 +176,7 @@ fn vec_simple(a: &Allocator) { fn coroutine(a: &Allocator, run_count: usize) { assert!(run_count < 4); - let mut gen = || { + let mut gen = #[coroutine] || { (a.alloc(), yield a.alloc(), a.alloc(), diff --git a/tests/ui/error-codes/E0504.stderr b/tests/ui/error-codes/E0504.stderr index 900cb706bd97..343bca9a72e2 100644 --- a/tests/ui/error-codes/E0504.stderr +++ b/tests/ui/error-codes/E0504.stderr @@ -18,7 +18,10 @@ note: if `FancyNum` implemented `Clone`, you could clone the value --> $DIR/E0504.rs:1:1 | LL | struct FancyNum { - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let fancy_ref = &fancy_num; + | ---------- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0505.stderr b/tests/ui/error-codes/E0505.stderr index ce01298a70d9..266df9ea32a7 100644 --- a/tests/ui/error-codes/E0505.stderr +++ b/tests/ui/error-codes/E0505.stderr @@ -15,7 +15,10 @@ note: if `Value` implemented `Clone`, you could clone the value --> $DIR/E0505.rs:1:1 | LL | struct Value {} - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _ref_to_val: &Value = &x; + | -- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0507.stderr b/tests/ui/error-codes/E0507.stderr index 60a4daa9d382..70d99ea2cce5 100644 --- a/tests/ui/error-codes/E0507.stderr +++ b/tests/ui/error-codes/E0507.stderr @@ -15,7 +15,10 @@ note: if `TheDarkKnight` implemented `Clone`, you could clone the value --> $DIR/E0507.rs:3:1 | LL | struct TheDarkKnight; - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | x.borrow().nothing_is_true(); + | ---------- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0508-fail.stderr b/tests/ui/error-codes/E0508-fail.stderr index 96d3bcb67a57..fcfac399e0df 100644 --- a/tests/ui/error-codes/E0508-fail.stderr +++ b/tests/ui/error-codes/E0508-fail.stderr @@ -11,7 +11,10 @@ note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/E0508-fail.rs:1:1 | LL | struct NonCopy; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _value = array[0]; + | -------- you could clone this value help: consider borrowing here | LL | let _value = &array[0]; diff --git a/tests/ui/error-codes/E0508.stderr b/tests/ui/error-codes/E0508.stderr index c1b622e24321..b9fa0f4d17a5 100644 --- a/tests/ui/error-codes/E0508.stderr +++ b/tests/ui/error-codes/E0508.stderr @@ -11,7 +11,10 @@ note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/E0508.rs:1:1 | LL | struct NonCopy; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _value = array[0]; + | -------- you could clone this value help: consider borrowing here | LL | let _value = &array[0]; diff --git a/tests/ui/error-codes/E0509.stderr b/tests/ui/error-codes/E0509.stderr index 75c372d04401..628a253e0859 100644 --- a/tests/ui/error-codes/E0509.stderr +++ b/tests/ui/error-codes/E0509.stderr @@ -11,7 +11,10 @@ note: if `FancyNum` implemented `Clone`, you could clone the value --> $DIR/E0509.rs:1:1 | LL | struct FancyNum { - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let fancy_field = drop_struct.fancy; + | ----------------- you could clone this value help: consider borrowing here | LL | let fancy_field = &drop_struct.fancy; diff --git a/tests/ui/feature-gates/feature-gate-closure_track_caller.rs b/tests/ui/feature-gates/feature-gate-closure_track_caller.rs index 93bf83ecf53c..d90fb765a237 100644 --- a/tests/ui/feature-gates/feature-gate-closure_track_caller.rs +++ b/tests/ui/feature-gates/feature-gate-closure_track_caller.rs @@ -4,6 +4,6 @@ fn main() { let _closure = #[track_caller] || {}; //~ `#[track_caller]` on closures - let _coroutine = #[track_caller] || { yield; }; //~ `#[track_caller]` on closures + let _coroutine = #[coroutine] #[track_caller] || { yield; }; //~ `#[track_caller]` on closures let _future = #[track_caller] async {}; //~ `#[track_caller]` on closures } diff --git a/tests/ui/feature-gates/feature-gate-closure_track_caller.stderr b/tests/ui/feature-gates/feature-gate-closure_track_caller.stderr index 17b5e6016a46..0b12b73fd1ff 100644 --- a/tests/ui/feature-gates/feature-gate-closure_track_caller.stderr +++ b/tests/ui/feature-gates/feature-gate-closure_track_caller.stderr @@ -9,10 +9,10 @@ LL | let _closure = #[track_caller] || {}; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `#[track_caller]` on closures is currently unstable - --> $DIR/feature-gate-closure_track_caller.rs:7:22 + --> $DIR/feature-gate-closure_track_caller.rs:7:35 | -LL | let _coroutine = #[track_caller] || { yield; }; - | ^^^^^^^^^^^^^^^ +LL | let _coroutine = #[coroutine] #[track_caller] || { yield; }; + | ^^^^^^^^^^^^^^^ | = note: see issue #87417 for more information = help: add `#![feature(closure_track_caller)]` to the crate attributes to enable diff --git a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr index 1cef163cef5c..3bb48e4a37a4 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr +++ b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr @@ -8,8 +8,19 @@ LL | yield true; = help: add `#![feature(coroutines)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/feature-gate-coroutines.rs:5:5 + | +LL | yield true; + | ^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] fn main() { + | ++++++++++++ + error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:9:16 + --> $DIR/feature-gate-coroutines.rs:10:16 | LL | let _ = || yield true; | ^^^^^^^^^^ @@ -18,13 +29,24 @@ LL | let _ = || yield true; = help: add `#![feature(coroutines)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/feature-gate-coroutines.rs:10:16 + | +LL | let _ = || yield true; + | ^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | let _ = #[coroutine] || yield true; + | ++++++++++++ + error[E0627]: yield expression outside of coroutine literal --> $DIR/feature-gate-coroutines.rs:5:5 | LL | yield true; | ^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0627, E0658. For more information about an error, try `rustc --explain E0627`. diff --git a/tests/ui/feature-gates/feature-gate-coroutines.none.stderr b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr index 403f0549aef2..65e7737ef84d 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.none.stderr +++ b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr @@ -9,7 +9,7 @@ LL | yield true; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:9:16 + --> $DIR/feature-gate-coroutines.rs:10:16 | LL | let _ = || yield true; | ^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | let _ = || yield true; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:16:5 + --> $DIR/feature-gate-coroutines.rs:18:5 | LL | yield; | ^^^^^ @@ -29,7 +29,7 @@ LL | yield; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:17:5 + --> $DIR/feature-gate-coroutines.rs:19:5 | LL | yield 0; | ^^^^^^^ @@ -49,8 +49,19 @@ LL | yield true; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/feature-gate-coroutines.rs:5:5 + | +LL | yield true; + | ^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | #[coroutine] fn main() { + | ++++++++++++ + error[E0658]: yield syntax is experimental - --> $DIR/feature-gate-coroutines.rs:9:16 + --> $DIR/feature-gate-coroutines.rs:10:16 | LL | let _ = || yield true; | ^^^^^^^^^^ @@ -60,13 +71,24 @@ LL | let _ = || yield true; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks + --> $DIR/feature-gate-coroutines.rs:10:16 + | +LL | let _ = || yield true; + | ^^^^^^^^^^ + | +help: use `#[coroutine]` to make this closure a coroutine + | +LL | let _ = #[coroutine] || yield true; + | ++++++++++++ + error[E0627]: yield expression outside of coroutine literal --> $DIR/feature-gate-coroutines.rs:5:5 | LL | yield true; | ^^^^^^^^^^ -error: aborting due to 7 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0627, E0658. For more information about an error, try `rustc --explain E0627`. diff --git a/tests/ui/feature-gates/feature-gate-coroutines.rs b/tests/ui/feature-gates/feature-gate-coroutines.rs index b3df2351b680..28dce8596d39 100644 --- a/tests/ui/feature-gates/feature-gate-coroutines.rs +++ b/tests/ui/feature-gates/feature-gate-coroutines.rs @@ -5,9 +5,11 @@ fn main() { yield true; //~ ERROR yield syntax is experimental //~^ ERROR yield expression outside of coroutine literal //[none]~^^ ERROR yield syntax is experimental + //~^^^ ERROR `yield` can only be used let _ = || yield true; //~ ERROR yield syntax is experimental //[none]~^ ERROR yield syntax is experimental + //~^^ ERROR `yield` can only be used } #[cfg(FALSE)] diff --git a/tests/ui/feature-gates/feature-gate-inline_const.rs b/tests/ui/feature-gates/feature-gate-inline_const.rs deleted file mode 100644 index 43ff90d234cb..000000000000 --- a/tests/ui/feature-gates/feature-gate-inline_const.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let _ = const { - //~^ ERROR inline-const is experimental [E0658] - true - }; -} diff --git a/tests/ui/feature-gates/feature-gate-inline_const.stderr b/tests/ui/feature-gates/feature-gate-inline_const.stderr deleted file mode 100644 index 6cf675065f34..000000000000 --- a/tests/ui/feature-gates/feature-gate-inline_const.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: inline-const is experimental - --> $DIR/feature-gate-inline_const.rs:2:13 - | -LL | let _ = const { - | ^^^^^ - | - = note: see issue #76001 for more information - = help: add `#![feature(inline_const)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/fn/fn_def_coercion.rs b/tests/ui/fn/fn_def_coercion.rs new file mode 100644 index 000000000000..313be6f28cdc --- /dev/null +++ b/tests/ui/fn/fn_def_coercion.rs @@ -0,0 +1,58 @@ +//! Test that coercing between function items of the same function, +//! but with different generic args succeeds in typeck, but then fails +//! in borrowck when the lifetimes can't actually be merged. + +fn foo(t: T) -> T { + t +} + +fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + let mut x = foo::<&'a ()>; //~ ERROR: lifetime may not live long enough + x = foo::<&'b ()>; //~ ERROR: lifetime may not live long enough + x = foo::<&'c ()>; + x(a); + x(b); + x(c); +} + +fn g<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + let x = foo::<&'c ()>; + let _: &'c () = x(a); //~ ERROR lifetime may not live long enough +} + +fn h<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + let x = foo::<&'a ()>; + let _: &'a () = x(c); +} + +fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + let mut x = foo::<&'c ()>; + x = foo::<&'b ()>; //~ ERROR lifetime may not live long enough + x = foo::<&'a ()>; //~ ERROR lifetime may not live long enough + x(a); + x(b); + x(c); +} + +fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + let x = match true { + true => foo::<&'b ()>, //~ ERROR lifetime may not live long enough + false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough + }; + x(a); + x(b); + x(c); +} + +fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + let x = match true { + true => foo::<&'c ()>, + false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough + }; + + x(a); + x(b); //~ ERROR lifetime may not live long enough + x(c); +} + +fn main() {} diff --git a/tests/ui/fn/fn_def_coercion.stderr b/tests/ui/fn/fn_def_coercion.stderr new file mode 100644 index 000000000000..ec4a1bde7fd6 --- /dev/null +++ b/tests/ui/fn/fn_def_coercion.stderr @@ -0,0 +1,154 @@ +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:10:17 + | +LL | fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let mut x = foo::<&'a ()>; + | ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:11:5 + | +LL | fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let mut x = foo::<&'a ()>; +LL | x = foo::<&'b ()>; + | ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:20:12 + | +LL | fn g<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'a` defined here +LL | let x = foo::<&'c ()>; +LL | let _: &'c () = x(a); + | ^^^^^^ type annotation requires that `'a` must outlive `'c` + | + = help: consider adding the following bound: `'a: 'c` + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:30:5 + | +LL | fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let mut x = foo::<&'c ()>; +LL | x = foo::<&'b ()>; + | ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:31:5 + | +LL | fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x = foo::<&'a ()>; + | ^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:39:17 + | +LL | fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | let x = match true { +LL | true => foo::<&'b ()>, + | ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:40:18 + | +LL | fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | false => foo::<&'a ()>, + | ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:50:18 + | +LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'a` defined here +... +LL | false => foo::<&'a ()>, + | ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'c` + | + = help: consider adding the following bound: `'a: 'c` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/fn_def_coercion.rs:54:5 + | +LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | x(b); + | ^^^^ argument requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + +help: the following changes may resolve your lifetime errors + | + = help: add bound `'a: 'c` + = help: add bound `'b: 'a` + +error: aborting due to 9 previous errors + diff --git a/tests/ui/fn/fn_def_opaque_coercion.rs b/tests/ui/fn/fn_def_opaque_coercion.rs new file mode 100644 index 000000000000..0a8810cf4f8a --- /dev/null +++ b/tests/ui/fn/fn_def_opaque_coercion.rs @@ -0,0 +1,69 @@ +//! Test that coercing between function items of the same function, +//! but with different generic args works. + +//@check-pass + +#![feature(type_alias_impl_trait)] + +fn foo(t: T) -> T { + t +} + +type F = impl Sized; + +fn f(a: F) { + let mut x = foo::; + x = foo::<()>; + x(a); + x(()); +} + +type G = impl Sized; + +fn g(a: G) { + let x = foo::<()>; + let _: () = x(a); +} + +type H = impl Sized; + +fn h(a: H) { + let x = foo::; + let _: H = x(()); +} + +type I = impl Sized; + +fn i(a: I) { + let mut x = foo::<()>; + x = foo::; + x(a); + x(()); +} + +type J = impl Sized; + +fn j(a: J) { + let x = match true { + true => foo::, + false => foo::<()>, + }; + x(a); + x(()); +} + +fn k() -> impl Sized { + fn bind T>(_: T, f: F) -> F { + f + } + let x = match true { + true => { + let f = foo; + bind(k(), f) + } + false => foo::<()>, + }; + todo!() +} + +fn main() {} diff --git a/tests/ui/fn/suggest-return-closure.rs b/tests/ui/fn/suggest-return-closure.rs index 81f202728679..30e25ca8edcc 100644 --- a/tests/ui/fn/suggest-return-closure.rs +++ b/tests/ui/fn/suggest-return-closure.rs @@ -18,6 +18,7 @@ fn fn_mut() -> _ { //~| NOTE for more information on `Fn` traits and closure types let x = String::new(); //~^ HELP: consider changing this to be mutable + //~| NOTE binding `x` declared here |c| { //~ NOTE: value captured here x.push(c); //~^ ERROR: does not live long enough diff --git a/tests/ui/fn/suggest-return-closure.stderr b/tests/ui/fn/suggest-return-closure.stderr index 8e80a11fe1b0..d276ce8be2ba 100644 --- a/tests/ui/fn/suggest-return-closure.stderr +++ b/tests/ui/fn/suggest-return-closure.stderr @@ -21,7 +21,7 @@ LL | fn fn_mut() -> _ { = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types - --> $DIR/suggest-return-closure.rs:31:13 + --> $DIR/suggest-return-closure.rs:32:13 | LL | fn fun() -> _ { | ^ @@ -32,7 +32,7 @@ LL | fn fun() -> _ { = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable - --> $DIR/suggest-return-closure.rs:22:9 + --> $DIR/suggest-return-closure.rs:23:9 | LL | let x = String::new(); | - help: consider changing this to be mutable: `mut x` @@ -41,8 +41,11 @@ LL | x.push(c); | ^ cannot borrow as mutable error[E0597]: `x` does not live long enough - --> $DIR/suggest-return-closure.rs:22:9 + --> $DIR/suggest-return-closure.rs:23:9 | +LL | let x = String::new(); + | - binding `x` declared here +... LL | |c| { | --- value captured here LL | x.push(c); diff --git a/tests/ui/impl-trait/issues/issue-58504.rs b/tests/ui/impl-trait/issues/issue-58504.rs index 4f7a35e81b80..856e1297e58b 100644 --- a/tests/ui/impl-trait/issues/issue-58504.rs +++ b/tests/ui/impl-trait/issues/issue-58504.rs @@ -3,7 +3,7 @@ use std::ops::Coroutine; fn mk_gen() -> impl Coroutine { - || { loop { yield; } } + #[coroutine] || { loop { yield; } } } fn main() { diff --git a/tests/ui/impl-trait/lifetimes.rs b/tests/ui/impl-trait/lifetimes.rs index 93a4801fa40e..df64b685eab8 100644 --- a/tests/ui/impl-trait/lifetimes.rs +++ b/tests/ui/impl-trait/lifetimes.rs @@ -115,7 +115,7 @@ impl<'unnecessary_lifetime> MyVec { } fn coroutine_doesnt_capture_unnecessary_lifetime<'s: 's>() -> impl Sized { - || yield + #[coroutine] || yield } } diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs index ccd073b80709..422c2e439cf0 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.rs +++ b/tests/ui/impl-trait/normalize-tait-in-const.rs @@ -3,7 +3,6 @@ #![feature(type_alias_impl_trait)] #![feature(const_trait_impl)] #![feature(const_refs_to_cell)] -#![feature(inline_const)] use std::marker::Destruct; diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index 7ae8306d74d5..fbd41b61730e 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -1,11 +1,11 @@ error: `~const` can only be applied to `#[const_trait]` traits - --> $DIR/normalize-tait-in-const.rs:25:42 + --> $DIR/normalize-tait-in-const.rs:24:42 | LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { | ^^^^^^^^^^^^^^^^^ error[E0015]: cannot call non-const closure in constant functions - --> $DIR/normalize-tait-in-const.rs:26:5 + --> $DIR/normalize-tait-in-const.rs:25:5 | LL | fun(filter_positive()); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL + #![feature(effects)] | error[E0493]: destructor of `F` cannot be evaluated at compile-time - --> $DIR/normalize-tait-in-const.rs:25:79 + --> $DIR/normalize-tait-in-const.rs:24:79 | LL | const fn with_positive Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { | ^^^ the destructor for this type cannot be evaluated in constant functions diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr index c0b399746eaf..96db2030a405 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/recursive-coroutine-boxed.rs:14:23 + --> $DIR/recursive-coroutine-boxed.rs:15:23 | LL | let mut gen = Box::pin(foo()); | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` @@ -13,7 +13,7 @@ LL | let mut gen = Box::::pin(foo()); | +++++ error[E0308]: mismatched types - --> $DIR/recursive-coroutine-boxed.rs:13:5 + --> $DIR/recursive-coroutine-boxed.rs:14:18 | LL | fn foo() -> impl Coroutine { | --------------------------------------- @@ -21,7 +21,8 @@ LL | fn foo() -> impl Coroutine { | the expected opaque type | expected `impl Coroutine` because of return type ... -LL | / || { +LL | #[coroutine] || { + | __________________^ LL | | let mut gen = Box::pin(foo()); LL | | LL | | let mut r = gen.as_mut().resume(()); @@ -31,7 +32,7 @@ LL | | } | |_____^ types differ | = note: expected opaque type `impl Coroutine` - found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:13:5: 13:7}` + found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:14:18: 14:20}` error: aborting due to 2 previous errors diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index 02c75be0f3aa..24a77d731141 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -10,7 +10,8 @@ fn foo() -> impl Coroutine { // FIXME(-Znext-solver): this fails with a mismatched types as the // hidden type of the opaque ends up as {type error}. We should not // emit errors for such goals. - || { //[next]~ ERROR mismatched types + + #[coroutine] || { //[next]~ ERROR mismatched types let mut gen = Box::pin(foo()); //[next]~^ ERROR type annotations needed let mut r = gen.as_mut().resume(()); diff --git a/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr b/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr index ee87c483d0d0..9814187e179e 100644 --- a/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-indirect.current.stderr @@ -1,8 +1,8 @@ error[E0733]: recursion in a coroutine requires boxing - --> $DIR/recursive-coroutine-indirect.rs:11:5 + --> $DIR/recursive-coroutine-indirect.rs:11:18 | -LL | move || { - | ^^^^^^^ +LL | #[coroutine] move || { + | ^^^^^^^ LL | let x = coroutine_hold(); | - recursive call here diff --git a/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr b/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr index ee87c483d0d0..9814187e179e 100644 --- a/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr +++ b/tests/ui/impl-trait/recursive-coroutine-indirect.next.stderr @@ -1,8 +1,8 @@ error[E0733]: recursion in a coroutine requires boxing - --> $DIR/recursive-coroutine-indirect.rs:11:5 + --> $DIR/recursive-coroutine-indirect.rs:11:18 | -LL | move || { - | ^^^^^^^ +LL | #[coroutine] move || { + | ^^^^^^^ LL | let x = coroutine_hold(); | - recursive call here diff --git a/tests/ui/impl-trait/recursive-coroutine-indirect.rs b/tests/ui/impl-trait/recursive-coroutine-indirect.rs index bba9792fe3cf..cec2176049b8 100644 --- a/tests/ui/impl-trait/recursive-coroutine-indirect.rs +++ b/tests/ui/impl-trait/recursive-coroutine-indirect.rs @@ -8,7 +8,7 @@ #![feature(coroutines)] #![allow(unconditional_recursion)] fn coroutine_hold() -> impl Sized { - move || { //~ ERROR recursion in a coroutine requires boxing + #[coroutine] move || { //~ ERROR recursion in a coroutine requires boxing let x = coroutine_hold(); yield; x; diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs index 432f80a1763e..8b9dac0e29b0 100644 --- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs +++ b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs @@ -57,6 +57,8 @@ fn coroutine_sig() -> impl Sized { fn coroutine_capture() -> impl Sized { //~^ ERROR let x = coroutine_capture(); + + #[coroutine] move || { yield; x; diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr index d5b8c531fd6e..2d2731e4368f 100644 --- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr +++ b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr @@ -98,10 +98,10 @@ LL | | yield; LL | | x; | | - coroutine captures itself here LL | | } - | |_____- returning here with type `{coroutine@$DIR/recursive-impl-trait-type-indirect.rs:60:5: 60:12}` + | |_____- returning here with type `{coroutine@$DIR/recursive-impl-trait-type-indirect.rs:62:5: 62:12}` error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-indirect.rs:66:35 + --> $DIR/recursive-impl-trait-type-indirect.rs:68:35 | LL | fn substs_change() -> impl Sized { | ^^^^^^^^^^ recursive opaque type @@ -110,7 +110,7 @@ LL | (substs_change::<&T>(),) | ------------------------ returning here with type `(impl Sized,)` error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-indirect.rs:76:26 + --> $DIR/recursive-impl-trait-type-indirect.rs:78:26 | LL | fn mutual_recursion() -> impl Sync { | ^^^^^^^^^ recursive opaque type @@ -122,7 +122,7 @@ LL | fn mutual_recursion_b() -> impl Sized { | ---------- returning this opaque type `impl Sized` error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-indirect.rs:81:28 + --> $DIR/recursive-impl-trait-type-indirect.rs:83:28 | LL | fn mutual_recursion() -> impl Sync { | --------- returning this opaque type `impl Sync` diff --git a/tests/ui/inline-const/const-expr-array-init.rs b/tests/ui/inline-const/const-expr-array-init.rs index 075c27c1cc92..eb126b61f2df 100644 --- a/tests/ui/inline-const/const-expr-array-init.rs +++ b/tests/ui/inline-const/const-expr-array-init.rs @@ -1,7 +1,5 @@ //@ build-pass -#![feature(inline_const)] - use std::cell::Cell; fn main() { diff --git a/tests/ui/inline-const/const-expr-basic.rs b/tests/ui/inline-const/const-expr-basic.rs index 6a19cc656d02..7f769d2b5c33 100644 --- a/tests/ui/inline-const/const-expr-basic.rs +++ b/tests/ui/inline-const/const-expr-basic.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(inline_const)] - fn foo() -> i32 { const { let x = 5 + 10; diff --git a/tests/ui/inline-const/const-expr-generic-err.rs b/tests/ui/inline-const/const-expr-generic-err.rs index 3c4bbcb3dc9a..3249e826a96b 100644 --- a/tests/ui/inline-const/const-expr-generic-err.rs +++ b/tests/ui/inline-const/const-expr-generic-err.rs @@ -1,5 +1,4 @@ //@ build-fail -#![feature(inline_const)] fn foo() { const { assert!(std::mem::size_of::() == 0); } //~ ERROR E0080 diff --git a/tests/ui/inline-const/const-expr-generic-err.stderr b/tests/ui/inline-const/const-expr-generic-err.stderr index 7331c7f18e97..dcd6b62bbfc1 100644 --- a/tests/ui/inline-const/const-expr-generic-err.stderr +++ b/tests/ui/inline-const/const-expr-generic-err.stderr @@ -1,37 +1,37 @@ error[E0080]: evaluation of `foo::::{constant#0}` failed - --> $DIR/const-expr-generic-err.rs:5:13 + --> $DIR/const-expr-generic-err.rs:4:13 | LL | const { assert!(std::mem::size_of::() == 0); } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::() == 0', $DIR/const-expr-generic-err.rs:5:13 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::() == 0', $DIR/const-expr-generic-err.rs:4:13 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/const-expr-generic-err.rs:5:5 + --> $DIR/const-expr-generic-err.rs:4:5 | LL | const { assert!(std::mem::size_of::() == 0); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn foo::` - --> $DIR/const-expr-generic-err.rs:13:5 + --> $DIR/const-expr-generic-err.rs:12:5 | LL | foo::(); | ^^^^^^^^^^^^ error[E0080]: evaluation of `bar::<0>::{constant#0}` failed - --> $DIR/const-expr-generic-err.rs:9:13 + --> $DIR/const-expr-generic-err.rs:8:13 | LL | const { N - 1 } | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow note: erroneous constant encountered - --> $DIR/const-expr-generic-err.rs:9:5 + --> $DIR/const-expr-generic-err.rs:8:5 | LL | const { N - 1 } | ^^^^^^^^^^^^^^^ note: erroneous constant encountered - --> $DIR/const-expr-generic-err.rs:9:5 + --> $DIR/const-expr-generic-err.rs:8:5 | LL | const { N - 1 } | ^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | const { N - 1 } = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn bar::<0>` - --> $DIR/const-expr-generic-err.rs:14:5 + --> $DIR/const-expr-generic-err.rs:13:5 | LL | bar::<0>(); | ^^^^^^^^^^ diff --git a/tests/ui/inline-const/const-expr-generic-err2.rs b/tests/ui/inline-const/const-expr-generic-err2.rs index e097cbe9dd6d..49cbdbfda5da 100644 --- a/tests/ui/inline-const/const-expr-generic-err2.rs +++ b/tests/ui/inline-const/const-expr-generic-err2.rs @@ -1,5 +1,3 @@ -#![feature(inline_const)] - fn foo() { let _ = [0u8; const { std::mem::size_of::() }]; //~^ ERROR: constant expression depends on a generic parameter diff --git a/tests/ui/inline-const/const-expr-generic-err2.stderr b/tests/ui/inline-const/const-expr-generic-err2.stderr index 5876a6c9e198..c6d77593c46f 100644 --- a/tests/ui/inline-const/const-expr-generic-err2.stderr +++ b/tests/ui/inline-const/const-expr-generic-err2.stderr @@ -1,5 +1,5 @@ error: constant expression depends on a generic parameter - --> $DIR/const-expr-generic-err2.rs:4:19 + --> $DIR/const-expr-generic-err2.rs:2:19 | LL | let _ = [0u8; const { std::mem::size_of::() }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/inline-const/const-expr-generic.rs b/tests/ui/inline-const/const-expr-generic.rs index e634e1d4a47f..0c33b02d3a2e 100644 --- a/tests/ui/inline-const/const-expr-generic.rs +++ b/tests/ui/inline-const/const-expr-generic.rs @@ -1,5 +1,4 @@ //@ check-pass -#![feature(inline_const)] fn foo() -> usize { const { std::mem::size_of::() } diff --git a/tests/ui/inline-const/const-expr-inference.rs b/tests/ui/inline-const/const-expr-inference.rs index f3b97d3430ef..99cea3204a19 100644 --- a/tests/ui/inline-const/const-expr-inference.rs +++ b/tests/ui/inline-const/const-expr-inference.rs @@ -1,7 +1,5 @@ //@ check-pass -#![feature(inline_const)] - pub fn todo() -> T { const { todo!() } } diff --git a/tests/ui/inline-const/const-expr-lifetime-err.rs b/tests/ui/inline-const/const-expr-lifetime-err.rs index 0a032a7338ad..df1e5fcb4735 100644 --- a/tests/ui/inline-const/const-expr-lifetime-err.rs +++ b/tests/ui/inline-const/const-expr-lifetime-err.rs @@ -1,5 +1,4 @@ #![feature(const_mut_refs)] -#![feature(inline_const)] use std::marker::PhantomData; diff --git a/tests/ui/inline-const/const-expr-lifetime-err.stderr b/tests/ui/inline-const/const-expr-lifetime-err.stderr index 75877bc093a7..f97e2d25e6c2 100644 --- a/tests/ui/inline-const/const-expr-lifetime-err.stderr +++ b/tests/ui/inline-const/const-expr-lifetime-err.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/const-expr-lifetime-err.rs:23:30 + --> $DIR/const-expr-lifetime-err.rs:22:30 | LL | fn foo<'a>() { | -- lifetime `'a` defined here diff --git a/tests/ui/inline-const/const-expr-lifetime.rs b/tests/ui/inline-const/const-expr-lifetime.rs index 5dac17645d7a..071e724a0faa 100644 --- a/tests/ui/inline-const/const-expr-lifetime.rs +++ b/tests/ui/inline-const/const-expr-lifetime.rs @@ -1,7 +1,6 @@ //@ run-pass #![feature(const_mut_refs)] -#![feature(inline_const)] use std::marker::PhantomData; diff --git a/tests/ui/inline-const/const-expr-macro.rs b/tests/ui/inline-const/const-expr-macro.rs index bf3cb3c3320f..cf07eb12f5a9 100644 --- a/tests/ui/inline-const/const-expr-macro.rs +++ b/tests/ui/inline-const/const-expr-macro.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(inline_const)] - macro_rules! do_const_block{ ($val:block) => { const $val } } diff --git a/tests/ui/inline-const/const-expr-reference.rs b/tests/ui/inline-const/const-expr-reference.rs index b3753b0d371a..208271e37c31 100644 --- a/tests/ui/inline-const/const-expr-reference.rs +++ b/tests/ui/inline-const/const-expr-reference.rs @@ -1,7 +1,5 @@ //@ run-pass -#![feature(inline_const)] - const fn bar() -> i32 { const { 2 + 3 diff --git a/tests/ui/inline-const/const-match-pat-lifetime.rs b/tests/ui/inline-const/const-match-pat-lifetime.rs index f909e68e7be5..590c426c7737 100644 --- a/tests/ui/inline-const/const-match-pat-lifetime.rs +++ b/tests/ui/inline-const/const-match-pat-lifetime.rs @@ -1,7 +1,6 @@ //@ run-pass #![feature(const_mut_refs)] -#![feature(inline_const)] #![feature(inline_const_pat)] use std::marker::PhantomData; diff --git a/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs b/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs index a1c3c61484ae..e0a889ac3471 100644 --- a/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs +++ b/tests/ui/inline-const/elided-lifetime-being-infer-vars.rs @@ -1,7 +1,5 @@ //@ check-pass -#![feature(inline_const)] - fn main() { let _my_usize = const { let a = 10_usize; diff --git a/tests/ui/inline-const/expr-unsafe-err.rs b/tests/ui/inline-const/expr-unsafe-err.rs index a05a29451683..d53d84b944f0 100644 --- a/tests/ui/inline-const/expr-unsafe-err.rs +++ b/tests/ui/inline-const/expr-unsafe-err.rs @@ -1,4 +1,3 @@ -#![feature(inline_const)] const unsafe fn require_unsafe() -> usize { 1 } diff --git a/tests/ui/inline-const/expr-unsafe-err.stderr b/tests/ui/inline-const/expr-unsafe-err.stderr index 45f850d1f99b..13a408b971c8 100644 --- a/tests/ui/inline-const/expr-unsafe-err.stderr +++ b/tests/ui/inline-const/expr-unsafe-err.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block - --> $DIR/expr-unsafe-err.rs:8:9 + --> $DIR/expr-unsafe-err.rs:7:9 | LL | require_unsafe(); | ^^^^^^^^^^^^^^^^ call to unsafe function diff --git a/tests/ui/inline-const/expr-unsafe.rs b/tests/ui/inline-const/expr-unsafe.rs index f9d1450503e2..cdd101f3e088 100644 --- a/tests/ui/inline-const/expr-unsafe.rs +++ b/tests/ui/inline-const/expr-unsafe.rs @@ -1,7 +1,7 @@ //@ check-pass #![warn(unused_unsafe)] -#![feature(inline_const)] + const unsafe fn require_unsafe() -> usize { 1 } fn main() { diff --git a/tests/ui/inline-const/expr-with-block-err.rs b/tests/ui/inline-const/expr-with-block-err.rs index f7547742ddcb..6f8507575588 100644 --- a/tests/ui/inline-const/expr-with-block-err.rs +++ b/tests/ui/inline-const/expr-with-block-err.rs @@ -1,5 +1,3 @@ -#![feature(inline_const)] - fn main() { const { 2 } - const { 1 }; //~^ ERROR mismatched types diff --git a/tests/ui/inline-const/expr-with-block-err.stderr b/tests/ui/inline-const/expr-with-block-err.stderr index a46d73950458..f127c11e9b7a 100644 --- a/tests/ui/inline-const/expr-with-block-err.stderr +++ b/tests/ui/inline-const/expr-with-block-err.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/expr-with-block-err.rs:4:13 + --> $DIR/expr-with-block-err.rs:2:13 | LL | const { 2 } - const { 1 }; | ^ expected `()`, found integer diff --git a/tests/ui/inline-const/expr-with-block.rs b/tests/ui/inline-const/expr-with-block.rs index 07a1c9a10f5c..a32afbcffadd 100644 --- a/tests/ui/inline-const/expr-with-block.rs +++ b/tests/ui/inline-const/expr-with-block.rs @@ -1,5 +1,5 @@ //@ check-pass -#![feature(inline_const)] + fn main() { match true { true => const {} diff --git a/tests/ui/inline-const/instance-doesnt-depend-on-type.rs b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs index e69106a43af4..c53aab60b06f 100644 --- a/tests/ui/inline-const/instance-doesnt-depend-on-type.rs +++ b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs @@ -1,8 +1,6 @@ //@ check-pass // issue: 114660 -#![feature(inline_const)] - fn main() { const { core::mem::transmute:: }; // Don't resolve the instance of this inline constant to be an intrinsic, diff --git a/tests/ui/inline-const/interpolated.rs b/tests/ui/inline-const/interpolated.rs index 582900e7aa01..38ed2a042e09 100644 --- a/tests/ui/inline-const/interpolated.rs +++ b/tests/ui/inline-const/interpolated.rs @@ -1,7 +1,5 @@ //@ check-pass -#![feature(inline_const)] - // This used to be unsupported since the parser first tries to check if we have // any nested items, and then checks for statements (and expressions). The heuristic // that we were using to detect the beginning of a const item was incorrect, so diff --git a/tests/ui/inline-const/promotion.rs b/tests/ui/inline-const/promotion.rs index 242959c6b516..2cfb8a0d19fc 100644 --- a/tests/ui/inline-const/promotion.rs +++ b/tests/ui/inline-const/promotion.rs @@ -1,4 +1,3 @@ -#![feature(inline_const)] #![allow(arithmetic_overflow, unconditional_panic)] // The only way to have promoteds that fail is in `const fn` called from `const`/`static`. diff --git a/tests/ui/inline-const/promotion.stderr b/tests/ui/inline-const/promotion.stderr index 7f06b97818bf..4e914c9e0872 100644 --- a/tests/ui/inline-const/promotion.stderr +++ b/tests/ui/inline-const/promotion.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/promotion.rs:17:37 + --> $DIR/promotion.rs:16:37 | LL | let _x: &'static i32 = &div_by_zero(); | ------------ ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use diff --git a/tests/ui/inline-const/required-const.rs b/tests/ui/inline-const/required-const.rs index 3de0ab2a0c06..8f640e933d01 100644 --- a/tests/ui/inline-const/required-const.rs +++ b/tests/ui/inline-const/required-const.rs @@ -1,6 +1,5 @@ //@ build-fail //@ compile-flags: -Zmir-opt-level=3 -#![feature(inline_const)] fn foo() { if false { diff --git a/tests/ui/inline-const/required-const.stderr b/tests/ui/inline-const/required-const.stderr index 2a13d18547c5..6ca4c250223e 100644 --- a/tests/ui/inline-const/required-const.stderr +++ b/tests/ui/inline-const/required-const.stderr @@ -1,13 +1,13 @@ error[E0080]: evaluation of `foo::::{constant#0}` failed - --> $DIR/required-const.rs:7:17 + --> $DIR/required-const.rs:6:17 | LL | const { panic!() } - | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/required-const.rs:7:17 + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/required-const.rs:6:17 | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered - --> $DIR/required-const.rs:7:9 + --> $DIR/required-const.rs:6:9 | LL | const { panic!() } | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/invalid-compile-flags/print.rs b/tests/ui/invalid-compile-flags/print.rs new file mode 100644 index 000000000000..0d0a9d22750d --- /dev/null +++ b/tests/ui/invalid-compile-flags/print.rs @@ -0,0 +1 @@ +//@ compile-flags: --print yyyy diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/invalid-compile-flags/print.stderr new file mode 100644 index 000000000000..0a032aabdfe8 --- /dev/null +++ b/tests/ui/invalid-compile-flags/print.stderr @@ -0,0 +1,4 @@ +error: unknown print request: `yyyy` + | + = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` + diff --git a/tests/ui/issues/issue-17385.stderr b/tests/ui/issues/issue-17385.stderr index 988db0fb1fc4..3c451a859e94 100644 --- a/tests/ui/issues/issue-17385.stderr +++ b/tests/ui/issues/issue-17385.stderr @@ -12,7 +12,10 @@ note: if `X` implemented `Clone`, you could clone the value --> $DIR/issue-17385.rs:1:1 | LL | struct X(isize); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | drop(foo); + | --- you could clone this value error[E0382]: use of moved value: `e` --> $DIR/issue-17385.rs:25:11 @@ -28,7 +31,10 @@ note: if `Enum` implemented `Clone`, you could clone the value --> $DIR/issue-17385.rs:3:1 | LL | enum Enum { - | ^^^^^^^^^ + | ^^^^^^^^^ consider implementing `Clone` for this type +... +LL | drop(e); + | - you could clone this value error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-24357.rs b/tests/ui/issues/issue-24357.rs index d1a9e37251ee..63c061594d87 100644 --- a/tests/ui/issues/issue-24357.rs +++ b/tests/ui/issues/issue-24357.rs @@ -1,10 +1,12 @@ struct NoCopy; //~ NOTE if `NoCopy` implemented `Clone`, you could clone the value +//~^ NOTE consider implementing `Clone` for this type fn main() { let x = NoCopy; //~^ NOTE move occurs because `x` has type `NoCopy` let f = move || { let y = x; }; //~^ NOTE value moved into closure here //~| NOTE variable moved due to use in closure + //~| NOTE you could clone this value let z = x; //~^ ERROR use of moved value: `x` //~| NOTE value used here after move diff --git a/tests/ui/issues/issue-24357.stderr b/tests/ui/issues/issue-24357.stderr index 6d50eea7e21a..2d85077fe4c2 100644 --- a/tests/ui/issues/issue-24357.stderr +++ b/tests/ui/issues/issue-24357.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/issue-24357.rs:8:12 + --> $DIR/issue-24357.rs:10:12 | LL | let x = NoCopy; | - move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait @@ -16,7 +16,10 @@ note: if `NoCopy` implemented `Clone`, you could clone the value --> $DIR/issue-24357.rs:1:1 | LL | struct NoCopy; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let f = move || { let y = x; }; + | - you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-4335.stderr b/tests/ui/issues/issue-4335.stderr index 8b4aff54dc3c..14b5cfa9f9ac 100644 --- a/tests/ui/issues/issue-4335.stderr +++ b/tests/ui/issues/issue-4335.stderr @@ -7,6 +7,14 @@ LL | id(Box::new(|| *v)) | -- ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait | | | captured by this `FnMut` closure + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/issue-4335.rs:5:10 + | +LL | fn f<'r, T>(v: &'r T) -> Box T + 'r> { + | ^ consider constraining this type parameter with `Clone` +LL | id(Box::new(|| *v)) + | -- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs index a2461cff9326..3bc87b9d480b 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.rs +++ b/tests/ui/lifetimes/unusual-rib-combinations.rs @@ -1,5 +1,3 @@ -#![feature(inline_const)] - struct S<'a>(&'a u8); fn foo() {} diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 320e64a2f774..2857fc72ea14 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -1,11 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/unusual-rib-combinations.rs:24:15 + --> $DIR/unusual-rib-combinations.rs:22:15 | LL | fn d() {} | ^ expected named lifetime parameter error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/unusual-rib-combinations.rs:29:22 + --> $DIR/unusual-rib-combinations.rs:27:22 | LL | struct Bar Foo<'a>)>; | ^^ the type must not depend on the parameter `'a` @@ -13,25 +13,25 @@ LL | struct Bar Foo<'a>)>; = note: lifetime parameters may not be used in the type of const parameters error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:7:16 + --> $DIR/unusual-rib-combinations.rs:5:16 | LL | fn a() -> [u8; foo::()] { | ^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:14:15 + --> $DIR/unusual-rib-combinations.rs:12:15 | LL | fn b() {} | ^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:18:10 + --> $DIR/unusual-rib-combinations.rs:16:10 | LL | fn c() {} | ^^^^ only `Fn` traits may use parentheses error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/unusual-rib-combinations.rs:18:6 + --> $DIR/unusual-rib-combinations.rs:16:6 | LL | fn c() {} | ^^^^^^^^ @@ -41,7 +41,7 @@ LL | fn c() {} = note: `#[deny(invalid_type_param_default)]` on by default error[E0308]: mismatched types - --> $DIR/unusual-rib-combinations.rs:7:16 + --> $DIR/unusual-rib-combinations.rs:5:16 | LL | fn a() -> [u8; foo::()] { | ^^^^^^^ expected `usize`, found fn item @@ -50,7 +50,7 @@ LL | fn a() -> [u8; foo::()] { found fn item `fn() {foo}` error: `S<'_>` is forbidden as the type of a const generic parameter - --> $DIR/unusual-rib-combinations.rs:24:15 + --> $DIR/unusual-rib-combinations.rs:22:15 | LL | fn d() {} | ^ diff --git a/tests/ui/lint/invalid_from_utf8.rs b/tests/ui/lint/invalid_from_utf8.rs index e87afe9094ca..2d1822a54ac3 100644 --- a/tests/ui/lint/invalid_from_utf8.rs +++ b/tests/ui/lint/invalid_from_utf8.rs @@ -1,6 +1,5 @@ //@ check-pass -#![feature(inline_const)] #![feature(concat_bytes)] #![warn(invalid_from_utf8_unchecked)] diff --git a/tests/ui/lint/invalid_from_utf8.stderr b/tests/ui/lint/invalid_from_utf8.stderr index 884165d4f123..07616e118010 100644 --- a/tests/ui/lint/invalid_from_utf8.stderr +++ b/tests/ui/lint/invalid_from_utf8.stderr @@ -1,5 +1,5 @@ warning: calls to `std::str::from_utf8_unchecked_mut` with a invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:21:9 + --> $DIR/invalid_from_utf8.rs:20:9 | LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -7,13 +7,13 @@ LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112 | the literal was valid UTF-8 up to the 2 bytes | note: the lint level is defined here - --> $DIR/invalid_from_utf8.rs:6:9 + --> $DIR/invalid_from_utf8.rs:5:9 | LL | #![warn(invalid_from_utf8_unchecked)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8_unchecked_mut` with a invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:23:9 + --> $DIR/invalid_from_utf8.rs:22:9 | LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -21,7 +21,7 @@ LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:41:9 + --> $DIR/invalid_from_utf8.rs:40:9 | LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -29,7 +29,7 @@ LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:43:9 + --> $DIR/invalid_from_utf8.rs:42:9 | LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -37,7 +37,7 @@ LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b' | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:45:9 + --> $DIR/invalid_from_utf8.rs:44:9 | LL | std::str::from_utf8_unchecked(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^ @@ -45,7 +45,7 @@ LL | std::str::from_utf8_unchecked(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_unchecked` with a invalid literal are undefined behavior - --> $DIR/invalid_from_utf8.rs:47:9 + --> $DIR/invalid_from_utf8.rs:46:9 | LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -53,7 +53,7 @@ LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:64:9 + --> $DIR/invalid_from_utf8.rs:63:9 | LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -61,13 +61,13 @@ LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes | note: the lint level is defined here - --> $DIR/invalid_from_utf8.rs:7:9 + --> $DIR/invalid_from_utf8.rs:6:9 | LL | #![warn(invalid_from_utf8)] | ^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8_mut` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:66:9 + --> $DIR/invalid_from_utf8.rs:65:9 | LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -75,7 +75,7 @@ LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p' | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:84:9 + --> $DIR/invalid_from_utf8.rs:83:9 | LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | ^^^^^^^^^^^^^^^^^^^^^----------------------------------^ @@ -83,7 +83,7 @@ LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:86:9 + --> $DIR/invalid_from_utf8.rs:85:9 | LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']); | ^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^ @@ -91,7 +91,7 @@ LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']) | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:88:9 + --> $DIR/invalid_from_utf8.rs:87:9 | LL | std::str::from_utf8(b"cl\x82ippy"); | ^^^^^^^^^^^^^^^^^^^^-------------^ @@ -99,7 +99,7 @@ LL | std::str::from_utf8(b"cl\x82ippy"); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:90:9 + --> $DIR/invalid_from_utf8.rs:89:9 | LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | ^^^^^^^^^^^^^^^^^^^^---------------------------------^ @@ -107,7 +107,7 @@ LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy")); | the literal was valid UTF-8 up to the 2 bytes warning: calls to `std::str::from_utf8_mut` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:97:5 + --> $DIR/invalid_from_utf8.rs:96:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -115,7 +115,7 @@ LL | std::str::from_utf8_mut(&mut a); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8_mut` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:101:5 + --> $DIR/invalid_from_utf8.rs:100:5 | LL | let mut a = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -124,7 +124,7 @@ LL | std::str::from_utf8_mut(c); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:104:5 + --> $DIR/invalid_from_utf8.rs:103:5 | LL | let mut c = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -132,7 +132,7 @@ LL | std::str::from_utf8(c); | ^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:107:5 + --> $DIR/invalid_from_utf8.rs:106:5 | LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -140,7 +140,7 @@ LL | std::str::from_utf8(&INVALID_1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:110:5 + --> $DIR/invalid_from_utf8.rs:109:5 | LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -148,7 +148,7 @@ LL | std::str::from_utf8(&INVALID_2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:113:5 + --> $DIR/invalid_from_utf8.rs:112:5 | LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121]; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes @@ -156,7 +156,7 @@ LL | std::str::from_utf8(INVALID_3); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: calls to `std::str::from_utf8` with a invalid literal always return an error - --> $DIR/invalid_from_utf8.rs:116:5 + --> $DIR/invalid_from_utf8.rs:115:5 | LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] }; | ---------------------------------- the literal was valid UTF-8 up to the 2 bytes diff --git a/tests/ui/lint/must_not_suspend/tuple-mismatch.rs b/tests/ui/lint/must_not_suspend/tuple-mismatch.rs index 2f3c5d9ea294..ec409925d724 100644 --- a/tests/ui/lint/must_not_suspend/tuple-mismatch.rs +++ b/tests/ui/lint/must_not_suspend/tuple-mismatch.rs @@ -1,7 +1,8 @@ -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] fn main() { - let _coroutine = || { + let _coroutine = #[coroutine] + || { yield ((), ((), ())); yield ((), ()); //~^ ERROR mismatched types diff --git a/tests/ui/lint/must_not_suspend/tuple-mismatch.stderr b/tests/ui/lint/must_not_suspend/tuple-mismatch.stderr index 3adf26cfee22..102eadd7affd 100644 --- a/tests/ui/lint/must_not_suspend/tuple-mismatch.stderr +++ b/tests/ui/lint/must_not_suspend/tuple-mismatch.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/tuple-mismatch.rs:6:20 + --> $DIR/tuple-mismatch.rs:7:20 | LL | yield ((), ()); | ^^ expected `((), ())`, found `()` diff --git a/tests/ui/lint/non-local-defs/consts.rs b/tests/ui/lint/non-local-defs/consts.rs index 2652447dcf59..d8a497e43e50 100644 --- a/tests/ui/lint/non-local-defs/consts.rs +++ b/tests/ui/lint/non-local-defs/consts.rs @@ -2,8 +2,6 @@ //@ edition:2021 //@ rustc-env:CARGO_CRATE_NAME=non_local_def -#![feature(inline_const)] - struct Test; trait Uto {} diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 5563ea9d93f0..d15b452b004e 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:15:5 + --> $DIR/consts.rs:13:5 | LL | const Z: () = { | - help: use a const-anon item to suppress this lint: `_` @@ -14,7 +14,7 @@ LL | impl Uto for &Test {} = note: `#[warn(non_local_definitions)]` on by default warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:26:5 + --> $DIR/consts.rs:24:5 | LL | impl Uto2 for Test {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | impl Uto2 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:34:5 + --> $DIR/consts.rs:32:5 | LL | impl Uto3 for Test {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | impl Uto3 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:45:5 + --> $DIR/consts.rs:43:5 | LL | / impl Test { LL | | @@ -50,7 +50,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:52:9 + --> $DIR/consts.rs:50:9 | LL | / impl Test { LL | | @@ -64,7 +64,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:61:9 + --> $DIR/consts.rs:59:9 | LL | / impl Test { LL | | @@ -78,7 +78,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:74:9 + --> $DIR/consts.rs:72:9 | LL | impl Uto9 for Test {} | ^^^^^^^^^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | impl Uto9 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/consts.rs:81:9 + --> $DIR/consts.rs:79:9 | LL | impl Uto10 for Test {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.rs b/tests/ui/lint/non-local-defs/from-local-for-global.rs index 0ab3a6b19887..fea9679d7375 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.rs +++ b/tests/ui/lint/non-local-defs/from-local-for-global.rs @@ -1,8 +1,6 @@ //@ check-pass //@ edition:2021 -#![feature(inline_const)] - struct Cat; struct Wrap(T); diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr index bd592a721572..0cd385049aa6 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr +++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/from-local-for-global.rs:10:5 + --> $DIR/from-local-for-global.rs:8:5 | LL | / impl From for () { LL | | @@ -16,7 +16,7 @@ LL | | } = note: `#[warn(non_local_definitions)]` on by default warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/from-local-for-global.rs:20:5 + --> $DIR/from-local-for-global.rs:18:5 | LL | / impl From>> for () { LL | | @@ -32,7 +32,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/from-local-for-global.rs:34:5 + --> $DIR/from-local-for-global.rs:32:5 | LL | impl StillNonLocal for &Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | impl StillNonLocal for &Foo {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/from-local-for-global.rs:42:5 + --> $DIR/from-local-for-global.rs:40:5 | LL | / impl From for GlobalSameFunction { LL | | @@ -59,7 +59,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, they should be avoided as they go against expectation - --> $DIR/from-local-for-global.rs:50:5 + --> $DIR/from-local-for-global.rs:48:5 | LL | / impl From for GlobalSameFunction { LL | | diff --git a/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs b/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs index c5dd281cb4e5..12e2bcb898ca 100644 --- a/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs +++ b/tests/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs @@ -1,12 +1,12 @@ #![feature(coroutine_trait)] -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![deny(unused_braces, unused_parens)] use std::ops::Coroutine; use std::pin::Pin; fn main() { - let mut x = |_| { + let mut x = #[coroutine] |_| { while let Some(_) = (yield) {} while let Some(_) = {yield} {} diff --git a/tests/ui/lint/unused/unused-closure.rs b/tests/ui/lint/unused/unused-closure.rs index 9106edee6538..4633038cc9bb 100644 --- a/tests/ui/lint/unused/unused-closure.rs +++ b/tests/ui/lint/unused/unused-closure.rs @@ -2,7 +2,7 @@ //@ edition:2018 #![feature(async_closure)] -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![deny(unused_must_use)] fn unused() { @@ -26,7 +26,7 @@ fn unused() { fn ignored() { let _ = || {}; - let _ = || yield 42; + let _ = #[coroutine] || yield 42; } fn main() { diff --git a/tests/ui/liveness/liveness-upvars.rs b/tests/ui/liveness/liveness-upvars.rs index 7898b9788823..f76efba3e6b3 100644 --- a/tests/ui/liveness/liveness-upvars.rs +++ b/tests/ui/liveness/liveness-upvars.rs @@ -1,6 +1,6 @@ //@ edition:2018 //@ check-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![warn(unused)] #![allow(unreachable_code)] @@ -131,7 +131,7 @@ pub fn async_coroutine() { pub fn coroutine() { let mut s: u32 = 0; - let _ = |_| { + let _ = #[coroutine] |_| { s = 0; yield (); s = 1; //~ WARN value assigned to `s` is never read diff --git a/tests/ui/loops/dont-suggest-break-thru-item.rs b/tests/ui/loops/dont-suggest-break-thru-item.rs index 34a9a57bfed0..b4262ec02bf4 100644 --- a/tests/ui/loops/dont-suggest-break-thru-item.rs +++ b/tests/ui/loops/dont-suggest-break-thru-item.rs @@ -1,7 +1,5 @@ //@ edition:2021 -#![feature(inline_const)] - fn closure() { loop { let closure = || { diff --git a/tests/ui/loops/dont-suggest-break-thru-item.stderr b/tests/ui/loops/dont-suggest-break-thru-item.stderr index c84a98198f55..642578ade60b 100644 --- a/tests/ui/loops/dont-suggest-break-thru-item.stderr +++ b/tests/ui/loops/dont-suggest-break-thru-item.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dont-suggest-break-thru-item.rs:9:17 + --> $DIR/dont-suggest-break-thru-item.rs:7:17 | LL | / if true { LL | | Err(1) @@ -17,7 +17,7 @@ LL | return Err(1); | ++++++ + error[E0308]: mismatched types - --> $DIR/dont-suggest-break-thru-item.rs:23:17 + --> $DIR/dont-suggest-break-thru-item.rs:21:17 | LL | / if true { LL | | Err(1) @@ -35,7 +35,7 @@ LL | return Err(1); | ++++++ + error[E0308]: mismatched types - --> $DIR/dont-suggest-break-thru-item.rs:37:17 + --> $DIR/dont-suggest-break-thru-item.rs:35:17 | LL | / if true { LL | | Err(1) @@ -48,7 +48,7 @@ LL | | } found enum `Result<_, {integer}>` error[E0308]: mismatched types - --> $DIR/dont-suggest-break-thru-item.rs:49:17 + --> $DIR/dont-suggest-break-thru-item.rs:47:17 | LL | / if true { LL | | Err(1) diff --git a/tests/ui/mir/issue-102389.stderr b/tests/ui/mir/issue-102389.stderr index 838eaffb5a0d..162d7ac031a6 100644 --- a/tests/ui/mir/issue-102389.stderr +++ b/tests/ui/mir/issue-102389.stderr @@ -8,7 +8,10 @@ note: if `Enum` implemented `Clone`, you could clone the value --> $DIR/issue-102389.rs:1:1 | LL | enum Enum { A, B, C } - | ^^^^^^^^^ + | ^^^^^^^^^ consider implementing `Clone` for this type +... +LL | array[*inbounds as usize] + | --------- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/moves/borrow-closures-instead-of-move.rs b/tests/ui/moves/borrow-closures-instead-of-move.rs index 51771ced7f22..e4bca54e995f 100644 --- a/tests/ui/moves/borrow-closures-instead-of-move.rs +++ b/tests/ui/moves/borrow-closures-instead-of-move.rs @@ -1,4 +1,4 @@ -fn takes_fn(f: impl Fn()) { +fn takes_fn(f: impl Fn()) { //~ HELP if `impl Fn()` implemented `Clone` loop { takes_fnonce(f); //~^ ERROR use of moved value @@ -6,7 +6,7 @@ fn takes_fn(f: impl Fn()) { } } -fn takes_fn_mut(m: impl FnMut()) { +fn takes_fn_mut(m: impl FnMut()) { //~ HELP if `impl FnMut()` implemented `Clone` if maybe() { takes_fnonce(m); //~^ HELP consider mutably borrowing diff --git a/tests/ui/moves/borrow-closures-instead-of-move.stderr b/tests/ui/moves/borrow-closures-instead-of-move.stderr index 9a84ddef7e64..ab6ff417efb6 100644 --- a/tests/ui/moves/borrow-closures-instead-of-move.stderr +++ b/tests/ui/moves/borrow-closures-instead-of-move.stderr @@ -15,6 +15,14 @@ LL | fn takes_fnonce(_: impl FnOnce()) {} | ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value | | | in this function +help: if `impl Fn()` implemented `Clone`, you could clone the value + --> $DIR/borrow-closures-instead-of-move.rs:1:16 + | +LL | fn takes_fn(f: impl Fn()) { + | ^^^^^^^^^ consider constraining this type parameter with `Clone` +LL | loop { +LL | takes_fnonce(f); + | - you could clone this value help: consider borrowing `f` | LL | takes_fnonce(&f); @@ -39,6 +47,14 @@ LL | fn takes_fnonce(_: impl FnOnce()) {} | ------------ ^^^^^^^^^^^^^ this parameter takes ownership of the value | | | in this function +help: if `impl FnMut()` implemented `Clone`, you could clone the value + --> $DIR/borrow-closures-instead-of-move.rs:9:20 + | +LL | fn takes_fn_mut(m: impl FnMut()) { + | ^^^^^^^^^^^^ consider constraining this type parameter with `Clone` +LL | if maybe() { +LL | takes_fnonce(m); + | - you could clone this value help: consider mutably borrowing `m` | LL | takes_fnonce(&mut m); diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.rs b/tests/ui/moves/issue-72649-uninit-in-loop.rs index 86f389cb3af1..8f2e01bdf1ab 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.rs +++ b/tests/ui/moves/issue-72649-uninit-in-loop.rs @@ -7,6 +7,10 @@ struct NonCopy; //~| NOTE if `NonCopy` implemented `Clone` //~| NOTE if `NonCopy` implemented `Clone` //~| NOTE if `NonCopy` implemented `Clone` +//~| NOTE consider implementing `Clone` for this type +//~| NOTE consider implementing `Clone` for this type +//~| NOTE consider implementing `Clone` for this type +//~| NOTE consider implementing `Clone` for this type fn good() { loop { @@ -21,6 +25,7 @@ fn moved_here_1() { //~^ NOTE move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait let _used = value; //~^ NOTE value moved here + //~| NOTE you could clone this value let _used2 = value; //~ ERROR use of moved value: `value` //~^ NOTE value used here after move } @@ -32,6 +37,7 @@ fn moved_here_2() { loop { //~ NOTE inside of this loop let _used = value; //~^ NOTE value moved here + //~| NOTE you could clone this value loop { let _used2 = value; //~ ERROR use of moved value: `value` //~^ NOTE value used here after move @@ -45,6 +51,7 @@ fn moved_loop_1() { loop { //~ NOTE inside of this loop let _used = value; //~ ERROR use of moved value: `value` //~^ NOTE value moved here, in previous iteration of loop + //~| NOTE you could clone this value } } @@ -56,6 +63,7 @@ fn moved_loop_2() { loop { //~ NOTE inside of this loop let _used2 = value; //~ ERROR use of moved value: `value` //~^ NOTE value moved here, in previous iteration of loop + //~| NOTE you could clone this value } } diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.stderr b/tests/ui/moves/issue-72649-uninit-in-loop.stderr index a613f35a35e0..3a93769ac454 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/tests/ui/moves/issue-72649-uninit-in-loop.stderr @@ -1,12 +1,12 @@ error[E0382]: use of moved value: `value` - --> $DIR/issue-72649-uninit-in-loop.rs:24:22 + --> $DIR/issue-72649-uninit-in-loop.rs:29:22 | LL | let value = NonCopy{}; | ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait LL | LL | let _used = value; | ----- value moved here -LL | +... LL | let _used2 = value; | ^^^^^ value used here after move | @@ -14,10 +14,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _used = value; + | ----- you could clone this value error[E0382]: use of moved value: `value` - --> $DIR/issue-72649-uninit-in-loop.rs:36:26 + --> $DIR/issue-72649-uninit-in-loop.rs:42:26 | LL | let value = NonCopy{}; | ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait @@ -34,10 +37,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _used = value; + | ----- you could clone this value error[E0382]: use of moved value: `value` - --> $DIR/issue-72649-uninit-in-loop.rs:46:21 + --> $DIR/issue-72649-uninit-in-loop.rs:52:21 | LL | let value = NonCopy{}; | ----- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait @@ -51,10 +57,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _used = value; + | ----- you could clone this value error[E0382]: use of moved value: `value` - --> $DIR/issue-72649-uninit-in-loop.rs:57:22 + --> $DIR/issue-72649-uninit-in-loop.rs:64:22 | LL | let mut value = NonCopy{}; | --------- move occurs because `value` has type `NonCopy`, which does not implement the `Copy` trait @@ -68,10 +77,13 @@ note: if `NonCopy` implemented `Clone`, you could clone the value --> $DIR/issue-72649-uninit-in-loop.rs:5:1 | LL | struct NonCopy; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _used2 = value; + | ----- you could clone this value error[E0381]: used binding `value` isn't initialized - --> $DIR/issue-72649-uninit-in-loop.rs:65:21 + --> $DIR/issue-72649-uninit-in-loop.rs:73:21 | LL | let value: NonCopy; | ----- binding declared here but left uninitialized @@ -84,7 +96,7 @@ LL | let value: NonCopy = /* value */; | +++++++++++++ error[E0381]: used binding `value` isn't initialized - --> $DIR/issue-72649-uninit-in-loop.rs:73:21 + --> $DIR/issue-72649-uninit-in-loop.rs:81:21 | LL | let mut value: NonCopy; | --------- binding declared here but left uninitialized diff --git a/tests/ui/moves/issue-75904-move-closure-loop.stderr b/tests/ui/moves/issue-75904-move-closure-loop.stderr index b6ad906bbdb0..815e91b0f4df 100644 --- a/tests/ui/moves/issue-75904-move-closure-loop.stderr +++ b/tests/ui/moves/issue-75904-move-closure-loop.stderr @@ -15,7 +15,10 @@ note: if `NotCopy` implemented `Clone`, you could clone the value --> $DIR/issue-75904-move-closure-loop.rs:5:1 | LL | struct NotCopy; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | a; + | - you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/moves/move-fn-self-receiver.stderr b/tests/ui/moves/move-fn-self-receiver.stderr index e6bf52276ac2..f2c6008d27ea 100644 --- a/tests/ui/moves/move-fn-self-receiver.stderr +++ b/tests/ui/moves/move-fn-self-receiver.stderr @@ -106,7 +106,10 @@ note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-fn-self-receiver.rs:5:1 | LL | struct Foo; - | ^^^^^^^^^^ + | ^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let ret = mut_foo.use_mut_self(); + | ------- you could clone this value error[E0382]: use of moved value: `rc_foo` --> $DIR/move-fn-self-receiver.rs:55:5 @@ -142,7 +145,10 @@ note: if `Foo` implemented `Clone`, you could clone the value --> $DIR/move-fn-self-receiver.rs:5:1 | LL | struct Foo; - | ^^^^^^^^^^ + | ^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | foo_add + Foo; + | ------- you could clone this value note: calling this operator moves the left-hand side --> $SRC_DIR/core/src/ops/arith.rs:LL:COL diff --git a/tests/ui/moves/move-out-of-array-1.stderr b/tests/ui/moves/move-out-of-array-1.stderr index 9e4a08e0cef5..8a030f021920 100644 --- a/tests/ui/moves/move-out-of-array-1.stderr +++ b/tests/ui/moves/move-out-of-array-1.stderr @@ -11,7 +11,10 @@ note: if `D` implemented `Clone`, you could clone the value --> $DIR/move-out-of-array-1.rs:5:1 | LL | struct D { _x: u8 } - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | a[i] + | ---- you could clone this value error: aborting due to 1 previous error diff --git a/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr b/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr index 4759b45892cc..a8473bb81983 100644 --- a/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr +++ b/tests/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr @@ -17,6 +17,13 @@ LL | let mut r = R {c: Box::new(f)}; LL | f(&mut r, false) | ^ value borrowed here after move | +help: if `F` implemented `Clone`, you could clone the value + --> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:30:16 + | +LL | fn conspirator(mut f: F) where F: FnMut(&mut R, bool) { + | ^ consider constraining this type parameter with `Clone` +LL | let mut r = R {c: Box::new(f)}; + | - you could clone this value help: consider mutably borrowing `f` | LL | let mut r = R {c: Box::new(&mut f)}; diff --git a/tests/ui/moves/use_of_moved_value_copy_suggestions.fixed b/tests/ui/moves/use_of_moved_value_copy_suggestions.fixed index e726c8145c3b..bfb855c7fb1f 100644 --- a/tests/ui/moves/use_of_moved_value_copy_suggestions.fixed +++ b/tests/ui/moves/use_of_moved_value_copy_suggestions.fixed @@ -3,6 +3,7 @@ fn duplicate_t(t: T) -> (T, T) { //~^ HELP consider restricting type parameter `T` + //~| HELP if `T` implemented `Clone`, you could clone the value (t, t) //~ use of moved value: `t` } @@ -72,10 +73,11 @@ where #[rustfmt::skip] fn existing_colon(t: T) { //~^ HELP consider restricting type parameter `T` + //~| HELP if `T` implemented `Clone`, you could clone the value [t, t]; //~ use of moved value: `t` } -fn existing_colon_in_where(t: T) +fn existing_colon_in_where(t: T) //~ HELP if `T` implemented `Clone`, you could clone the value where T:, T: Copy //~^ HELP consider further restricting type parameter `T` diff --git a/tests/ui/moves/use_of_moved_value_copy_suggestions.rs b/tests/ui/moves/use_of_moved_value_copy_suggestions.rs index ee08ce0fa5ba..fbe5a1d74c37 100644 --- a/tests/ui/moves/use_of_moved_value_copy_suggestions.rs +++ b/tests/ui/moves/use_of_moved_value_copy_suggestions.rs @@ -3,6 +3,7 @@ fn duplicate_t(t: T) -> (T, T) { //~^ HELP consider restricting type parameter `T` + //~| HELP if `T` implemented `Clone`, you could clone the value (t, t) //~ use of moved value: `t` } @@ -72,10 +73,11 @@ where #[rustfmt::skip] fn existing_colon(t: T) { //~^ HELP consider restricting type parameter `T` + //~| HELP if `T` implemented `Clone`, you could clone the value [t, t]; //~ use of moved value: `t` } -fn existing_colon_in_where(t: T) +fn existing_colon_in_where(t: T) //~ HELP if `T` implemented `Clone`, you could clone the value where T:, //~^ HELP consider further restricting type parameter `T` diff --git a/tests/ui/moves/use_of_moved_value_copy_suggestions.stderr b/tests/ui/moves/use_of_moved_value_copy_suggestions.stderr index 3e37fcb2141f..c03204c7b9f1 100644 --- a/tests/ui/moves/use_of_moved_value_copy_suggestions.stderr +++ b/tests/ui/moves/use_of_moved_value_copy_suggestions.stderr @@ -1,21 +1,29 @@ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:6:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:7:9 | LL | fn duplicate_t(t: T) -> (T, T) { | - move occurs because `t` has type `T`, which does not implement the `Copy` trait -LL | +... LL | (t, t) | - ^ value used here after move | | | value moved here | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/use_of_moved_value_copy_suggestions.rs:4:16 + | +LL | fn duplicate_t(t: T) -> (T, T) { + | ^ consider constraining this type parameter with `Clone` +... +LL | (t, t) + | - you could clone this value help: consider restricting type parameter `T` | LL | fn duplicate_t(t: T) -> (T, T) { | ++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:11:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:12:9 | LL | fn duplicate_opt(t: Option) -> (Option, Option) { | - move occurs because `t` has type `Option`, which does not implement the `Copy` trait @@ -31,7 +39,7 @@ LL | fn duplicate_opt(t: Option) -> (Option, Option) { | ++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:16:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:17:9 | LL | fn duplicate_tup1(t: (T,)) -> ((T,), (T,)) { | - move occurs because `t` has type `(T,)`, which does not implement the `Copy` trait @@ -47,7 +55,7 @@ LL | fn duplicate_tup1(t: (T,)) -> ((T,), (T,)) { | ++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:21:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:22:9 | LL | fn duplicate_tup2(t: (A, B)) -> ((A, B), (A, B)) { | - move occurs because `t` has type `(A, B)`, which does not implement the `Copy` trait @@ -63,7 +71,7 @@ LL | fn duplicate_tup2(t: (A, B)) -> ((A, B), (A, B)) { | ++++++ ++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:26:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:27:9 | LL | fn duplicate_custom(t: S) -> (S, S) { | - move occurs because `t` has type `S`, which does not implement the `Copy` trait @@ -79,7 +87,7 @@ LL | fn duplicate_custom(t: S) -> (S, S) { | ++++++++++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:44:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:45:9 | LL | fn duplicate_custom_1(t: S) -> (S, S) where { | - move occurs because `t` has type `S`, which does not implement the `Copy` trait @@ -95,7 +103,7 @@ LL | fn duplicate_custom_1(t: S) -> (S, S) where { | ++++++++++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:52:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:53:9 | LL | fn duplicate_custom_2(t: S) -> (S, S) | - move occurs because `t` has type `S`, which does not implement the `Copy` trait @@ -111,7 +119,7 @@ LL | T: A + Copy + Trait, | ++++++++++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:61:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:62:9 | LL | fn duplicate_custom_3(t: S) -> (S, S) | - move occurs because `t` has type `S`, which does not implement the `Copy` trait @@ -127,7 +135,7 @@ LL | T: A + Copy + Trait, | ++++++++++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:69:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:70:9 | LL | fn duplicate_custom_4(t: S) -> (S, S) | - move occurs because `t` has type `S`, which does not implement the `Copy` trait @@ -143,23 +151,31 @@ LL | fn duplicate_custom_4(t: S) -> (S, S) | ++++++++++++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:75:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:77:9 | LL | fn existing_colon(t: T) { | - move occurs because `t` has type `T`, which does not implement the `Copy` trait -LL | +... LL | [t, t]; | - ^ value used here after move | | | value moved here | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/use_of_moved_value_copy_suggestions.rs:74:19 + | +LL | fn existing_colon(t: T) { + | ^ consider constraining this type parameter with `Clone` +... +LL | [t, t]; + | - you could clone this value help: consider restricting type parameter `T` | LL | fn existing_colon(t: T) { | ++++ error[E0382]: use of moved value: `t` - --> $DIR/use_of_moved_value_copy_suggestions.rs:83:9 + --> $DIR/use_of_moved_value_copy_suggestions.rs:85:9 | LL | fn existing_colon_in_where(t: T) | - move occurs because `t` has type `T`, which does not implement the `Copy` trait @@ -169,6 +185,14 @@ LL | [t, t]; | | | value moved here | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/use_of_moved_value_copy_suggestions.rs:80:28 + | +LL | fn existing_colon_in_where(t: T) + | ^ consider constraining this type parameter with `Clone` +... +LL | [t, t]; + | - you could clone this value help: consider further restricting type parameter `T` | LL | T:, T: Copy diff --git a/tests/ui/nll/closure-borrow-spans.stderr b/tests/ui/nll/closure-borrow-spans.stderr index cac22c2ecda4..c466cad25d2e 100644 --- a/tests/ui/nll/closure-borrow-spans.stderr +++ b/tests/ui/nll/closure-borrow-spans.stderr @@ -25,6 +25,8 @@ LL | f.use_ref(); error[E0597]: `x` does not live long enough --> $DIR/closure-borrow-spans.rs:19:16 | +LL | let x = 1; + | - binding `x` declared here LL | f = || x; | -- ^ borrowed value does not live long enough | | @@ -85,6 +87,8 @@ LL | f.use_ref(); error[E0597]: `x` does not live long enough --> $DIR/closure-borrow-spans.rs:52:16 | +LL | let mut x = 1; + | ----- binding `x` declared here LL | f = || x = 0; | -- ^ borrowed value does not live long enough | | @@ -145,6 +149,8 @@ LL | f.use_ref(); error[E0597]: `x` does not live long enough --> $DIR/closure-borrow-spans.rs:86:16 | +LL | let x = &mut z; + | - binding `x` declared here LL | f = || *x = 0; | -- ^^ borrowed value does not live long enough | | diff --git a/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr b/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr index aa73e91cc77e..8e47ab780f21 100644 --- a/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -37,6 +37,9 @@ LL | fn test() { error[E0597]: `y` does not live long enough --> $DIR/escape-upvar-nested.rs:21:40 | +LL | let y = 22; + | - binding `y` declared here +LL | LL | let mut closure = || { | -- value captured here LL | let mut closure1 = || p = &y; diff --git a/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr b/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr index 949dcc78703a..c428150aa2f4 100644 --- a/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -23,6 +23,8 @@ LL | fn test() { error[E0597]: `y` does not live long enough --> $DIR/escape-upvar-ref.rs:23:35 | +LL | let y = 22; + | - binding `y` declared here LL | let mut closure = || p = &y; | -- ^ borrowed value does not live long enough | | diff --git a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr index 81b5f09b0415..15f48d88c379 100644 --- a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr +++ b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr @@ -1,6 +1,8 @@ error[E0597]: `local_arr` does not live long enough --> $DIR/propagate-multiple-requirements.rs:15:14 | +LL | let local_arr = other_local_arr; + | --------- binding `local_arr` declared here LL | let mut out: &mut &'static [i32] = &mut (&[1] as _); | ------------------- type annotation requires that `local_arr` is borrowed for `'static` LL | once(|mut z: &[i32], mut out_val: &mut &[i32]| { diff --git a/tests/ui/nll/coroutine-distinct-lifetime.rs b/tests/ui/nll/coroutine-distinct-lifetime.rs index ff94a3d54b76..471fad686c4c 100644 --- a/tests/ui/nll/coroutine-distinct-lifetime.rs +++ b/tests/ui/nll/coroutine-distinct-lifetime.rs @@ -9,6 +9,7 @@ //@ check-pass fn foo(x: &mut u32) { + #[coroutine] move || { let s = &mut *x; yield; diff --git a/tests/ui/nll/coroutine-upvar-mutability.rs b/tests/ui/nll/coroutine-upvar-mutability.rs index 12853b16b9b7..a7d14173fb9f 100644 --- a/tests/ui/nll/coroutine-upvar-mutability.rs +++ b/tests/ui/nll/coroutine-upvar-mutability.rs @@ -4,6 +4,8 @@ fn mutate_upvar() { let x = 0; + + #[coroutine] move || { x = 1; //~^ ERROR diff --git a/tests/ui/nll/coroutine-upvar-mutability.stderr b/tests/ui/nll/coroutine-upvar-mutability.stderr index 8922eae31518..8b9be877c8f3 100644 --- a/tests/ui/nll/coroutine-upvar-mutability.stderr +++ b/tests/ui/nll/coroutine-upvar-mutability.stderr @@ -1,9 +1,9 @@ error[E0594]: cannot assign to `x`, as it is not declared as mutable - --> $DIR/coroutine-upvar-mutability.rs:8:9 + --> $DIR/coroutine-upvar-mutability.rs:10:9 | LL | let x = 0; | - help: consider changing this to be mutable: `mut x` -LL | move || { +... LL | x = 1; | ^^^^^ cannot assign diff --git a/tests/ui/nll/extra-unused-mut.rs b/tests/ui/nll/extra-unused-mut.rs index 786ba98508fb..b040dcc6e5db 100644 --- a/tests/ui/nll/extra-unused-mut.rs +++ b/tests/ui/nll/extra-unused-mut.rs @@ -18,6 +18,8 @@ fn mutable_upvar() { // #50897 fn coroutine_mutable_upvar() { let mut x = 0; + + #[coroutine] move || { x = 1; yield; @@ -36,13 +38,13 @@ struct Expr { // #51904 fn parse_dot_or_call_expr_with(mut attrs: Vec) { let x = Expr { attrs: vec![] }; - Some(Some(x)).map(|expr| + Some(Some(x)).map(|expr| { expr.map(|mut expr| { attrs.push(666); expr.attrs = attrs; expr }) - ); + }); } // Found when trying to bootstrap rustc diff --git a/tests/ui/nll/issue-21232-partial-init-and-use.stderr b/tests/ui/nll/issue-21232-partial-init-and-use.stderr index 2aff375f0a77..496a298a36ce 100644 --- a/tests/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/tests/ui/nll/issue-21232-partial-init-and-use.stderr @@ -32,7 +32,10 @@ note: if `S>` implemented `Clone`, you could clone the value --> $DIR/issue-21232-partial-init-and-use.rs:15:1 | LL | struct S { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let mut s: S = S::new(); drop(s); + | - you could clone this value error[E0382]: assign to part of moved value: `t` --> $DIR/issue-21232-partial-init-and-use.rs:116:5 @@ -83,7 +86,10 @@ note: if `S>` implemented `Clone`, you could clone the value --> $DIR/issue-21232-partial-init-and-use.rs:15:1 | LL | struct S { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let mut s: S = S::new(); drop(s); + | - you could clone this value error[E0382]: assign to part of moved value: `t` --> $DIR/issue-21232-partial-init-and-use.rs:142:5 diff --git a/tests/ui/nll/issue-27282-move-ref-mut-into-guard.fixed b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.fixed new file mode 100644 index 000000000000..7692be7ccc80 --- /dev/null +++ b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.fixed @@ -0,0 +1,23 @@ +// Issue 27282: Example 1: This sidesteps the AST checks disallowing +// mutable borrows in match guards by hiding the mutable borrow in a +// guard behind a move (of the ref mut pattern id) within a closure. +//@ run-rustfix +#![feature(if_let_guard)] + +fn main() { + match Some(&4) { + None => {}, + ref mut foo + if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {}, + //~^ ERROR cannot move out of `foo` in pattern guard [E0507] + Some(s) => std::process::exit(*s), + } + + match Some(&4) { + None => {}, + ref mut foo + if let Some(()) = { (|| { let mut bar = foo.clone(); bar.take() })(); None } => {}, + //~^ ERROR cannot move out of `foo` in pattern guard [E0507] + Some(s) => std::process::exit(*s), + } +} diff --git a/tests/ui/nll/issue-27282-move-ref-mut-into-guard.rs b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.rs index 833ca8afd618..f3d0a184e03c 100644 --- a/tests/ui/nll/issue-27282-move-ref-mut-into-guard.rs +++ b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.rs @@ -1,14 +1,14 @@ // Issue 27282: Example 1: This sidesteps the AST checks disallowing // mutable borrows in match guards by hiding the mutable borrow in a // guard behind a move (of the ref mut pattern id) within a closure. - +//@ run-rustfix #![feature(if_let_guard)] fn main() { match Some(&4) { None => {}, ref mut foo - if { (|| { let bar = foo; bar.take() })(); false } => {}, + if { (|| { let mut bar = foo; bar.take() })(); false } => {}, //~^ ERROR cannot move out of `foo` in pattern guard [E0507] Some(s) => std::process::exit(*s), } @@ -16,7 +16,7 @@ fn main() { match Some(&4) { None => {}, ref mut foo - if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {}, + if let Some(()) = { (|| { let mut bar = foo; bar.take() })(); None } => {}, //~^ ERROR cannot move out of `foo` in pattern guard [E0507] Some(s) => std::process::exit(*s), } diff --git a/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr index 4a512560c875..7781e77894b8 100644 --- a/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr +++ b/tests/ui/nll/issue-27282-move-ref-mut-into-guard.stderr @@ -1,22 +1,30 @@ error[E0507]: cannot move out of `foo` in pattern guard --> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19 | -LL | if { (|| { let bar = foo; bar.take() })(); false } => {}, - | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait +LL | if { (|| { let mut bar = foo; bar.take() })(); false } => {}, + | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait | | | `foo` is moved here | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard +help: consider cloning the value if the performance cost is acceptable + | +LL | if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {}, + | ++++++++ error[E0507]: cannot move out of `foo` in pattern guard --> $DIR/issue-27282-move-ref-mut-into-guard.rs:19:34 | -LL | if let Some(()) = { (|| { let bar = foo; bar.take() })(); None } => {}, - | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait +LL | if let Some(()) = { (|| { let mut bar = foo; bar.take() })(); None } => {}, + | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait | | | `foo` is moved here | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard +help: consider cloning the value if the performance cost is acceptable + | +LL | if let Some(()) = { (|| { let mut bar = foo.clone(); bar.take() })(); None } => {}, + | ++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/issue-27282-mutation-in-guard.stderr b/tests/ui/nll/issue-27282-mutation-in-guard.stderr index 0b5d723172c7..f73e4aaa489a 100644 --- a/tests/ui/nll/issue-27282-mutation-in-guard.stderr +++ b/tests/ui/nll/issue-27282-mutation-in-guard.stderr @@ -7,6 +7,10 @@ LL | (|| { let bar = foo; bar.take() })(); | `foo` is moved here | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard +help: consider cloning the value if the performance cost is acceptable + | +LL | (|| { let bar = foo.clone(); bar.take() })(); + | ++++++++ error[E0507]: cannot move out of `foo` in pattern guard --> $DIR/issue-27282-mutation-in-guard.rs:20:18 @@ -17,6 +21,10 @@ LL | (|| { let bar = foo; bar.take() })(); | `foo` is moved here | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard +help: consider cloning the value if the performance cost is acceptable + | +LL | (|| { let bar = foo.clone(); bar.take() })(); + | ++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr b/tests/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr index f7a525ee9b04..e3f44467550c 100644 --- a/tests/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr +++ b/tests/ui/nll/issue-42574-diagnostic-in-nested-closure.stderr @@ -11,6 +11,8 @@ LL | || doit(data); error[E0597]: `data` does not live long enough --> $DIR/issue-42574-diagnostic-in-nested-closure.rs:6:13 | +LL | fn doit(data: &'static mut ()) { + | ---- binding `data` declared here LL | || doit(data); | -- -----^^^^- | | | | diff --git a/tests/ui/nll/issue-48623-coroutine.rs b/tests/ui/nll/issue-48623-coroutine.rs index 3a4a27855d99..63348a2047c0 100644 --- a/tests/ui/nll/issue-48623-coroutine.rs +++ b/tests/ui/nll/issue-48623-coroutine.rs @@ -12,7 +12,7 @@ impl Drop for WithDrop { fn reborrow_from_coroutine(r: &mut ()) { let d = WithDrop; - move || { d; yield; &mut *r }; //~ WARN unused coroutine that must be used + #[coroutine] move || { d; yield; &mut *r }; //~ WARN unused coroutine that must be used } fn main() {} diff --git a/tests/ui/nll/issue-48623-coroutine.stderr b/tests/ui/nll/issue-48623-coroutine.stderr index 1b7b1735aacb..4e4cd28ef2ae 100644 --- a/tests/ui/nll/issue-48623-coroutine.stderr +++ b/tests/ui/nll/issue-48623-coroutine.stderr @@ -1,8 +1,8 @@ warning: unused coroutine that must be used - --> $DIR/issue-48623-coroutine.rs:15:5 + --> $DIR/issue-48623-coroutine.rs:15:18 | -LL | move || { d; yield; &mut *r }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[coroutine] move || { d; yield; &mut *r }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: coroutines are lazy and do nothing unless resumed = note: `#[warn(unused_must_use)]` on by default diff --git a/tests/ui/nll/issue-55850.rs b/tests/ui/nll/issue-55850.rs index fc873af94638..bf1e2e7caef6 100644 --- a/tests/ui/nll/issue-55850.rs +++ b/tests/ui/nll/issue-55850.rs @@ -23,7 +23,7 @@ where } fn bug<'a>() -> impl Iterator { - GenIter(move || { + GenIter(#[coroutine] move || { let mut s = String::new(); yield &s[..] //~ ERROR cannot yield value referencing local variable `s` [E0515] //~| ERROR borrow may still be in use when coroutine yields diff --git a/tests/ui/nll/match-guards-always-borrow.fixed b/tests/ui/nll/match-guards-always-borrow.fixed new file mode 100644 index 000000000000..56e743bf196a --- /dev/null +++ b/tests/ui/nll/match-guards-always-borrow.fixed @@ -0,0 +1,66 @@ +#![feature(if_let_guard)] +#![allow(unused_mut)] +//@ run-rustfix + +// Here is arielb1's basic example from rust-lang/rust#27282 +// that AST borrowck is flummoxed by: + +fn should_reject_destructive_mutate_in_guard() { + match Some(&4) { + None => {}, + ref mut foo if { + (|| { let mut bar = foo.clone(); bar.take() })(); + //~^ ERROR cannot move out of `foo` in pattern guard [E0507] + false } => { }, + Some(s) => std::process::exit(*s), + } + + match Some(&4) { + None => {}, + ref mut foo if let Some(()) = { + (|| { let mut bar = foo.clone(); bar.take() })(); + //~^ ERROR cannot move out of `foo` in pattern guard [E0507] + None } => { }, + Some(s) => std::process::exit(*s), + } +} + +// Here below is a case that needs to keep working: we only use the +// binding via immutable-borrow in the guard, and we mutate in the arm +// body. +fn allow_mutate_in_arm_body() { + match Some(&4) { + None => {}, + ref mut foo if foo.is_some() => { foo.take(); () } + Some(s) => std::process::exit(*s), + } + + match Some(&4) { + None => {}, + ref mut foo if let Some(_) = foo => { foo.take(); () } + Some(s) => std::process::exit(*s), + } +} + +// Here below is a case that needs to keep working: we only use the +// binding via immutable-borrow in the guard, and we move into the arm +// body. +fn allow_move_into_arm_body() { + match Some(&4) { + None => {}, + mut foo if foo.is_some() => { foo.unwrap(); () } + Some(s) => std::process::exit(*s), + } + + match Some(&4) { + None => {}, + mut foo if let Some(_) = foo => { foo.unwrap(); () } + Some(s) => std::process::exit(*s), + } +} + +fn main() { + should_reject_destructive_mutate_in_guard(); + allow_mutate_in_arm_body(); + allow_move_into_arm_body(); +} diff --git a/tests/ui/nll/match-guards-always-borrow.rs b/tests/ui/nll/match-guards-always-borrow.rs index ff63cc092734..927d55c42a6e 100644 --- a/tests/ui/nll/match-guards-always-borrow.rs +++ b/tests/ui/nll/match-guards-always-borrow.rs @@ -1,4 +1,6 @@ #![feature(if_let_guard)] +#![allow(unused_mut)] +//@ run-rustfix // Here is arielb1's basic example from rust-lang/rust#27282 // that AST borrowck is flummoxed by: @@ -7,7 +9,7 @@ fn should_reject_destructive_mutate_in_guard() { match Some(&4) { None => {}, ref mut foo if { - (|| { let bar = foo; bar.take() })(); + (|| { let mut bar = foo; bar.take() })(); //~^ ERROR cannot move out of `foo` in pattern guard [E0507] false } => { }, Some(s) => std::process::exit(*s), @@ -16,7 +18,7 @@ fn should_reject_destructive_mutate_in_guard() { match Some(&4) { None => {}, ref mut foo if let Some(()) = { - (|| { let bar = foo; bar.take() })(); + (|| { let mut bar = foo; bar.take() })(); //~^ ERROR cannot move out of `foo` in pattern guard [E0507] None } => { }, Some(s) => std::process::exit(*s), diff --git a/tests/ui/nll/match-guards-always-borrow.stderr b/tests/ui/nll/match-guards-always-borrow.stderr index afd853c403ee..bb0c5bd4c976 100644 --- a/tests/ui/nll/match-guards-always-borrow.stderr +++ b/tests/ui/nll/match-guards-always-borrow.stderr @@ -1,22 +1,30 @@ error[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/match-guards-always-borrow.rs:10:14 + --> $DIR/match-guards-always-borrow.rs:12:14 | -LL | (|| { let bar = foo; bar.take() })(); - | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait +LL | (|| { let mut bar = foo; bar.take() })(); + | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait | | | `foo` is moved here | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard +help: consider cloning the value if the performance cost is acceptable + | +LL | (|| { let mut bar = foo.clone(); bar.take() })(); + | ++++++++ error[E0507]: cannot move out of `foo` in pattern guard - --> $DIR/match-guards-always-borrow.rs:19:14 + --> $DIR/match-guards-always-borrow.rs:21:14 | -LL | (|| { let bar = foo; bar.take() })(); - | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait +LL | (|| { let mut bar = foo; bar.take() })(); + | ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait | | | `foo` is moved here | = note: variables bound in patterns cannot be moved from until after the end of the pattern guard +help: consider cloning the value if the performance cost is acceptable + | +LL | (|| { let mut bar = foo.clone(); bar.take() })(); + | ++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/move-errors.stderr b/tests/ui/nll/move-errors.stderr index 842ecaf524b4..d13841213795 100644 --- a/tests/ui/nll/move-errors.stderr +++ b/tests/ui/nll/move-errors.stderr @@ -8,7 +8,10 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let b = *a; + | -- you could clone this value help: consider removing the dereference here | LL - let b = *a; @@ -28,7 +31,10 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let b = a[0]; + | ---- you could clone this value help: consider borrowing here | LL | let b = &a[0]; @@ -44,7 +50,10 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let s = **r; + | --- you could clone this value help: consider removing the dereference here | LL - let s = **r; @@ -61,7 +70,10 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let s = *r; + | -- you could clone this value help: consider removing the dereference here | LL - let s = *r; @@ -81,7 +93,10 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | let a = [A("".to_string())][0]; + | ---------------------- you could clone this value help: consider borrowing here | LL | let a = &[A("".to_string())][0]; @@ -126,7 +141,10 @@ note: if `A` implemented `Clone`, you could clone the value --> $DIR/move-errors.rs:1:1 | LL | struct A(String); - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | b = *a; + | -- you could clone this value error[E0508]: cannot move out of type `[B; 1]`, a non-copy array --> $DIR/move-errors.rs:74:11 diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr index 5227ca8ec17d..1d086c658dfc 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr @@ -1,6 +1,8 @@ error[E0597]: `a` does not live long enough --> $DIR/location-insensitive-scopes-issue-117146.rs:10:18 | +LL | let a = (); + | - binding `a` declared here LL | let b = |_| &a; | --- -^ | | || diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr index 5227ca8ec17d..1d086c658dfc 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr @@ -1,6 +1,8 @@ error[E0597]: `a` does not live long enough --> $DIR/location-insensitive-scopes-issue-117146.rs:10:18 | +LL | let a = (); + | - binding `a` declared here LL | let b = |_| &a; | --- -^ | | || diff --git a/tests/ui/nll/user-annotations/method-ufcs-1.stderr b/tests/ui/nll/user-annotations/method-ufcs-1.stderr index c7c08c948abd..c42ea0172cf7 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-1.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-1.stderr @@ -33,7 +33,9 @@ error[E0597]: `a` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let a = 22; + | - binding `a` declared here +LL | let b = 44; LL | let _closure = || { | -- value captured here LL | let c = 66; diff --git a/tests/ui/nll/user-annotations/method-ufcs-2.stderr b/tests/ui/nll/user-annotations/method-ufcs-2.stderr index b7861a3bd069..287337c7d52d 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-2.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-2.stderr @@ -34,7 +34,9 @@ error[E0597]: `b` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let a = 22; +LL | let b = 44; + | - binding `b` declared here LL | let _closure = || { | -- value captured here LL | let c = 66; diff --git a/tests/ui/packed/packed-struct-drop-aligned.rs b/tests/ui/packed/packed-struct-drop-aligned.rs index 037b8cb78b72..ba3dcb10c61e 100644 --- a/tests/ui/packed/packed-struct-drop-aligned.rs +++ b/tests/ui/packed/packed-struct-drop-aligned.rs @@ -1,5 +1,5 @@ //@ run-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![feature(coroutine_trait)] use std::cell::Cell; use std::mem; @@ -7,13 +7,12 @@ use std::ops::Coroutine; use std::pin::Pin; struct Aligned<'a> { - drop_count: &'a Cell + drop_count: &'a Cell, } #[inline(never)] fn check_align(ptr: *const Aligned) { - assert_eq!(ptr as usize % mem::align_of::(), - 0); + assert_eq!(ptr as usize % mem::align_of::(), 0); } impl<'a> Drop for Aligned<'a> { @@ -39,7 +38,8 @@ fn main() { assert_eq!(drop_count.get(), 2); let drop_count = &Cell::new(0); - let mut g = || { + let mut g = #[coroutine] + || { let mut p = Packed(NotCopy(0), Aligned { drop_count }); let _ = &p; p.1 = Aligned { drop_count }; diff --git a/tests/ui/parser/bad-let-else-statement.rs b/tests/ui/parser/bad-let-else-statement.rs index c3126a493e54..de41a07568fb 100644 --- a/tests/ui/parser/bad-let-else-statement.rs +++ b/tests/ui/parser/bad-let-else-statement.rs @@ -1,4 +1,3 @@ -#![feature(inline_const)] #![feature(yeet_expr)] #![allow(incomplete_features)] // Necessary for now, while explicit_tail_calls is incomplete #![feature(explicit_tail_calls)] diff --git a/tests/ui/parser/bad-let-else-statement.stderr b/tests/ui/parser/bad-let-else-statement.stderr index 12df8f849abd..3f7e176b3e31 100644 --- a/tests/ui/parser/bad-let-else-statement.stderr +++ b/tests/ui/parser/bad-let-else-statement.stderr @@ -1,5 +1,5 @@ error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:10:5 + --> $DIR/bad-let-else-statement.rs:9:5 | LL | } else { | ^ @@ -13,7 +13,7 @@ LL ~ }) else { | error: `for...else` loops are not supported - --> $DIR/bad-let-else-statement.rs:19:7 + --> $DIR/bad-let-else-statement.rs:18:7 | LL | let foo = for i in 1..2 { | --- `else` is attached to this loop @@ -28,7 +28,7 @@ LL | | }; = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:31:5 + --> $DIR/bad-let-else-statement.rs:30:5 | LL | } else { | ^ @@ -43,7 +43,7 @@ LL ~ }) else { | error: `loop...else` loops are not supported - --> $DIR/bad-let-else-statement.rs:40:7 + --> $DIR/bad-let-else-statement.rs:39:7 | LL | let foo = loop { | ---- `else` is attached to this loop @@ -58,7 +58,7 @@ LL | | }; = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:51:5 + --> $DIR/bad-let-else-statement.rs:50:5 | LL | } else { | ^ @@ -73,7 +73,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:62:5 + --> $DIR/bad-let-else-statement.rs:61:5 | LL | } else { | ^ @@ -87,7 +87,7 @@ LL ~ }) else { | error: `while...else` loops are not supported - --> $DIR/bad-let-else-statement.rs:71:7 + --> $DIR/bad-let-else-statement.rs:70:7 | LL | let foo = while false { | ----- `else` is attached to this loop @@ -102,7 +102,7 @@ LL | | }; = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:81:5 + --> $DIR/bad-let-else-statement.rs:80:5 | LL | } else { | ^ @@ -116,7 +116,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:91:5 + --> $DIR/bad-let-else-statement.rs:90:5 | LL | } else { | ^ @@ -130,7 +130,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:102:5 + --> $DIR/bad-let-else-statement.rs:101:5 | LL | } else { | ^ @@ -144,7 +144,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:112:5 + --> $DIR/bad-let-else-statement.rs:111:5 | LL | } else { | ^ @@ -158,7 +158,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:122:5 + --> $DIR/bad-let-else-statement.rs:121:5 | LL | } else { | ^ @@ -172,7 +172,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:132:5 + --> $DIR/bad-let-else-statement.rs:131:5 | LL | } else { | ^ @@ -186,7 +186,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:142:5 + --> $DIR/bad-let-else-statement.rs:141:5 | LL | } else { | ^ @@ -200,7 +200,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:152:5 + --> $DIR/bad-let-else-statement.rs:151:5 | LL | } else { | ^ @@ -214,7 +214,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:162:5 + --> $DIR/bad-let-else-statement.rs:161:5 | LL | } else { | ^ @@ -228,7 +228,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:172:5 + --> $DIR/bad-let-else-statement.rs:171:5 | LL | } else { | ^ @@ -242,7 +242,7 @@ LL ~ }) else { | error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:182:31 + --> $DIR/bad-let-else-statement.rs:181:31 | LL | let bad = format_args! {""} else { return; }; | ^ @@ -253,7 +253,7 @@ LL | let bad = format_args! ("") else { return; }; | ~ ~ error: right curly brace `}` before `else` in a `let...else` statement not allowed - --> $DIR/bad-let-else-statement.rs:199:25 + --> $DIR/bad-let-else-statement.rs:198:25 | LL | let x = a! {} else { return; }; | ^ @@ -268,7 +268,7 @@ LL | let x = a! () else { return; }; | ~~ warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:7:5 + --> $DIR/bad-let-else-statement.rs:6:5 | LL | / let foo = { LL | | @@ -281,7 +281,7 @@ LL | | } else { = note: `#[warn(irrefutable_let_patterns)]` on by default warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:26:5 + --> $DIR/bad-let-else-statement.rs:25:5 | LL | / let foo = if true { LL | | @@ -295,7 +295,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:47:5 + --> $DIR/bad-let-else-statement.rs:46:5 | LL | / let foo = match true { LL | | @@ -308,7 +308,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:59:5 + --> $DIR/bad-let-else-statement.rs:58:5 | LL | / let foo = X { LL | | @@ -320,7 +320,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:78:5 + --> $DIR/bad-let-else-statement.rs:77:5 | LL | / let foo = const { LL | | @@ -332,7 +332,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:88:5 + --> $DIR/bad-let-else-statement.rs:87:5 | LL | / let foo = &{ LL | | @@ -344,7 +344,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:99:5 + --> $DIR/bad-let-else-statement.rs:98:5 | LL | / let foo = bar = { LL | | @@ -356,7 +356,7 @@ LL | | } else { = help: consider removing the `else` clause error[E0384]: cannot assign twice to immutable variable `bar` - --> $DIR/bad-let-else-statement.rs:99:15 + --> $DIR/bad-let-else-statement.rs:98:15 | LL | let bar = 0; | --- @@ -371,7 +371,7 @@ LL | | } else { | |_____^ cannot assign twice to immutable variable warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:109:5 + --> $DIR/bad-let-else-statement.rs:108:5 | LL | / let foo = 1 + { LL | | @@ -383,7 +383,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:119:5 + --> $DIR/bad-let-else-statement.rs:118:5 | LL | / let foo = 1..{ LL | | @@ -395,7 +395,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:129:5 + --> $DIR/bad-let-else-statement.rs:128:5 | LL | / let foo = return { LL | | @@ -407,7 +407,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:139:5 + --> $DIR/bad-let-else-statement.rs:138:5 | LL | / let foo = -{ LL | | @@ -419,7 +419,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:149:5 + --> $DIR/bad-let-else-statement.rs:148:5 | LL | / let foo = do yeet { LL | | @@ -431,7 +431,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:159:5 + --> $DIR/bad-let-else-statement.rs:158:5 | LL | / let foo = become { LL | | @@ -443,7 +443,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:169:5 + --> $DIR/bad-let-else-statement.rs:168:5 | LL | / let foo = |x: i32| { LL | | @@ -455,7 +455,7 @@ LL | | } else { = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:179:5 + --> $DIR/bad-let-else-statement.rs:178:5 | LL | let ok = format_args!("") else { return; }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -464,7 +464,7 @@ LL | let ok = format_args!("") else { return; }; = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:182:5 + --> $DIR/bad-let-else-statement.rs:181:5 | LL | let bad = format_args! {""} else { return; }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -473,7 +473,7 @@ LL | let bad = format_args! {""} else { return; }; = help: consider removing the `else` clause warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:189:19 + --> $DIR/bad-let-else-statement.rs:188:19 | LL | () => { {} } | ___________________^ @@ -493,7 +493,7 @@ LL | b!(1); b!(2); = note: this warning originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable `let...else` pattern - --> $DIR/bad-let-else-statement.rs:189:19 + --> $DIR/bad-let-else-statement.rs:188:19 | LL | () => { {} } | ___________________^ diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index 00964cb8336e..e925fe78f339 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -337,7 +337,10 @@ note: if `U` implemented `Clone`, you could clone the value --> $DIR/borrowck-pat-ref-mut-and-ref.rs:17:5 | LL | struct U; - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} + | - you could clone this value error[E0507]: cannot move out of `b` in pattern guard --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66 @@ -350,7 +353,10 @@ note: if `U` implemented `Clone`, you could clone the value --> $DIR/borrowck-pat-ref-mut-and-ref.rs:17:5 | LL | struct U; - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} + | - you could clone this value = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0507]: cannot move out of `a` in pattern guard diff --git a/tests/ui/polymorphization/coroutine.rs b/tests/ui/polymorphization/coroutine.rs index a989947f7873..22ceadfb194d 100644 --- a/tests/ui/polymorphization/coroutine.rs +++ b/tests/ui/polymorphization/coroutine.rs @@ -32,6 +32,7 @@ where #[rustc_polymorphize_error] pub fn unused_type() -> impl Coroutine<(), Yield = u32, Return = u32> + Unpin { + #[coroutine] || { //~^ ERROR item has unused generic parameters yield 1; @@ -41,6 +42,7 @@ pub fn unused_type() -> impl Coroutine<(), Yield = u32, Return = u32> + Unpin #[rustc_polymorphize_error] pub fn used_type_in_yield() -> impl Coroutine<(), Yield = Y, Return = u32> + Unpin { + #[coroutine] || { yield Y::default(); 2 @@ -49,6 +51,7 @@ pub fn used_type_in_yield() -> impl Coroutine<(), Yield = Y, Return #[rustc_polymorphize_error] pub fn used_type_in_return() -> impl Coroutine<(), Yield = u32, Return = R> + Unpin { + #[coroutine] || { yield 3; R::default() @@ -57,6 +60,7 @@ pub fn used_type_in_return() -> impl Coroutine<(), Yield = u32, Retu #[rustc_polymorphize_error] pub fn unused_const() -> impl Coroutine<(), Yield = u32, Return = u32> + Unpin { + #[coroutine] || { //~^ ERROR item has unused generic parameters yield 1; @@ -67,6 +71,7 @@ pub fn unused_const() -> impl Coroutine<(), Yield = u32, Return = #[rustc_polymorphize_error] pub fn used_const_in_yield() -> impl Coroutine<(), Yield = u32, Return = u32> + Unpin { + #[coroutine] || { yield Y; 2 @@ -76,6 +81,7 @@ pub fn used_const_in_yield() -> impl Coroutine<(), Yield = u32, Re #[rustc_polymorphize_error] pub fn used_const_in_return() -> impl Coroutine<(), Yield = u32, Return = u32> + Unpin { + #[coroutine] || { yield 4; R diff --git a/tests/ui/polymorphization/coroutine.stderr b/tests/ui/polymorphization/coroutine.stderr index 67b55a598831..07e29184226d 100644 --- a/tests/ui/polymorphization/coroutine.stderr +++ b/tests/ui/polymorphization/coroutine.stderr @@ -8,18 +8,20 @@ LL | #![feature(generic_const_exprs, coroutines, coroutine_trait, rustc_attrs)] = note: `#[warn(incomplete_features)]` on by default error: item has unused generic parameters - --> $DIR/coroutine.rs:35:5 + --> $DIR/coroutine.rs:36:5 | LL | pub fn unused_type() -> impl Coroutine<(), Yield = u32, Return = u32> + Unpin { | - generic parameter `T` is unused +LL | #[coroutine] LL | || { | ^^ error: item has unused generic parameters - --> $DIR/coroutine.rs:60:5 + --> $DIR/coroutine.rs:64:5 | LL | pub fn unused_const() -> impl Coroutine<(), Yield = u32, Return = u32> + Unpin { | ------------ generic parameter `T` is unused +LL | #[coroutine] LL | || { | ^^ diff --git a/tests/ui/print_type_sizes/coroutine.rs b/tests/ui/print_type_sizes/coroutine.rs index 61488c51f053..153357887894 100644 --- a/tests/ui/print_type_sizes/coroutine.rs +++ b/tests/ui/print_type_sizes/coroutine.rs @@ -7,6 +7,7 @@ use std::ops::Coroutine; fn coroutine(array: [u8; C]) -> impl Coroutine { + #[coroutine] move |()| { yield (); let _ = array; diff --git a/tests/ui/print_type_sizes/coroutine.stdout b/tests/ui/print_type_sizes/coroutine.stdout index 5d51339558ca..339bbddfc2a9 100644 --- a/tests/ui/print_type_sizes/coroutine.stdout +++ b/tests/ui/print_type_sizes/coroutine.stdout @@ -1,4 +1,4 @@ -print-type-size type: `{coroutine@$DIR/coroutine.rs:10:5: 10:14}`: 8193 bytes, alignment: 1 bytes +print-type-size type: `{coroutine@$DIR/coroutine.rs:11:5: 11:14}`: 8193 bytes, alignment: 1 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 8192 bytes print-type-size upvar `.array`: 8192 bytes diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.rs b/tests/ui/print_type_sizes/coroutine_discr_placement.rs index 4b9f67a79997..d97b0b28ed0f 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.rs +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.rs @@ -5,11 +5,12 @@ // Tests a coroutine that has its discriminant as the *final* field. // Avoid emitting panic handlers, like the rest of these tests... -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![allow(dropping_copy_types)] pub fn foo() { - let a = || { + let a = #[coroutine] + || { { let w: i32 = 4; yield; diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout index 71a7f3c63815..4ce1ce46f6e8 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout @@ -1,4 +1,4 @@ -print-type-size type: `{coroutine@$DIR/coroutine_discr_placement.rs:12:13: 12:15}`: 8 bytes, alignment: 4 bytes +print-type-size type: `{coroutine@$DIR/coroutine_discr_placement.rs:13:5: 13:7}`: 8 bytes, alignment: 4 bytes print-type-size discriminant: 1 bytes print-type-size variant `Unresumed`: 0 bytes print-type-size variant `Suspend0`: 7 bytes diff --git a/tests/ui/regions/regions-addr-of-upvar-self.stderr b/tests/ui/regions/regions-addr-of-upvar-self.stderr index c16a6f8585b6..3a028cc9e211 100644 --- a/tests/ui/regions/regions-addr-of-upvar-self.stderr +++ b/tests/ui/regions/regions-addr-of-upvar-self.stderr @@ -20,6 +20,8 @@ LL | let p: &'static mut usize = &mut self.food; error[E0597]: `self` does not live long enough --> $DIR/regions-addr-of-upvar-self.rs:8:46 | +LL | pub fn chase_cat(&mut self) { + | --------- binding `self` declared here LL | let _f = || { | -- value captured here LL | let p: &'static mut usize = &mut self.food; diff --git a/tests/ui/regions/regions-nested-fns-2.stderr b/tests/ui/regions/regions-nested-fns-2.stderr index 254497639a17..02359fe1213d 100644 --- a/tests/ui/regions/regions-nested-fns-2.stderr +++ b/tests/ui/regions/regions-nested-fns-2.stderr @@ -1,6 +1,9 @@ error[E0597]: `y` does not live long enough --> $DIR/regions-nested-fns-2.rs:7:25 | +LL | let y = 3; + | - binding `y` declared here +LL | ignore( LL | |z| { | --- value captured here LL | if false { &y } else { z } diff --git a/tests/ui/regions/regions-nested-fns.stderr b/tests/ui/regions/regions-nested-fns.stderr index ee43f9fa5724..23b3f78dd4eb 100644 --- a/tests/ui/regions/regions-nested-fns.stderr +++ b/tests/ui/regions/regions-nested-fns.stderr @@ -27,6 +27,9 @@ LL | } error[E0597]: `y` does not live long enough --> $DIR/regions-nested-fns.rs:10:15 | +LL | let y = 3; + | - binding `y` declared here +... LL | ignore:: FnMut(&'z isize)>>(Box::new(|z| { | --- value captured here LL | ay = x; diff --git a/tests/ui/regions/regions-steal-closure.stderr b/tests/ui/regions/regions-steal-closure.stderr index 9324eb892a67..50068b32fa3a 100644 --- a/tests/ui/regions/regions-steal-closure.stderr +++ b/tests/ui/regions/regions-steal-closure.stderr @@ -4,6 +4,7 @@ error[E0597]: `i` does not live long enough LL | let mut cl_box = { | ---------- borrow later stored here LL | let mut i = 3; + | ----- binding `i` declared here LL | box_it(Box::new(|| i += 1)) | -- ^ borrowed value does not live long enough | | diff --git a/tests/ui/rfcs/rfc-2091-track-caller/tracked-closure.rs b/tests/ui/rfcs/rfc-2091-track-caller/tracked-closure.rs index d5c8a529e1e3..9fdceefbf9b9 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/tracked-closure.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/tracked-closure.rs @@ -113,7 +113,7 @@ fn dyn_coroutine( } fn test_coroutine() { - let coroutine = #[track_caller] |arg: String| { + let coroutine = #[track_caller] #[coroutine] |arg: String| { yield ("first", arg.clone(), Location::caller()); yield ("second", arg.clone(), Location::caller()); }; @@ -136,7 +136,7 @@ fn test_coroutine() { assert_eq!(mono_loc.line(), mono_line); assert_eq!(mono_loc.column(), 42); - let non_tracked_coroutine = || { yield Location::caller(); }; + let non_tracked_coroutine = #[coroutine] || { yield Location::caller(); }; let non_tracked_line = line!() - 1; // This is the line of the coroutine, not its caller let non_tracked_loc = match Box::pin(non_tracked_coroutine).as_mut().resume(()) { CoroutineState::Yielded(val) => val, @@ -144,7 +144,7 @@ fn test_coroutine() { }; assert_eq!(non_tracked_loc.file(), file!()); assert_eq!(non_tracked_loc.line(), non_tracked_line); - assert_eq!(non_tracked_loc.column(), 44); + assert_eq!(non_tracked_loc.column(), 57); } diff --git a/tests/ui/sanitizer/cfi-coroutine.rs b/tests/ui/sanitizer/cfi-coroutine.rs index 5c6a489a7e89..ad994fcf7370 100644 --- a/tests/ui/sanitizer/cfi-coroutine.rs +++ b/tests/ui/sanitizer/cfi-coroutine.rs @@ -14,7 +14,7 @@ //@ compile-flags: --test -Z unstable-options //@ run-pass -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] #![feature(coroutine_trait)] #![feature(noop_waker)] #![feature(gen_blocks)] @@ -27,7 +27,7 @@ use std::async_iter::AsyncIterator; #[test] fn general_coroutine() { - let mut coro = |x: i32| { + let mut coro = #[coroutine] |x: i32| { yield x; "done" }; diff --git a/tests/ui/simd/const-err-trumps-simd-err.rs b/tests/ui/simd/const-err-trumps-simd-err.rs index 06a747273ab7..fda044344517 100644 --- a/tests/ui/simd/const-err-trumps-simd-err.rs +++ b/tests/ui/simd/const-err-trumps-simd-err.rs @@ -5,7 +5,7 @@ #![feature(generic_arg_infer)] #![feature(core_intrinsics)] #![feature(repr_simd)] -#![feature(inline_const)] + use std::intrinsics::simd::*; #[repr(simd)] diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs index 730030878193..a81d8ebdf50c 100644 --- a/tests/ui/simd/intrinsic/generic-elements-pass.rs +++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs @@ -2,7 +2,6 @@ //@ ignore-emscripten FIXME(#45351) hits an LLVM assert #![feature(repr_simd, intrinsics)] -#![feature(inline_const)] #[repr(simd)] #[derive(Copy, Clone, Debug, PartialEq)] diff --git a/tests/ui/span/send-is-not-static-ensures-scoping.stderr b/tests/ui/span/send-is-not-static-ensures-scoping.stderr index bae0befcacaa..c15547e84125 100644 --- a/tests/ui/span/send-is-not-static-ensures-scoping.stderr +++ b/tests/ui/span/send-is-not-static-ensures-scoping.stderr @@ -16,6 +16,9 @@ error[E0597]: `y` does not live long enough | LL | let bad = { | --- borrow later stored here +LL | let x = 1; +LL | let y = &x; + | - binding `y` declared here ... LL | scoped(|| { | -- value captured here diff --git a/tests/ui/suggestions/issue-84973-blacklist.rs b/tests/ui/suggestions/issue-84973-blacklist.rs index 6a35d779c1cd..edc0637636b5 100644 --- a/tests/ui/suggestions/issue-84973-blacklist.rs +++ b/tests/ui/suggestions/issue-84973-blacklist.rs @@ -14,7 +14,7 @@ struct S; fn main() { f_copy("".to_string()); //~ ERROR: the trait bound `String: Copy` is not satisfied [E0277] f_clone(S); //~ ERROR: the trait bound `S: Clone` is not satisfied [E0277] - f_unpin(static || { yield; }); + f_unpin(#[coroutine] static || { yield; }); //~^ ERROR: cannot be unpinned [E0277] let cl = || (); diff --git a/tests/ui/suggestions/issue-84973-blacklist.stderr b/tests/ui/suggestions/issue-84973-blacklist.stderr index 333382283285..4fd063e46926 100644 --- a/tests/ui/suggestions/issue-84973-blacklist.stderr +++ b/tests/ui/suggestions/issue-84973-blacklist.stderr @@ -36,11 +36,11 @@ LL + #[derive(Clone)] LL | struct S; | -error[E0277]: `{static coroutine@$DIR/issue-84973-blacklist.rs:17:13: 17:22}` cannot be unpinned - --> $DIR/issue-84973-blacklist.rs:17:13 +error[E0277]: `{static coroutine@$DIR/issue-84973-blacklist.rs:17:26: 17:35}` cannot be unpinned + --> $DIR/issue-84973-blacklist.rs:17:26 | -LL | f_unpin(static || { yield; }); - | ------- ^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/issue-84973-blacklist.rs:17:13: 17:22}` +LL | f_unpin(#[coroutine] static || { yield; }); + | ------- ^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/issue-84973-blacklist.rs:17:26: 17:35}` | | | required by a bound introduced by this call | diff --git a/tests/ui/suggestions/option-content-move2.rs b/tests/ui/suggestions/option-content-move2.rs index 88e8a5b7aeef..b0104d9bafb7 100644 --- a/tests/ui/suggestions/option-content-move2.rs +++ b/tests/ui/suggestions/option-content-move2.rs @@ -1,8 +1,10 @@ struct NotCopyable; +#[derive(Clone)] +struct NotCopyableButCloneable; fn func H, H: FnMut()>(_: F) {} -fn parse() { +fn foo() { let mut var = None; func(|| { // Shouldn't suggest `move ||.as_ref()` here @@ -12,5 +14,15 @@ fn parse() { } }); } +fn bar() { + let mut var = None; + func(|| { + // Shouldn't suggest `move ||.as_ref()` nor to `clone()` here + move || { + //~^ ERROR: cannot move out of `var` + var = Some(NotCopyableButCloneable); + } + }); +} fn main() {} diff --git a/tests/ui/suggestions/option-content-move2.stderr b/tests/ui/suggestions/option-content-move2.stderr index 0297c031ecca..be97cba17b90 100644 --- a/tests/ui/suggestions/option-content-move2.stderr +++ b/tests/ui/suggestions/option-content-move2.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure - --> $DIR/option-content-move2.rs:9:9 + --> $DIR/option-content-move2.rs:11:9 | LL | let mut var = None; | ------- captured outer variable @@ -15,6 +15,23 @@ LL | var = Some(NotCopyable); | variable moved due to use in closure | move occurs because `var` has type `Option`, which does not implement the `Copy` trait -error: aborting due to 1 previous error +error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure + --> $DIR/option-content-move2.rs:21:9 + | +LL | let mut var = None; + | ------- captured outer variable +LL | func(|| { + | -- captured by this `FnMut` closure +LL | // Shouldn't suggest `move ||.as_ref()` nor to `clone()` here +LL | move || { + | ^^^^^^^ `var` is moved here +LL | +LL | var = Some(NotCopyableButCloneable); + | --- + | | + | variable moved due to use in closure + | move occurs because `var` has type `Option`, which does not implement the `Copy` trait + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/suggestions/option-content-move3.rs b/tests/ui/suggestions/option-content-move3.rs new file mode 100644 index 000000000000..a245309d97fd --- /dev/null +++ b/tests/ui/suggestions/option-content-move3.rs @@ -0,0 +1,30 @@ +#[derive(Debug)] +struct NotCopyable; +#[derive(Debug, Clone)] +struct NotCopyableButCloneable; + +fn func H, H: FnMut()>(_: F) {} + +fn foo() { + let var = NotCopyable; + func(|| { + // Shouldn't suggest `move ||.as_ref()` here + move || { //~ ERROR cannot move out of `var` + let x = var; //~ ERROR cannot move out of `var` + println!("{x:?}"); + } + }); +} + +fn bar() { + let var = NotCopyableButCloneable; + func(|| { + // Shouldn't suggest `move ||.as_ref()` here + move || { //~ ERROR cannot move out of `var` + let x = var; //~ ERROR cannot move out of `var` + println!("{x:?}"); + } + }); +} + +fn main() {} diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr new file mode 100644 index 000000000000..a20dcce1ee31 --- /dev/null +++ b/tests/ui/suggestions/option-content-move3.stderr @@ -0,0 +1,95 @@ +error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure + --> $DIR/option-content-move3.rs:13:21 + | +LL | let var = NotCopyable; + | --- captured outer variable +... +LL | move || { + | ------- captured by this `FnMut` closure +LL | let x = var; + | ^^^ move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait + | +note: if `NotCopyable` implemented `Clone`, you could clone the value + --> $DIR/option-content-move3.rs:2:1 + | +LL | struct NotCopyable; + | ^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let x = var; + | --- you could clone this value +help: consider borrowing here + | +LL | let x = &var; + | + + +error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure + --> $DIR/option-content-move3.rs:12:9 + | +LL | let var = NotCopyable; + | --- captured outer variable +LL | func(|| { + | -- captured by this `FnMut` closure +LL | // Shouldn't suggest `move ||.as_ref()` here +LL | move || { + | ^^^^^^^ `var` is moved here +LL | let x = var; + | --- + | | + | variable moved due to use in closure + | move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait + | +note: if `NotCopyable` implemented `Clone`, you could clone the value + --> $DIR/option-content-move3.rs:2:1 + | +LL | struct NotCopyable; + | ^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let x = var; + | --- you could clone this value + +error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure + --> $DIR/option-content-move3.rs:24:21 + | +LL | let var = NotCopyableButCloneable; + | --- captured outer variable +... +LL | move || { + | ------- captured by this `FnMut` closure +LL | let x = var; + | ^^^ move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait + | +help: consider borrowing here + | +LL | let x = &var; + | + + +error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure + --> $DIR/option-content-move3.rs:23:9 + | +LL | let var = NotCopyableButCloneable; + | --- captured outer variable +LL | func(|| { + | -- captured by this `FnMut` closure +LL | // Shouldn't suggest `move ||.as_ref()` here +LL | move || { + | ^^^^^^^ `var` is moved here +LL | let x = var; + | --- + | | + | variable moved due to use in closure + | move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait + | +help: clone the value before moving it into the closure + | +LL ~ { +LL + let value = var.clone(); +LL ~ move || { +LL ~ let x = value; +LL | println!("{x:?}"); +LL ~ } +LL + } + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/suggestions/unnamable-types.rs b/tests/ui/suggestions/unnamable-types.rs index a4e32d7c8065..dd2c3536eb92 100644 --- a/tests/ui/suggestions/unnamable-types.rs +++ b/tests/ui/suggestions/unnamable-types.rs @@ -1,7 +1,7 @@ // Test that we do not suggest to add type annotations for unnamable types. #![crate_type="lib"] -#![feature(coroutines)] +#![feature(coroutines, stmt_expr_attributes)] const A = 5; //~^ ERROR: missing type for `const` item @@ -34,6 +34,6 @@ const F = S { t: foo }; //~| HELP: provide a type for the constant -const G = || -> i32 { yield 0; return 1; }; +const G = #[coroutine] || -> i32 { yield 0; return 1; }; //~^ ERROR: missing type for `const` item //~| NOTE: however, the inferred type diff --git a/tests/ui/suggestions/unnamable-types.stderr b/tests/ui/suggestions/unnamable-types.stderr index d003b91691c0..6623678fd0c2 100644 --- a/tests/ui/suggestions/unnamable-types.stderr +++ b/tests/ui/suggestions/unnamable-types.stderr @@ -52,14 +52,14 @@ LL | const F = S { t: foo }; error: missing type for `const` item --> $DIR/unnamable-types.rs:37:8 | -LL | const G = || -> i32 { yield 0; return 1; }; +LL | const G = #[coroutine] || -> i32 { yield 0; return 1; }; | ^ | -note: however, the inferred type `{coroutine@$DIR/unnamable-types.rs:37:11: 37:20}` cannot be named - --> $DIR/unnamable-types.rs:37:11 +note: however, the inferred type `{coroutine@$DIR/unnamable-types.rs:37:24: 37:33}` cannot be named + --> $DIR/unnamable-types.rs:37:24 | -LL | const G = || -> i32 { yield 0; return 1; }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const G = #[coroutine] || -> i32 { yield 0; return 1; }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr index 14e67727d0ba..e880d05a4dd3 100644 --- a/tests/ui/traits/next-solver/coroutine.fail.stderr +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr @@ -1,16 +1,16 @@ -error[E0277]: the trait bound `{coroutine@$DIR/coroutine.rs:18:21: 18:23}: Coroutine` is not satisfied - --> $DIR/coroutine.rs:18:21 +error[E0277]: the trait bound `{coroutine@$DIR/coroutine.rs:20:9: 20:11}: Coroutine` is not satisfied + --> $DIR/coroutine.rs:20:9 | -LL | needs_coroutine(|| { - | _____---------------_^ - | | | - | | required by a bound introduced by this call +LL | needs_coroutine( + | --------------- required by a bound introduced by this call +LL | #[coroutine] +LL | / || { LL | | LL | | LL | | -LL | | yield (); -LL | | }); - | |_____^ the trait `Coroutine` is not implemented for `{coroutine@$DIR/coroutine.rs:18:21: 18:23}` +LL | | yield (); +LL | | }, + | |_________^ the trait `Coroutine` is not implemented for `{coroutine@$DIR/coroutine.rs:20:9: 20:11}` | note: required by a bound in `needs_coroutine` --> $DIR/coroutine.rs:14:28 @@ -18,19 +18,19 @@ note: required by a bound in `needs_coroutine` LL | fn needs_coroutine(_: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `needs_coroutine` -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:18:21: 18:23} as Coroutine>::Yield == B` - --> $DIR/coroutine.rs:18:21 +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Yield == B` + --> $DIR/coroutine.rs:20:9 | -LL | needs_coroutine(|| { - | _____---------------_^ - | | | - | | required by a bound introduced by this call +LL | needs_coroutine( + | --------------- required by a bound introduced by this call +LL | #[coroutine] +LL | / || { LL | | LL | | LL | | -LL | | yield (); -LL | | }); - | |_____^ types differ +LL | | yield (); +LL | | }, + | |_________^ types differ | note: required by a bound in `needs_coroutine` --> $DIR/coroutine.rs:14:41 @@ -38,19 +38,19 @@ note: required by a bound in `needs_coroutine` LL | fn needs_coroutine(_: impl Coroutine) {} | ^^^^^^^^^ required by this bound in `needs_coroutine` -error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:18:21: 18:23} as Coroutine>::Return == C` - --> $DIR/coroutine.rs:18:21 +error[E0271]: type mismatch resolving `<{coroutine@$DIR/coroutine.rs:20:9: 20:11} as Coroutine>::Return == C` + --> $DIR/coroutine.rs:20:9 | -LL | needs_coroutine(|| { - | _____---------------_^ - | | | - | | required by a bound introduced by this call +LL | needs_coroutine( + | --------------- required by a bound introduced by this call +LL | #[coroutine] +LL | / || { LL | | LL | | LL | | -LL | | yield (); -LL | | }); - | |_____^ types differ +LL | | yield (); +LL | | }, + | |_________^ types differ | note: required by a bound in `needs_coroutine` --> $DIR/coroutine.rs:14:52 diff --git a/tests/ui/traits/next-solver/coroutine.rs b/tests/ui/traits/next-solver/coroutine.rs index 2b5bf01cefd7..1882a62cf29c 100644 --- a/tests/ui/traits/next-solver/coroutine.rs +++ b/tests/ui/traits/next-solver/coroutine.rs @@ -15,18 +15,24 @@ fn needs_coroutine(_: impl Coroutine) {} #[cfg(fail)] fn main() { - needs_coroutine(|| { - //[fail]~^ ERROR Coroutine` is not satisfied - //[fail]~| ERROR as Coroutine>::Yield == B` - //[fail]~| ERROR as Coroutine>::Return == C` - yield (); - }); + needs_coroutine( + #[coroutine] + || { + //[fail]~^ ERROR Coroutine` is not satisfied + //[fail]~| ERROR as Coroutine>::Yield == B` + //[fail]~| ERROR as Coroutine>::Return == C` + yield (); + }, + ); } #[cfg(pass)] fn main() { - needs_coroutine(|_: A| { - let _: A = yield B; - C - }) + needs_coroutine( + #[coroutine] + |_: A| { + let _: A = yield B; + C + }, + ) } diff --git a/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs b/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs index cd14bc1fd098..0d9126d39933 100644 --- a/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs +++ b/tests/ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs @@ -9,6 +9,7 @@ mod gen { pub type CoroOnce = impl Coroutine; pub const fn const_coroutine(yielding: Y, returning: R) -> CoroOnce { + #[coroutine] move || { yield yielding; diff --git a/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs b/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs index 78a1d5116bed..899e81ed562f 100644 --- a/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/issue-58662-coroutine-with-lifetime.rs @@ -8,6 +8,7 @@ use std::pin::Pin; type RandCoroutine<'a> = impl Coroutine + 'a; fn rand_coroutine<'a>(rng: &'a ()) -> RandCoroutine<'a> { + #[coroutine] move || { let _rng = rng; loop { @@ -19,6 +20,7 @@ fn rand_coroutine<'a>(rng: &'a ()) -> RandCoroutine<'a> { pub type RandCoroutineWithIndirection<'c> = impl Coroutine + 'c; pub fn rand_coroutine_with_indirection<'a>(rng: &'a ()) -> RandCoroutineWithIndirection<'a> { fn helper<'b>(rng: &'b ()) -> impl 'b + Coroutine { + #[coroutine] move || { let _rng = rng; loop { diff --git a/tests/ui/type-alias-impl-trait/issue-94429.rs b/tests/ui/type-alias-impl-trait/issue-94429.rs index 306e73003fa9..11beed06a20c 100644 --- a/tests/ui/type-alias-impl-trait/issue-94429.rs +++ b/tests/ui/type-alias-impl-trait/issue-94429.rs @@ -14,6 +14,7 @@ impl Runnable for Implementor { fn run(&mut self) -> Self::Coro { //~^ ERROR: type mismatch resolving + #[coroutine] move || { yield 1; } diff --git a/tests/ui/type-alias-impl-trait/issue-94429.stderr b/tests/ui/type-alias-impl-trait/issue-94429.stderr index 5d081e6b1eff..4c2020becbe3 100644 --- a/tests/ui/type-alias-impl-trait/issue-94429.stderr +++ b/tests/ui/type-alias-impl-trait/issue-94429.stderr @@ -1,4 +1,4 @@ -error[E0271]: type mismatch resolving `<{coroutine@$DIR/issue-94429.rs:17:9: 17:16} as Coroutine>::Yield == ()` +error[E0271]: type mismatch resolving `<{coroutine@$DIR/issue-94429.rs:18:9: 18:16} as Coroutine>::Yield == ()` --> $DIR/issue-94429.rs:15:26 | LL | fn run(&mut self) -> Self::Coro { diff --git a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr index 23aa18d7156a..fc6f610ddd4c 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-1.stderr @@ -1,6 +1,9 @@ error[E0597]: `factorial` does not live long enough --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:15:17 | +LL | let mut factorial: Option u32>> = None; + | ------------- binding `factorial` declared here +LL | LL | let f = |x: u32| -> u32 { | --------------- value captured here LL | let g = factorial.as_ref().unwrap(); @@ -30,7 +33,9 @@ error[E0597]: `factorial` does not live long enough --> $DIR/unboxed-closures-failed-recursive-fn-1.rs:28:17 | LL | let mut factorial: Option u32 + 'static>> = None; - | ----------------------------------------- type annotation requires that `factorial` is borrowed for `'static` + | ------------- ----------------------------------------- type annotation requires that `factorial` is borrowed for `'static` + | | + | binding `factorial` declared here LL | LL | let f = |x: u32| -> u32 { | --------------- value captured here diff --git a/tests/ui/union/union-borrow-move-parent-sibling.stderr b/tests/ui/union/union-borrow-move-parent-sibling.stderr index 782fa63280ed..f8e9609cb1c5 100644 --- a/tests/ui/union/union-borrow-move-parent-sibling.stderr +++ b/tests/ui/union/union-borrow-move-parent-sibling.stderr @@ -54,7 +54,10 @@ note: if `MockVec` implemented `Clone`, you could clone the value --> $DIR/union-borrow-move-parent-sibling.rs:25:1 | LL | struct MockVec { - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let a = (u.x.0).0; + | --------- you could clone this value help: consider borrowing here | LL | let a = &(u.x.0).0; diff --git a/tests/ui/union/union-move.stderr b/tests/ui/union/union-move.stderr index 5ebb2716e5a0..d520fb00ea9d 100644 --- a/tests/ui/union/union-move.stderr +++ b/tests/ui/union/union-move.stderr @@ -20,7 +20,10 @@ note: if `U1` implemented `Clone`, you could clone the value --> $DIR/union-move.rs:9:1 | LL | union U1 { - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | move_out(x.f1_nocopy); + | ----------- you could clone this value error[E0382]: use of moved value: `x` --> $DIR/union-move.rs:42:18 @@ -44,7 +47,10 @@ note: if `U1` implemented `Clone`, you could clone the value --> $DIR/union-move.rs:9:1 | LL | union U1 { - | ^^^^^^^^ + | ^^^^^^^^ consider implementing `Clone` for this type +... +LL | move_out(x.f2_nocopy); + | ----------- you could clone this value error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait --> $DIR/union-move.rs:49:18 diff --git a/tests/ui/unop-move-semantics.stderr b/tests/ui/unop-move-semantics.stderr index 187dd66b2fe5..bc9b3ea99038 100644 --- a/tests/ui/unop-move-semantics.stderr +++ b/tests/ui/unop-move-semantics.stderr @@ -33,6 +33,14 @@ LL | !x; ... LL | use_mut(n); use_imm(m); | - borrow later used here + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/unop-move-semantics.rs:11:18 + | +LL | fn move_borrowed>(x: T, mut y: T) { + | ^ consider constraining this type parameter with `Clone` +LL | let m = &x; + | -- you could clone this value error[E0505]: cannot move out of `y` because it is borrowed --> $DIR/unop-move-semantics.rs:17:6 @@ -47,6 +55,15 @@ LL | !y; | ^ move out of `y` occurs here LL | use_mut(n); use_imm(m); | - borrow later used here + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/unop-move-semantics.rs:11:18 + | +LL | fn move_borrowed>(x: T, mut y: T) { + | ^ consider constraining this type parameter with `Clone` +LL | let m = &x; +LL | let n = &mut y; + | ------ you could clone this value error[E0507]: cannot move out of `*m` which is behind a mutable reference --> $DIR/unop-move-semantics.rs:24:6 @@ -59,6 +76,14 @@ LL | !*m; | note: calling this operator moves the value --> $SRC_DIR/core/src/ops/bit.rs:LL:COL +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/unop-move-semantics.rs:20:24 + | +LL | fn illegal_dereference>(mut x: T, y: T) { + | ^ consider constraining this type parameter with `Clone` +... +LL | !*m; + | -- you could clone this value error[E0507]: cannot move out of `*n` which is behind a shared reference --> $DIR/unop-move-semantics.rs:26:6 @@ -68,6 +93,15 @@ LL | !*n; | || | |move occurs because `*n` has type `T`, which does not implement the `Copy` trait | `*n` moved due to usage in operator + | +help: if `T` implemented `Clone`, you could clone the value + --> $DIR/unop-move-semantics.rs:20:24 + | +LL | fn illegal_dereference>(mut x: T, y: T) { + | ^ consider constraining this type parameter with `Clone` +... +LL | !*n; + | -- you could clone this value error: aborting due to 5 previous errors diff --git a/tests/ui/variance/variance-issue-20533.stderr b/tests/ui/variance/variance-issue-20533.stderr index 4515d313ec0a..03cada07a9e3 100644 --- a/tests/ui/variance/variance-issue-20533.stderr +++ b/tests/ui/variance/variance-issue-20533.stderr @@ -14,7 +14,10 @@ note: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let x = foo(&a); + | -- you could clone this value error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:41:14 @@ -32,7 +35,10 @@ note: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let x = bar(&a); + | -- you could clone this value error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:47:14 @@ -50,7 +56,10 @@ note: if `AffineU32` implemented `Clone`, you could clone the value --> $DIR/variance-issue-20533.rs:26:1 | LL | struct AffineU32(u32); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let x = baz(&a); + | -- you could clone this value error[E0505]: cannot move out of `a` because it is borrowed --> $DIR/variance-issue-20533.rs:53:14 diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs index 0009ed0e34c8..08b5517aae22 100644 --- a/tests/ui/weird-exprs.rs +++ b/tests/ui/weird-exprs.rs @@ -152,6 +152,7 @@ fn r#match() { } fn i_yield() { + #[coroutine] static || { yield yield yield yield yield yield yield yield yield; };