diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 4651cf504fa5a..6f4cc83fd1050 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -296,6 +296,9 @@ pub enum AttributeKind { /// Represents `#[rustc_layout_scalar_valid_range_start]`. RustcLayoutScalarValidRangeStart(Box, Span), + /// Represents `#[rustc_object_lifetime_default]`. + RustcObjectLifetimeDefault, + /// Represents `#[rustc_skip_during_method_dispatch]`. SkipDuringMethodDispatch { array: bool, boxed_slice: bool, span: Span }, diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 17f7a7a2e6dd7..58ced8e328173 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { PubTransparent(..) => Yes, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, + RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, TrackCaller(..) => Yes, Used { .. } => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/must_use.rs b/compiler/rustc_attr_parsing/src/attributes/must_use.rs index a672d95612746..b5eb85f68b4f8 100644 --- a/compiler/rustc_attr_parsing/src/attributes/must_use.rs +++ b/compiler/rustc_attr_parsing/src/attributes/must_use.rs @@ -21,7 +21,16 @@ impl SingleAttributeParser for MustUseParser { span: cx.attr_span, reason: match args { ArgParser::NoArgs => None, - ArgParser::NameValue(name_value) => name_value.value_as_str(), + ArgParser::NameValue(name_value) => { + let Some(value_str) = name_value.value_as_str() else { + cx.expected_string_literal( + name_value.value_span, + Some(&name_value.value_as_lit()), + ); + return None; + }; + Some(value_str) + } ArgParser::List(_) => { let suggestions = >::TEMPLATE.suggestions(false, "must_use"); diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 7364a3f20e27f..e6b6a6fe3c9e5 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -57,3 +57,21 @@ fn parse_rustc_layout_scalar_valid_range( }; Some(Box::new(num.0)) } + +pub(crate) struct RustcObjectLifetimeDefaultParser; + +impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const TEMPLATE: AttributeTemplate = template!(Word); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + if let Err(span) = args.no_args() { + cx.expected_no_args(span); + return None; + } + + Some(AttributeKind::RustcObjectLifetimeDefault) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 6a03cde3a53a8..cfba06509325b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -29,6 +29,7 @@ use crate::attributes::must_use::MustUseParser; use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, + RustcObjectLifetimeDefaultParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -136,6 +137,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index a815aa8c7a8ae..6145f1e1d3e30 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -577,10 +577,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError { diag.code(E0565); } AttributeParseErrorReason::ExpectedNameValue(None) => { - diag.span_label( - self.span, - format!("expected this to be of the form `{name} = \"...\"`"), - ); + // The suggestion we add below this match already contains enough information } AttributeParseErrorReason::ExpectedNameValue(Some(name)) => { diag.span_label( diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fd8a2a6bc3544..7c69baba62e8b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1168,6 +1168,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { _, mir::Rvalue::Use(mir::Operand::Copy(place)), )), + .. }) = self.body[location.block].statements.get(location.statement_index) { self.body.local_decls[place.local].source_info.span diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4bb6a796be444..f8506d8b29b49 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4400,27 +4400,6 @@ impl ItemKind<'_> { _ => return None, }) } - - pub fn descr(&self) -> &'static str { - match self { - ItemKind::ExternCrate(..) => "extern crate", - ItemKind::Use(..) => "`use` import", - ItemKind::Static(..) => "static item", - ItemKind::Const(..) => "constant item", - ItemKind::Fn { .. } => "function", - ItemKind::Macro(..) => "macro", - ItemKind::Mod(..) => "module", - ItemKind::ForeignMod { .. } => "extern block", - ItemKind::GlobalAsm { .. } => "global asm item", - ItemKind::TyAlias(..) => "type alias", - ItemKind::Enum(..) => "enum", - ItemKind::Struct(..) => "struct", - ItemKind::Union(..) => "union", - ItemKind::Trait(..) => "trait", - ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "implementation", - } - } } /// A reference from an trait to one of its associated items. This diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9f39908c3b2f8..33e97766a027b 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1336,6 +1336,7 @@ impl BasicBlock { /// /// See [`BasicBlock`] for documentation on what basic blocks are at a high level. #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct BasicBlockData<'tcx> { /// List of statements in this block. pub statements: Vec>, diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index d16477adb7767..683d7b486171f 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -11,6 +11,7 @@ use crate::ty::CoroutineArgsExt; /// A statement in a basic block, including information about its source code. #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] +#[non_exhaustive] pub struct Statement<'tcx> { pub source_info: SourceInfo, pub kind: StatementKind<'tcx>, diff --git a/compiler/rustc_mir_transform/src/check_enums.rs b/compiler/rustc_mir_transform/src/check_enums.rs index e06e0c6122e8d..240da87ab278b 100644 --- a/compiler/rustc_mir_transform/src/check_enums.rs +++ b/compiler/rustc_mir_transform/src/check_enums.rs @@ -230,11 +230,11 @@ fn split_block( let block_data = &mut basic_blocks[location.block]; // Drain every statement after this one and move the current terminator to a new basic block. - let new_block = BasicBlockData { - statements: block_data.statements.split_off(location.statement_index), - terminator: block_data.terminator.take(), - is_cleanup: block_data.is_cleanup, - }; + let new_block = BasicBlockData::new_stmts( + block_data.statements.split_off(location.statement_index), + block_data.terminator.take(), + block_data.is_cleanup, + ); basic_blocks.push(new_block) } @@ -270,10 +270,9 @@ fn insert_discr_cast_to_u128<'tcx>( let mu_array = local_decls.push(LocalDecl::with_source_info(mu_array_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, mu_array_ty); - block_data.statements.push(Statement { - source_info, - kind: StatementKind::Assign(Box::new((mu_array, rvalue))), - }); + block_data + .statements + .push(Statement::new(source_info, StatementKind::Assign(Box::new((mu_array, rvalue))))); // Index into the array of MaybeUninit to get something that is actually // as wide as the discriminant. @@ -294,10 +293,10 @@ fn insert_discr_cast_to_u128<'tcx>( let op_as_int = local_decls.push(LocalDecl::with_source_info(operand_int_ty, source_info)).into(); let rvalue = Rvalue::Cast(CastKind::Transmute, source_op, operand_int_ty); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((op_as_int, rvalue))), - }); + StatementKind::Assign(Box::new((op_as_int, rvalue))), + )); (CastKind::IntToInt, Operand::Copy(op_as_int)) }; @@ -306,10 +305,10 @@ fn insert_discr_cast_to_u128<'tcx>( let rvalue = Rvalue::Cast(cast_kind, discr_ty_bits, discr.ty); let discr_in_discr_ty = local_decls.push(LocalDecl::with_source_info(discr.ty, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), - }); + StatementKind::Assign(Box::new((discr_in_discr_ty, rvalue))), + )); // Cast the discriminant to a u128 (base for comparisions of enum discriminants). let const_u128 = Ty::new_uint(tcx, ty::UintTy::U128); @@ -317,7 +316,7 @@ fn insert_discr_cast_to_u128<'tcx>( let discr = local_decls.push(LocalDecl::with_source_info(const_u128, source_info)).into(); block_data .statements - .push(Statement { source_info, kind: StatementKind::Assign(Box::new((discr, rvalue))) }); + .push(Statement::new(source_info, StatementKind::Assign(Box::new((discr, rvalue))))); discr } @@ -390,9 +389,9 @@ fn insert_uninhabited_enum_check<'tcx>( ) { let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::Use(Operand::Constant(Box::new(ConstOperand { span: source_info.span, @@ -400,7 +399,7 @@ fn insert_uninhabited_enum_check<'tcx>( const_: Const::Val(ConstValue::from_bool(false), tcx.types.bool), }))), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, @@ -463,19 +462,19 @@ fn insert_niche_check<'tcx>( let discr_diff: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.u128, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( discr_diff, Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(discr), start_const))), ))), - }); + )); let is_ok: Place<'_> = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); - block_data.statements.push(Statement { + block_data.statements.push(Statement::new( source_info, - kind: StatementKind::Assign(Box::new(( + StatementKind::Assign(Box::new(( is_ok, Rvalue::BinaryOp( // This is a `WrappingRange`, so make sure to get the wrapping right. @@ -483,7 +482,7 @@ fn insert_niche_check<'tcx>( Box::new((Operand::Copy(discr_diff), end_start_diff_const)), ), ))), - }); + )); block_data.terminator = Some(Terminator { source_info, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 8b1d864c9957d..6c2c571d240c9 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -303,6 +303,11 @@ fn emit_malformed_attribute( | sym::must_use | sym::track_caller | sym::link_name + | sym::export_name + | sym::rustc_macro_transparency + | sym::link_section + | sym::rustc_layout_scalar_valid_range_start + | sym::rustc_layout_scalar_valid_range_end ) { return; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4bc48cb6aca6f..1b965b9545c29 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -164,7 +164,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } Attribute::Parsed(AttributeKind::Repr(_)) => { /* handled below this loop and elsewhere */ } - + Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => { + self.check_object_lifetime_default(hir_id); + } &Attribute::Parsed(AttributeKind::PubTransparent(attr_span)) => { self.check_rustc_pub_transparent(attr_span, span, attrs) } @@ -303,7 +305,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::no_implicit_prelude, ..] => { self.check_generic_attr(hir_id, attr, target, Target::Mod) } - [sym::rustc_object_lifetime_default, ..] => self.check_object_lifetime_default(hir_id), [sym::proc_macro, ..] => { self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) } @@ -2831,7 +2832,7 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { .find(|item| !item.span.is_dummy()) // Skip prelude `use`s .map(|item| errors::ItemFollowingInnerAttr { span: if let Some(ident) = item.kind.ident() { ident.span } else { item.span }, - kind: item.kind.descr(), + kind: tcx.def_descr(item.owner_id.to_def_id()), }); let err = tcx.dcx().create_err(errors::InvalidAttrAtCrateLevel { span, diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index cfbd88bbe7998..fab13bb7c8535 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -4,7 +4,8 @@ use crate::ops; use crate::pin::Pin; use crate::task::{Context, Poll}; -/// A future represents an asynchronous computation obtained by use of [`async`]. +/// A future represents an asynchronous computation, commonly obtained by use of +/// [`async`]. /// /// A future is a value that might not have finished computing yet. This kind of /// "asynchronous value" makes it possible for a thread to continue doing useful @@ -68,13 +69,21 @@ pub trait Future { /// /// # Runtime characteristics /// - /// Futures alone are *inert*; they must be *actively* `poll`ed to make - /// progress, meaning that each time the current task is woken up, it should - /// actively re-`poll` pending futures that it still has an interest in. + /// Futures alone are *inert*; they must be *actively* `poll`ed for the + /// underlying computation to make progress, meaning that each time the + /// current task is woken up, it should actively re-`poll` pending futures + /// that it still has an interest in. /// - /// The `poll` function is not called repeatedly in a tight loop -- instead, - /// it should only be called when the future indicates that it is ready to - /// make progress (by calling `wake()`). If you're familiar with the + /// Having said that, some Futures may represent a value that is being + /// computed in a different task. In this case, the future's underlying + /// computation is simply acting as a conduit for a value being computed + /// by that other task, which will proceed independently of the Future. + /// Futures of this kind are typically obtained when spawning a new task into an + /// async runtime. + /// + /// The `poll` function should not be called repeatedly in a tight loop -- + /// instead, it should only be called when the future indicates that it is + /// ready to make progress (by calling `wake()`). If you're familiar with the /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures /// typically do *not* suffer the same problems of "all wakeups must poll /// all events"; they are more like `epoll(4)`. diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 98a3b784233f1..f55bdfeb3540d 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1083,11 +1083,13 @@ mod prim_str {} /// * [`Debug`] /// * [`Default`] /// * [`Hash`] +/// * [`Random`] /// * [`From<[T; N]>`][from] /// /// [from]: convert::From /// [`Debug`]: fmt::Debug /// [`Hash`]: hash::Hash +/// [`Random`]: random::Random /// /// The following traits are implemented for tuples of any length. These traits have /// implementations that are automatically generated by the compiler, so are not limited by diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 3ff55792431b8..6327c41f052c9 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -3,6 +3,7 @@ use crate::cmp::Ordering::{self, *}; use crate::marker::{ConstParamTy_, PointeeSized, StructuralPartialEq, UnsizedConstParamTy}; use crate::ops::ControlFlow::{self, Break, Continue}; +use crate::random::{Random, RandomSource}; // Recursive macro for implementing n-ary tuple functions and operations // @@ -139,6 +140,16 @@ macro_rules! tuple_impls { } } + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "random", issue = "130703")] + impl<$($T: Random),+> Random for ($($T,)+) { + fn random(source: &mut (impl RandomSource + ?Sized)) -> Self { + ($({ let x: $T = Random::random(source); x},)+) + } + } + } + maybe_tuple_doc! { $($T)+ @ #[stable(feature = "array_tuple_conv", since = "1.71.0")] diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 865ea620a283f..ea342ec9c128d 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -682,11 +682,11 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle/descriptor, or a clone of it, already holds an lock the exact behavior + /// If this file handle/descriptor, or a clone of it, already holds a lock the exact behavior /// is unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns, then an exclusive lock is held. /// - /// If the file not open for writing, it is unspecified whether this function returns an error. + /// If the file is not open for writing, it is unspecified whether this function returns an error. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. @@ -736,7 +736,7 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle/descriptor, or a clone of it, already holds an lock, the exact behavior + /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior /// is unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns, then a shared lock is held. /// @@ -790,11 +790,11 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle/descriptor, or a clone of it, already holds an lock, the exact behavior + /// If this file handle/descriptor, or a clone of it, already holds a lock, the exact behavior /// is unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns `Ok(true)`, then it has acquired an exclusive lock. /// - /// If the file not open for writing, it is unspecified whether this function returns an error. + /// If the file is not open for writing, it is unspecified whether this function returns an error. /// /// The lock will be released when this file (along with any other file descriptors/handles /// duplicated or inherited from it) is closed, or if the [`unlock`] method is called. @@ -855,7 +855,7 @@ impl File { /// other methods, such as [`read`] and [`write`] are platform specific, and it may or may not /// cause non-lockholders to block. /// - /// If this file handle, or a clone of it, already holds an lock, the exact behavior is + /// If this file handle, or a clone of it, already holds a lock, the exact behavior is /// unspecified and platform dependent, including the possibility that it will deadlock. /// However, if this method returns `Ok(true)`, then it has acquired a shared lock. /// diff --git a/src/bootstrap/defaults/bootstrap.dist.toml b/src/bootstrap/defaults/bootstrap.dist.toml index f0cb34eb45856..9daf9faac14a2 100644 --- a/src/bootstrap/defaults/bootstrap.dist.toml +++ b/src/bootstrap/defaults/bootstrap.dist.toml @@ -20,7 +20,6 @@ download-ci-llvm = false channel = "auto-detect" # Never download a rustc, distributions must build a fresh compiler. download-rustc = false -lld = true # Build the llvm-bitcode-linker llvm-bitcode-linker = true diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 83c0525d7c421..a7220515ca09d 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -120,14 +120,14 @@ impl Step for ToolBuild { match self.mode { Mode::ToolRustc => { - // If compiler was forced, its artifacts should be prepared earlier. + // If compiler was forced, its artifacts should have been prepared earlier. if !self.compiler.is_forced_compiler() { builder.std(self.compiler, self.compiler.host); builder.ensure(compile::Rustc::new(self.compiler, target)); } } Mode::ToolStd => { - // If compiler was forced, its artifacts should be prepared earlier. + // If compiler was forced, its artifacts should have been prepared earlier. if !self.compiler.is_forced_compiler() { builder.std(self.compiler, target) } diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 006c294d4458f..f873c62588bdd 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -436,4 +436,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "It is no longer possible to combine `rust.lld = true` with configuring external LLVM using `llvm.llvm-config`.", }, + ChangeInfo { + change_id: 143255, + severity: ChangeSeverity::Warning, + summary: "`llvm.lld` is no longer enabled by default for the dist profile.", + }, ]; diff --git a/src/ci/run.sh b/src/ci/run.sh index a6721a818b303..f58a067041dd8 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -86,13 +86,12 @@ fi # space required for CI artifacts. RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz" -if [ "$EXTERNAL_LLVM" = "1" ]; then - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.lld=false" -fi - # Enable the `c` feature for compiler_builtins, but only when the `compiler-rt` source is available # (to avoid spending a lot of time cloning llvm) if [ "$EXTERNAL_LLVM" = "" ]; then + # Enable building & shipping lld + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.lld=true" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.optimized-compiler-builtins" # Likewise, only demand we test all LLVM components if we know we built LLVM with them export COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS=1 diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs index 92427473a8ee9..6cc4b589a7207 100644 --- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -256,7 +256,10 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { cx, UNNECESSARY_SAFETY_COMMENT, span, - format!("{} has unnecessary safety comment", item.kind.descr()), + format!( + "{} has unnecessary safety comment", + cx.tcx.def_descr(item.owner_id.to_def_id()), + ), |diag| { diag.span_help(help_span, "consider removing the safety comment"); }, @@ -274,7 +277,10 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { cx, UNNECESSARY_SAFETY_COMMENT, span, - format!("{} has unnecessary safety comment", item.kind.descr()), + format!( + "{} has unnecessary safety comment", + cx.tcx.def_descr(item.owner_id.to_def_id()), + ), |diag| { diag.span_help(help_span, "consider removing the safety comment"); }, diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr index 8a2f201009a92..bfc14be5421fc 100644 --- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr +++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr @@ -240,7 +240,7 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: | = help: consider adding a safety comment on the preceding line -error: constant item has unnecessary safety comment +error: constant has unnecessary safety comment --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | const BIG_NUMBER: i32 = 1000000; diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr index e9c5e5f9f1146..20cdff5fcd12b 100644 --- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr +++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr @@ -240,7 +240,7 @@ LL | unsafe impl TrailingComment for () {} // SAFETY: | = help: consider adding a safety comment on the preceding line -error: constant item has unnecessary safety comment +error: constant has unnecessary safety comment --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:508:5 | LL | const BIG_NUMBER: i32 = 1000000; diff --git a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr index b56e8b354931c..732e6767c1780 100644 --- a/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_safety_comment.stderr @@ -1,4 +1,4 @@ -error: constant item has unnecessary safety comment +error: constant has unnecessary safety comment --> tests/ui/unnecessary_safety_comment.rs:6:5 | LL | const CONST: u32 = 0; @@ -12,7 +12,7 @@ LL | // SAFETY: = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]` -error: static item has unnecessary safety comment +error: static has unnecessary safety comment --> tests/ui/unnecessary_safety_comment.rs:10:5 | LL | static STATIC: u32 = 0; diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 9b9d94bbead09..cdce5d941d015 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -11,6 +11,7 @@ use serde::de::{Deserialize, Deserializer, Error as _}; pub use self::Mode::*; use crate::executor::{ColorConfig, OutputFormat}; +use crate::fatal; use crate::util::{Utf8PathBufExt, add_dylib_path}; macro_rules! string_enum { @@ -783,11 +784,13 @@ fn rustc_output(config: &Config, args: &[&str], envs: HashMap) - let output = match command.output() { Ok(output) => output, - Err(e) => panic!("error: failed to run {command:?}: {e}"), + Err(e) => { + fatal!("failed to run {command:?}: {e}"); + } }; if !output.status.success() { - panic!( - "error: failed to run {command:?}\n--- stdout\n{}\n--- stderr\n{}", + fatal!( + "failed to run {command:?}\n--- stdout\n{}\n--- stderr\n{}", String::from_utf8(output.stdout).unwrap(), String::from_utf8(output.stderr).unwrap(), ); diff --git a/src/tools/compiletest/src/diagnostics.rs b/src/tools/compiletest/src/diagnostics.rs new file mode 100644 index 0000000000000..207a6cb91d7ca --- /dev/null +++ b/src/tools/compiletest/src/diagnostics.rs @@ -0,0 +1,46 @@ +//! Collection of diagnostics helpers for `compiletest` *itself*. + +#[macro_export] +macro_rules! fatal { + ($($arg:tt)*) => { + let status = ::colored::Colorize::bright_red("FATAL: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + // This intentionally uses a seemingly-redundant panic to include backtrace location. + // + // FIXME: in the long term, we should handle "logic bug in compiletest itself" vs "fatal + // user error" separately. + panic!("fatal error"); + }; +} + +#[macro_export] +macro_rules! error { + ($($arg:tt)*) => { + let status = ::colored::Colorize::red("ERROR: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + }; +} + +#[macro_export] +macro_rules! warning { + ($($arg:tt)*) => { + let status = ::colored::Colorize::yellow("WARNING: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + }; +} + +#[macro_export] +macro_rules! help { + ($($arg:tt)*) => { + let status = ::colored::Colorize::cyan("HELP: "); + let status = ::colored::Colorize::bold(status); + eprint!("{status}"); + eprintln!($($arg)*); + }; +} diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 2b203bb309c63..5636a146b0f4d 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -15,6 +15,7 @@ use crate::errors::ErrorKind; use crate::executor::{CollectedTestDesc, ShouldPanic}; use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; use crate::header::needs::CachedNeedsConditions; +use crate::help; use crate::util::static_regex; pub(crate) mod auxiliary; @@ -920,9 +921,9 @@ fn iter_header( if !is_known_directive { *poisoned = true; - eprintln!( - "error: detected unknown compiletest test directive `{}` in {}:{}", - directive_line.raw_directive, testfile, line_number, + error!( + "{testfile}:{line_number}: detected unknown compiletest test directive `{}`", + directive_line.raw_directive, ); return; @@ -931,11 +932,11 @@ fn iter_header( if let Some(trailing_directive) = &trailing_directive { *poisoned = true; - eprintln!( - "error: detected trailing compiletest test directive `{}` in {}:{}\n \ - help: put the trailing directive in it's own line: `//@ {}`", - trailing_directive, testfile, line_number, trailing_directive, + error!( + "{testfile}:{line_number}: detected trailing compiletest test directive `{}`", + trailing_directive, ); + help!("put the trailing directive in it's own line: `//@ {}`", trailing_directive); return; } @@ -1031,10 +1032,9 @@ impl Config { }; let Some((regex, replacement)) = parse_normalize_rule(raw_value) else { - panic!( - "couldn't parse custom normalization rule: `{raw_directive}`\n\ - help: expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`" - ); + error!("couldn't parse custom normalization rule: `{raw_directive}`"); + help!("expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`"); + panic!("invalid normalization rule detected"); }; Some(NormalizeRule { kind, regex, replacement }) } @@ -1406,7 +1406,7 @@ pub(crate) fn make_test_description( ignore_message = Some(reason.into()); } IgnoreDecision::Error { message } => { - eprintln!("error: {}:{line_number}: {message}", path); + error!("{path}:{line_number}: {message}"); *poisoned = true; return; } diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 23a4dd73796e2..09de3eb4c7025 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -11,6 +11,7 @@ mod tests; pub mod common; pub mod compute_diff; mod debuggers; +pub mod diagnostics; pub mod errors; mod executor; pub mod header; @@ -33,7 +34,7 @@ use build_helper::git::{get_git_modified_files, get_git_untracked_files}; use camino::{Utf8Path, Utf8PathBuf}; use getopts::Options; use rayon::iter::{ParallelBridge, ParallelIterator}; -use tracing::*; +use tracing::debug; use walkdir::WalkDir; use self::header::{EarlyProps, make_test_description}; @@ -651,10 +652,7 @@ pub(crate) fn collect_and_make_tests(config: Arc) -> Vec let common_inputs_stamp = common_inputs_stamp(&config); let modified_tests = modified_tests(&config, &config.src_test_suite_root).unwrap_or_else(|err| { - panic!( - "modified_tests got error from dir: {}, error: {}", - config.src_test_suite_root, err - ) + fatal!("modified_tests: {}: {err}", config.src_test_suite_root); }); let cache = HeadersCache::load(&config); @@ -1108,22 +1106,17 @@ fn check_for_overlapping_test_paths(found_path_stems: &HashSet) { pub fn early_config_check(config: &Config) { if !config.has_html_tidy && config.mode == Mode::Rustdoc { - eprintln!("warning: `tidy` (html-tidy.org) is not installed; diffs will not be generated"); + warning!("`tidy` (html-tidy.org) is not installed; diffs will not be generated"); } if !config.profiler_runtime && config.mode == Mode::CoverageRun { let actioned = if config.bless { "blessed" } else { "checked" }; - eprintln!( - r#" -WARNING: profiler runtime is not available, so `.coverage` files won't be {actioned} -help: try setting `profiler = true` in the `[build]` section of `bootstrap.toml`"# - ); + warning!("profiler runtime is not available, so `.coverage` files won't be {actioned}"); + help!("try setting `profiler = true` in the `[build]` section of `bootstrap.toml`"); } // `RUST_TEST_NOCAPTURE` is a libtest env var, but we don't callout to libtest. if env::var("RUST_TEST_NOCAPTURE").is_ok() { - eprintln!( - "WARNING: RUST_TEST_NOCAPTURE is not supported. Use the `--no-capture` flag instead." - ); + warning!("`RUST_TEST_NOCAPTURE` is not supported; use the `--no-capture` flag instead"); } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 980e89889abba..53b5990d3cde1 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -27,7 +27,7 @@ use crate::errors::{Error, ErrorKind, load_errors}; use crate::header::TestProps; use crate::read2::{Truncated, read2_abbreviated}; use crate::util::{Utf8PathBufExt, add_dylib_path, logv, static_regex}; -use crate::{ColorConfig, json, stamp_file_path}; +use crate::{ColorConfig, help, json, stamp_file_path, warning}; mod debugger; @@ -485,12 +485,15 @@ impl<'test> TestCx<'test> { .windows(2) .any(|args| args == cfg_arg || args[0] == arg || args[1] == arg) { - panic!( - "error: redundant cfg argument `{normalized_revision}` is already created by the revision" + error!( + "redundant cfg argument `{normalized_revision}` is already created by the \ + revision" ); + panic!("redundant cfg argument"); } if self.config.builtin_cfg_names().contains(&normalized_revision) { - panic!("error: revision `{normalized_revision}` collides with a builtin cfg"); + error!("revision `{normalized_revision}` collides with a built-in cfg"); + panic!("revision collides with built-in cfg"); } cmd.args(cfg_arg); } @@ -2167,9 +2170,10 @@ impl<'test> TestCx<'test> { println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); } else { - eprintln!("warning: no pager configured, falling back to unified diff"); - eprintln!( - "help: try configuring a git pager (e.g. `delta`) with `git config --global core.pager delta`" + warning!("no pager configured, falling back to unified diff"); + help!( + "try configuring a git pager (e.g. `delta`) with \ + `git config --global core.pager delta`" ); let mut out = io::stdout(); let mut diff = BufReader::new(File::open(&diff_filename).unwrap()); diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs index 8dfa8d18d1a0b..44ddcb1d28882 100644 --- a/src/tools/compiletest/src/runtest/codegen_units.rs +++ b/src/tools/compiletest/src/runtest/codegen_units.rs @@ -1,8 +1,8 @@ use std::collections::HashSet; use super::{Emit, TestCx, WillExecute}; -use crate::errors; use crate::util::static_regex; +use crate::{errors, fatal}; impl TestCx<'_> { pub(super) fn run_codegen_units_test(&self) { @@ -100,7 +100,7 @@ impl TestCx<'_> { } if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty()) { - panic!(); + fatal!("!(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty())"); } #[derive(Clone, Eq, PartialEq)] diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs new file mode 100644 index 0000000000000..64c0d223f835c --- /dev/null +++ b/tests/ui/attributes/malformed-attrs.rs @@ -0,0 +1,221 @@ +// This file contains a bunch of malformed attributes. +// We enable a bunch of features to not get feature-gate errs in this test. +#![feature(rustc_attrs)] +#![feature(rustc_allow_const_fn_unstable)] +#![feature(allow_internal_unstable)] +#![feature(fn_align)] +#![feature(optimize_attribute)] +#![feature(dropck_eyepatch)] +#![feature(export_stable)] +#![allow(incomplete_features)] +#![feature(min_generic_const_args)] +#![feature(ffi_const, ffi_pure)] +#![feature(coverage_attribute)] +#![feature(no_sanitize)] +#![feature(marker_trait_attr)] +#![feature(thread_local)] +#![feature(must_not_suspend)] +#![feature(coroutines)] +#![feature(linkage)] +#![feature(cfi_encoding, extern_types)] +#![feature(patchable_function_entry)] +#![feature(omit_gdb_pretty_printer_section)] +#![feature(fundamental)] + + +#![omit_gdb_pretty_printer_section = 1] +//~^ ERROR malformed `omit_gdb_pretty_printer_section` attribute input + +#![windows_subsystem] +//~^ ERROR malformed + +#[unsafe(export_name)] +//~^ ERROR malformed +#[rustc_allow_const_fn_unstable] +//~^ ERROR `rustc_allow_const_fn_unstable` expects a list of feature names +#[allow_internal_unstable] +//~^ ERROR `allow_internal_unstable` expects a list of feature names +#[rustc_confusables] +//~^ ERROR malformed +#[deprecated = 5] +//~^ ERROR malformed +#[doc] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[rustc_macro_transparency] +//~^ ERROR malformed +#[repr] +//~^ ERROR malformed +#[rustc_as_ptr = 5] +//~^ ERROR malformed +#[inline = 5] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[align] +//~^ ERROR malformed +#[optimize] +//~^ ERROR malformed +#[cold = 1] +//~^ ERROR malformed +#[must_use()] +//~^ ERROR valid forms for the attribute are +#[no_mangle = 1] +//~^ ERROR malformed +#[unsafe(naked())] +//~^ ERROR malformed +#[track_caller()] +//~^ ERROR malformed +#[export_name()] +//~^ ERROR malformed +#[used()] +//~^ ERROR malformed +#[crate_name] +//~^ ERROR malformed +#[doc] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[target_feature] +//~^ ERROR malformed +#[export_stable = 1] +//~^ ERROR malformed +#[link] +//~^ ERROR attribute must be of the form +//~| WARN this was previously accepted by the compiler +#[link_name] +//~^ ERROR malformed +#[link_section] +//~^ ERROR malformed +#[coverage] +//~^ ERROR malformed `coverage` attribute input +#[no_sanitize] +//~^ ERROR malformed +#[ignore()] +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler +#[no_implicit_prelude = 23] +//~^ ERROR malformed +#[proc_macro = 18] +//~^ ERROR malformed +//~| ERROR the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type +#[cfg] +//~^ ERROR is not followed by parentheses +#[cfg_attr] +//~^ ERROR malformed +#[instruction_set] +//~^ ERROR malformed +#[patchable_function_entry] +//~^ ERROR malformed +fn test() { + #[coroutine = 63] || {} + //~^ ERROR malformed `coroutine` attribute input + //~| ERROR mismatched types [E0308] +} + +#[proc_macro_attribute = 19] +//~^ ERROR malformed +//~| ERROR the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type +#[must_use = 1] +//~^ ERROR malformed +fn test2() { } + +#[proc_macro_derive] +//~^ ERROR malformed `proc_macro_derive` attribute +//~| ERROR the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type +pub fn test3() {} + +#[rustc_layout_scalar_valid_range_start] +//~^ ERROR malformed +#[rustc_layout_scalar_valid_range_end] +//~^ ERROR malformed +#[must_not_suspend()] +//~^ ERROR malformed +#[cfi_encoding] +//~^ ERROR malformed +struct Test; + +#[diagnostic::on_unimplemented] +//~^ WARN missing options for `on_unimplemented` attribute +#[diagnostic::on_unimplemented = 1] +//~^ WARN malformed +trait Hey { + #[type_const = 1] + //~^ ERROR malformed + const HEY: usize = 5; +} + +struct Empty; +#[diagnostic::do_not_recommend()] +//~^ WARN does not expect any arguments +impl Hey for Empty { + +} + +#[marker = 3] +//~^ ERROR malformed +#[fundamental()] +//~^ ERROR malformed +trait EmptyTrait { + +} + + +extern "C" { + #[unsafe(ffi_pure = 1)] + //~^ ERROR malformed + #[link_ordinal] + //~^ ERROR malformed + pub fn baz(); + + #[unsafe(ffi_const = 1)] + //~^ ERROR malformed + #[linkage] + //~^ ERROR malformed + pub fn bar(); +} + +#[allow] +//~^ ERROR malformed +#[expect] +//~^ ERROR malformed +#[warn] +//~^ ERROR malformed +#[deny] +//~^ ERROR malformed +#[forbid] +//~^ ERROR malformed +#[debugger_visualizer] +//~^ ERROR invalid argument +//~| ERROR malformed `debugger_visualizer` attribute input +#[automatically_derived = 18] +//~^ ERROR malformed +mod yooo { + +} + +#[non_exhaustive = 1] +//~^ ERROR malformed +enum Slenum { + +} + +#[thread_local()] +//~^ ERROR malformed +static mut TLS: u8 = 42; + +#[no_link()] +//~^ ERROR malformed +#[macro_use = 1] +//~^ ERROR malformed +extern crate wloop; +//~^ ERROR can't find crate for `wloop` [E0463] + +#[macro_export = 18] +//~^ ERROR malformed `macro_export` attribute input +#[allow_internal_unsafe = 1] +//~^ ERROR malformed +//~| ERROR allow_internal_unsafe side-steps the unsafe_code lint +macro_rules! slump { + () => {} +} + +fn main() {} diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr new file mode 100644 index 0000000000000..bf063e8f6e54b --- /dev/null +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -0,0 +1,596 @@ +error: `cfg` is not followed by parentheses + --> $DIR/malformed-attrs.rs:100:1 + | +LL | #[cfg] + | ^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: malformed `cfg_attr` attribute input + --> $DIR/malformed-attrs.rs:102:1 + | +LL | #[cfg_attr] + | ^^^^^^^^^^^ + | + = note: for more information, visit +help: missing condition and attribute + | +LL | #[cfg_attr(condition, attribute, other_attribute, ...)] + | ++++++++++++++++++++++++++++++++++++++++++++ + +error[E0463]: can't find crate for `wloop` + --> $DIR/malformed-attrs.rs:209:1 + | +LL | extern crate wloop; + | ^^^^^^^^^^^^^^^^^^^ can't find crate + +error: malformed `omit_gdb_pretty_printer_section` attribute input + --> $DIR/malformed-attrs.rs:26:1 + | +LL | #![omit_gdb_pretty_printer_section = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![omit_gdb_pretty_printer_section]` + +error: malformed `windows_subsystem` attribute input + --> $DIR/malformed-attrs.rs:29:1 + | +LL | #![windows_subsystem] + | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![windows_subsystem = "windows|console"]` + +error: malformed `crate_name` attribute input + --> $DIR/malformed-attrs.rs:72:1 + | +LL | #[crate_name] + | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` + +error: malformed `target_feature` attribute input + --> $DIR/malformed-attrs.rs:77:1 + | +LL | #[target_feature] + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]` + +error: malformed `export_stable` attribute input + --> $DIR/malformed-attrs.rs:79:1 + | +LL | #[export_stable = 1] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]` + +error: malformed `coverage` attribute input + --> $DIR/malformed-attrs.rs:88:1 + | +LL | #[coverage] + | ^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL | #[coverage(off)] + | +++++ +LL | #[coverage(on)] + | ++++ + +error: malformed `no_sanitize` attribute input + --> $DIR/malformed-attrs.rs:90:1 + | +LL | #[no_sanitize] + | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` + +error: malformed `no_implicit_prelude` attribute input + --> $DIR/malformed-attrs.rs:95:1 + | +LL | #[no_implicit_prelude = 23] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[no_implicit_prelude]` + +error: malformed `proc_macro` attribute input + --> $DIR/malformed-attrs.rs:97:1 + | +LL | #[proc_macro = 18] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro]` + +error: malformed `instruction_set` attribute input + --> $DIR/malformed-attrs.rs:104:1 + | +LL | #[instruction_set] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` + +error: malformed `patchable_function_entry` attribute input + --> $DIR/malformed-attrs.rs:106:1 + | +LL | #[patchable_function_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` + +error: malformed `coroutine` attribute input + --> $DIR/malformed-attrs.rs:109:5 + | +LL | #[coroutine = 63] || {} + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[coroutine]` + +error: malformed `proc_macro_attribute` attribute input + --> $DIR/malformed-attrs.rs:114:1 + | +LL | #[proc_macro_attribute = 19] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_attribute]` + +error: malformed `proc_macro_derive` attribute input + --> $DIR/malformed-attrs.rs:121:1 + | +LL | #[proc_macro_derive] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]` + +error: malformed `must_not_suspend` attribute input + --> $DIR/malformed-attrs.rs:130:1 + | +LL | #[must_not_suspend()] + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL - #[must_not_suspend()] +LL + #[must_not_suspend = "reason"] + | +LL - #[must_not_suspend()] +LL + #[must_not_suspend] + | + +error: malformed `cfi_encoding` attribute input + --> $DIR/malformed-attrs.rs:132:1 + | +LL | #[cfi_encoding] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` + +error: malformed `type_const` attribute input + --> $DIR/malformed-attrs.rs:141:5 + | +LL | #[type_const = 1] + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]` + +error: malformed `marker` attribute input + --> $DIR/malformed-attrs.rs:153:1 + | +LL | #[marker = 3] + | ^^^^^^^^^^^^^ help: must be of the form: `#[marker]` + +error: malformed `fundamental` attribute input + --> $DIR/malformed-attrs.rs:155:1 + | +LL | #[fundamental()] + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[fundamental]` + +error: malformed `ffi_pure` attribute input + --> $DIR/malformed-attrs.rs:163:5 + | +LL | #[unsafe(ffi_pure = 1)] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_pure]` + +error: malformed `link_ordinal` attribute input + --> $DIR/malformed-attrs.rs:165:5 + | +LL | #[link_ordinal] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_ordinal(ordinal)]` + +error: malformed `ffi_const` attribute input + --> $DIR/malformed-attrs.rs:169:5 + | +LL | #[unsafe(ffi_const = 1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[ffi_const]` + +error: malformed `linkage` attribute input + --> $DIR/malformed-attrs.rs:171:5 + | +LL | #[linkage] + | ^^^^^^^^^^ help: must be of the form: `#[linkage = "external|internal|..."]` + +error: malformed `allow` attribute input + --> $DIR/malformed-attrs.rs:176:1 + | +LL | #[allow] + | ^^^^^^^^ help: must be of the form: `#[allow(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `expect` attribute input + --> $DIR/malformed-attrs.rs:178:1 + | +LL | #[expect] + | ^^^^^^^^^ help: must be of the form: `#[expect(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `warn` attribute input + --> $DIR/malformed-attrs.rs:180:1 + | +LL | #[warn] + | ^^^^^^^ help: must be of the form: `#[warn(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `deny` attribute input + --> $DIR/malformed-attrs.rs:182:1 + | +LL | #[deny] + | ^^^^^^^ help: must be of the form: `#[deny(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `forbid` attribute input + --> $DIR/malformed-attrs.rs:184:1 + | +LL | #[forbid] + | ^^^^^^^^^ help: must be of the form: `#[forbid(lint1, lint2, ..., /*opt*/ reason = "...")]` + +error: malformed `debugger_visualizer` attribute input + --> $DIR/malformed-attrs.rs:186:1 + | +LL | #[debugger_visualizer] + | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` + +error: malformed `automatically_derived` attribute input + --> $DIR/malformed-attrs.rs:189:1 + | +LL | #[automatically_derived = 18] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[automatically_derived]` + +error: malformed `non_exhaustive` attribute input + --> $DIR/malformed-attrs.rs:195:1 + | +LL | #[non_exhaustive = 1] + | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` + +error: malformed `thread_local` attribute input + --> $DIR/malformed-attrs.rs:201:1 + | +LL | #[thread_local()] + | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` + +error: malformed `no_link` attribute input + --> $DIR/malformed-attrs.rs:205:1 + | +LL | #[no_link()] + | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` + +error: malformed `macro_use` attribute input + --> $DIR/malformed-attrs.rs:207:1 + | +LL | #[macro_use = 1] + | ^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL - #[macro_use = 1] +LL + #[macro_use(name1, name2, ...)] + | +LL - #[macro_use = 1] +LL + #[macro_use] + | + +error: malformed `macro_export` attribute input + --> $DIR/malformed-attrs.rs:212:1 + | +LL | #[macro_export = 18] + | ^^^^^^^^^^^^^^^^^^^^ + | +help: the following are the possible correct uses + | +LL - #[macro_export = 18] +LL + #[macro_export(local_inner_macros)] + | +LL - #[macro_export = 18] +LL + #[macro_export] + | + +error: malformed `allow_internal_unsafe` attribute input + --> $DIR/malformed-attrs.rs:214:1 + | +LL | #[allow_internal_unsafe = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` + +error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/malformed-attrs.rs:97:1 + | +LL | #[proc_macro = 18] + | ^^^^^^^^^^^^^^^^^^ + +error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/malformed-attrs.rs:114:1 + | +LL | #[proc_macro_attribute = 19] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/malformed-attrs.rs:121:1 + | +LL | #[proc_macro_derive] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint + --> $DIR/malformed-attrs.rs:214:1 + | +LL | #[allow_internal_unsafe = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(allow_internal_unsafe)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` + --> $DIR/malformed-attrs.rs:42:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` on by default + +error: valid forms for the attribute are `#[doc(hidden|inline|...)]` and `#[doc = "string"]` + --> $DIR/malformed-attrs.rs:74:1 + | +LL | #[doc] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` + --> $DIR/malformed-attrs.rs:81:1 + | +LL | #[link] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: valid forms for the attribute are `#[ignore]` and `#[ignore = "reason"]` + --> $DIR/malformed-attrs.rs:92:1 + | +LL | #[ignore()] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: invalid argument + --> $DIR/malformed-attrs.rs:186:1 + | +LL | #[debugger_visualizer] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expected: `natvis_file = "..."` + = note: OR + = note: expected: `gdb_script_file = "..."` + +error[E0539]: malformed `export_name` attribute input + --> $DIR/malformed-attrs.rs:32:1 + | +LL | #[unsafe(export_name)] + | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` + +error: `rustc_allow_const_fn_unstable` expects a list of feature names + --> $DIR/malformed-attrs.rs:34:1 + | +LL | #[rustc_allow_const_fn_unstable] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `allow_internal_unstable` expects a list of feature names + --> $DIR/malformed-attrs.rs:36:1 + | +LL | #[allow_internal_unstable] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0539]: malformed `rustc_confusables` attribute input + --> $DIR/malformed-attrs.rs:38:1 + | +LL | #[rustc_confusables] + | ^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_confusables("name1", "name2", ...)]` + +error[E0539]: malformed `deprecated` attribute input + --> $DIR/malformed-attrs.rs:40:1 + | +LL | #[deprecated = 5] + | ^^^^^^^^^^^^^^^-^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[deprecated = 5] +LL + #[deprecated = "reason"] + | +LL - #[deprecated = 5] +LL + #[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason")] + | +LL - #[deprecated = 5] +LL + #[deprecated] + | + +error[E0539]: malformed `rustc_macro_transparency` attribute input + --> $DIR/malformed-attrs.rs:45:1 + | +LL | #[rustc_macro_transparency] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_macro_transparency = "transparent|semitransparent|opaque"]` + +error[E0539]: malformed `repr` attribute input + --> $DIR/malformed-attrs.rs:47:1 + | +LL | #[repr] + | ^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[repr(C | Rust | align(...) | packed(...) | | transparent)]` + +error[E0565]: malformed `rustc_as_ptr` attribute input + --> $DIR/malformed-attrs.rs:49:1 + | +LL | #[rustc_as_ptr = 5] + | ^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[rustc_as_ptr]` + +error[E0539]: malformed `align` attribute input + --> $DIR/malformed-attrs.rs:54:1 + | +LL | #[align] + | ^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[align()]` + +error[E0539]: malformed `optimize` attribute input + --> $DIR/malformed-attrs.rs:56:1 + | +LL | #[optimize] + | ^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[optimize(size|speed|none)]` + +error[E0565]: malformed `cold` attribute input + --> $DIR/malformed-attrs.rs:58:1 + | +LL | #[cold = 1] + | ^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[cold]` + +error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` + --> $DIR/malformed-attrs.rs:60:1 + | +LL | #[must_use()] + | ^^^^^^^^^^^^^ + +error[E0565]: malformed `no_mangle` attribute input + --> $DIR/malformed-attrs.rs:62:1 + | +LL | #[no_mangle = 1] + | ^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[no_mangle]` + +error[E0565]: malformed `naked` attribute input + --> $DIR/malformed-attrs.rs:64:1 + | +LL | #[unsafe(naked())] + | ^^^^^^^^^^^^^^--^^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[naked]` + +error[E0565]: malformed `track_caller` attribute input + --> $DIR/malformed-attrs.rs:66:1 + | +LL | #[track_caller()] + | ^^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[track_caller]` + +error[E0539]: malformed `export_name` attribute input + --> $DIR/malformed-attrs.rs:68:1 + | +LL | #[export_name()] + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` + +error[E0805]: malformed `used` attribute input + --> $DIR/malformed-attrs.rs:70:1 + | +LL | #[used()] + | ^^^^^^--^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL | #[used(compiler|linker)] + | +++++++++++++++ +LL - #[used()] +LL + #[used] + | + +error[E0539]: malformed `link_name` attribute input + --> $DIR/malformed-attrs.rs:84:1 + | +LL | #[link_name] + | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` + +error[E0539]: malformed `link_section` attribute input + --> $DIR/malformed-attrs.rs:86:1 + | +LL | #[link_section] + | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` + +error[E0539]: malformed `must_use` attribute input + --> $DIR/malformed-attrs.rs:117:1 + | +LL | #[must_use = 1] + | ^^^^^^^^^^^^^-^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use = 1] +LL + #[must_use = "reason"] + | +LL - #[must_use = 1] +LL + #[must_use] + | + +error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input + --> $DIR/malformed-attrs.rs:126:1 + | +LL | #[rustc_layout_scalar_valid_range_start] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` + +error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input + --> $DIR/malformed-attrs.rs:128:1 + | +LL | #[rustc_layout_scalar_valid_range_end] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` + +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/malformed-attrs.rs:147:1 + | +LL | #[diagnostic::do_not_recommend()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: missing options for `on_unimplemented` attribute + --> $DIR/malformed-attrs.rs:136:1 + | +LL | #[diagnostic::on_unimplemented] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: at least one of the `message`, `note` and `label` options are expected + +warning: malformed `on_unimplemented` attribute + --> $DIR/malformed-attrs.rs:138:1 + | +LL | #[diagnostic::on_unimplemented = 1] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here + | + = help: only `message`, `note` and `label` are allowed as options + +error: valid forms for the attribute are `#[inline(always|never)]` and `#[inline]` + --> $DIR/malformed-attrs.rs:51:1 + | +LL | #[inline = 5] + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error[E0308]: mismatched types + --> $DIR/malformed-attrs.rs:109:23 + | +LL | fn test() { + | - help: a return type might be missing here: `-> _` +LL | #[coroutine = 63] || {} + | ^^^^^ expected `()`, found coroutine + | + = note: expected unit type `()` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:109:23: 109:25}` + +error: aborting due to 72 previous errors; 3 warnings emitted + +Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/cast/non-primitive-cast-suggestion.fixed b/tests/ui/cast/non-primitive-cast-suggestion.fixed new file mode 100644 index 0000000000000..9a1a3c022c791 --- /dev/null +++ b/tests/ui/cast/non-primitive-cast-suggestion.fixed @@ -0,0 +1,23 @@ +//! Test that casting non-primitive types with `as` is rejected with a helpful suggestion. +//! +//! You can't use `as` to cast between non-primitive types, even if they have +//! `From`/`Into` implementations. The compiler should suggest using `From::from()` +//! or `.into()` instead, and rustfix should be able to apply the suggestion. + +//@ run-rustfix + +#[derive(Debug)] +struct Foo { + x: isize, +} + +impl From for isize { + fn from(val: Foo) -> isize { + val.x + } +} + +fn main() { + let _ = isize::from(Foo { x: 1 }); + //~^ ERROR non-primitive cast: `Foo` as `isize` [E0605] +} diff --git a/tests/ui/cast/non-primitive-cast-suggestion.rs b/tests/ui/cast/non-primitive-cast-suggestion.rs new file mode 100644 index 0000000000000..79006f4ba26d3 --- /dev/null +++ b/tests/ui/cast/non-primitive-cast-suggestion.rs @@ -0,0 +1,23 @@ +//! Test that casting non-primitive types with `as` is rejected with a helpful suggestion. +//! +//! You can't use `as` to cast between non-primitive types, even if they have +//! `From`/`Into` implementations. The compiler should suggest using `From::from()` +//! or `.into()` instead, and rustfix should be able to apply the suggestion. + +//@ run-rustfix + +#[derive(Debug)] +struct Foo { + x: isize, +} + +impl From for isize { + fn from(val: Foo) -> isize { + val.x + } +} + +fn main() { + let _ = Foo { x: 1 } as isize; + //~^ ERROR non-primitive cast: `Foo` as `isize` [E0605] +} diff --git a/tests/ui/cast/non-primitive-cast-suggestion.stderr b/tests/ui/cast/non-primitive-cast-suggestion.stderr new file mode 100644 index 0000000000000..bd35ded15a46c --- /dev/null +++ b/tests/ui/cast/non-primitive-cast-suggestion.stderr @@ -0,0 +1,15 @@ +error[E0605]: non-primitive cast: `Foo` as `isize` + --> $DIR/non-primitive-cast-suggestion.rs:21:13 + | +LL | let _ = Foo { x: 1 } as isize; + | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + | +help: consider using the `From` trait instead + | +LL - let _ = Foo { x: 1 } as isize; +LL + let _ = isize::from(Foo { x: 1 }); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/closures/basic-closure-syntax.rs b/tests/ui/closures/basic-closure-syntax.rs new file mode 100644 index 0000000000000..1d968f8cf4af7 --- /dev/null +++ b/tests/ui/closures/basic-closure-syntax.rs @@ -0,0 +1,35 @@ +//! Test basic closure syntax and usage with generic functions. +//! +//! This test checks that closure syntax works correctly for: +//! - Closures with parameters and return values +//! - Closures without parameters (both expression and block forms) +//! - Integration with generic functions and FnOnce trait bounds + +//@ run-pass + +fn f(i: isize, f: F) -> isize +where + F: FnOnce(isize) -> isize, +{ + f(i) +} + +fn g(_g: G) +where + G: FnOnce(), +{ +} + +pub fn main() { + // Closure with parameter that returns the same value + assert_eq!(f(10, |a| a), 10); + + // Closure without parameters - expression form + g(|| ()); + + // Test closure reuse in generic context + assert_eq!(f(10, |a| a), 10); + + // Closure without parameters - block form + g(|| {}); +} diff --git a/tests/ui/closures/closure-clone-requires-captured-clone.rs b/tests/ui/closures/closure-clone-requires-captured-clone.rs new file mode 100644 index 0000000000000..80938e50b67a7 --- /dev/null +++ b/tests/ui/closures/closure-clone-requires-captured-clone.rs @@ -0,0 +1,19 @@ +//! Test that closures only implement `Clone` if all captured values implement `Clone`. +//! +//! When a closure captures variables from its environment, it can only be cloned +//! if all those captured variables are cloneable. This test makes sure the compiler +//! properly rejects attempts to clone closures that capture non-Clone types. + +//@ compile-flags: --diagnostic-width=300 + +struct NonClone(i32); + +fn main() { + let captured_value = NonClone(5); + let closure = move || { + let _ = captured_value.0; + }; + + closure.clone(); + //~^ ERROR the trait bound `NonClone: Clone` is not satisfied +} diff --git a/tests/ui/closures/closure-clone-requires-captured-clone.stderr b/tests/ui/closures/closure-clone-requires-captured-clone.stderr new file mode 100644 index 0000000000000..785cc8a3032e2 --- /dev/null +++ b/tests/ui/closures/closure-clone-requires-captured-clone.stderr @@ -0,0 +1,23 @@ +error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{closure@$DIR/closure-clone-requires-captured-clone.rs:13:19: 13:26}` + --> $DIR/closure-clone-requires-captured-clone.rs:17:13 + | +LL | let closure = move || { + | ------- within this `{closure@$DIR/closure-clone-requires-captured-clone.rs:13:19: 13:26}` +... +LL | closure.clone(); + | ^^^^^ within `{closure@$DIR/closure-clone-requires-captured-clone.rs:13:19: 13:26}`, the trait `Clone` is not implemented for `NonClone` + | +note: required because it's used within this closure + --> $DIR/closure-clone-requires-captured-clone.rs:13:19 + | +LL | let closure = move || { + | ^^^^^^^ +help: consider annotating `NonClone` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct NonClone(i32); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/array-repeat-expr-not-const.rs b/tests/ui/consts/array-repeat-expr-not-const.rs new file mode 100644 index 0000000000000..55aee7336da32 --- /dev/null +++ b/tests/ui/consts/array-repeat-expr-not-const.rs @@ -0,0 +1,10 @@ +//! Arrays created with `[value; length]` syntax need the length to be known at +//! compile time. This test makes sure the compiler rejects runtime values like +//! function parameters in the length position. + +fn main() { + fn create_array(n: usize) { + let _x = [0; n]; + //~^ ERROR attempt to use a non-constant value in a constant [E0435] + } +} diff --git a/tests/ui/non-constant-expr-for-arr-len.stderr b/tests/ui/consts/array-repeat-expr-not-const.stderr similarity index 62% rename from tests/ui/non-constant-expr-for-arr-len.stderr rename to tests/ui/consts/array-repeat-expr-not-const.stderr index c9f977fbaa409..f576154525964 100644 --- a/tests/ui/non-constant-expr-for-arr-len.stderr +++ b/tests/ui/consts/array-repeat-expr-not-const.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/non-constant-expr-for-arr-len.rs:5:22 + --> $DIR/array-repeat-expr-not-const.rs:7:22 | -LL | fn bar(n: usize) { - | - this would need to be a `const` +LL | fn create_array(n: usize) { + | - this would need to be a `const` LL | let _x = [0; n]; | ^ diff --git a/tests/ui/auxiliary/noexporttypelib.rs b/tests/ui/cross-crate/auxiliary/unexported-type-error-message.rs similarity index 100% rename from tests/ui/auxiliary/noexporttypelib.rs rename to tests/ui/cross-crate/auxiliary/unexported-type-error-message.rs diff --git a/tests/ui/noexporttypeexe.rs b/tests/ui/cross-crate/unexported-type-error-message.rs similarity index 73% rename from tests/ui/noexporttypeexe.rs rename to tests/ui/cross-crate/unexported-type-error-message.rs index 35257b20ccdf8..5998f0dc6e233 100644 --- a/tests/ui/noexporttypeexe.rs +++ b/tests/ui/cross-crate/unexported-type-error-message.rs @@ -1,13 +1,13 @@ -//@ aux-build:noexporttypelib.rs +//@ aux-build:unexported-type-error-message.rs -extern crate noexporttypelib; +extern crate unexported_type_error_message; fn main() { // Here, the type returned by foo() is not exported. // This used to cause internal errors when serializing // because the def_id associated with the type was // not convertible to a path. - let x: isize = noexporttypelib::foo(); + let x: isize = unexported_type_error_message::foo(); //~^ ERROR mismatched types //~| NOTE expected type `isize` //~| NOTE found enum `Option` diff --git a/tests/ui/cross-crate/unexported-type-error-message.stderr b/tests/ui/cross-crate/unexported-type-error-message.stderr new file mode 100644 index 0000000000000..b468d9839e10e --- /dev/null +++ b/tests/ui/cross-crate/unexported-type-error-message.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/unexported-type-error-message.rs:10:20 + | +LL | let x: isize = unexported_type_error_message::foo(); + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `Option` + | | + | expected due to this + | + = note: expected type `isize` + found enum `Option` +help: consider using `Option::expect` to unwrap the `Option` value, panicking if the value is an `Option::None` + | +LL | let x: isize = unexported_type_error_message::foo().expect("REASON"); + | +++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/drop/field-replace-in-struct-with-drop.rs b/tests/ui/drop/field-replace-in-struct-with-drop.rs new file mode 100644 index 0000000000000..8c65a4b3ad1e0 --- /dev/null +++ b/tests/ui/drop/field-replace-in-struct-with-drop.rs @@ -0,0 +1,40 @@ +//! Circa 2016-06-05, `fn inline` below issued an +//! erroneous warning from the elaborate_drops pass about moving out of +//! a field in `Foo`, which has a destructor (and thus cannot have +//! content moved out of it). The reason that the warning is erroneous +//! in this case is that we are doing a *replace*, not a move, of the +//! content in question, and it is okay to replace fields within `Foo`. +//! +//! Another more subtle problem was that the elaborate_drops was +//! creating a separate drop flag for that internally replaced content, +//! even though the compiler should enforce an invariant that any drop +//! flag for such subcontent of `Foo` will always have the same value +//! as the drop flag for `Foo` itself. +//! +//! Regression test for . + +//@ check-pass + +struct Foo(String); + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn test_inline_replacement() { + // dummy variable so `f` gets assigned `var1` in MIR for both functions + let _s = (); + let mut f = Foo(String::from("foo")); + f.0 = String::from("bar"); // This should not warn +} + +fn test_outline_replacement() { + let _s = String::from("foo"); + let mut f = Foo(_s); + f.0 = String::from("bar"); // This should not warn either +} + +fn main() { + test_inline_replacement(); + test_outline_replacement(); +} diff --git a/tests/ui/extern/issue-47725.rs b/tests/ui/extern/issue-47725.rs index 012673b9159f1..60d0cd6234745 100644 --- a/tests/ui/extern/issue-47725.rs +++ b/tests/ui/extern/issue-47725.rs @@ -17,7 +17,6 @@ extern "C" { #[link_name] //~^ ERROR malformed `link_name` attribute input //~| HELP must be of the form -//~| NOTE expected this to be of the form `link_name = "..." extern "C" { fn bar() -> u32; } diff --git a/tests/ui/extern/issue-47725.stderr b/tests/ui/extern/issue-47725.stderr index 53d6b4927f89f..4fd02a1778be6 100644 --- a/tests/ui/extern/issue-47725.stderr +++ b/tests/ui/extern/issue-47725.stderr @@ -2,10 +2,7 @@ error[E0539]: malformed `link_name` attribute input --> $DIR/issue-47725.rs:17:1 | LL | #[link_name] - | ^^^^^^^^^^^^ - | | - | expected this to be of the form `link_name = "..."` - | help: must be of the form: `#[link_name = "name"]` + | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` warning: attribute should be applied to a foreign function or static --> $DIR/issue-47725.rs:3:1 diff --git a/tests/ui/generics/newtype-with-generics.rs b/tests/ui/generics/newtype-with-generics.rs new file mode 100644 index 0000000000000..c5e200e4bc4c4 --- /dev/null +++ b/tests/ui/generics/newtype-with-generics.rs @@ -0,0 +1,32 @@ +//! Test newtype pattern with generic parameters. + +//@ run-pass + +#[derive(Clone)] +struct MyVec(Vec); + +fn extract_inner_vec(wrapper: MyVec) -> Vec { + let MyVec(inner_vec) = wrapper; + inner_vec.clone() +} + +fn get_first_element(wrapper: MyVec) -> T { + let MyVec(inner_vec) = wrapper; + inner_vec.into_iter().next().unwrap() +} + +pub fn main() { + let my_vec = MyVec(vec![1, 2, 3]); + let cloned_vec = my_vec.clone(); + + // Test extracting inner vector + let extracted = extract_inner_vec(cloned_vec); + assert_eq!(extracted[1], 2); + + // Test getting first element + assert_eq!(get_first_element(my_vec.clone()), 1); + + // Test direct destructuring + let MyVec(inner) = my_vec; + assert_eq!(inner[2], 3); +} diff --git a/tests/ui/new-impl-syntax.rs b/tests/ui/impl-trait/basic-trait-impl.rs similarity index 75% rename from tests/ui/new-impl-syntax.rs rename to tests/ui/impl-trait/basic-trait-impl.rs index 124d604e6a87a..2706c9c179879 100644 --- a/tests/ui/new-impl-syntax.rs +++ b/tests/ui/impl-trait/basic-trait-impl.rs @@ -1,10 +1,12 @@ +//! Test basic trait implementation syntax for both simple and generic types. + //@ run-pass use std::fmt; struct Thingy { x: isize, - y: isize + y: isize, } impl fmt::Debug for Thingy { @@ -14,10 +16,10 @@ impl fmt::Debug for Thingy { } struct PolymorphicThingy { - x: T + x: T, } -impl fmt::Debug for PolymorphicThingy { +impl fmt::Debug for PolymorphicThingy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.x) } diff --git a/tests/ui/lowering/issue-121108.stderr b/tests/ui/lowering/issue-121108.stderr index e4942e8cb0796..f68655a70021f 100644 --- a/tests/ui/lowering/issue-121108.stderr +++ b/tests/ui/lowering/issue-121108.stderr @@ -5,7 +5,7 @@ LL | #![derive(Clone, Copy)] | ^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | use std::ptr::addr_of; - | ------- the inner attribute doesn't annotate this `use` import + | ------- the inner attribute doesn't annotate this import | help: perhaps you meant to use an outer attribute | diff --git a/tests/ui/new-import-syntax.rs b/tests/ui/new-import-syntax.rs deleted file mode 100644 index 547900fab6128..0000000000000 --- a/tests/ui/new-import-syntax.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ run-pass - -pub fn main() { - println!("Hello world!"); -} diff --git a/tests/ui/new-style-constants.rs b/tests/ui/new-style-constants.rs deleted file mode 100644 index e33a2da38785e..0000000000000 --- a/tests/ui/new-style-constants.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -static FOO: isize = 3; - -pub fn main() { - println!("{}", FOO); -} diff --git a/tests/ui/newlambdas.rs b/tests/ui/newlambdas.rs deleted file mode 100644 index 75e851fb73a28..0000000000000 --- a/tests/ui/newlambdas.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -// Tests for the new |args| expr lambda syntax - - -fn f(i: isize, f: F) -> isize where F: FnOnce(isize) -> isize { f(i) } - -fn g(_g: G) where G: FnOnce() { } - -pub fn main() { - assert_eq!(f(10, |a| a), 10); - g(||()); - assert_eq!(f(10, |a| a), 10); - g(||{}); -} diff --git a/tests/ui/newtype-polymorphic.rs b/tests/ui/newtype-polymorphic.rs deleted file mode 100644 index 146d49fdf6819..0000000000000 --- a/tests/ui/newtype-polymorphic.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ run-pass - -#![allow(non_camel_case_types)] - - -#[derive(Clone)] -struct myvec(Vec ); - -fn myvec_deref(mv: myvec) -> Vec { - let myvec(v) = mv; - return v.clone(); -} - -fn myvec_elt(mv: myvec) -> X { - let myvec(v) = mv; - return v.into_iter().next().unwrap(); -} - -pub fn main() { - let mv = myvec(vec![1, 2, 3]); - let mv_clone = mv.clone(); - let mv_clone = myvec_deref(mv_clone); - assert_eq!(mv_clone[1], 2); - assert_eq!(myvec_elt(mv.clone()), 1); - let myvec(v) = mv; - assert_eq!(v[2], 3); -} diff --git a/tests/ui/newtype.rs b/tests/ui/newtype.rs deleted file mode 100644 index 8a07c67eb4f9c..0000000000000 --- a/tests/ui/newtype.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ run-pass - -#![allow(non_camel_case_types)] -#[derive(Copy, Clone)] -struct mytype(Mytype); - -#[derive(Copy, Clone)] -struct Mytype { - compute: fn(mytype) -> isize, - val: isize, -} - -fn compute(i: mytype) -> isize { - let mytype(m) = i; - return m.val + 20; -} - -pub fn main() { - let myval = mytype(Mytype{compute: compute, val: 30}); - println!("{}", compute(myval)); - let mytype(m) = myval; - assert_eq!((m.compute)(myval), 50); -} diff --git a/tests/ui/no-core-1.rs b/tests/ui/no-core-1.rs deleted file mode 100644 index d6d2ba6044585..0000000000000 --- a/tests/ui/no-core-1.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass - -#![allow(stable_features)] -#![feature(no_core, core)] -#![no_core] - -extern crate std; -extern crate core; - -use std::option::Option::Some; - -fn main() { - let a = Some("foo"); - a.unwrap(); -} diff --git a/tests/ui/no-core-2.rs b/tests/ui/no-core-2.rs deleted file mode 100644 index 2f55365bdd0f3..0000000000000 --- a/tests/ui/no-core-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ run-pass - -#![allow(dead_code, unused_imports)] -#![feature(no_core)] -#![no_core] -//@ edition:2018 - -extern crate std; -extern crate core; -use core::{prelude::v1::*, *}; - -fn foo() { - for _ in &[()] {} -} - -fn bar() -> Option<()> { - None? -} - -fn main() {} diff --git a/tests/ui/no-warn-on-field-replace-issue-34101.rs b/tests/ui/no-warn-on-field-replace-issue-34101.rs deleted file mode 100644 index e1d5e9c5268b8..0000000000000 --- a/tests/ui/no-warn-on-field-replace-issue-34101.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Issue 34101: Circa 2016-06-05, `fn inline` below issued an -// erroneous warning from the elaborate_drops pass about moving out of -// a field in `Foo`, which has a destructor (and thus cannot have -// content moved out of it). The reason that the warning is erroneous -// in this case is that we are doing a *replace*, not a move, of the -// content in question, and it is okay to replace fields within `Foo`. -// -// Another more subtle problem was that the elaborate_drops was -// creating a separate drop flag for that internally replaced content, -// even though the compiler should enforce an invariant that any drop -// flag for such subcontent of `Foo` will always have the same value -// as the drop flag for `Foo` itself. - - - - - - - - -//@ check-pass - -struct Foo(String); - -impl Drop for Foo { - fn drop(&mut self) {} -} - -fn inline() { - // (dummy variable so `f` gets assigned `var1` in MIR for both fn's) - let _s = (); - let mut f = Foo(String::from("foo")); - f.0 = String::from("bar"); -} - -fn outline() { - let _s = String::from("foo"); - let mut f = Foo(_s); - f.0 = String::from("bar"); -} - - -fn main() { - inline(); - outline(); -} diff --git a/tests/ui/no_send-enum.rs b/tests/ui/no_send-enum.rs deleted file mode 100644 index bd560649b990e..0000000000000 --- a/tests/ui/no_send-enum.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![feature(negative_impls)] - -use std::marker::Send; - -struct NoSend; -impl !Send for NoSend {} - -enum Foo { - A(NoSend) -} - -fn bar(_: T) {} - -fn main() { - let x = Foo::A(NoSend); - bar(x); - //~^ ERROR `NoSend` cannot be sent between threads safely -} diff --git a/tests/ui/no_send-enum.stderr b/tests/ui/no_send-enum.stderr deleted file mode 100644 index 3b66c7db545e1..0000000000000 --- a/tests/ui/no_send-enum.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0277]: `NoSend` cannot be sent between threads safely - --> $DIR/no_send-enum.rs:16:9 - | -LL | bar(x); - | --- ^ `NoSend` cannot be sent between threads safely - | | - | required by a bound introduced by this call - | - = help: within `Foo`, the trait `Send` is not implemented for `NoSend` -note: required because it appears within the type `Foo` - --> $DIR/no_send-enum.rs:8:6 - | -LL | enum Foo { - | ^^^ -note: required by a bound in `bar` - --> $DIR/no_send-enum.rs:12:11 - | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/no_send-rc.rs b/tests/ui/no_send-rc.rs deleted file mode 100644 index f31db15ef2eb6..0000000000000 --- a/tests/ui/no_send-rc.rs +++ /dev/null @@ -1,9 +0,0 @@ -use std::rc::Rc; - -fn bar(_: T) {} - -fn main() { - let x = Rc::new(5); - bar(x); - //~^ ERROR `Rc<{integer}>` cannot be sent between threads safely -} diff --git a/tests/ui/no_send-rc.stderr b/tests/ui/no_send-rc.stderr deleted file mode 100644 index 1430a7a29ea26..0000000000000 --- a/tests/ui/no_send-rc.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0277]: `Rc<{integer}>` cannot be sent between threads safely - --> $DIR/no_send-rc.rs:7:9 - | -LL | bar(x); - | --- ^ `Rc<{integer}>` cannot be sent between threads safely - | | - | required by a bound introduced by this call - | - = help: the trait `Send` is not implemented for `Rc<{integer}>` -note: required by a bound in `bar` - --> $DIR/no_send-rc.rs:3:11 - | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` -help: consider dereferencing here - | -LL | bar(*x); - | + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/no_share-enum.rs b/tests/ui/no_share-enum.rs deleted file mode 100644 index 44bf1913e7aac..0000000000000 --- a/tests/ui/no_share-enum.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![feature(negative_impls)] - -use std::marker::Sync; - -struct NoSync; -impl !Sync for NoSync {} - -enum Foo { A(NoSync) } - -fn bar(_: T) {} - -fn main() { - let x = Foo::A(NoSync); - bar(x); - //~^ ERROR `NoSync` cannot be shared between threads safely [E0277] -} diff --git a/tests/ui/no_share-enum.stderr b/tests/ui/no_share-enum.stderr deleted file mode 100644 index 89939216d5b16..0000000000000 --- a/tests/ui/no_share-enum.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0277]: `NoSync` cannot be shared between threads safely - --> $DIR/no_share-enum.rs:14:9 - | -LL | bar(x); - | --- ^ `NoSync` cannot be shared between threads safely - | | - | required by a bound introduced by this call - | - = help: within `Foo`, the trait `Sync` is not implemented for `NoSync` -note: required because it appears within the type `Foo` - --> $DIR/no_share-enum.rs:8:6 - | -LL | enum Foo { A(NoSync) } - | ^^^ -note: required by a bound in `bar` - --> $DIR/no_share-enum.rs:10:11 - | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/no_share-struct.rs b/tests/ui/no_share-struct.rs deleted file mode 100644 index 7d8a36a76f274..0000000000000 --- a/tests/ui/no_share-struct.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![feature(negative_impls)] - -use std::marker::Sync; - -struct Foo { a: isize } -impl !Sync for Foo {} - -fn bar(_: T) {} - -fn main() { - let x = Foo { a: 5 }; - bar(x); - //~^ ERROR `Foo` cannot be shared between threads safely [E0277] -} diff --git a/tests/ui/no_share-struct.stderr b/tests/ui/no_share-struct.stderr deleted file mode 100644 index 9c7a921b8d8ba..0000000000000 --- a/tests/ui/no_share-struct.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: `Foo` cannot be shared between threads safely - --> $DIR/no_share-struct.rs:12:9 - | -LL | bar(x); - | --- ^ `Foo` cannot be shared between threads safely - | | - | required by a bound introduced by this call - | - = help: the trait `Sync` is not implemented for `Foo` -note: required by a bound in `bar` - --> $DIR/no_share-struct.rs:8:11 - | -LL | fn bar(_: T) {} - | ^^^^ required by this bound in `bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/no_std/no-core-edition2018-syntax.rs b/tests/ui/no_std/no-core-edition2018-syntax.rs new file mode 100644 index 0000000000000..9a327e4c8e316 --- /dev/null +++ b/tests/ui/no_std/no-core-edition2018-syntax.rs @@ -0,0 +1,28 @@ +//! Test that `#![no_core]` doesn't break modern Rust syntax in edition 2018. +//! +//! When you use `#![no_core]`, you lose the automatic prelude, but you can still +//! get everything back by manually importing `use core::{prelude::v1::*, *}`. +//! This test makes sure that after doing that, things like `for` loops and the +//! `?` operator still work as expected. + +//@ run-pass +//@ edition:2018 + +#![allow(dead_code, unused_imports)] +#![feature(no_core)] +#![no_core] + +extern crate core; +extern crate std; +use core::prelude::v1::*; +use core::*; + +fn test_for_loop() { + for _ in &[()] {} +} + +fn test_question_mark_operator() -> Option<()> { + None? +} + +fn main() {} diff --git a/tests/ui/no_std/no-core-with-explicit-std-core.rs b/tests/ui/no_std/no-core-with-explicit-std-core.rs new file mode 100644 index 0000000000000..3940bcb3aa4fb --- /dev/null +++ b/tests/ui/no_std/no-core-with-explicit-std-core.rs @@ -0,0 +1,21 @@ +//! Test that you can use `#![no_core]` and still import std and core manually. +//! +//! The `#![no_core]` attribute disables the automatic core prelude, but you should +//! still be able to explicitly import both `std` and `core` crates and use types +//! like `Option` normally. + +//@ run-pass + +#![allow(stable_features)] +#![feature(no_core, core)] +#![no_core] + +extern crate core; +extern crate std; + +use std::option::Option::Some; + +fn main() { + let a = Some("foo"); + a.unwrap(); +} diff --git a/tests/ui/noexporttypeexe.stderr b/tests/ui/noexporttypeexe.stderr deleted file mode 100644 index 59759b696c7a2..0000000000000 --- a/tests/ui/noexporttypeexe.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/noexporttypeexe.rs:10:18 - | -LL | let x: isize = noexporttypelib::foo(); - | ----- ^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `Option` - | | - | expected due to this - | - = note: expected type `isize` - found enum `Option` -help: consider using `Option::expect` to unwrap the `Option` value, panicking if the value is an `Option::None` - | -LL | let x: isize = noexporttypelib::foo().expect("REASON"); - | +++++++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/non-constant-expr-for-arr-len.rs b/tests/ui/non-constant-expr-for-arr-len.rs deleted file mode 100644 index 1b101d3233f14..0000000000000 --- a/tests/ui/non-constant-expr-for-arr-len.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Check that non constant exprs fail for array repeat syntax - -fn main() { - fn bar(n: usize) { - let _x = [0; n]; - //~^ ERROR attempt to use a non-constant value in a constant [E0435] - } -} diff --git a/tests/ui/nonscalar-cast.fixed b/tests/ui/nonscalar-cast.fixed deleted file mode 100644 index cb5591dbb9de4..0000000000000 --- a/tests/ui/nonscalar-cast.fixed +++ /dev/null @@ -1,16 +0,0 @@ -//@ run-rustfix - -#[derive(Debug)] -struct Foo { - x: isize -} - -impl From for isize { - fn from(val: Foo) -> isize { - val.x - } -} - -fn main() { - println!("{}", isize::from(Foo { x: 1 })); //~ ERROR non-primitive cast: `Foo` as `isize` [E0605] -} diff --git a/tests/ui/nonscalar-cast.rs b/tests/ui/nonscalar-cast.rs deleted file mode 100644 index 27429b44cd086..0000000000000 --- a/tests/ui/nonscalar-cast.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ run-rustfix - -#[derive(Debug)] -struct Foo { - x: isize -} - -impl From for isize { - fn from(val: Foo) -> isize { - val.x - } -} - -fn main() { - println!("{}", Foo { x: 1 } as isize); //~ ERROR non-primitive cast: `Foo` as `isize` [E0605] -} diff --git a/tests/ui/nonscalar-cast.stderr b/tests/ui/nonscalar-cast.stderr deleted file mode 100644 index 834d4ea241c12..0000000000000 --- a/tests/ui/nonscalar-cast.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0605]: non-primitive cast: `Foo` as `isize` - --> $DIR/nonscalar-cast.rs:15:20 - | -LL | println!("{}", Foo { x: 1 } as isize); - | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object - | -help: consider using the `From` trait instead - | -LL - println!("{}", Foo { x: 1 } as isize); -LL + println!("{}", isize::from(Foo { x: 1 })); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/not-clone-closure.rs b/tests/ui/not-clone-closure.rs deleted file mode 100644 index 976e3b9e81c2e..0000000000000 --- a/tests/ui/not-clone-closure.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@compile-flags: --diagnostic-width=300 -// Check that closures do not implement `Clone` if their environment is not `Clone`. - -struct S(i32); - -fn main() { - let a = S(5); - let hello = move || { - println!("Hello {}", a.0); - }; - - let hello = hello.clone(); //~ ERROR the trait bound `S: Clone` is not satisfied -} diff --git a/tests/ui/not-clone-closure.stderr b/tests/ui/not-clone-closure.stderr deleted file mode 100644 index 0c95a99d0c095..0000000000000 --- a/tests/ui/not-clone-closure.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0277]: the trait bound `S: Clone` is not satisfied in `{closure@$DIR/not-clone-closure.rs:8:17: 8:24}` - --> $DIR/not-clone-closure.rs:12:23 - | -LL | let hello = move || { - | ------- within this `{closure@$DIR/not-clone-closure.rs:8:17: 8:24}` -... -LL | let hello = hello.clone(); - | ^^^^^ within `{closure@$DIR/not-clone-closure.rs:8:17: 8:24}`, the trait `Clone` is not implemented for `S` - | -note: required because it's used within this closure - --> $DIR/not-clone-closure.rs:8:17 - | -LL | let hello = move || { - | ^^^^^^^ -help: consider annotating `S` with `#[derive(Clone)]` - | -LL + #[derive(Clone)] -LL | struct S(i32); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/parser/bad-lit-suffixes.rs b/tests/ui/parser/bad-lit-suffixes.rs index 13287aabb1d96..0a01bb84f01a3 100644 --- a/tests/ui/parser/bad-lit-suffixes.rs +++ b/tests/ui/parser/bad-lit-suffixes.rs @@ -33,6 +33,7 @@ fn f() {} #[must_use = "string"suffix] //~^ ERROR suffixes on string literals are invalid +//~| ERROR malformed `must_use` attribute input fn g() {} #[link(name = "string"suffix)] diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr index 295e3112ec0a8..7876d75c5a427 100644 --- a/tests/ui/parser/bad-lit-suffixes.stderr +++ b/tests/ui/parser/bad-lit-suffixes.stderr @@ -23,13 +23,13 @@ LL | #[must_use = "string"suffix] | ^^^^^^^^^^^^^^ invalid suffix `suffix` error: suffixes on string literals are invalid - --> $DIR/bad-lit-suffixes.rs:38:15 + --> $DIR/bad-lit-suffixes.rs:39:15 | LL | #[link(name = "string"suffix)] | ^^^^^^^^^^^^^^ invalid suffix `suffix` error: invalid suffix `suffix` for number literal - --> $DIR/bad-lit-suffixes.rs:42:41 + --> $DIR/bad-lit-suffixes.rs:43:41 | LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | ^^^^^^^ invalid suffix `suffix` @@ -150,8 +150,25 @@ LL | 1.0e10suffix; | = help: valid suffixes are `f32` and `f64` +error[E0539]: malformed `must_use` attribute input + --> $DIR/bad-lit-suffixes.rs:34:1 + | +LL | #[must_use = "string"suffix] + | ^^^^^^^^^^^^^--------------^ + | | + | expected a string literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use = "string"suffix] +LL + #[must_use = "reason"] + | +LL - #[must_use = "string"suffix] +LL + #[must_use] + | + error[E0805]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/bad-lit-suffixes.rs:42:1 + --> $DIR/bad-lit-suffixes.rs:43:1 | LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^ @@ -159,6 +176,7 @@ LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | | expected a single argument here | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` -error: aborting due to 21 previous errors; 2 warnings emitted +error: aborting due to 22 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0805`. +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/new-unicode-escapes.rs b/tests/ui/parser/unicode-escape-sequences.rs similarity index 56% rename from tests/ui/new-unicode-escapes.rs rename to tests/ui/parser/unicode-escape-sequences.rs index 867a50da081c7..8b084866f196e 100644 --- a/tests/ui/new-unicode-escapes.rs +++ b/tests/ui/parser/unicode-escape-sequences.rs @@ -1,6 +1,12 @@ +//! Test ES6-style Unicode escape sequences in string literals. +//! +//! Regression test for RFC 446 implementation. +//! See . + //@ run-pass pub fn main() { + // Basic Unicode escape - snowman character let s = "\u{2603}"; assert_eq!(s, "☃"); diff --git a/tests/ui/structs/basic-newtype-pattern.rs b/tests/ui/structs/basic-newtype-pattern.rs new file mode 100644 index 0000000000000..38ccd0ea8e0c2 --- /dev/null +++ b/tests/ui/structs/basic-newtype-pattern.rs @@ -0,0 +1,25 @@ +//! Test basic newtype pattern functionality. + +//@ run-pass + +#[derive(Copy, Clone)] +struct Counter(CounterData); + +#[derive(Copy, Clone)] +struct CounterData { + compute: fn(Counter) -> isize, + val: isize, +} + +fn compute_value(counter: Counter) -> isize { + let Counter(data) = counter; + data.val + 20 +} + +pub fn main() { + let my_counter = Counter(CounterData { compute: compute_value, val: 30 }); + + // Test destructuring and function pointer call + let Counter(data) = my_counter; + assert_eq!((data.compute)(my_counter), 50); +} diff --git a/tests/ui/no-send-res-ports.rs b/tests/ui/threads-sendsync/rc-is-not-send.rs similarity index 52% rename from tests/ui/no-send-res-ports.rs rename to tests/ui/threads-sendsync/rc-is-not-send.rs index 1bac5868e73fe..dd562e9e8f34f 100644 --- a/tests/ui/no-send-res-ports.rs +++ b/tests/ui/threads-sendsync/rc-is-not-send.rs @@ -1,28 +1,28 @@ -use std::thread; +//! Test that `Rc` cannot be sent between threads. + use std::rc::Rc; +use std::thread; #[derive(Debug)] struct Port(Rc); -fn main() { - #[derive(Debug)] - struct Foo { - _x: Port<()>, - } +#[derive(Debug)] +struct Foo { + _x: Port<()>, +} - impl Drop for Foo { - fn drop(&mut self) {} - } +impl Drop for Foo { + fn drop(&mut self) {} +} - fn foo(x: Port<()>) -> Foo { - Foo { - _x: x - } - } +fn foo(x: Port<()>) -> Foo { + Foo { _x: x } +} +fn main() { let x = foo(Port(Rc::new(()))); - thread::spawn(move|| { + thread::spawn(move || { //~^ ERROR `Rc<()>` cannot be sent between threads safely let y = x; println!("{:?}", y); diff --git a/tests/ui/no-send-res-ports.stderr b/tests/ui/threads-sendsync/rc-is-not-send.stderr similarity index 58% rename from tests/ui/no-send-res-ports.stderr rename to tests/ui/threads-sendsync/rc-is-not-send.stderr index 9c30261e5cb73..a06b683f729e0 100644 --- a/tests/ui/no-send-res-ports.stderr +++ b/tests/ui/threads-sendsync/rc-is-not-send.stderr @@ -1,10 +1,10 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely - --> $DIR/no-send-res-ports.rs:25:19 + --> $DIR/rc-is-not-send.rs:25:19 | -LL | thread::spawn(move|| { - | ------------- ^----- +LL | thread::spawn(move || { + | ------------- ^------ | | | - | _____|_____________within this `{closure@$DIR/no-send-res-ports.rs:25:19: 25:25}` + | _____|_____________within this `{closure@$DIR/rc-is-not-send.rs:25:19: 25:26}` | | | | | required by a bound introduced by this call LL | | @@ -13,22 +13,22 @@ LL | | println!("{:?}", y); LL | | }); | |_____^ `Rc<()>` cannot be sent between threads safely | - = help: within `{closure@$DIR/no-send-res-ports.rs:25:19: 25:25}`, the trait `Send` is not implemented for `Rc<()>` + = help: within `{closure@$DIR/rc-is-not-send.rs:25:19: 25:26}`, the trait `Send` is not implemented for `Rc<()>` note: required because it appears within the type `Port<()>` - --> $DIR/no-send-res-ports.rs:5:8 + --> $DIR/rc-is-not-send.rs:7:8 | LL | struct Port(Rc); | ^^^^ note: required because it appears within the type `Foo` - --> $DIR/no-send-res-ports.rs:9:12 + --> $DIR/rc-is-not-send.rs:10:8 | -LL | struct Foo { - | ^^^ +LL | struct Foo { + | ^^^ note: required because it's used within this closure - --> $DIR/no-send-res-ports.rs:25:19 + --> $DIR/rc-is-not-send.rs:25:19 | -LL | thread::spawn(move|| { - | ^^^^^^ +LL | thread::spawn(move || { + | ^^^^^^^ note: required by a bound in `spawn` --> $SRC_DIR/std/src/thread/mod.rs:LL:COL diff --git a/tests/ui/traits/enum-negative-send-impl.rs b/tests/ui/traits/enum-negative-send-impl.rs new file mode 100644 index 0000000000000..6bff42e999919 --- /dev/null +++ b/tests/ui/traits/enum-negative-send-impl.rs @@ -0,0 +1,22 @@ +//! Test that enums inherit Send/!Send properties from their variants. +//! +//! Uses the unstable `negative_impls` feature to explicitly opt-out of Send. + +#![feature(negative_impls)] + +use std::marker::Send; + +struct NoSend; +impl !Send for NoSend {} + +enum Container { + WithNoSend(NoSend), +} + +fn requires_send(_: T) {} + +fn main() { + let container = Container::WithNoSend(NoSend); + requires_send(container); + //~^ ERROR `NoSend` cannot be sent between threads safely +} diff --git a/tests/ui/traits/enum-negative-send-impl.stderr b/tests/ui/traits/enum-negative-send-impl.stderr new file mode 100644 index 0000000000000..1992becccf40e --- /dev/null +++ b/tests/ui/traits/enum-negative-send-impl.stderr @@ -0,0 +1,23 @@ +error[E0277]: `NoSend` cannot be sent between threads safely + --> $DIR/enum-negative-send-impl.rs:20:19 + | +LL | requires_send(container); + | ------------- ^^^^^^^^^ `NoSend` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: within `Container`, the trait `Send` is not implemented for `NoSend` +note: required because it appears within the type `Container` + --> $DIR/enum-negative-send-impl.rs:12:6 + | +LL | enum Container { + | ^^^^^^^^^ +note: required by a bound in `requires_send` + --> $DIR/enum-negative-send-impl.rs:16:21 + | +LL | fn requires_send(_: T) {} + | ^^^^ required by this bound in `requires_send` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/enum-negative-sync-impl.rs b/tests/ui/traits/enum-negative-sync-impl.rs new file mode 100644 index 0000000000000..aa81a9fbbf9a9 --- /dev/null +++ b/tests/ui/traits/enum-negative-sync-impl.rs @@ -0,0 +1,22 @@ +//! Test that enums inherit Sync/!Sync properties from their variants. +//! +//! Uses the unstable `negative_impls` feature to explicitly opt-out of Sync. + +#![feature(negative_impls)] + +use std::marker::Sync; + +struct NoSync; +impl !Sync for NoSync {} + +enum Container { + WithNoSync(NoSync), +} + +fn requires_sync(_: T) {} + +fn main() { + let container = Container::WithNoSync(NoSync); + requires_sync(container); + //~^ ERROR `NoSync` cannot be shared between threads safely [E0277] +} diff --git a/tests/ui/traits/enum-negative-sync-impl.stderr b/tests/ui/traits/enum-negative-sync-impl.stderr new file mode 100644 index 0000000000000..a97b7a36a7bec --- /dev/null +++ b/tests/ui/traits/enum-negative-sync-impl.stderr @@ -0,0 +1,23 @@ +error[E0277]: `NoSync` cannot be shared between threads safely + --> $DIR/enum-negative-sync-impl.rs:20:19 + | +LL | requires_sync(container); + | ------------- ^^^^^^^^^ `NoSync` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: within `Container`, the trait `Sync` is not implemented for `NoSync` +note: required because it appears within the type `Container` + --> $DIR/enum-negative-sync-impl.rs:12:6 + | +LL | enum Container { + | ^^^^^^^^^ +note: required by a bound in `requires_sync` + --> $DIR/enum-negative-sync-impl.rs:16:21 + | +LL | fn requires_sync(_: T) {} + | ^^^^ required by this bound in `requires_sync` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/rc-not-send.rs b/tests/ui/traits/rc-not-send.rs new file mode 100644 index 0000000000000..83084c6173a00 --- /dev/null +++ b/tests/ui/traits/rc-not-send.rs @@ -0,0 +1,11 @@ +//! Test that `Rc` does not implement `Send`. + +use std::rc::Rc; + +fn requires_send(_: T) {} + +fn main() { + let rc_value = Rc::new(5); + requires_send(rc_value); + //~^ ERROR `Rc<{integer}>` cannot be sent between threads safely +} diff --git a/tests/ui/traits/rc-not-send.stderr b/tests/ui/traits/rc-not-send.stderr new file mode 100644 index 0000000000000..d6171a39ad047 --- /dev/null +++ b/tests/ui/traits/rc-not-send.stderr @@ -0,0 +1,22 @@ +error[E0277]: `Rc<{integer}>` cannot be sent between threads safely + --> $DIR/rc-not-send.rs:9:19 + | +LL | requires_send(rc_value); + | ------------- ^^^^^^^^ `Rc<{integer}>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `Rc<{integer}>` +note: required by a bound in `requires_send` + --> $DIR/rc-not-send.rs:5:21 + | +LL | fn requires_send(_: T) {} + | ^^^^ required by this bound in `requires_send` +help: consider dereferencing here + | +LL | requires_send(*rc_value); + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/struct-negative-sync-impl.rs b/tests/ui/traits/struct-negative-sync-impl.rs new file mode 100644 index 0000000000000..d32846276f626 --- /dev/null +++ b/tests/ui/traits/struct-negative-sync-impl.rs @@ -0,0 +1,21 @@ +//! Test negative Sync implementation on structs. +//! +//! Uses the unstable `negative_impls` feature to explicitly opt-out of Sync. + +#![feature(negative_impls)] + +use std::marker::Sync; + +struct NotSync { + value: isize, +} + +impl !Sync for NotSync {} + +fn requires_sync(_: T) {} + +fn main() { + let not_sync = NotSync { value: 5 }; + requires_sync(not_sync); + //~^ ERROR `NotSync` cannot be shared between threads safely [E0277] +} diff --git a/tests/ui/traits/struct-negative-sync-impl.stderr b/tests/ui/traits/struct-negative-sync-impl.stderr new file mode 100644 index 0000000000000..c5fd13f42e50e --- /dev/null +++ b/tests/ui/traits/struct-negative-sync-impl.stderr @@ -0,0 +1,18 @@ +error[E0277]: `NotSync` cannot be shared between threads safely + --> $DIR/struct-negative-sync-impl.rs:19:19 + | +LL | requires_sync(not_sync); + | ------------- ^^^^^^^^ `NotSync` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Sync` is not implemented for `NotSync` +note: required by a bound in `requires_sync` + --> $DIR/struct-negative-sync-impl.rs:15:21 + | +LL | fn requires_sync(_: T) {} + | ^^^^ required by this bound in `requires_sync` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.