diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index b1785af444a17..28d1ec7d89564 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -926,10 +926,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { .get_address(self.location) } - fn dynamic_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { - unimplemented!(); - } - fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index d0aa7320b4b68..9c3b866aa3c6f 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -538,16 +538,6 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } - fn dynamic_alloca(&mut self, size: &'ll Value, align: Align) -> &'ll Value { - unsafe { - let alloca = - llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), size, UNNAMED); - llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); - // Cast to default addrspace if necessary - llvm::LLVMBuildPointerCast(self.llbuilder, alloca, self.cx().type_ptr(), UNNAMED) - } - } - fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value { unsafe { let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 91ada856d5977..5c34ab2e3040d 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1492,12 +1492,6 @@ unsafe extern "C" { Ty: &'a Type, Name: *const c_char, ) -> &'a Value; - pub(crate) fn LLVMBuildArrayAlloca<'a>( - B: &Builder<'a>, - Ty: &'a Type, - Val: &'a Value, - Name: *const c_char, - ) -> &'a Value; pub(crate) fn LLVMBuildLoad2<'a>( B: &Builder<'a>, Ty: &'a Type, @@ -1980,12 +1974,12 @@ unsafe extern "C" { pub(crate) fn LLVMRustBuildMinNum<'a>( B: &Builder<'a>, LHS: &'a Value, - LHS: &'a Value, + RHS: &'a Value, ) -> &'a Value; pub(crate) fn LLVMRustBuildMaxNum<'a>( B: &Builder<'a>, LHS: &'a Value, - LHS: &'a Value, + RHS: &'a Value, ) -> &'a Value; // Atomic Operations diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 10b44a1faf087..fa69820d5d2ed 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -140,8 +140,13 @@ enum LocalRef<'tcx, V> { Place(PlaceRef<'tcx, V>), /// `UnsizedPlace(p)`: `p` itself is a thin pointer (indirect place). /// `*p` is the wide pointer that references the actual unsized place. - /// Every time it is initialized, we have to reallocate the place - /// and update the wide pointer. That's the reason why it is indirect. + /// + /// MIR only supports unsized args, not dynamically-sized locals, so + /// new unsized temps don't exist and we must reuse the referred-to place. + /// + /// FIXME: Since the removal of unsized locals in , + /// can we maybe use `Place` here? Or refactor it in another way? There are quite a few + /// `UnsizedPlace => bug` branches now. UnsizedPlace(PlaceRef<'tcx, V>), /// The backend [`OperandValue`] has already been generated. Operand(OperandRef<'tcx, V>), @@ -498,7 +503,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( LocalRef::Place(PlaceRef::new_sized(llarg, arg.layout)) } } - // Unsized indirect qrguments + // Unsized indirect arguments PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { // As the storage for the indirect argument lives during // the whole function call, we just copy the wide pointer. diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index e5b95e5ecc55f..231c1c1017a97 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -16,9 +16,9 @@ use tracing::{debug, instrument}; use super::place::{PlaceRef, PlaceValue}; use super::rvalue::transmute_scalar; use super::{FunctionCx, LocalRef}; +use crate::MemFlags; use crate::common::IntPredicate; use crate::traits::*; -use crate::{MemFlags, size_of_val}; /// The representation of a Rust value. The enum variant is in fact /// uniquely determined by the value's type, but is kept as a @@ -861,44 +861,6 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { } } } - - pub fn store_unsized>( - self, - bx: &mut Bx, - indirect_dest: PlaceRef<'tcx, V>, - ) { - debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest); - // `indirect_dest` must have `*mut T` type. We extract `T` out of it. - let unsized_ty = indirect_dest - .layout - .ty - .builtin_deref(true) - .unwrap_or_else(|| bug!("indirect_dest has non-pointer type: {:?}", indirect_dest)); - - let OperandValue::Ref(PlaceValue { llval: llptr, llextra: Some(llextra), .. }) = self - else { - bug!("store_unsized called with a sized value (or with an extern type)") - }; - - // Allocate an appropriate region on the stack, and copy the value into it. Since alloca - // doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the - // pointer manually. - let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); - let one = bx.const_usize(1); - 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.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); - let dst = bx.inbounds_ptradd(alloca, offset); - bx.memcpy(dst, min_align, llptr, min_align, size, MemFlags::empty()); - - // Store the allocated region and the extra to the indirect place. - let indirect_operand = OperandValue::Pair(dst, llextra); - indirect_operand.store(bx, indirect_dest); - } } impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index cbbb0196890fd..ae30b33902c3c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -327,27 +327,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(imm) } - pub(crate) fn codegen_rvalue_unsized( - &mut self, - bx: &mut Bx, - indirect_dest: PlaceRef<'tcx, Bx::Value>, - rvalue: &mir::Rvalue<'tcx>, - ) { - debug!( - "codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})", - indirect_dest.val.llval, rvalue - ); - - match *rvalue { - mir::Rvalue::Use(ref operand) => { - let cg_operand = self.codegen_operand(bx, operand); - cg_operand.val.store_unsized(bx, indirect_dest); - } - - _ => bug!("unsized assignment other than `Rvalue::Use`"), - } - } - pub(crate) fn codegen_rvalue_operand( &mut self, bx: &mut Bx, diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index cd55a838a7561..f164e0f912373 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -15,7 +15,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match self.locals[index] { LocalRef::Place(cg_dest) => self.codegen_rvalue(bx, cg_dest, rvalue), LocalRef::UnsizedPlace(cg_indirect_dest) => { - self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue) + let ty = cg_indirect_dest.layout.ty; + span_bug!( + statement.source_info.span, + "cannot reallocate from `UnsizedPlace({ty})` \ + into `{rvalue:?}`; dynamic alloca is not supported", + ); } LocalRef::PendingOperand => { let operand = self.codegen_rvalue_operand(bx, rvalue); diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 9d367748c2a8a..1f266514f346f 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -224,7 +224,6 @@ pub trait BuilderMethods<'a, 'tcx>: fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> 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_expand/messages.ftl b/compiler/rustc_expand/messages.ftl index 3fc0fa0619145..89d6e62834d66 100644 --- a/compiler/rustc_expand/messages.ftl +++ b/compiler/rustc_expand/messages.ftl @@ -133,6 +133,32 @@ expand_module_multiple_candidates = expand_must_repeat_once = this must repeat at least once +expand_mve_extra_tokens = + unexpected trailing tokens + .label = for this metavariable expression + .range = the `{$name}` metavariable expression takes between {$min_or_exact_args} and {$max_args} arguments + .exact = the `{$name}` metavariable expression takes {$min_or_exact_args -> + [zero] no arguments + [one] a single argument + *[other] {$min_or_exact_args} arguments + } + .suggestion = try removing {$extra_count -> + [one] this token + *[other] these tokens + } + +expand_mve_missing_paren = + expected `(` + .label = for this this metavariable expression + .unexpected = unexpected token + .note = metavariable expressions use function-like parentheses syntax + .suggestion = try adding parentheses + +expand_mve_unrecognized_expr = + unrecognized metavariable expression + .label = not a valid metavariable expression + .note = valid metavariable expressions are {$valid_expr_list} + expand_mve_unrecognized_var = variable `{$key}` is not recognized in meta-variable expression diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index fdbc65aff688c..3ac5d2130535f 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -496,6 +496,50 @@ pub(crate) use metavar_exprs::*; mod metavar_exprs { use super::*; + #[derive(Diagnostic, Default)] + #[diag(expand_mve_extra_tokens)] + pub(crate) struct MveExtraTokens { + #[primary_span] + #[suggestion(code = "", applicability = "machine-applicable")] + pub span: Span, + #[label] + pub ident_span: Span, + pub extra_count: usize, + + // The rest is only used for specific diagnostics and can be default if neither + // `note` is `Some`. + #[note(expand_exact)] + pub exact_args_note: Option<()>, + #[note(expand_range)] + pub range_args_note: Option<()>, + pub min_or_exact_args: usize, + pub max_args: usize, + pub name: String, + } + + #[derive(Diagnostic)] + #[note] + #[diag(expand_mve_missing_paren)] + pub(crate) struct MveMissingParen { + #[primary_span] + #[label] + pub ident_span: Span, + #[label(expand_unexpected)] + pub unexpected_span: Option, + #[suggestion(code = "( /* ... */ )", applicability = "has-placeholders")] + pub insert_span: Option, + } + + #[derive(Diagnostic)] + #[note] + #[diag(expand_mve_unrecognized_expr)] + pub(crate) struct MveUnrecognizedExpr { + #[primary_span] + #[label] + pub span: Span, + pub valid_expr_list: &'static str, + } + #[derive(Diagnostic)] #[diag(expand_mve_unrecognized_var)] pub(crate) struct MveUnrecognizedVar { diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index ffd3548019a8e..d2b275ad20a9f 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -7,6 +7,8 @@ use rustc_macros::{Decodable, Encodable}; use rustc_session::parse::ParseSess; use rustc_span::{Ident, Span, Symbol}; +use crate::errors; + pub(crate) const RAW_IDENT_ERR: &str = "`${concat(..)}` currently does not support raw identifiers"; pub(crate) const UNSUPPORTED_CONCAT_ELEM_ERR: &str = "expected identifier or string literal"; @@ -40,11 +42,32 @@ impl MetaVarExpr { ) -> PResult<'psess, MetaVarExpr> { let mut iter = input.iter(); let ident = parse_ident(&mut iter, psess, outer_span)?; - let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = iter.next() else { - let msg = "meta-variable expression parameter must be wrapped in parentheses"; - return Err(psess.dcx().struct_span_err(ident.span, msg)); + let next = iter.next(); + let Some(TokenTree::Delimited(.., Delimiter::Parenthesis, args)) = next else { + // No `()`; wrong or no delimiters. Point at a problematic span or a place to + // add parens if it makes sense. + let (unexpected_span, insert_span) = match next { + Some(TokenTree::Delimited(..)) => (None, None), + Some(tt) => (Some(tt.span()), None), + None => (None, Some(ident.span.shrink_to_hi())), + }; + let err = + errors::MveMissingParen { ident_span: ident.span, unexpected_span, insert_span }; + return Err(psess.dcx().create_err(err)); }; - check_trailing_token(&mut iter, psess)?; + + // Ensure there are no trailing tokens in the braces, e.g. `${foo() extra}` + if iter.peek().is_some() { + let span = iter_span(&iter).expect("checked is_some above"); + let err = errors::MveExtraTokens { + span, + ident_span: ident.span, + extra_count: iter.count(), + ..Default::default() + }; + return Err(psess.dcx().create_err(err)); + } + let mut iter = args.iter(); let rslt = match ident.as_str() { "concat" => parse_concat(&mut iter, psess, outer_span, ident.span)?, @@ -56,18 +79,14 @@ impl MetaVarExpr { "index" => MetaVarExpr::Index(parse_depth(&mut iter, psess, ident.span)?), "len" => MetaVarExpr::Len(parse_depth(&mut iter, psess, ident.span)?), _ => { - let err_msg = "unrecognized meta-variable expression"; - let mut err = psess.dcx().struct_span_err(ident.span, err_msg); - err.span_suggestion( - ident.span, - "supported expressions are count, ignore, index and len", - "", - Applicability::MachineApplicable, - ); - return Err(err); + let err = errors::MveUnrecognizedExpr { + span: ident.span, + valid_expr_list: "`count`, `ignore`, `index`, `len`, and `concat`", + }; + return Err(psess.dcx().create_err(err)); } }; - check_trailing_token(&mut iter, psess)?; + check_trailing_tokens(&mut iter, psess, ident)?; Ok(rslt) } @@ -87,20 +106,51 @@ impl MetaVarExpr { } } -// Checks if there are any remaining tokens. For example, `${ignore(ident ... a b c ...)}` -fn check_trailing_token<'psess>( +/// Checks if there are any remaining tokens (for example, `${ignore($valid, extra)}`) and create +/// a diag with the correct arg count if so. +fn check_trailing_tokens<'psess>( iter: &mut TokenStreamIter<'_>, psess: &'psess ParseSess, + ident: Ident, ) -> PResult<'psess, ()> { - if let Some(tt) = iter.next() { - let mut diag = psess - .dcx() - .struct_span_err(tt.span(), format!("unexpected token: {}", pprust::tt_to_string(tt))); - diag.span_note(tt.span(), "meta-variable expression must not have trailing tokens"); - Err(diag) - } else { - Ok(()) + if iter.peek().is_none() { + // All tokens consumed, as expected + return Ok(()); } + + // `None` for max indicates the arg count must be exact, `Some` indicates a range is accepted. + let (min_or_exact_args, max_args) = match ident.as_str() { + "concat" => panic!("concat takes unlimited tokens but didn't eat them all"), + "ignore" => (1, None), + // 1 or 2 args + "count" => (1, Some(2)), + // 0 or 1 arg + "index" => (0, Some(1)), + "len" => (0, Some(1)), + other => unreachable!("unknown MVEs should be rejected earlier (got `{other}`)"), + }; + + let err = errors::MveExtraTokens { + span: iter_span(iter).expect("checked is_none above"), + ident_span: ident.span, + extra_count: iter.count(), + + exact_args_note: if max_args.is_some() { None } else { Some(()) }, + range_args_note: if max_args.is_some() { Some(()) } else { None }, + min_or_exact_args, + max_args: max_args.unwrap_or_default(), + name: ident.to_string(), + }; + Err(psess.dcx().create_err(err)) +} + +/// Returns a span encompassing all tokens in the iterator if there is at least one item. +fn iter_span(iter: &TokenStreamIter<'_>) -> Option { + let mut iter = iter.clone(); // cloning is cheap + let first_sp = iter.next()?.span(); + let last_sp = iter.last().map(TokenTree::span).unwrap_or(first_sp); + let span = first_sp.with_hi(last_sp.hi()); + Some(span) } /// Indicates what is placed in a `concat` parameter. For example, literals diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index eeb8d33ef65c3..eb8d671c939ce 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -241,6 +241,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg_expr.span, ObligationCauseCode::WellFormed(None), ); + + self.check_place_expr_if_unsized(fn_input_ty, arg_expr); } // First, let's unify the formal method signature with the expectation eagerly. @@ -543,6 +545,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// If `unsized_fn_params` is active, check that unsized values are place expressions. Since + /// the removal of `unsized_locals` in we can't + /// store them in MIR locals as temporaries. + /// + /// If `unsized_fn_params` is inactive, this will be checked in borrowck instead. + fn check_place_expr_if_unsized(&self, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if self.tcx.features().unsized_fn_params() && !expr.is_syntactic_place_expr() { + self.require_type_is_sized( + ty, + expr.span, + ObligationCauseCode::UnsizedNonPlaceExpr(expr.span), + ); + } + } + fn report_arg_errors( &self, compatibility_diagonal: IndexVec>, @@ -1873,7 +1890,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } hir::StmtKind::Semi(expr) => { - self.check_expr(expr); + let ty = self.check_expr(expr); + self.check_place_expr_if_unsized(ty, expr); } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 1a5a9765ce7a4..5bdde3a514e48 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -412,6 +412,10 @@ pub enum ObligationCauseCode<'tcx> { /// Obligations emitted during the normalization of a free type alias. TypeAlias(ObligationCauseCodeHandle<'tcx>, Span, DefId), + + /// Only reachable if the `unsized_fn_params` feature is used. Unsized function arguments must + /// be place expressions because we can't store them in MIR locals as temporaries. + UnsizedNonPlaceExpr(Span), } /// Whether a value can be extracted into a const. diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 3e64573aa0348..263d04ded912e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3697,6 +3697,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ); suggest_remove_deref(err, &expr); } + ObligationCauseCode::UnsizedNonPlaceExpr(span) => { + err.span_note( + span, + "unsized values must be place expressions and cannot be put in temporaries", + ); + } } } diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index c00585de06496..1bd12d818cfe6 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -151,7 +151,7 @@ pub const fn forget(t: T) { /// /// While Rust does not permit unsized locals since its removal in [#111942] it is /// still possible to call functions with unsized values from a function argument -/// or in-place construction. +/// or place expression. /// /// ```rust /// #![feature(unsized_fn_params, forget_unsized)] diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs index 003ac4f0cd37f..668e988abff39 100644 --- a/library/panic_unwind/src/seh.rs +++ b/library/panic_unwind/src/seh.rs @@ -61,6 +61,7 @@ struct Exception { // and its destructor is executed by the C++ runtime. When we take the Box // out of the exception, we need to leave the exception in a valid state // for its destructor to run without double-dropping the Box. + // We also construct this as None for copies of the exception. data: Option>, } @@ -264,7 +265,11 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor { // runtime under a try/catch block and the panic that we generate here will be // used as the result of the exception copy. This is used by the C++ runtime to // support capturing exceptions with std::exception_ptr, which we can't support -// because Box isn't clonable. +// because Box isn't clonable. Thus we throw an exception without data, +// which the C++ runtime will attempt to copy, which will once again fail, and +// a std::bad_exception instance ends up in the std::exception_ptr instance. +// The lack of data doesn't matter because the exception will never be rethrown +// - it is purely used to signal to the C++ runtime that copying failed. macro_rules! define_cleanup { ($abi:tt $abi2:tt) => { unsafe extern $abi fn exception_cleanup(e: *mut Exception) { @@ -278,7 +283,9 @@ macro_rules! define_cleanup { unsafe extern $abi2 fn exception_copy( _dest: *mut Exception, _src: *mut Exception ) -> *mut Exception { - panic!("Rust panics cannot be copied"); + unsafe { + throw_exception(None); + } } } } @@ -291,6 +298,10 @@ cfg_if::cfg_if! { } pub(crate) unsafe fn panic(data: Box) -> u32 { + unsafe { throw_exception(Some(data)) } +} + +unsafe fn throw_exception(data: Option>) -> ! { use core::intrinsics::{AtomicOrdering, atomic_store}; // _CxxThrowException executes entirely on this stack frame, so there's no @@ -300,8 +311,7 @@ pub(crate) unsafe fn panic(data: Box) -> u32 { // The ManuallyDrop is needed here since we don't want Exception to be // dropped when unwinding. Instead it will be dropped by exception_cleanup // which is invoked by the C++ runtime. - let mut exception = - ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data: Some(data) }); + let mut exception = ManuallyDrop::new(Exception { canary: (&raw const TYPE_DESCRIPTOR), data }); let throw_ptr = (&raw mut exception) as *mut _; // This... may seems surprising, and justifiably so. On 32-bit MSVC the diff --git a/library/proc_macro/src/bridge/symbol.rs b/library/proc_macro/src/bridge/symbol.rs index 6a1cecd69fb5f..57ca7db9fcdd7 100644 --- a/library/proc_macro/src/bridge/symbol.rs +++ b/library/proc_macro/src/bridge/symbol.rs @@ -33,7 +33,7 @@ impl Symbol { /// Validates and normalizes before converting it to a symbol. pub(crate) fn new_ident(string: &str, is_raw: bool) -> Self { // Fast-path: check if this is a valid ASCII identifier - if Self::is_valid_ascii_ident(string.as_bytes()) { + if Self::is_valid_ascii_ident(string.as_bytes()) || string == "$crate" { if is_raw && !Self::can_be_raw(string) { panic!("`{}` cannot be a raw identifier", string); } @@ -79,7 +79,7 @@ impl Symbol { // Mimics the behavior of `Symbol::can_be_raw` from `rustc_span` fn can_be_raw(string: &str) -> bool { match string { - "_" | "super" | "self" | "Self" | "crate" => false, + "_" | "super" | "self" | "Self" | "crate" | "$crate" => false, _ => true, } } diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index bfc06f90d4f26..19e0d3413bb01 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -383,7 +383,10 @@ pub enum Subcommand { bless: bool, #[arg(long)] /// comma-separated list of other files types to check (accepts py, py:lint, - /// py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix) + /// py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck) + /// + /// Any argument can be prefixed with "auto:" to only run if + /// relevant files are modified (eg. "auto:py"). extra_checks: Option, #[arg(long)] /// rerun tests even if the inputs are unchanged diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 424f211c7d4bb..29591edc9cc6e 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -461,4 +461,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "`download-rustc` has been temporarily disabled for the library profile due to implementation bugs (see #142505).", }, + ChangeInfo { + change_id: 143398, + severity: ChangeSeverity::Info, + summary: "The --extra-checks flag now supports prefixing any check with `auto:` to only run it if relevant files are modified", + }, ]; diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index 69bd525a31221..3009dd85e9370 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -293,7 +293,7 @@ complete -c x -n "__fish_x_using_subcommand doc" -l skip-std-check-if-no-downloa complete -c x -n "__fish_x_using_subcommand doc" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x -n "__fish_x_using_subcommand test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r complete -c x -n "__fish_x_using_subcommand test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r -complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)' -r +complete -c x -n "__fish_x_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)' -r complete -c x -n "__fish_x_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r complete -c x -n "__fish_x_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r complete -c x -n "__fish_x_using_subcommand test" -l run -d 'whether to execute run-* tests' -r diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index 7b142ba97ce51..8002ec31592f3 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -339,7 +339,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { 'x;test' { [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)') [CompletionResult]::new('--compiletest-rustc-args', '--compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests') - [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)') + [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)') [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to') [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode') [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index e982cde634fc7..4766a5ee0c70c 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -293,7 +293,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l skip-std-check-if-no-d complete -c x.py -n "__fish_x.py_using_subcommand doc" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r -complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)' -r +complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l run -d 'whether to execute run-* tests' -r diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index f4b26fac0bcf4..1aff3c433b4c4 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -339,7 +339,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { 'x.py;test' { [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)') [CompletionResult]::new('--compiletest-rustc-args', '--compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests') - [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)') + [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck)') [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to') [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode') [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests') diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 8fc4f05225238..77f995c170499 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -338,7 +338,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \ '*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \ -'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck, spellcheck\:fix)]:EXTRA_CHECKS:_default' \ +'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck)]:EXTRA_CHECKS:_default' \ '--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \ '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \ '--run=[whether to execute run-* tests]:auto | always | never:_default' \ diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index c495e8318ba46..6c6d7b3f49fe5 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -338,7 +338,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \ '*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \ -'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck, spellcheck\:fix)]:EXTRA_CHECKS:_default' \ +'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck)]:EXTRA_CHECKS:_default' \ '--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \ '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \ '--run=[whether to execute run-* tests]:auto | always | never:_default' \ diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs index d2da63a970311..baab46752a51b 100644 --- a/src/tools/tidy/src/ext_tool_checks.rs +++ b/src/tools/tidy/src/ext_tool_checks.rs @@ -20,8 +20,11 @@ use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::process::Command; +use std::str::FromStr; use std::{fmt, fs, io}; +use crate::CiInfo; + const MIN_PY_REV: (u32, u32) = (3, 9); const MIN_PY_REV_STR: &str = "≥3.9"; @@ -36,15 +39,19 @@ const RUFF_CONFIG_PATH: &[&str] = &["src", "tools", "tidy", "config", "ruff.toml const RUFF_CACHE_PATH: &[&str] = &["cache", "ruff_cache"]; const PIP_REQ_PATH: &[&str] = &["src", "tools", "tidy", "config", "requirements.txt"]; +// this must be kept in sync with with .github/workflows/spellcheck.yml +const SPELLCHECK_DIRS: &[&str] = &["compiler", "library", "src/bootstrap", "src/librustdoc"]; + pub fn check( root_path: &Path, outdir: &Path, + ci_info: &CiInfo, bless: bool, extra_checks: Option<&str>, pos_args: &[String], bad: &mut bool, ) { - if let Err(e) = check_impl(root_path, outdir, bless, extra_checks, pos_args) { + if let Err(e) = check_impl(root_path, outdir, ci_info, bless, extra_checks, pos_args) { tidy_error!(bad, "{e}"); } } @@ -52,6 +59,7 @@ pub fn check( fn check_impl( root_path: &Path, outdir: &Path, + ci_info: &CiInfo, bless: bool, extra_checks: Option<&str>, pos_args: &[String], @@ -61,25 +69,45 @@ fn check_impl( // Split comma-separated args up let lint_args = match extra_checks { - Some(s) => s.strip_prefix("--extra-checks=").unwrap().split(',').collect(), + Some(s) => s + .strip_prefix("--extra-checks=") + .unwrap() + .split(',') + .map(|s| { + if s == "spellcheck:fix" { + eprintln!("warning: `spellcheck:fix` is no longer valid, use `--extra-checks=spellcheck --bless`"); + } + (ExtraCheckArg::from_str(s), s) + }) + .filter_map(|(res, src)| match res { + Ok(arg) => { + if arg.is_inactive_auto(ci_info) { + None + } else { + Some(arg) + } + } + Err(err) => { + // only warn because before bad extra checks would be silently ignored. + eprintln!("warning: bad extra check argument {src:?}: {err:?}"); + None + } + }) + .collect(), None => vec![], }; - if lint_args.contains(&"spellcheck:fix") { - return Err(Error::Generic( - "`spellcheck:fix` is no longer valid, use `--extra=check=spellcheck --bless`" - .to_string(), - )); + macro_rules! extra_check { + ($lang:ident, $kind:ident) => { + lint_args.iter().any(|arg| arg.matches(ExtraCheckLang::$lang, ExtraCheckKind::$kind)) + }; } - let python_all = lint_args.contains(&"py"); - let python_lint = lint_args.contains(&"py:lint") || python_all; - let python_fmt = lint_args.contains(&"py:fmt") || python_all; - let shell_all = lint_args.contains(&"shell"); - let shell_lint = lint_args.contains(&"shell:lint") || shell_all; - let cpp_all = lint_args.contains(&"cpp"); - let cpp_fmt = lint_args.contains(&"cpp:fmt") || cpp_all; - let spellcheck = lint_args.contains(&"spellcheck"); + let python_lint = extra_check!(Py, Lint); + let python_fmt = extra_check!(Py, Fmt); + let shell_lint = extra_check!(Shell, Lint); + let cpp_fmt = extra_check!(Cpp, Fmt); + let spellcheck = extra_check!(Spellcheck, None); let mut py_path = None; @@ -234,15 +262,9 @@ fn check_impl( if spellcheck { let config_path = root_path.join("typos.toml"); - // sync target files with .github/workflows/spellcheck.yml - let mut args = vec![ - "-c", - config_path.as_os_str().to_str().unwrap(), - "./compiler", - "./library", - "./src/bootstrap", - "./src/librustdoc", - ]; + let mut args = vec!["-c", config_path.as_os_str().to_str().unwrap()]; + + args.extend_from_slice(SPELLCHECK_DIRS); if bless { eprintln!("spellcheck files and fix"); @@ -638,3 +660,136 @@ impl From for Error { Self::Io(value) } } + +#[derive(Debug)] +enum ExtraCheckParseError { + #[allow(dead_code, reason = "shown through Debug")] + UnknownKind(String), + #[allow(dead_code)] + UnknownLang(String), + UnsupportedKindForLang, + /// Too many `:` + TooManyParts, + /// Tried to parse the empty string + Empty, + /// `auto` specified without lang part. + AutoRequiresLang, +} + +struct ExtraCheckArg { + auto: bool, + lang: ExtraCheckLang, + /// None = run all extra checks for the given lang + kind: Option, +} + +impl ExtraCheckArg { + fn matches(&self, lang: ExtraCheckLang, kind: ExtraCheckKind) -> bool { + self.lang == lang && self.kind.map(|k| k == kind).unwrap_or(true) + } + + /// Returns `true` if this is an auto arg and the relevant files are not modified. + fn is_inactive_auto(&self, ci_info: &CiInfo) -> bool { + if !self.auto { + return false; + } + let ext = match self.lang { + ExtraCheckLang::Py => ".py", + ExtraCheckLang::Cpp => ".cpp", + ExtraCheckLang::Shell => ".sh", + ExtraCheckLang::Spellcheck => { + return !crate::files_modified(ci_info, |s| { + SPELLCHECK_DIRS.iter().any(|dir| Path::new(s).starts_with(dir)) + }); + } + }; + !crate::files_modified(ci_info, |s| s.ends_with(ext)) + } + + fn has_supported_kind(&self) -> bool { + let Some(kind) = self.kind else { + // "run all extra checks" mode is supported for all languages. + return true; + }; + use ExtraCheckKind::*; + let supported_kinds: &[_] = match self.lang { + ExtraCheckLang::Py => &[Fmt, Lint], + ExtraCheckLang::Cpp => &[Fmt], + ExtraCheckLang::Shell => &[Lint], + ExtraCheckLang::Spellcheck => &[], + }; + supported_kinds.contains(&kind) + } +} + +impl FromStr for ExtraCheckArg { + type Err = ExtraCheckParseError; + + fn from_str(s: &str) -> Result { + let mut auto = false; + let mut parts = s.split(':'); + let Some(mut first) = parts.next() else { + return Err(ExtraCheckParseError::Empty); + }; + if first == "auto" { + let Some(part) = parts.next() else { + return Err(ExtraCheckParseError::AutoRequiresLang); + }; + auto = true; + first = part; + } + let second = parts.next(); + if parts.next().is_some() { + return Err(ExtraCheckParseError::TooManyParts); + } + let arg = Self { auto, lang: first.parse()?, kind: second.map(|s| s.parse()).transpose()? }; + if !arg.has_supported_kind() { + return Err(ExtraCheckParseError::UnsupportedKindForLang); + } + + Ok(arg) + } +} + +#[derive(PartialEq, Copy, Clone)] +enum ExtraCheckLang { + Py, + Shell, + Cpp, + Spellcheck, +} + +impl FromStr for ExtraCheckLang { + type Err = ExtraCheckParseError; + + fn from_str(s: &str) -> Result { + Ok(match s { + "py" => Self::Py, + "shell" => Self::Shell, + "cpp" => Self::Cpp, + "spellcheck" => Self::Spellcheck, + _ => return Err(ExtraCheckParseError::UnknownLang(s.to_string())), + }) + } +} + +#[derive(PartialEq, Copy, Clone)] +enum ExtraCheckKind { + Lint, + Fmt, + /// Never parsed, but used as a placeholder for + /// langs that never have a specific kind. + None, +} + +impl FromStr for ExtraCheckKind { + type Err = ExtraCheckParseError; + + fn from_str(s: &str) -> Result { + Ok(match s { + "lint" => Self::Lint, + "fmt" => Self::Fmt, + _ => return Err(ExtraCheckParseError::UnknownKind(s.to_string())), + }) + } +} diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 237737f0f1697..77855392b4dac 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -124,6 +124,40 @@ pub fn git_diff>(base_commit: &str, extra_arg: S) -> Option bool) -> bool { + if CiEnv::is_ci() { + // assume everything is modified on CI because we really don't want false positives there. + return true; + } + let Some(base_commit) = &ci_info.base_commit else { + eprintln!("No base commit, assuming all files are modified"); + return true; + }; + match crate::git_diff(&base_commit, "--name-status") { + Some(output) => { + let modified_files = output.lines().filter_map(|ln| { + let (status, name) = ln + .trim_end() + .split_once('\t') + .expect("bad format from `git diff --name-status`"); + if status == "M" { Some(name) } else { None } + }); + for modified_file in modified_files { + if pred(modified_file) { + return true; + } + } + false + } + None => { + eprintln!("warning: failed to run `git diff` to check for changes"); + eprintln!("warning: assuming all files are modified"); + true + } + } +} + pub mod alphabetical; pub mod bins; pub mod debug_artifacts; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index ef6ff5c9277aa..1eb5485f2b869 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -173,7 +173,15 @@ fn main() { }; check!(unstable_book, &src_path, collected); - check!(ext_tool_checks, &root_path, &output_directory, bless, extra_checks, pos_args); + check!( + ext_tool_checks, + &root_path, + &output_directory, + &ci_info, + bless, + extra_checks, + pos_args + ); }); if bad.load(Ordering::Relaxed) { diff --git a/src/tools/tidy/src/rustdoc_json.rs b/src/tools/tidy/src/rustdoc_json.rs index dfbb35d69f17a..19b8e79ec33a3 100644 --- a/src/tools/tidy/src/rustdoc_json.rs +++ b/src/tools/tidy/src/rustdoc_json.rs @@ -14,22 +14,10 @@ pub fn check(src_path: &Path, ci_info: &crate::CiInfo, bad: &mut bool) { }; // First we check that `src/rustdoc-json-types` was modified. - match crate::git_diff(&base_commit, "--name-status") { - Some(output) => { - if !output - .lines() - .any(|line| line.starts_with("M") && line.contains(RUSTDOC_JSON_TYPES)) - { - // `rustdoc-json-types` was not modified so nothing more to check here. - println!("`rustdoc-json-types` was not modified."); - return; - } - } - None => { - *bad = true; - eprintln!("error: failed to run `git diff` in rustdoc_json check"); - return; - } + if !crate::files_modified(ci_info, |p| p == RUSTDOC_JSON_TYPES) { + // `rustdoc-json-types` was not modified so nothing more to check here. + println!("`rustdoc-json-types` was not modified."); + return; } // Then we check that if `FORMAT_VERSION` was updated, the `Latest feature:` was also updated. match crate::git_diff(&base_commit, src_path.join("rustdoc-json-types")) { diff --git a/tests/codegen/enum/enum-match.rs b/tests/codegen/enum/enum-match.rs index 6da6ad1f078d3..98635008d068f 100644 --- a/tests/codegen/enum/enum-match.rs +++ b/tests/codegen/enum/enum-match.rs @@ -98,7 +98,7 @@ pub enum Enum2 { E, } -// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, [0-9]+\))?}} i8 @match2(i8{{.+}}%0) +// CHECK-LABEL: define{{( dso_local)?}} noundef{{( range\(i8 [0-9]+, -?[0-9]+\))?}} i8 @match2(i8{{.+}}%0) // CHECK-NEXT: start: // CHECK-NEXT: %[[REL_VAR:.+]] = add i8 %0, 2 // CHECK-NEXT: %[[REL_VAR_WIDE:.+]] = zext i8 %[[REL_VAR]] to i64 diff --git a/tests/ui/output-slot-variants.rs b/tests/ui/codegen/output-slot-init-vs-noninit.rs similarity index 65% rename from tests/ui/output-slot-variants.rs rename to tests/ui/codegen/output-slot-init-vs-noninit.rs index 97757e74fc4ea..55586843740a7 100644 --- a/tests/ui/output-slot-variants.rs +++ b/tests/ui/codegen/output-slot-init-vs-noninit.rs @@ -1,26 +1,48 @@ +//! Check that output slots work correctly for both initializing and non-initializing assignments. +//! +//! Regression test for . + //@ run-pass #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unknown_lints)] - #![allow(dead_assignment)] #![allow(unused_variables)] -struct A { a: isize, b: isize } -struct Abox { a: Box, b: Box } +struct A { + a: isize, + b: isize, +} -fn ret_int_i() -> isize { 10 } +struct Abox { + a: Box, + b: Box, +} -fn ret_ext_i() -> Box { Box::new(10) } +fn ret_int_i() -> isize { + 10 +} -fn ret_int_rec() -> A { A {a: 10, b: 10} } +fn ret_ext_i() -> Box { + Box::new(10) +} -fn ret_ext_rec() -> Box { Box::new(A {a: 10, b: 10}) } +fn ret_int_rec() -> A { + A { a: 10, b: 10 } +} -fn ret_ext_mem() -> Abox { Abox {a: Box::new(10), b: Box::new(10) } } +fn ret_ext_rec() -> Box { + Box::new(A { a: 10, b: 10 }) +} + +fn ret_ext_mem() -> Abox { + Abox { a: Box::new(10), b: Box::new(10) } +} -fn ret_ext_ext_mem() -> Box { Box::new(Abox{a: Box::new(10), b: Box::new(10) }) } +fn ret_ext_ext_mem() -> Box { + Box::new(Abox { a: Box::new(10), b: Box::new(10) }) +} pub fn main() { let mut int_i: isize; @@ -29,40 +51,28 @@ pub fn main() { let mut ext_rec: Box; let mut ext_mem: Abox; let mut ext_ext_mem: Box; - int_i = ret_int_i(); // initializing + int_i = ret_int_i(); // initializing int_i = ret_int_i(); // non-initializing - int_i = ret_int_i(); // non-initializing ext_i = ret_ext_i(); // initializing - ext_i = ret_ext_i(); // non-initializing - ext_i = ret_ext_i(); // non-initializing int_rec = ret_int_rec(); // initializing - int_rec = ret_int_rec(); // non-initializing - int_rec = ret_int_rec(); // non-initializing ext_rec = ret_ext_rec(); // initializing - ext_rec = ret_ext_rec(); // non-initializing - ext_rec = ret_ext_rec(); // non-initializing ext_mem = ret_ext_mem(); // initializing - ext_mem = ret_ext_mem(); // non-initializing - ext_mem = ret_ext_mem(); // non-initializing ext_ext_mem = ret_ext_ext_mem(); // initializing - ext_ext_mem = ret_ext_ext_mem(); // non-initializing - ext_ext_mem = ret_ext_ext_mem(); // non-initializing - } diff --git a/tests/ui/optimization-remark.rs b/tests/ui/codegen/remark-flag-functionality.rs similarity index 79% rename from tests/ui/optimization-remark.rs rename to tests/ui/codegen/remark-flag-functionality.rs index 165fc63c0076a..797c55ba830c1 100644 --- a/tests/ui/optimization-remark.rs +++ b/tests/ui/codegen/remark-flag-functionality.rs @@ -1,24 +1,26 @@ +//! Check that `-Cremark` flag correctly emits LLVM optimization remarks. +//! +//! Regression test for . + //@ build-pass //@ ignore-pass //@ revisions: all inline merge1 merge2 //@ compile-flags: --crate-type=lib -Cdebuginfo=1 -Copt-level=2 -// + // Check that remarks can be enabled individually or with "all": -// //@ [all] compile-flags: -Cremark=all //@ [inline] compile-flags: -Cremark=inline -// + // Check that values of -Cremark flag are accumulated: -// //@ [merge1] compile-flags: -Cremark=all -Cremark=giraffe //@ [merge2] compile-flags: -Cremark=inline -Cremark=giraffe + //@ dont-check-compiler-stderr //@ dont-require-annotations: NOTE #[no_mangle] #[inline(never)] -pub fn f() { -} +pub fn f() {} #[no_mangle] pub fn g() { diff --git a/tests/ui/codegen/shift-right-operand-mutation.rs b/tests/ui/codegen/shift-right-operand-mutation.rs new file mode 100644 index 0000000000000..b37a0baa6f8e7 --- /dev/null +++ b/tests/ui/codegen/shift-right-operand-mutation.rs @@ -0,0 +1,19 @@ +//! Ensure shift operations don't mutate their right operand. +//! +//! This test checks that expressions like `0 << b` don't accidentally +//! modify the variable `b` due to codegen issues with virtual registers. +//! +//! Regression test for . + +//@ run-pass + +pub fn main() { + let mut b: usize = 1; + while b < size_of::() { + // This shift operation should not mutate `b` + let _ = 0_usize << b; + b <<= 1; + std::hint::black_box(b); + } + assert_eq!(size_of::(), b); +} diff --git a/tests/ui/codegen/sret-aliasing-rules.rs b/tests/ui/codegen/sret-aliasing-rules.rs new file mode 100644 index 0000000000000..f35e722f764a5 --- /dev/null +++ b/tests/ui/codegen/sret-aliasing-rules.rs @@ -0,0 +1,28 @@ +//! Check that functions with sret results don't violate aliasing rules. +//! +//! When `foo = func(&mut foo)` is called, the compiler must avoid creating +//! two mutable references to the same variable simultaneously (one for the +//! parameter and one for the hidden sret out-pointer). +//! +//! Regression test for . + +//@ run-pass + +#[derive(Copy, Clone)] +pub struct Foo { + f1: isize, + _f2: isize, +} + +#[inline(never)] +pub fn foo(f: &mut Foo) -> Foo { + let ret = *f; + f.f1 = 0; + ret +} + +pub fn main() { + let mut f = Foo { f1: 8, _f2: 9 }; + f = foo(&mut f); + assert_eq!(f.f1, 8); +} diff --git a/tests/ui/paren-span.rs b/tests/ui/macros/macro-paren-span-diagnostic.rs similarity index 72% rename from tests/ui/paren-span.rs rename to tests/ui/macros/macro-paren-span-diagnostic.rs index c8cb63d5190d1..cbcb0231e4e30 100644 --- a/tests/ui/paren-span.rs +++ b/tests/ui/macros/macro-paren-span-diagnostic.rs @@ -1,5 +1,6 @@ -// Be smart about span of parenthesized expression in macro. +//! Check that error spans in parenthesized macro expressions point to the call site. +#[rustfmt::skip] macro_rules! paren { ($e:expr) => (($e)) // ^^^^ do not highlight here @@ -7,8 +8,9 @@ macro_rules! paren { mod m { pub struct S { - x: i32 + x: i32, } + pub fn make() -> S { S { x: 0 } } diff --git a/tests/ui/paren-span.stderr b/tests/ui/macros/macro-paren-span-diagnostic.stderr similarity index 82% rename from tests/ui/paren-span.stderr rename to tests/ui/macros/macro-paren-span-diagnostic.stderr index da2f57033a44e..ede6ff51c7129 100644 --- a/tests/ui/paren-span.stderr +++ b/tests/ui/macros/macro-paren-span-diagnostic.stderr @@ -1,5 +1,5 @@ error[E0616]: field `x` of struct `S` is private - --> $DIR/paren-span.rs:19:14 + --> $DIR/macro-paren-span-diagnostic.rs:21:14 | LL | paren!(s.x); | ^ private field diff --git a/tests/ui/macros/metavar-expressions/syntax-errors.rs b/tests/ui/macros/metavar-expressions/syntax-errors.rs index 8fc76a74baa42..585ea4d5979ce 100644 --- a/tests/ui/macros/metavar-expressions/syntax-errors.rs +++ b/tests/ui/macros/metavar-expressions/syntax-errors.rs @@ -30,7 +30,7 @@ macro_rules! metavar_with_literal_suffix { macro_rules! mve_without_parens { ( $( $i:ident ),* ) => { ${ count } }; - //~^ ERROR meta-variable expression parameter must be wrapped in parentheses + //~^ ERROR expected `(` } #[rustfmt::skip] @@ -45,9 +45,14 @@ macro_rules! open_brackets_with_lit { //~^ ERROR expected identifier } +macro_rules! mvs_missing_paren { + ( $( $i:ident ),* ) => { ${ count $i ($i) } }; + //~^ ERROR expected `(` +} + macro_rules! mve_wrong_delim { ( $( $i:ident ),* ) => { ${ count{i} } }; - //~^ ERROR meta-variable expression parameter must be wrapped in parentheses + //~^ ERROR expected `(` } macro_rules! invalid_metavar { @@ -64,28 +69,30 @@ macro_rules! open_brackets_with_group { macro_rules! extra_garbage_after_metavar { ( $( $i:ident ),* ) => { ${count() a b c} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${count($i a b c)} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${count($i, 1 a b c)} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${count($i) a b c} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${ignore($i) a b c} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${ignore($i a b c)} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${index() a b c} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${index(1 a b c)} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${index() a b c} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens ${index(1 a b c)} - //~^ ERROR unexpected token: a + //~^ ERROR unexpected trailing tokens + ${index(1, a b c)} + //~^ ERROR unexpected trailing tokens }; } @@ -111,7 +118,7 @@ macro_rules! unknown_ignore_ident { macro_rules! unknown_metavar { ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } }; - //~^ ERROR unrecognized meta-variable expression + //~^ ERROR unrecognized metavariable expression } fn main() {} diff --git a/tests/ui/macros/metavar-expressions/syntax-errors.stderr b/tests/ui/macros/metavar-expressions/syntax-errors.stderr index 20d2358facc2b..bf1c7673a6ce1 100644 --- a/tests/ui/macros/metavar-expressions/syntax-errors.stderr +++ b/tests/ui/macros/metavar-expressions/syntax-errors.stderr @@ -40,167 +40,165 @@ error: only unsuffixes integer literals are supported in meta-variable expressio LL | ( $( $i:ident ),* ) => { ${ index(1u32) } }; | ^^^^^ -error: meta-variable expression parameter must be wrapped in parentheses +error: expected `(` --> $DIR/syntax-errors.rs:32:33 | LL | ( $( $i:ident ),* ) => { ${ count } }; - | ^^^^^ + | ^^^^^- help: try adding parentheses: `( /* ... */ )` + | | + | for this this metavariable expression + | + = note: metavariable expressions use function-like parentheses syntax -error: meta-variable expression parameter must be wrapped in parentheses +error: expected `(` --> $DIR/syntax-errors.rs:49:33 | +LL | ( $( $i:ident ),* ) => { ${ count $i ($i) } }; + | ^^^^^ - unexpected token + | | + | for this this metavariable expression + | + = note: metavariable expressions use function-like parentheses syntax + +error: expected `(` + --> $DIR/syntax-errors.rs:54:33 + | LL | ( $( $i:ident ),* ) => { ${ count{i} } }; - | ^^^^^ + | ^^^^^ for this this metavariable expression + | + = note: metavariable expressions use function-like parentheses syntax error: expected identifier, found `123` - --> $DIR/syntax-errors.rs:54:23 + --> $DIR/syntax-errors.rs:59:23 | LL | () => { ${ignore($123)} } | ^^^ help: try removing `123` -error: unexpected token: a - --> $DIR/syntax-errors.rs:66:19 - | -LL | ${count() a b c} - | ^ - | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:66:19 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:71:19 | LL | ${count() a b c} - | ^ + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression -error: unexpected token: a - --> $DIR/syntax-errors.rs:68:20 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:73:20 | LL | ${count($i a b c)} - | ^ - | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:68:20 + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression | -LL | ${count($i a b c)} - | ^ + = note: the `count` metavariable expression takes between 1 and 2 arguments -error: unexpected token: a - --> $DIR/syntax-errors.rs:70:23 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:75:23 | LL | ${count($i, 1 a b c)} - | ^ + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:70:23 - | -LL | ${count($i, 1 a b c)} - | ^ + = note: the `count` metavariable expression takes between 1 and 2 arguments -error: unexpected token: a - --> $DIR/syntax-errors.rs:72:21 - | -LL | ${count($i) a b c} - | ^ - | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:72:21 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:77:21 | LL | ${count($i) a b c} - | ^ + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression -error: unexpected token: a - --> $DIR/syntax-errors.rs:75:22 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:80:22 | LL | ${ignore($i) a b c} - | ^ - | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:75:22 - | -LL | ${ignore($i) a b c} - | ^ + | ------ ^^^^^ help: try removing these tokens + | | + | for this metavariable expression -error: unexpected token: a - --> $DIR/syntax-errors.rs:77:21 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:82:21 | LL | ${ignore($i a b c)} - | ^ + | ------ ^^^^^ help: try removing these tokens + | | + | for this metavariable expression | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:77:21 - | -LL | ${ignore($i a b c)} - | ^ + = note: the `ignore` metavariable expression takes a single argument -error: unexpected token: a - --> $DIR/syntax-errors.rs:80:19 - | -LL | ${index() a b c} - | ^ - | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:80:19 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:85:19 | LL | ${index() a b c} - | ^ + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression -error: unexpected token: a - --> $DIR/syntax-errors.rs:82:19 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:87:19 | LL | ${index(1 a b c)} - | ^ - | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:82:19 + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression | -LL | ${index(1 a b c)} - | ^ + = note: the `index` metavariable expression takes between 0 and 1 arguments -error: unexpected token: a - --> $DIR/syntax-errors.rs:85:19 - | -LL | ${index() a b c} - | ^ - | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:85:19 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:90:19 | LL | ${index() a b c} - | ^ + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression -error: unexpected token: a - --> $DIR/syntax-errors.rs:87:19 +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:92:19 | LL | ${index(1 a b c)} - | ^ + | ----- ^^^^^ help: try removing these tokens + | | + | for this metavariable expression | -note: meta-variable expression must not have trailing tokens - --> $DIR/syntax-errors.rs:87:19 + = note: the `index` metavariable expression takes between 0 and 1 arguments + +error: unexpected trailing tokens + --> $DIR/syntax-errors.rs:94:18 | -LL | ${index(1 a b c)} - | ^ +LL | ${index(1, a b c)} + | ----- ^^^^^^^ help: try removing these tokens + | | + | for this metavariable expression + | + = note: the `index` metavariable expression takes between 0 and 1 arguments error: meta-variable expression depth must be a literal - --> $DIR/syntax-errors.rs:94:33 + --> $DIR/syntax-errors.rs:101:33 | LL | ( $( $i:ident ),* ) => { ${ index(IDX) } }; | ^^^^^ error: meta-variables within meta-variable expressions must be referenced using a dollar sign - --> $DIR/syntax-errors.rs:100:11 + --> $DIR/syntax-errors.rs:107:11 | LL | ${count(foo)} | ^^^^^ error: meta-variables within meta-variable expressions must be referenced using a dollar sign - --> $DIR/syntax-errors.rs:107:11 + --> $DIR/syntax-errors.rs:114:11 | LL | ${ignore(bar)} | ^^^^^^ -error: unrecognized meta-variable expression - --> $DIR/syntax-errors.rs:113:33 +error: unrecognized metavariable expression + --> $DIR/syntax-errors.rs:120:33 | LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } }; - | ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and len + | ^^^^^^^^^^^^^^ not a valid metavariable expression + | + = note: valid metavariable expressions are `count`, `ignore`, `index`, `len`, and `concat` error: expected identifier or string literal --> $DIR/syntax-errors.rs:38:14 @@ -215,10 +213,10 @@ LL | () => { ${ "hi" } }; | ^^^^ help: try removing `"hi"` error: expected identifier or string literal - --> $DIR/syntax-errors.rs:60:33 + --> $DIR/syntax-errors.rs:65:33 | LL | ( $( $i:ident ),* ) => { ${ {} } }; | ^^ -error: aborting due to 25 previous errors +error: aborting due to 27 previous errors diff --git a/tests/ui/out-pointer-aliasing.rs b/tests/ui/out-pointer-aliasing.rs deleted file mode 100644 index 0dfaa19fadb0f..0000000000000 --- a/tests/ui/out-pointer-aliasing.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ run-pass - -#[derive(Copy, Clone)] -pub struct Foo { - f1: isize, - _f2: isize, -} - -#[inline(never)] -pub fn foo(f: &mut Foo) -> Foo { - let ret = *f; - f.f1 = 0; - ret -} - -pub fn main() { - let mut f = Foo { - f1: 8, - _f2: 9, - }; - f = foo(&mut f); - assert_eq!(f.f1, 8); -} diff --git a/tests/ui/over-constrained-vregs.rs b/tests/ui/over-constrained-vregs.rs deleted file mode 100644 index 016a667e93785..0000000000000 --- a/tests/ui/over-constrained-vregs.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass - -#![allow(unused_must_use)] -// Regression test for issue #152. -pub fn main() { - let mut b: usize = 1_usize; - while b < std::mem::size_of::() { - 0_usize << b; - b <<= 1_usize; - println!("{}", b); - } -} diff --git a/tests/ui/panic_implementation-closures.rs b/tests/ui/panic_implementation-closures.rs deleted file mode 100644 index b161859bf9c51..0000000000000 --- a/tests/ui/panic_implementation-closures.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ build-pass (FIXME(62277): could be check-pass?) - -#![crate_type = "rlib"] -#![no_std] - -#[panic_handler] -pub fn panic_fmt(_: &::core::panic::PanicInfo) -> ! { - |x: u8| x; - loop {} -} diff --git a/tests/ui/panic-while-printing.rs b/tests/ui/panics/panic-during-display-formatting.rs similarity index 65% rename from tests/ui/panic-while-printing.rs rename to tests/ui/panics/panic-during-display-formatting.rs index 6505a69fef7cf..a307ee493854a 100644 --- a/tests/ui/panic-while-printing.rs +++ b/tests/ui/panics/panic-during-display-formatting.rs @@ -1,3 +1,5 @@ +//! Check that panics in `Display::fmt` during printing are properly handled. + //@ run-pass //@ needs-unwind @@ -18,8 +20,10 @@ impl Display for A { fn main() { set_output_capture(Some(Arc::new(Mutex::new(Vec::new())))); - assert!(std::panic::catch_unwind(|| { - eprintln!("{}", A); - }) - .is_err()); + assert!( + std::panic::catch_unwind(|| { + eprintln!("{}", A); + }) + .is_err() + ); } diff --git a/tests/ui/panics/panic-handler-closures.rs b/tests/ui/panics/panic-handler-closures.rs new file mode 100644 index 0000000000000..27fea92572050 --- /dev/null +++ b/tests/ui/panics/panic-handler-closures.rs @@ -0,0 +1,12 @@ +//! Check that closures can be used inside `#[panic_handler]` functions. + +//@ check-pass + +#![crate_type = "rlib"] +#![no_std] + +#[panic_handler] +pub fn panicfmt(_: &::core::panic::PanicInfo) -> ! { + |x: u8| x; + loop {} +} diff --git a/tests/ui/parser/ufcs-return-unused-parens.fixed b/tests/ui/parser/ufcs-return-unused-parens.fixed new file mode 100644 index 0000000000000..811a853b76933 --- /dev/null +++ b/tests/ui/parser/ufcs-return-unused-parens.fixed @@ -0,0 +1,20 @@ +//! Check that UFCS syntax works correctly in return statements +//! without requiring workaround parentheses. +//! +//! Regression test for . + +//@ run-pass +//@ run-rustfix + +#![allow(dead_code)] +#![warn(unused_parens)] + +fn with_parens(arg: T) -> String { + return ::to_string(&arg); //~ WARN unnecessary parentheses around `return` value +} + +fn no_parens(arg: T) -> String { + return ::to_string(&arg); +} + +fn main() {} diff --git a/tests/ui/parser/ufcs-return-unused-parens.rs b/tests/ui/parser/ufcs-return-unused-parens.rs new file mode 100644 index 0000000000000..6ea69ef9a2627 --- /dev/null +++ b/tests/ui/parser/ufcs-return-unused-parens.rs @@ -0,0 +1,20 @@ +//! Check that UFCS syntax works correctly in return statements +//! without requiring workaround parentheses. +//! +//! Regression test for . + +//@ run-pass +//@ run-rustfix + +#![allow(dead_code)] +#![warn(unused_parens)] + +fn with_parens(arg: T) -> String { + return (::to_string(&arg)); //~ WARN unnecessary parentheses around `return` value +} + +fn no_parens(arg: T) -> String { + return ::to_string(&arg); +} + +fn main() {} diff --git a/tests/ui/path-lookahead.stderr b/tests/ui/parser/ufcs-return-unused-parens.stderr similarity index 82% rename from tests/ui/path-lookahead.stderr rename to tests/ui/parser/ufcs-return-unused-parens.stderr index 2cc786fd947c2..6c09e98e7b105 100644 --- a/tests/ui/path-lookahead.stderr +++ b/tests/ui/parser/ufcs-return-unused-parens.stderr @@ -1,11 +1,11 @@ warning: unnecessary parentheses around `return` value - --> $DIR/path-lookahead.rs:10:12 + --> $DIR/ufcs-return-unused-parens.rs:13:12 | LL | return (::to_string(&arg)); | ^ ^ | note: the lint level is defined here - --> $DIR/path-lookahead.rs:5:9 + --> $DIR/ufcs-return-unused-parens.rs:10:9 | LL | #![warn(unused_parens)] | ^^^^^^^^^^^^^ diff --git a/tests/ui/path-lookahead.fixed b/tests/ui/path-lookahead.fixed deleted file mode 100644 index 440b22edd7d51..0000000000000 --- a/tests/ui/path-lookahead.fixed +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -//@ run-rustfix - -#![allow(dead_code)] -#![warn(unused_parens)] - -// Parser test for #37765 - -fn with_parens(arg: T) -> String { - return ::to_string(&arg); //~WARN unnecessary parentheses around `return` value -} - -fn no_parens(arg: T) -> String { - return ::to_string(&arg); -} - -fn main() {} diff --git a/tests/ui/path-lookahead.rs b/tests/ui/path-lookahead.rs deleted file mode 100644 index 7eaacd6bba78b..0000000000000 --- a/tests/ui/path-lookahead.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -//@ run-rustfix - -#![allow(dead_code)] -#![warn(unused_parens)] - -// Parser test for #37765 - -fn with_parens(arg: T) -> String { - return (::to_string(&arg)); //~WARN unnecessary parentheses around `return` value -} - -fn no_parens(arg: T) -> String { - return ::to_string(&arg); -} - -fn main() {} diff --git a/tests/ui/proc-macro/auxiliary/mixed-site-span.rs b/tests/ui/proc-macro/auxiliary/mixed-site-span.rs index d837c88c9556a..18df712debc77 100644 --- a/tests/ui/proc-macro/auxiliary/mixed-site-span.rs +++ b/tests/ui/proc-macro/auxiliary/mixed-site-span.rs @@ -3,33 +3,89 @@ extern crate proc_macro; use proc_macro::*; + +#[proc_macro] +pub fn proc_macro_item(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro] +pub fn proc_macro_rules(_input: TokenStream) -> TokenStream { + let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site())); + let item_def = id("ItemDef"); + let local_def = id("local_def"); + let item_use = id("ItemUse"); + let local_use = id("local_use"); + let mut single_quote = Punct::new('\'', Spacing::Joint); + single_quote.set_span(Span::mixed_site()); + let label_use: TokenStream = [ + TokenTree::from(single_quote), + id("label_use"), + ].iter().cloned().collect(); + let dollar_crate = id("$crate"); + quote!( + use $dollar_crate::proc_macro_item as _; // OK + type A = $dollar_crate::ItemUse; // ERROR + + struct $item_def; + let $local_def = 0; + + $item_use; // OK + $local_use; // ERROR + break $label_use; // ERROR + ) +} + +#[proc_macro] +pub fn with_crate(input: TokenStream) -> TokenStream { + let mut input = input.into_iter(); + let TokenTree::Ident(mut krate) = input.next().unwrap() else { panic!("missing $crate") }; + let TokenTree::Ident(span) = input.next().unwrap() else { panic!("missing span") }; + let TokenTree::Ident(ident) = input.next().unwrap() else { panic!("missing ident") }; + + match (krate.to_string().as_str(), span.to_string().as_str()) { + ("$crate", "input") => {}, + (_, "input") => krate = Ident::new("$crate", krate.span()), + + ("$crate", "mixed") => krate.set_span(Span::mixed_site()), + (_, "mixed") => krate = Ident::new("$crate", Span::mixed_site()), + + ("$crate", "call") => krate.set_span(Span::call_site()), + (_, "call") => krate = Ident::new("$crate", Span::call_site()), + + (_, x) => panic!("bad span {}", x), + } + + quote!(use $krate::$ident as _;) +} + #[proc_macro] -pub fn proc_macro_rules(input: TokenStream) -> TokenStream { - if input.is_empty() { - let id = |s| TokenTree::from(Ident::new(s, Span::mixed_site())); - let item_def = id("ItemDef"); - let local_def = id("local_def"); - let item_use = id("ItemUse"); - let local_use = id("local_use"); - let mut single_quote = Punct::new('\'', Spacing::Joint); - single_quote.set_span(Span::mixed_site()); - let label_use: TokenStream = [ - TokenTree::from(single_quote), - id("label_use"), - ].iter().cloned().collect(); - quote!( - struct $item_def; - let $local_def = 0; - - $item_use; // OK - $local_use; // ERROR - break $label_use; // ERROR - ) - } else { - let mut dollar_crate = input.into_iter().next().unwrap(); - dollar_crate.set_span(Span::mixed_site()); - quote!( - type A = $dollar_crate::ItemUse; - ) +pub fn declare_macro(input: TokenStream) -> TokenStream { + let mut input = input.into_iter(); + let TokenTree::Ident(mut krate) = input.next().unwrap() else { panic!("missing $crate") }; + let TokenTree::Ident(span) = input.next().unwrap() else { panic!("missing span") }; + let TokenTree::Ident(ident) = input.next().unwrap() else { panic!("missing ident") }; + + + match (krate.to_string().as_str(), span.to_string().as_str()) { + ("$crate", "input") => {}, + (_, "input") => krate = Ident::new("$crate", krate.span()), + + ("$crate", "mixed") => krate.set_span(Span::mixed_site()), + (_, "mixed") => krate = Ident::new("$crate", Span::mixed_site()), + + ("$crate", "call") => krate.set_span(Span::call_site()), + (_, "call") => krate = Ident::new("$crate", Span::call_site()), + + (_, x) => panic!("bad span {}", x), } + + quote!( + #[macro_export] + macro_rules! $ident { + ($$i:ident) => { + use $krate::$$i as _; + }; + } + ) } diff --git a/tests/ui/proc-macro/auxiliary/token-site-span.rs b/tests/ui/proc-macro/auxiliary/token-site-span.rs new file mode 100644 index 0000000000000..39ad8368a5007 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/token-site-span.rs @@ -0,0 +1,30 @@ +// Testing token span hygiene. + +//@ proc-macro: mixed-site-span.rs + +extern crate mixed_site_span; + +use mixed_site_span::declare_macro; + +pub struct TokenItem; + +#[macro_export] +macro_rules! invoke_with_crate { + ($s:ident $i:ident) => { with_crate!{$crate $s $i} }; +} + +#[macro_export] +macro_rules! invoke_with_ident { + ($s:ident $i:ident) => { with_crate!{krate $s $i} }; + ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} }; +} + +macro_rules! local {() => { + declare_macro!{$crate input use_input_crate} + declare_macro!{$crate mixed use_mixed_crate} + declare_macro!{$crate call use_call_crate} +}} +local!{} +declare_macro!{krate input use_input_krate} +declare_macro!{krate mixed use_mixed_krate} +declare_macro!{krate call use_call_krate} diff --git a/tests/ui/proc-macro/mixed-site-span.rs b/tests/ui/proc-macro/mixed-site-span.rs index 2b5d97570438a..442b440c1211a 100644 --- a/tests/ui/proc-macro/mixed-site-span.rs +++ b/tests/ui/proc-macro/mixed-site-span.rs @@ -1,24 +1,174 @@ // Proc macros using `mixed_site` spans exhibit usual properties of `macro_rules` hygiene. +//@ aux-build: token-site-span.rs //@ proc-macro: mixed-site-span.rs -#[macro_use] extern crate mixed_site_span; +extern crate token_site_span; -struct ItemUse; +use mixed_site_span::{proc_macro_rules, with_crate}; +use token_site_span::{ + invoke_with_crate, invoke_with_ident, + use_input_crate, use_mixed_crate, use_call_crate, + use_input_krate, use_mixed_krate, use_call_krate, +}; + +pub struct ItemUse; fn main() { 'label_use: loop { let local_use = 1; proc_macro_rules!(); - //~^ ERROR use of undeclared label `'label_use` + //~^ ERROR cannot find type `ItemUse` in crate `$crate` + //~| ERROR use of undeclared label `'label_use` //~| ERROR cannot find value `local_use` in this scope ItemDef; // OK local_def; //~ ERROR cannot find value `local_def` in this scope } } -macro_rules! pass_dollar_crate { - () => (proc_macro_rules!($crate);) //~ ERROR cannot find type `ItemUse` in crate `$crate` -} -pass_dollar_crate!(); +// Successful resolutions of `mixed_site_span::proc_macro_item` +const _: () = { + invoke_with_crate!{mixed proc_macro_item} + invoke_with_ident!{mixed proc_macro_item} + invoke_with_ident!{krate mixed proc_macro_item} + with_crate!{krate mixed proc_macro_item} + + macro_rules! test {() => { + invoke_with_ident!{$crate mixed proc_macro_item} + with_crate!{$crate mixed proc_macro_item} + }} + test!(); +}; + +// Failed resolutions of `proc_macro_item` +const _: () = { + // token_site_span::proc_macro_item + invoke_with_crate!{input proc_macro_item} //~ ERROR unresolved import `$crate` + invoke_with_ident!{input proc_macro_item} //~ ERROR unresolved import `$crate` + invoke_with_crate!{call proc_macro_item} //~ ERROR unresolved import `$crate` + invoke_with_ident!{call proc_macro_item} //~ ERROR unresolved import `$crate` + invoke_with_ident!{hello call proc_macro_item} //~ ERROR unresolved import `$crate` + + // crate::proc_macro_item + invoke_with_ident!{krate input proc_macro_item} //~ ERROR unresolved import `$crate::proc_macro_item` + with_crate!{krate input proc_macro_item} //~ ERROR unresolved import `$crate::proc_macro_item` + with_crate!{krate call proc_macro_item} //~ ERROR unresolved import `$crate` + + macro_rules! test {() => { + // crate::proc_macro_item + invoke_with_ident!{$crate input proc_macro_item} //~ ERROR unresolved import `$crate` + with_crate!{$crate input proc_macro_item} //~ ERROR unresolved import `$crate` + with_crate!{$crate call proc_macro_item} //~ ERROR unresolved import `$crate` + + // token_site_span::proc_macro_item + invoke_with_ident!{$crate call proc_macro_item} //~ ERROR unresolved import `$crate` + }} + test!(); +}; + +// Successful resolutions of `token_site_span::TokenItem` +const _: () = { + invoke_with_crate!{input TokenItem} + invoke_with_ident!{input TokenItem} + invoke_with_crate!{call TokenItem} + invoke_with_ident!{call TokenItem} + invoke_with_ident!{hello call TokenItem} + + macro_rules! test {() => { + invoke_with_ident!{$crate call TokenItem} + }} + test!(); +}; + +// Failed resolutions of `TokenItem` +const _: () = { + // crate::TokenItem + invoke_with_ident!{krate input TokenItem} //~ ERROR unresolved import `$crate::TokenItem` + with_crate!{krate input TokenItem} //~ ERROR unresolved import `$crate::TokenItem` + with_crate!{krate call TokenItem} //~ ERROR unresolved import `$crate` + + // mixed_site_span::TokenItem + invoke_with_crate!{mixed TokenItem} //~ ERROR unresolved import `$crate` + invoke_with_ident!{mixed TokenItem} //~ ERROR unresolved import `$crate` + invoke_with_ident!{krate mixed TokenItem} //~ ERROR unresolved import `$crate` + with_crate!{krate mixed TokenItem} //~ ERROR unresolved import `$crate` + + macro_rules! test {() => { + // crate::TokenItem + invoke_with_ident!{$crate input TokenItem} //~ ERROR unresolved import `$crate` + with_crate!{$crate input TokenItem} //~ ERROR unresolved import `$crate` + with_crate!{$crate call TokenItem} //~ ERROR unresolved import `$crate` + + // mixed_site_span::TokenItem + invoke_with_ident!{$crate mixed TokenItem} //~ ERROR unresolved import `$crate` + with_crate!{$crate mixed TokenItem} //~ ERROR unresolved import `$crate` + + }} + test!(); +}; + + +// Successful resolutions of `crate::ItemUse` +const _: () = { + invoke_with_ident!{krate input ItemUse} + with_crate!{krate input ItemUse} + with_crate!{krate call ItemUse} + + macro_rules! test {() => { + invoke_with_ident!{$crate input ItemUse} + with_crate!{$crate input ItemUse} + with_crate!{$crate call ItemUse} + }} + test!(); +}; + +// Failed resolutions of `ItemUse` +const _: () = { + // token_site_span::ItemUse + invoke_with_crate!{input ItemUse} //~ ERROR unresolved import `$crate` + invoke_with_ident!{input ItemUse} //~ ERROR unresolved import `$crate` + + // mixed_site_span::ItemUse + invoke_with_crate!{mixed ItemUse} //~ ERROR unresolved import `$crate` + invoke_with_ident!{mixed ItemUse} //~ ERROR unresolved import `$crate` + invoke_with_ident!{krate mixed ItemUse} //~ ERROR unresolved import `$crate` + with_crate!{krate mixed ItemUse} //~ ERROR unresolved import `$crate` + + invoke_with_crate!{call ItemUse} //~ ERROR unresolved import `$crate` + invoke_with_ident!{call ItemUse} //~ ERROR unresolved import `$crate` + invoke_with_ident!{hello call ItemUse} //~ ERROR unresolved import `$crate` + + macro_rules! test {() => { + invoke_with_ident!{$crate mixed ItemUse} //~ ERROR unresolved import `$crate` + with_crate!{$crate mixed ItemUse} //~ ERROR unresolved import `$crate` + + invoke_with_ident!{$crate call ItemUse} //~ ERROR unresolved import `$crate` + }} + test!(); +}; + + +// Only mixed should see mixed_site_span::proc_macro_item +use_input_crate!{proc_macro_item} //~ ERROR unresolved import `$crate` +use_input_krate!{proc_macro_item} //~ ERROR unresolved import `$crate` +use_mixed_crate!{proc_macro_item} +use_mixed_krate!{proc_macro_item} +use_call_crate!{proc_macro_item} //~ ERROR unresolved import `$crate` +use_call_krate!{proc_macro_item} //~ ERROR unresolved import `$crate` + +// Only mixed should fail to see token_site_span::TokenItem +use_input_crate!{TokenItem} +use_input_krate!{TokenItem} +use_mixed_crate!{TokenItem} //~ ERROR unresolved import `$crate` +use_mixed_krate!{TokenItem} //~ ERROR unresolved import `$crate` +use_call_crate!{TokenItem} +use_call_krate!{TokenItem} + +// Everything should fail to see crate::ItemUse +use_input_crate!{ItemUse} //~ ERROR unresolved import `$crate` +use_input_krate!{ItemUse} //~ ERROR unresolved import `$crate` +use_mixed_crate!{ItemUse} //~ ERROR unresolved import `$crate` +use_mixed_krate!{ItemUse} //~ ERROR unresolved import `$crate` +use_call_crate!{ItemUse} //~ ERROR unresolved import `$crate` +use_call_krate!{ItemUse} //~ ERROR unresolved import `$crate` diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 1378608012464..d62031a853c05 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -1,13 +1,595 @@ +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:47:5 + | +LL | invoke_with_crate!{input proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:48:5 + | +LL | invoke_with_ident!{input proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:49:5 + | +LL | invoke_with_crate!{call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:50:5 + | +LL | invoke_with_ident!{call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:51:5 + | +LL | invoke_with_ident!{hello call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate::proc_macro_item` + --> $DIR/mixed-site-span.rs:54:5 + | +LL | invoke_with_ident!{krate input proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^ + | | | + | | help: a similar name exists in the module: `proc_macro_rules` + | no `proc_macro_item` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate::proc_macro_item` + --> $DIR/mixed-site-span.rs:55:5 + | +LL | with_crate!{krate input proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^---------------^ + | | | + | | help: a similar name exists in the module: `proc_macro_rules` + | no `proc_macro_item` in the root + | + = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:56:5 + | +LL | with_crate!{krate call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ + | | | + | | help: a similar name exists in the module: `proc_macro_rules` + | no `proc_macro_item` in the root + | + = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:60:28 + | +LL | invoke_with_ident!{$crate input proc_macro_item} + | ^^^^^^ --------------- help: a similar name exists in the module: `proc_macro_rules` + | | + | no `proc_macro_item` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:61:21 + | +LL | with_crate!{$crate input proc_macro_item} + | ^^^^^^ --------------- help: a similar name exists in the module: `proc_macro_rules` + | | + | no `proc_macro_item` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:62:9 + | +LL | with_crate!{$crate call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^---------------^ + | | | + | | help: a similar name exists in the module: `proc_macro_rules` + | no `proc_macro_item` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:67:5 + | +LL | test!(); + | ^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate::TokenItem` + --> $DIR/mixed-site-span.rs:87:5 + | +LL | invoke_with_ident!{krate input TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/mixed-site-span.rs:59:34 + | +LL | quote!(use $krate::$ident as token_site_span::TokenItem as _;) + | +++++++++++++++++++++++++++++ + +error[E0432]: unresolved import `$crate::TokenItem` + --> $DIR/mixed-site-span.rs:88:5 + | +LL | with_crate!{krate input TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/mixed-site-span.rs:59:34 + | +LL | quote!(use $krate::$ident as token_site_span::TokenItem as _;) + | +++++++++++++++++++++++++++++ + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:89:5 + | +LL | with_crate!{krate call TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - with_crate!{krate call TokenItem} +LL + token_site_span::TokenItem as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:92:5 + | +LL | invoke_with_crate!{mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:13:30 + | +LL - ($s:ident $i:ident) => { with_crate!{$crate $s $i} }; +LL + ($s:ident $i:ident) => { token_site_span::TokenItem as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:93:5 + | +LL | invoke_with_ident!{mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:18:30 + | +LL - ($s:ident $i:ident) => { with_crate!{krate $s $i} }; +LL + ($s:ident $i:ident) => { token_site_span::TokenItem as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:94:5 + | +LL | invoke_with_ident!{krate mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:19:39 + | +LL - ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} }; +LL + ($m:ident $s:ident $i:ident) => { token_site_span::TokenItem as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:95:5 + | +LL | with_crate!{krate mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - with_crate!{krate mixed TokenItem} +LL + token_site_span::TokenItem as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:99:28 + | +LL | invoke_with_ident!{$crate input TokenItem} + | ^^^^^^ no `TokenItem` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - invoke_with_ident!{$crate input TokenItem} +LL + invoke_with_ident!{token_site_span::TokenItem as _ input TokenItem} + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:100:21 + | +LL | with_crate!{$crate input TokenItem} + | ^^^^^^ no `TokenItem` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - with_crate!{$crate input TokenItem} +LL + with_crate!{token_site_span::TokenItem as _ input TokenItem} + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:101:9 + | +LL | with_crate!{$crate call TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - with_crate!{$crate call TokenItem} +LL + token_site_span::TokenItem as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:108:5 + | +LL | test!(); + | ^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:19:39 + | +LL - ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} }; +LL + ($m:ident $s:ident $i:ident) => { token_site_span::TokenItem as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:105:9 + | +LL | with_crate!{$crate mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - with_crate!{$crate mixed TokenItem} +LL + token_site_span::TokenItem as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:129:5 + | +LL | invoke_with_crate!{input ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:13:42 + | +LL - ($s:ident $i:ident) => { with_crate!{$crate $s $i} }; +LL + ($s:ident $i:ident) => { with_crate!{ItemUse as _ $s $i} }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:130:5 + | +LL | invoke_with_ident!{input ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:18:42 + | +LL - ($s:ident $i:ident) => { with_crate!{krate $s $i} }; +LL + ($s:ident $i:ident) => { with_crate!{ItemUse as _ $s $i} }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:133:5 + | +LL | invoke_with_crate!{mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:13:30 + | +LL - ($s:ident $i:ident) => { with_crate!{$crate $s $i} }; +LL + ($s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:134:5 + | +LL | invoke_with_ident!{mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:18:30 + | +LL - ($s:ident $i:ident) => { with_crate!{krate $s $i} }; +LL + ($s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:135:5 + | +LL | invoke_with_ident!{krate mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:19:39 + | +LL - ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} }; +LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:136:5 + | +LL | with_crate!{krate mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - with_crate!{krate mixed ItemUse} +LL + ItemUse as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:138:5 + | +LL | invoke_with_crate!{call ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:13:30 + | +LL - ($s:ident $i:ident) => { with_crate!{$crate $s $i} }; +LL + ($s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:139:5 + | +LL | invoke_with_ident!{call ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:18:30 + | +LL - ($s:ident $i:ident) => { with_crate!{krate $s $i} }; +LL + ($s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:140:5 + | +LL | invoke_with_ident!{hello call ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:19:39 + | +LL - ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} }; +LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:148:5 + | +LL | test!(); + | ^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:19:39 + | +LL - ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} }; +LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:144:9 + | +LL | with_crate!{$crate mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root +... +LL | test!(); + | ------- in this macro invocation + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + | +LL - with_crate!{$crate mixed ItemUse} +LL + ItemUse as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:148:5 + | +LL | test!(); + | ^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:19:39 + | +LL - ($m:ident $s:ident $i:ident) => { with_crate!{$m $s $i} }; +LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:153:1 + | +LL | use_input_crate!{proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `use_input_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:154:1 + | +LL | use_input_krate!{proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `use_input_krate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:157:1 + | +LL | use_call_crate!{proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `use_call_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:158:1 + | +LL | use_call_krate!{proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root + | + = note: this error originates in the macro `use_call_krate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:163:1 + | +LL | use_mixed_crate!{TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `use_mixed_crate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:24:5 + | +LL - declare_macro!{$crate mixed use_mixed_crate} +LL + token_site_span::TokenItem as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:164:1 + | +LL | use_mixed_krate!{TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root + | + = note: this error originates in the macro `use_mixed_krate` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct instead + --> $DIR/auxiliary/token-site-span.rs:29:1 + | +LL - declare_macro!{krate mixed use_mixed_krate} +LL + token_site_span::TokenItem as _ + | + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:169:1 + | +LL | use_input_crate!{ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `use_input_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:170:1 + | +LL | use_input_krate!{ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `use_input_krate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:171:1 + | +LL | use_mixed_crate!{ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `use_mixed_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:172:1 + | +LL | use_mixed_krate!{ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `use_mixed_krate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:173:1 + | +LL | use_call_crate!{ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `use_call_crate` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0432]: unresolved import `$crate` + --> $DIR/mixed-site-span.rs:174:1 + | +LL | use_call_krate!{ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root + | + = note: this error originates in the macro `use_call_krate` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0426]: use of undeclared label `'label_use` - --> $DIR/mixed-site-span.rs:13:9 + --> $DIR/mixed-site-span.rs:21:9 | LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ undeclared label `'label_use` | = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0412]: cannot find type `ItemUse` in crate `$crate` + --> $DIR/mixed-site-span.rs:21:9 + | +LL | proc_macro_rules!(); + | ^^^^^^^^^^^^^^^^^^^ not found in `$crate` + | + = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct + | +LL + use ItemUse; + | + error[E0425]: cannot find value `local_use` in this scope - --> $DIR/mixed-site-span.rs:13:9 + --> $DIR/mixed-site-span.rs:21:9 | LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` @@ -15,20 +597,12 @@ LL | proc_macro_rules!(); = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_def` in this scope - --> $DIR/mixed-site-span.rs:17:9 + --> $DIR/mixed-site-span.rs:26:9 | LL | local_def; | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` -error[E0412]: cannot find type `ItemUse` in crate `$crate` - --> $DIR/mixed-site-span.rs:24:1 - | -LL | pass_dollar_crate!(); - | ^^^^^^^^^^^^^^^^^^^^ not found in `$crate` - | - = note: this error originates in the macro `proc_macro_rules` which comes from the expansion of the macro `pass_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 4 previous errors +error: aborting due to 52 previous errors -Some errors have detailed explanations: E0412, E0425, E0426. +Some errors have detailed explanations: E0412, E0425, E0426, E0432. For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/partialeq_help.rs b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.rs similarity index 52% rename from tests/ui/partialeq_help.rs rename to tests/ui/traits/partialeq-ref-mismatch-diagnostic.rs index 34b88b8a86685..26ef8050b8769 100644 --- a/tests/ui/partialeq_help.rs +++ b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.rs @@ -1,8 +1,10 @@ +//! Check diagnostic messages for `PartialEq` trait bound mismatches between `&T` and `T`. + fn foo(a: &T, b: T) { a == b; //~ ERROR E0277 } -fn foo2(a: &T, b: T) where { +fn foo2(a: &T, b: T) { a == b; //~ ERROR E0277 } diff --git a/tests/ui/partialeq_help.stderr b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.stderr similarity index 80% rename from tests/ui/partialeq_help.stderr rename to tests/ui/traits/partialeq-ref-mismatch-diagnostic.stderr index f5de1308e8714..4cbd31656dc53 100644 --- a/tests/ui/partialeq_help.stderr +++ b/tests/ui/traits/partialeq-ref-mismatch-diagnostic.stderr @@ -1,5 +1,5 @@ error[E0277]: can't compare `&T` with `T` - --> $DIR/partialeq_help.rs:2:7 + --> $DIR/partialeq-ref-mismatch-diagnostic.rs:4:7 | LL | a == b; | ^^ no implementation for `&T == T` @@ -15,7 +15,7 @@ LL | fn foo(a: &T, b: T) where &T: PartialEq { | ++++++++++++++++++++++ error[E0277]: can't compare `&T` with `T` - --> $DIR/partialeq_help.rs:6:7 + --> $DIR/partialeq-ref-mismatch-diagnostic.rs:8:7 | LL | a == b; | ^^ no implementation for `&T == T` @@ -25,10 +25,10 @@ help: consider dereferencing here | LL | *a == b; | + -help: consider extending the `where` clause, but there might be an alternative better way to express this requirement +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement | LL | fn foo2(a: &T, b: T) where &T: PartialEq { - | ++++++++++++++++ + | ++++++++++++++++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/unsized-locals/unsized-exprs-rpass.rs b/tests/ui/unsized-locals/unsized-exprs-rpass.rs index 54ecd00034365..ce31bd63f7cc1 100644 --- a/tests/ui/unsized-locals/unsized-exprs-rpass.rs +++ b/tests/ui/unsized-locals/unsized-exprs-rpass.rs @@ -18,11 +18,6 @@ impl std::ops::Add for A<[u8]> { } fn main() { - udrop::<[u8]>(loop { - break *foo(); - }); - udrop::<[u8]>(if true { *foo() } else { *foo() }); - udrop::<[u8]>({ *foo() }); udrop::<[u8]>((*foo())); *afoo() + 42; udrop as fn([u8]); diff --git a/tests/ui/unsized-locals/unsized-exprs.stderr b/tests/ui/unsized-locals/unsized-exprs.stderr index 1b61254870f67..0455edbe8e77b 100644 --- a/tests/ui/unsized-locals/unsized-exprs.stderr +++ b/tests/ui/unsized-locals/unsized-exprs.stderr @@ -10,7 +10,11 @@ note: required because it appears within the type `A<[u8]>` | LL | struct A(X); | ^ - = note: structs must have a statically known size to be initialized +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-exprs.rs:19:22 + | +LL | udrop::>(A { 0: *foo() }); + | ^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/unsized-exprs.rs:21:22 @@ -24,7 +28,11 @@ note: required because it appears within the type `A<[u8]>` | LL | struct A(X); | ^ - = note: the return type of a function must have a statically known size +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-exprs.rs:21:22 + | +LL | udrop::>(A(*foo())); + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/unsized-locals/unsized-non-place-exprs.rs b/tests/ui/unsized-locals/unsized-non-place-exprs.rs new file mode 100644 index 0000000000000..d724fcf81a481 --- /dev/null +++ b/tests/ui/unsized-locals/unsized-non-place-exprs.rs @@ -0,0 +1,27 @@ +//! `#![feature(unsized_fn_params)]` lets you use unsized function parameters. In particular this +//! is load bearing for `Box: FnOnce()`. To do that, borrowck relaxes the requirement +//! that certain places must be `Sized`. But in #142911 we removed alloca support, so these +//! arguments cannot be put in temporaries (or ICE at codegen) That means when `unsized_fn_params` +//! is enabled, we must explicitly check that unsized function arguments are place expressions. +//! +//! Also see tests/ui/unsized_locals/unsized-exprs-rpass.rs + +#![feature(unsized_fn_params)] + +fn foo() -> Box<[u8]> { + Box::new(*b"foo") +} + +fn udrop(_x: T) {} + +fn main(){ + // NB The ordering of the following operations matters, otherwise errors get swallowed somehow. + + udrop::<[u8]>(if true { *foo() } else { *foo() }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + udrop::<[u8]>({ *foo() }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + udrop(match foo() { x => *x }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + udrop::<[u8]>({ loop { break *foo(); } }); //~ERROR the size for values of type `[u8]` cannot be known at compilation time + + { *foo() }; //~ERROR the size for values of type `[u8]` cannot be known at compilation time + { loop { break *foo(); } }; //~ERROR the size for values of type `[u8]` cannot be known at compilation time +} diff --git a/tests/ui/unsized-locals/unsized-non-place-exprs.stderr b/tests/ui/unsized-locals/unsized-non-place-exprs.stderr new file mode 100644 index 0000000000000..f9507e9a88858 --- /dev/null +++ b/tests/ui/unsized-locals/unsized-non-place-exprs.stderr @@ -0,0 +1,81 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:20:19 + | +LL | udrop::<[u8]>(if true { *foo() } else { *foo() }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:20:19 + | +LL | udrop::<[u8]>(if true { *foo() } else { *foo() }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:21:19 + | +LL | udrop::<[u8]>({ *foo() }); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:21:19 + | +LL | udrop::<[u8]>({ *foo() }); + | ^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:22:11 + | +LL | udrop(match foo() { x => *x }); + | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:22:11 + | +LL | udrop(match foo() { x => *x }); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:23:19 + | +LL | udrop::<[u8]>({ loop { break *foo(); } }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:23:19 + | +LL | udrop::<[u8]>({ loop { break *foo(); } }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:25:5 + | +LL | { *foo() }; + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:25:5 + | +LL | { *foo() }; + | ^^^^^^^^^^ + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-non-place-exprs.rs:26:5 + | +LL | { loop { break *foo(); } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: unsized values must be place expressions and cannot be put in temporaries + --> $DIR/unsized-non-place-exprs.rs:26:5 + | +LL | { loop { break *foo(); } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/triagebot.toml b/triagebot.toml index 4e3dff219f1d6..6b989102f1237 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -931,6 +931,15 @@ instead. """ cc = ["@tgross35"] +[mentions."library/stdarch"] +message = """ +`stdarch` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/stdarch](https://github.com/rust-lang/stdarch) \ +instead. +""" +cc = ["@Amanieu", "@folkertdev", "@sayantn"] + [mentions."library/core/src/intrinsics/simd.rs"] message = """ Some changes occurred to the platform-builtins intrinsics. Make sure the