diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 1060f911a9ed4..b309a124e8089 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -918,12 +918,29 @@ fn generic_simd_intrinsic( } if let Some(stripped) = name_str.strip_prefix("simd_shuffle") { - let n: u64 = stripped.parse().unwrap_or_else(|_| { - span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") - }); + // If this intrinsic is the older "simd_shuffleN" form, simply parse the integer. + // If there is no suffix, use the index array length. + let n: u64 = if stripped.is_empty() { + // Make sure this is actually an array, since typeck only checks the length-suffixed + // version of this intrinsic. + match args[2].layout.ty.kind() { + ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => { + len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| { + span_bug!(span, "could not evaluate shuffle index array length") + }) + } + _ => return_error!( + "simd_shuffle index must be an array of `u32`, got `{}`", + args[2].layout.ty + ), + } + } else { + stripped.parse().unwrap_or_else(|_| { + span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?") + }) + }; require_simd!(ret_ty, "return"); - let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( out_len == n, diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index cd0e9354c2441..0861aab2e318c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -665,8 +665,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") { if let mir::Operand::Constant(constant) = arg { let c = self.eval_mir_constant(constant); - let (llval, ty) = - self.simd_shuffle_indices(&bx, constant.span, constant.ty(), c); + let (llval, ty) = self.simd_shuffle_indices( + &bx, + constant.span, + self.monomorphize(constant.ty()), + c, + ); return OperandRef { val: Immediate(llval), layout: bx.layout_of(ty), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 0e5a896a8f18b..9eec930f59e52 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -384,11 +384,11 @@ impl Checker<'mir, 'tcx> { match pred.skip_binder() { ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => { - self.check_op(ops::ty::TraitBound(kind)) + self.check_op(ops::ty::DynTrait(kind)) } ty::ExistentialPredicate::Trait(trait_ref) => { if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() { - self.check_op(ops::ty::TraitBound(kind)) + self.check_op(ops::ty::DynTrait(kind)) } } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 2a29675083888..1d0ee949a221b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -599,7 +599,7 @@ pub mod ty { } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - let mut builder = feature_err( + let mut err = feature_err( &ccx.tcx.sess.parse_sess, sym::const_fn_trait_bound, span, @@ -608,12 +608,51 @@ pub mod ty { match ccx.fn_sig() { Some(fn_sig) if !fn_sig.span.contains(span) => { - builder.span_label(fn_sig.span, "function declared as const here"); + err.span_label(fn_sig.span, "function declared as const here"); } _ => {} } - builder + err + } + } + + #[derive(Debug)] + pub struct DynTrait(pub mir::LocalKind); + impl NonConstOp for DynTrait { + fn importance(&self) -> DiagnosticImportance { + match self.0 { + mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary, + mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => { + DiagnosticImportance::Primary + } + } + } + + fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { + if ccx.const_kind() != hir::ConstContext::ConstFn { + Status::Allowed + } else { + Status::Unstable(sym::const_fn_trait_bound) + } + } + + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + let mut err = feature_err( + &ccx.tcx.sess.parse_sess, + sym::const_fn_trait_bound, + span, + "trait objects in const fn are unstable", + ); + + match ccx.fn_sig() { + Some(fn_sig) if !fn_sig.span.contains(span) => { + err.span_label(fn_sig.span, "function declared as const here"); + } + _ => {} + } + + err } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0439.md b/compiler/rustc_error_codes/src/error_codes/E0439.md index 3e663df866caa..24268aef2222a 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0439.md +++ b/compiler/rustc_error_codes/src/error_codes/E0439.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + The length of the platform-intrinsic function `simd_shuffle` wasn't specified. Erroneous code example: -```compile_fail,E0439 +```ignore (no longer emitted) #![feature(platform_intrinsics)] extern "platform-intrinsic" { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 62066ca965784..d32593f34adef 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1386,14 +1386,17 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { // `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` lint if needed. // See #78991 for an investigation of treating macros in this position // as statements, rather than expressions, during parsing. - if let StmtKind::Expr(expr) = &stmt.kind { - if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) { + let res = match &stmt.kind { + StmtKind::Expr(expr) + if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) => + { self.cx.current_expansion.is_trailing_mac = true; + // Don't use `assign_id` for this statement - it may get removed + // entirely due to a `#[cfg]` on the contained expression + noop_flat_map_stmt(stmt, self) } - } - - let res = assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self)); - + _ => assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self)), + }; self.cx.current_expansion.is_trailing_mac = false; res } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index a5dbbffeaa86b..a158e0e48e86c 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1652,7 +1652,11 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) { } fn expression_label(ex: &hir::Expr<'_>) -> Option { - if let hir::ExprKind::Loop(_, Some(label), ..) = ex.kind { Some(label.ident) } else { None } + match ex.kind { + hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident), + hir::ExprKind::Block(_, Some(label)) => Some(label.ident), + _ => None, + } } fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 78846d8ffb26b..322bea3806cfa 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1212,6 +1212,7 @@ symbols! { simd_select_bitmask, simd_shl, simd_shr, + simd_shuffle, simd_sub, simd_trunc, simd_xor, diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 53c1470c601d2..11b6c93a11528 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1860,6 +1860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field, expr_t, expr, + None, ); } err.emit(); @@ -1886,9 +1887,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let expr_snippet = self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new()); - if expr_is_call && expr_snippet.starts_with("(") && expr_snippet.ends_with(")") { - let after_open = expr.span.lo() + rustc_span::BytePos(1); - let before_close = expr.span.hi() - rustc_span::BytePos(1); + let is_wrapped = expr_snippet.starts_with("(") && expr_snippet.ends_with(")"); + let after_open = expr.span.lo() + rustc_span::BytePos(1); + let before_close = expr.span.hi() - rustc_span::BytePos(1); + + if expr_is_call && is_wrapped { err.multipart_suggestion( "remove wrapping parentheses to call the method", vec![ @@ -1898,12 +1901,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } else if !self.expr_in_place(expr.hir_id) { + // Suggest call parentheses inside the wrapping parentheses + let span = if is_wrapped { + expr.span.with_lo(after_open).with_hi(before_close) + } else { + expr.span + }; self.suggest_method_call( &mut err, "use parentheses to call the method", field, expr_t, expr, + Some(span), ); } else { err.help("methods are immutable and cannot be assigned to"); diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs index 664954b0eb7a2..ff7a26853b188 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_typeck/src/check/intrinsic.rs @@ -2,7 +2,7 @@ //! intrinsics that the compiler exposes. use crate::errors::{ - SimdShuffleMissingLength, UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, + UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction, WrongNumberOfGenericArgumentsToIntrinsic, }; use crate::require_same_types; @@ -468,6 +468,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) | sym::simd_reduce_max | sym::simd_reduce_min_nanless | sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)), + sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)), name if name.as_str().starts_with("simd_shuffle") => { match name.as_str()["simd_shuffle".len()..].parse() { Ok(n) => { @@ -475,7 +476,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) (2, params, param(1)) } Err(_) => { - tcx.sess.emit_err(SimdShuffleMissingLength { span: it.span, name }); + let msg = + format!("unrecognized platform-specific intrinsic function: `{}`", name); + tcx.sess.struct_span_err(it.span, &msg).emit(); return; } } diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 2136d925423b9..8e09aa97dcf34 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -141,6 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name: Ident, self_ty: Ty<'tcx>, call_expr: &hir::Expr<'_>, + span: Option, ) { let params = self .probe_for_name( @@ -159,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(0); // Account for `foo.bar`; - let sugg_span = call_expr.span.shrink_to_hi(); + let sugg_span = span.unwrap_or_else(|| call_expr.span).shrink_to_hi(); let (suggestion, applicability) = ( format!("({})", (0..params).map(|_| "_").collect::>().join(", ")), if params > 0 { Applicability::HasPlaceholders } else { Applicability::MaybeIncorrect }, diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index a056ab6aef2ae..829268e3cb527 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1452,7 +1452,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { plural ), ); - if plural == "" { + + if unmentioned_fields.len() == 1 { let input = unmentioned_fields.iter().map(|(_, field)| field.name).collect::>(); let suggested_name = find_best_match_for_name(&input, ident.name, None); @@ -1473,6 +1474,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We don't want to throw `E0027` in case we have thrown `E0026` for them. unmentioned_fields.retain(|&(_, x)| x.name != suggested_name); } + } else if inexistent_fields.len() == 1 { + let unmentioned_field = unmentioned_fields[0].1.name; + err.span_suggestion_short( + ident.span, + &format!( + "`{}` has a field named `{}`", + tcx.def_path_str(variant.def_id), + unmentioned_field + ), + unmentioned_field.to_string(), + Applicability::MaybeIncorrect, + ); } } } diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 1e6a240b2f86d..47077779616c0 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -121,14 +121,6 @@ pub struct AssocTypeBindingNotAllowed { pub span: Span, } -#[derive(SessionDiagnostic)] -#[error = "E0439"] -pub struct SimdShuffleMissingLength { - #[message = "invalid `simd_shuffle`, needs length: `{name}`"] - pub span: Span, - pub name: Symbol, -} - #[derive(SessionDiagnostic)] #[error = "E0436"] pub struct FunctionalRecordUpdateOnNonStruct { diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 5f13c3bf30387..54a157be0b96a 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -17,7 +17,13 @@ pub struct IntoIter< T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, > { - pub(crate) inner: VecDeque, + inner: VecDeque, +} + +impl IntoIter { + pub(super) fn new(inner: VecDeque) -> Self { + IntoIter { inner } + } } #[stable(feature = "collection_debug", since = "1.17.0")] diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index e4b28204158d9..10144cc17bf30 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2827,7 +2827,7 @@ impl IntoIterator for VecDeque { /// Consumes the `VecDeque` into a front-to-back iterator yielding elements by /// value. fn into_iter(self) -> IntoIter { - IntoIter { inner: self } + IntoIter::new(self) } } diff --git a/library/std/src/error.rs b/library/std/src/error.rs index ec9f012295000..8164ec5698579 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -182,7 +182,7 @@ impl<'a, E: Error + 'a> From for Box { /// /// impl fmt::Display for AnError { /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - /// write!(f , "An error") + /// write!(f, "An error") /// } /// } /// @@ -215,7 +215,7 @@ impl<'a, E: Error + Send + Sync + 'a> From for Box) -> fmt::Result { - /// write!(f , "An error") + /// write!(f, "An error") /// } /// } /// diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 559d2672a0da3..f69baba9e733f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -234,6 +234,7 @@ #![feature(atomic_mut_ptr)] #![feature(auto_traits)] #![feature(bench_black_box)] +#![feature(bool_to_option)] #![feature(box_syntax)] #![feature(c_unwind)] #![feature(c_variadic)] diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs index 9b7af97616c9d..9d18ccbeb2494 100644 --- a/library/std/src/os/linux/fs.rs +++ b/library/std/src/os/linux/fs.rs @@ -1,4 +1,6 @@ -//! Linux-specific extensions to primitives in the `std::fs` module. +//! Linux-specific extensions to primitives in the [`std::fs`] module. +//! +//! [`std::fs`]: crate::fs #![stable(feature = "metadata_ext", since = "1.1.0")] diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs index e3e7143c851ef..540363c03494e 100644 --- a/library/std/src/os/linux/process.rs +++ b/library/std/src/os/linux/process.rs @@ -1,4 +1,6 @@ -//! Linux-specific extensions to primitives in the `std::process` module. +//! Linux-specific extensions to primitives in the [`std::process`] module. +//! +//! [`std::process`]: crate::process #![unstable(feature = "linux_pidfd", issue = "82971")] diff --git a/library/std/src/os/unix/ffi/mod.rs b/library/std/src/os/unix/ffi/mod.rs index c29df6596fd94..5b49f50763d74 100644 --- a/library/std/src/os/unix/ffi/mod.rs +++ b/library/std/src/os/unix/ffi/mod.rs @@ -1,4 +1,4 @@ -//! Unix-specific extension to the primitives in the `std::ffi` module. +//! Unix-specific extensions to primitives in the [`std::ffi`] module. //! //! # Examples //! @@ -31,6 +31,8 @@ //! let bytes = os_str.as_bytes(); //! assert_eq!(bytes, b"foo"); //! ``` +//! +//! [`std::ffi`]: crate::ffi #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 30eead9b05901..0284a428b5d74 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -1,4 +1,6 @@ -//! Unix-specific extensions to primitives in the `std::fs` module. +//! Unix-specific extensions to primitives in the [`std::fs`] module. +//! +//! [`std::fs`]: crate::fs #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index 17a0259572446..62f750fa607c9 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -4,8 +4,8 @@ //! exposes Unix-specific functions that would otherwise be inappropriate as //! part of the core `std` library. //! -//! It exposes more ways to deal with platform-specific strings (`OsStr`, -//! `OsString`), allows to set permissions more granularly, extract low-level +//! It exposes more ways to deal with platform-specific strings ([`OsStr`], +//! [`OsString`]), allows to set permissions more granularly, extract low-level //! file descriptors from files and sockets, and has platform-specific helpers //! for spawning processes. //! @@ -24,6 +24,9 @@ //! Ok(()) //! } //! ``` +//! +//! [`OsStr`]: crate::ffi::OsStr +//! [`OsString`]: crate::ffi::OsString #![stable(feature = "rust1", since = "1.0.0")] #![doc(cfg(unix))] diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index d462bd4b5f75e..8ce8220885419 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -1,4 +1,4 @@ -//! Unix-specific networking functionality +//! Unix-specific networking functionality. #![stable(feature = "unix_socket", since = "1.10.0")] diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 650dcbabbae8c..4d23805e479ba 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -1,4 +1,6 @@ -//! Unix-specific extensions to primitives in the `std::process` module. +//! Unix-specific extensions to primitives in the [`std::process`] module. +//! +//! [`std::process`]: crate::process #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/os/unix/thread.rs b/library/std/src/os/unix/thread.rs index 7221da1a9a7bb..03dcc3a4f9ba0 100644 --- a/library/std/src/os/unix/thread.rs +++ b/library/std/src/os/unix/thread.rs @@ -1,4 +1,6 @@ -//! Unix-specific extensions to primitives in the `std::thread` module. +//! Unix-specific extensions to primitives in the [`std::thread`] module. +//! +//! [`std::thread`]: crate::thread #![stable(feature = "thread_extensions", since = "1.9.0")] diff --git a/library/std/src/os/wasi/ffi.rs b/library/std/src/os/wasi/ffi.rs index 17e12a395a670..41dd8702e98e9 100644 --- a/library/std/src/os/wasi/ffi.rs +++ b/library/std/src/os/wasi/ffi.rs @@ -1,4 +1,6 @@ -//! WASI-specific extension to the primitives in the `std::ffi` module +//! WASI-specific extensions to primitives in the [`std::ffi`] module +//! +//! [`std::ffi`]: crate::ffi #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index 3df27563e21e9..907368061d7c4 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -1,4 +1,6 @@ -//! WASI-specific extensions to primitives in the `std::fs` module. +//! WASI-specific extensions to primitives in the [`std::fs`] module. +//! +//! [`std::fs`]: crate::fs #![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "71213")] diff --git a/library/std/src/os/wasi/mod.rs b/library/std/src/os/wasi/mod.rs index d767c149dc5d0..bbaf328f457e4 100644 --- a/library/std/src/os/wasi/mod.rs +++ b/library/std/src/os/wasi/mod.rs @@ -24,6 +24,9 @@ //! Ok(()) //! } //! ``` +//! +//! [`OsStr`]: crate::ffi::OsStr +//! [`OsString`]: crate::ffi::OsString #![stable(feature = "rust1", since = "1.0.0")] #![deny(unsafe_op_in_unsafe_fn)] diff --git a/library/std/src/os/windows/ffi.rs b/library/std/src/os/windows/ffi.rs index 8d29fa7d66f99..a9493a94cac26 100644 --- a/library/std/src/os/windows/ffi.rs +++ b/library/std/src/os/windows/ffi.rs @@ -1,4 +1,4 @@ -//! Windows-specific extensions to the primitives in the `std::ffi` module. +//! Windows-specific extensions to primitives in the [`std::ffi`] module. //! //! # Overview //! @@ -49,6 +49,7 @@ //! [ill-formed-utf-16]: https://simonsapin.github.io/wtf-8/#ill-formed-utf-16 //! [`collect`]: crate::iter::Iterator::collect //! [U+FFFD]: crate::char::REPLACEMENT_CHARACTER +//! [`std::ffi`]: crate::ffi #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs index 71563a02dcbb9..be35ab0ca1e66 100644 --- a/library/std/src/os/windows/fs.rs +++ b/library/std/src/os/windows/fs.rs @@ -1,4 +1,6 @@ -//! Windows-specific extensions for the primitives in the `std::fs` module. +//! Windows-specific extensions to primitives in the [`std::fs`] module. +//! +//! [`std::fs`]: crate::fs #![stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/os/windows/mod.rs b/library/std/src/os/windows/mod.rs index 969054dd3b3dc..52eb3b7c06769 100644 --- a/library/std/src/os/windows/mod.rs +++ b/library/std/src/os/windows/mod.rs @@ -5,6 +5,22 @@ //! the core `std` library. These extensions allow developers to use //! `std` types and idioms with Windows in a way that the normal //! platform-agnostic idioms would not normally support. +//! +//! # Examples +//! +//! ```no_run +//! use std::fs::File; +//! use std::os::windows::prelude::*; +//! +//! fn main() -> std::io::Result<()> { +//! let f = File::create("foo.txt")?; +//! let handle = f.as_raw_handle(); +//! +//! // use handle with native windows bindings +//! +//! Ok(()) +//! } +//! ``` #![stable(feature = "rust1", since = "1.0.0")] #![doc(cfg(windows))] diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index b246599dfc0a9..9510d104806db 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -1,4 +1,6 @@ -//! Extensions to `std::process` for Windows. +//! Windows-specific extensions to primitives in the [`std::process`] module. +//! +//! [`std::process`]: crate::process #![stable(feature = "process_extensions", since = "1.2.0")] diff --git a/library/std/src/os/windows/thread.rs b/library/std/src/os/windows/thread.rs index fb1bf66ceed35..d81d6d0ac28a9 100644 --- a/library/std/src/os/windows/thread.rs +++ b/library/std/src/os/windows/thread.rs @@ -1,4 +1,6 @@ -//! Extensions to `std::thread` for Windows. +//! Windows-specific extensions to primitives in the [`std::thread`] module. +//! +//! [`std::thread`]: crate::thread #![stable(feature = "thread_extensions", since = "1.9.0")] diff --git a/library/std/src/time/monotonic.rs b/library/std/src/time/monotonic.rs index fa96b7abff6d6..198ae739b5567 100644 --- a/library/std/src/time/monotonic.rs +++ b/library/std/src/time/monotonic.rs @@ -37,35 +37,36 @@ pub mod inner { // This could be a problem for programs that call instants at intervals greater // than 68 years. Interstellar probes may want to ensure that actually_monotonic() is true. let packed = (secs << 32) | nanos; - let old = mono.load(Relaxed); - - if old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2 { - mono.store(packed, Relaxed); - raw - } else { - // Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the - // passed in value and the 64bits loaded from the atomic - let seconds_lower = old >> 32; - let mut seconds_upper = secs & 0xffff_ffff_0000_0000; - if secs & 0xffff_ffff > seconds_lower { - // Backslide caused the lower 32bit of the seconds part to wrap. - // This must be the case because the seconds part is larger even though - // we are in the backslide branch, i.e. the seconds count should be smaller or equal. - // - // We assume that backslides are smaller than 2^32 seconds - // which means we need to add 1 to the upper half to restore it. - // - // Example: - // most recent observed time: 0xA1_0000_0000_0000_0000u128 - // bits stored in AtomicU64: 0x0000_0000_0000_0000u64 - // backslide by 1s - // caller time is 0xA0_ffff_ffff_0000_0000u128 - // -> we can fix up the upper half time by adding 1 << 32 - seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000); + let updated = mono.fetch_update(Relaxed, Relaxed, |old| { + (old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2).then_some(packed) + }); + match updated { + Ok(_) => raw, + Err(newer) => { + // Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the + // passed in value and the 64bits loaded from the atomic + let seconds_lower = newer >> 32; + let mut seconds_upper = secs & 0xffff_ffff_0000_0000; + if secs & 0xffff_ffff > seconds_lower { + // Backslide caused the lower 32bit of the seconds part to wrap. + // This must be the case because the seconds part is larger even though + // we are in the backslide branch, i.e. the seconds count should be smaller or equal. + // + // We assume that backslides are smaller than 2^32 seconds + // which means we need to add 1 to the upper half to restore it. + // + // Example: + // most recent observed time: 0xA1_0000_0000_0000_0000u128 + // bits stored in AtomicU64: 0x0000_0000_0000_0000u64 + // backslide by 1s + // caller time is 0xA0_ffff_ffff_0000_0000u128 + // -> we can fix up the upper half time by adding 1 << 32 + seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000); + } + let secs = seconds_upper | seconds_lower; + let nanos = newer as u32; + ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap() } - let secs = seconds_upper | seconds_lower; - let nanos = old as u32; - ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap() } } } diff --git a/src/test/ui/consts/const_fn_trait_bound.rs b/src/test/ui/consts/const_fn_trait_bound.rs index b1ef820d827b4..19c08b6214425 100644 --- a/src/test/ui/consts/const_fn_trait_bound.rs +++ b/src/test/ui/consts/const_fn_trait_bound.rs @@ -8,9 +8,9 @@ const fn test1() {} //[stock]~^ trait bounds const fn test2(_x: &dyn Send) {} -//[stock]~^ trait bounds +//[stock]~^ trait objects in const fn are unstable const fn test3() -> &'static dyn Send { loop {} } -//[stock]~^ trait bounds +//[stock]~^ trait objects in const fn are unstable #[rustc_error] diff --git a/src/test/ui/consts/const_fn_trait_bound.stock.stderr b/src/test/ui/consts/const_fn_trait_bound.stock.stderr index 2ad45f3afde8f..d652b5268a8bf 100644 --- a/src/test/ui/consts/const_fn_trait_bound.stock.stderr +++ b/src/test/ui/consts/const_fn_trait_bound.stock.stderr @@ -7,7 +7,7 @@ LL | const fn test1() {} = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/const_fn_trait_bound.rs:10:16 | LL | const fn test2(_x: &dyn Send) {} @@ -16,7 +16,7 @@ LL | const fn test2(_x: &dyn Send) {} = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/const_fn_trait_bound.rs:12:21 | LL | const fn test3() -> &'static dyn Send { loop {} } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index bb525d5719778..10347a02074ec 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -130,16 +130,16 @@ const fn no_apit(_x: impl std::fmt::Debug) {} //~^ ERROR trait bounds other than `Sized` //~| ERROR destructor const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} -//~^ ERROR trait bounds other than `Sized` +//~^ ERROR trait objects in const fn are unstable const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } -//~^ ERROR trait bounds other than `Sized` +//~^ ERROR trait objects in const fn are unstable const fn no_unsafe() { unsafe {} } const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } -//~^ ERROR trait bounds other than `Sized` -//~| ERROR trait bounds other than `Sized` -//~| ERROR trait bounds other than `Sized` +//~^ ERROR trait objects in const fn are unstable +//~| ERROR trait objects in const fn are unstable +//~| ERROR trait objects in const fn are unstable const fn no_fn_ptrs(_x: fn()) {} //~^ ERROR function pointer diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index d1c2a04d6a61b..1e275d77bac67 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -279,7 +279,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {} | | | constant functions cannot evaluate destructors -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/min_const_fn.rs:132:23 | LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} @@ -288,7 +288,7 @@ LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/min_const_fn.rs:134:32 | LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } @@ -297,7 +297,7 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/min_const_fn.rs:139:41 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } @@ -308,7 +308,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/min_const_fn.rs:139:42 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } @@ -319,7 +319,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/min_const_fn.rs:139:42 | LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs index 6ca1e59b3af10..1ab8253b414a3 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs @@ -7,9 +7,9 @@ struct Hide(HasDyn); const fn no_inner_dyn_trait(_x: Hide) {} const fn no_inner_dyn_trait2(x: Hide) { x.0.field; -//~^ ERROR trait bounds other than `Sized` +//~^ ERROR trait objects in const fn are unstable } const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } -//~^ ERROR trait bounds other than `Sized` +//~^ ERROR trait objects in const fn are unstable fn main() {} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr index 2cad8a862be4c..6eec1df5aeca7 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr @@ -1,4 +1,4 @@ -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/min_const_fn_dyn.rs:9:5 | LL | const fn no_inner_dyn_trait2(x: Hide) { @@ -9,7 +9,7 @@ LL | x.0.field; = note: see issue #57563 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable -error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable +error[E0658]: trait objects in const fn are unstable --> $DIR/min_const_fn_dyn.rs:12:66 | LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) } diff --git a/src/test/ui/error-codes/E0439.rs b/src/test/ui/error-codes/E0439.rs deleted file mode 100644 index 86e9cb55a9c86..0000000000000 --- a/src/test/ui/error-codes/E0439.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![feature(platform_intrinsics)] - -extern "platform-intrinsic" { - fn simd_shuffle(a: A, b: A, c: [u32; 8]) -> B; //~ ERROR E0439 -} - -fn main () { -} diff --git a/src/test/ui/error-codes/E0439.stderr b/src/test/ui/error-codes/E0439.stderr deleted file mode 100644 index 8021f7d3951a8..0000000000000 --- a/src/test/ui/error-codes/E0439.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0439]: invalid `simd_shuffle`, needs length: `simd_shuffle` - --> $DIR/E0439.rs:4:5 - | -LL | fn simd_shuffle(a: A, b: A, c: [u32; 8]) -> B; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0439`. diff --git a/src/test/ui/issues/issue-51102.stderr b/src/test/ui/issues/issue-51102.stderr index eb9eb68020067..09c52292dccaf 100644 --- a/src/test/ui/issues/issue-51102.stderr +++ b/src/test/ui/issues/issue-51102.stderr @@ -2,7 +2,10 @@ error[E0026]: struct `SimpleStruct` does not have a field named `state` --> $DIR/issue-51102.rs:13:17 | LL | state: 0, - | ^^^^^ struct `SimpleStruct` does not have this field + | ^^^^^ + | | + | struct `SimpleStruct` does not have this field + | help: `SimpleStruct` has a field named `no_state_here` error[E0025]: field `no_state_here` bound multiple times in the pattern --> $DIR/issue-51102.rs:24:17 diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs index 3a860f508ff78..68a19a8f6f717 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs @@ -1,7 +1,7 @@ // check-pass +#![feature(label_break_value)] - -// Issue #21633: reject duplicate loop labels in function bodies. +// Issue #21633: reject duplicate loop labels and block labels in function bodies. // // This is testing the generalization (to the whole function body) // discussed here: @@ -26,6 +26,8 @@ pub fn foo() { { 'lt: loop { break; } } { 'lt: while let Some(_) = None:: { break; } } //~^ WARN label name `'lt` shadows a label name that is already in scope + { 'bl: {} } + { 'bl: {} } //~ WARN label name `'bl` shadows a label name that is already in scope } diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr index 6c53d04e10790..2c372fcff7a12 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr +++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr @@ -62,5 +62,13 @@ LL | { 'lt: loop { break; } } LL | { 'lt: while let Some(_) = None:: { break; } } | ^^^ label `'lt` already in scope -warning: 8 warnings emitted +warning: label name `'bl` shadows a label name that is already in scope + --> $DIR/loops-reject-duplicate-labels-2.rs:30:7 + | +LL | { 'bl: {} } + | --- first declared here +LL | { 'bl: {} } + | ^^^ label `'bl` already in scope + +warning: 9 warnings emitted diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.rs b/src/test/ui/loops/loops-reject-duplicate-labels.rs index d9334ce385718..c34bcf3df1d76 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.rs +++ b/src/test/ui/loops/loops-reject-duplicate-labels.rs @@ -1,8 +1,7 @@ // check-pass +#![feature(label_break_value)] - -// Issue #21633: reject duplicate loop labels in function bodies. -// This is testing the exact cases that are in the issue description. +// Issue #21633: reject duplicate loop labels and block labels in function bodies. #[allow(unused_labels)] fn foo() { @@ -24,6 +23,8 @@ fn foo() { 'lt: loop { break; } 'lt: while let Some(_) = None:: { break; } //~^ WARN label name `'lt` shadows a label name that is already in scope + 'bl: {} + 'bl: {} //~ WARN label name `'bl` shadows a label name that is already in scope } // Note however that it is okay for the same label to be reused in @@ -33,6 +34,8 @@ struct S; impl S { fn m1(&self) { 'okay: loop { break 'okay; } } fn m2(&self) { 'okay: loop { break 'okay; } } + fn m3(&self) { 'okay: { break 'okay; } } + fn m4(&self) { 'okay: { break 'okay; } } } @@ -40,5 +43,7 @@ pub fn main() { let s = S; s.m1(); s.m2(); + s.m3(); + s.m4(); foo(); } diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.stderr b/src/test/ui/loops/loops-reject-duplicate-labels.stderr index 5bdf64849f305..3bf3af763ecfc 100644 --- a/src/test/ui/loops/loops-reject-duplicate-labels.stderr +++ b/src/test/ui/loops/loops-reject-duplicate-labels.stderr @@ -1,5 +1,5 @@ warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:10:5 + --> $DIR/loops-reject-duplicate-labels.rs:9:5 | LL | 'fl: for _ in 0..10 { break; } | --- first declared here @@ -7,7 +7,7 @@ LL | 'fl: loop { break; } | ^^^ label `'fl` already in scope warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:13:5 + --> $DIR/loops-reject-duplicate-labels.rs:12:5 | LL | 'lf: loop { break; } | --- first declared here @@ -15,7 +15,7 @@ LL | 'lf: for _ in 0..10 { break; } | ^^^ label `'lf` already in scope warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:15:5 + --> $DIR/loops-reject-duplicate-labels.rs:14:5 | LL | 'wl: while 2 > 1 { break; } | --- first declared here @@ -23,7 +23,7 @@ LL | 'wl: loop { break; } | ^^^ label `'wl` already in scope warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:17:5 + --> $DIR/loops-reject-duplicate-labels.rs:16:5 | LL | 'lw: loop { break; } | --- first declared here @@ -31,7 +31,7 @@ LL | 'lw: while 2 > 1 { break; } | ^^^ label `'lw` already in scope warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:19:5 + --> $DIR/loops-reject-duplicate-labels.rs:18:5 | LL | 'fw: for _ in 0..10 { break; } | --- first declared here @@ -39,7 +39,7 @@ LL | 'fw: while 2 > 1 { break; } | ^^^ label `'fw` already in scope warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:21:5 + --> $DIR/loops-reject-duplicate-labels.rs:20:5 | LL | 'wf: while 2 > 1 { break; } | --- first declared here @@ -47,7 +47,7 @@ LL | 'wf: for _ in 0..10 { break; } | ^^^ label `'wf` already in scope warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:23:5 + --> $DIR/loops-reject-duplicate-labels.rs:22:5 | LL | 'tl: while let Some(_) = None:: { break; } | --- first declared here @@ -55,12 +55,20 @@ LL | 'tl: loop { break; } | ^^^ label `'tl` already in scope warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:25:5 + --> $DIR/loops-reject-duplicate-labels.rs:24:5 | LL | 'lt: loop { break; } | --- first declared here LL | 'lt: while let Some(_) = None:: { break; } | ^^^ label `'lt` already in scope -warning: 8 warnings emitted +warning: label name `'bl` shadows a label name that is already in scope + --> $DIR/loops-reject-duplicate-labels.rs:27:5 + | +LL | 'bl: {} + | --- first declared here +LL | 'bl: {} + | ^^^ label `'bl` already in scope + +warning: 9 warnings emitted diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs index 3212b78b08cd8..ce2d07eb06a4d 100644 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs +++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs @@ -1,10 +1,10 @@ // check-pass - +#![feature(label_break_value)] #![allow(dead_code, unused_variables)] -// Issue #21633: reject duplicate loop labels in function bodies. +// Issue #21633: reject duplicate loop labels and block labels in function bodies. // -// Test rejection of lifetimes in *expressions* that shadow loop labels. +// Test rejection of lifetimes in *expressions* that shadow labels. fn foo() { // Reusing lifetime `'a` in function item is okay. @@ -23,8 +23,13 @@ fn foo() { assert_eq!((*b)(&z), z); break 'a; } -} + 'b: { + let b = Box::new(|x: &()| ()) as Box Fn(&'b ())>; + //~^ WARN lifetime name `'b` shadows a label name that is already in scope + break 'b; + } +} pub fn main() { foo(); diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr index dcee1a8009053..9702b71600b5e 100644 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr +++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr @@ -6,5 +6,13 @@ LL | 'a: loop { LL | let b = Box::new(|x: &i8| *x) as Box Fn(&'a i8) -> i8>; | ^^ label `'a` already in scope -warning: 1 warning emitted +warning: lifetime name `'b` shadows a label name that is already in scope + --> $DIR/loops-reject-lifetime-shadowing-label.rs:28:55 + | +LL | 'b: { + | -- first declared here +LL | let b = Box::new(|x: &()| ()) as Box Fn(&'b ())>; + | ^^ label `'b` already in scope + +warning: 2 warnings emitted diff --git a/src/test/ui/macros/lint-trailing-macro-call.rs b/src/test/ui/macros/lint-trailing-macro-call.rs new file mode 100644 index 0000000000000..f8e847563915e --- /dev/null +++ b/src/test/ui/macros/lint-trailing-macro-call.rs @@ -0,0 +1,16 @@ +// check-pass +// +// Ensures that we properly lint +// a removed 'expression' resulting from a macro +// in trailing expression position + +macro_rules! expand_it { + () => { + #[cfg(FALSE)] 25; //~ WARN trailing semicolon in macro + //~| WARN this was previously + } +} + +fn main() { + expand_it!() +} diff --git a/src/test/ui/macros/lint-trailing-macro-call.stderr b/src/test/ui/macros/lint-trailing-macro-call.stderr new file mode 100644 index 0000000000000..a98a559c8afad --- /dev/null +++ b/src/test/ui/macros/lint-trailing-macro-call.stderr @@ -0,0 +1,18 @@ +warning: trailing semicolon in macro used in expression position + --> $DIR/lint-trailing-macro-call.rs:9:25 + | +LL | #[cfg(FALSE)] 25; + | ^ +... +LL | expand_it!() + | ------------ in this macro invocation + | + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default + = 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 #79813 + = note: macro invocations at the end of a block are treated as expressions + = note: to ignore the value produced by the macro, add a semicolon after the invocation of `expand_it` + = note: this warning originates in the macro `expand_it` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 1 warning emitted + diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr index b328fbe2cfb87..668405ed638c1 100644 --- a/src/test/ui/numeric/numeric-fields.stderr +++ b/src/test/ui/numeric/numeric-fields.stderr @@ -16,7 +16,10 @@ error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:7:17 | LL | S{0: a, 0x1: b, ..} => {} - | ^^^ struct `S` does not have this field + | ^^^ + | | + | struct `S` does not have this field + | help: `S` has a field named `1` error: aborting due to 2 previous errors diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs new file mode 100644 index 0000000000000..9611780ac079e --- /dev/null +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs @@ -0,0 +1,33 @@ +// build-fail + +// Test that the simd_shuffle intrinsic produces ok-ish error +// messages when misused. + +#![feature(repr_simd, platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct Simd([T; N]); + +extern "platform-intrinsic" { + fn simd_shuffle(a: T, b: T, i: I) -> U; +} + +fn main() { + const I: [u32; 2] = [0; 2]; + const I2: [f32; 2] = [0.; 2]; + let v = Simd::([0; 4]); + + unsafe { + let _: Simd = simd_shuffle(v, v, I); + + let _: Simd = simd_shuffle(v, v, I); + //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic + + let _: Simd = simd_shuffle(v, v, I); + //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic + + let _: Simd = simd_shuffle(v, v, I2); + //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic + } +} diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr new file mode 100644 index 0000000000000..9eeb000fd261f --- /dev/null +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr @@ -0,0 +1,21 @@ +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd` with length 4 + --> $DIR/simd-intrinsic-generic-shuffle.rs:24:31 + | +LL | let _: Simd = simd_shuffle(v, v, I); + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd`), found `Simd` with element type `f32` + --> $DIR/simd-intrinsic-generic-shuffle.rs:27:31 + | +LL | let _: Simd = simd_shuffle(v, v, I); + | ^^^^^^^^^^^^^^^^^^^^^ + +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]` + --> $DIR/simd-intrinsic-generic-shuffle.rs:30:31 + | +LL | let _: Simd = simd_shuffle(v, v, I2); + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0511`. diff --git a/src/test/ui/simd/monomorphize-shuffle-index.rs b/src/test/ui/simd/monomorphize-shuffle-index.rs new file mode 100644 index 0000000000000..2467baa08b0a7 --- /dev/null +++ b/src/test/ui/simd/monomorphize-shuffle-index.rs @@ -0,0 +1,40 @@ +//run-pass +#![feature(repr_simd, platform_intrinsics)] + +extern "platform-intrinsic" { + fn simd_shuffle(a: T, b: T, i: I) -> U; +} + +#[derive(Copy, Clone)] +#[repr(simd)] +struct Simd([T; N]); + +trait Shuffle { + const I: [u32; N]; + + unsafe fn shuffle(&self, a: Simd, b: Simd) -> Simd { + simd_shuffle(a, b, Self::I) + } +} + +fn main() { + struct I1; + impl Shuffle<4> for I1 { + const I: [u32; 4] = [0, 2, 4, 6]; + } + + struct I2; + impl Shuffle<2> for I2 { + const I: [u32; 2] = [1, 5]; + } + + let a = Simd::([0, 1, 2, 3]); + let b = Simd::([4, 5, 6, 7]); + unsafe { + let x: Simd = I1.shuffle(a, b); + assert_eq!(x.0, [0, 2, 4, 6]); + + let y: Simd = I2.shuffle(a, b); + assert_eq!(y.0, [1, 5]); + } +} diff --git a/src/test/ui/simd/shuffle-not-out-of-bounds.rs b/src/test/ui/simd/shuffle-not-out-of-bounds.rs index 8a533453e75fd..aae6ce4663fba 100644 --- a/src/test/ui/simd/shuffle-not-out-of-bounds.rs +++ b/src/test/ui/simd/shuffle-not-out-of-bounds.rs @@ -188,4 +188,14 @@ fn main() { 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)); + + extern "platform-intrinsic" { + fn simd_shuffle(a: T, b: T, i: I) -> U; + } + let v = u8x2(0, 0); + const I: [u32; 2] = [4, 4]; + unsafe { + let _: u8x2 = simd_shuffle(v, v, I); + //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic + } } diff --git a/src/test/ui/simd/shuffle-not-out-of-bounds.stderr b/src/test/ui/simd/shuffle-not-out-of-bounds.stderr index 07253a4ae46bc..737fb5e6e51e2 100644 --- a/src/test/ui/simd/shuffle-not-out-of-bounds.stderr +++ b/src/test/ui/simd/shuffle-not-out-of-bounds.stderr @@ -71,6 +71,12 @@ LL | | 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)); | = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 4) + --> $DIR/shuffle-not-out-of-bounds.rs:198:23 + | +LL | let _: u8x2 = simd_shuffle(v, v, I); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0511`. diff --git a/src/test/ui/simd/shuffle.rs b/src/test/ui/simd/shuffle.rs new file mode 100644 index 0000000000000..3592adfdc6ad1 --- /dev/null +++ b/src/test/ui/simd/shuffle.rs @@ -0,0 +1,24 @@ +//run-pass +#![feature(repr_simd, platform_intrinsics)] + +extern "platform-intrinsic" { + fn simd_shuffle(a: T, b: T, i: I) -> U; +} + +#[derive(Copy, Clone)] +#[repr(simd)] +struct Simd([T; N]); + +fn main() { + const I1: [u32; 4] = [0, 2, 4, 6]; + const I2: [u32; 2] = [1, 5]; + let a = Simd::([0, 1, 2, 3]); + let b = Simd::([4, 5, 6, 7]); + unsafe { + let x: Simd = simd_shuffle(a, b, I1); + assert_eq!(x.0, [0, 2, 4, 6]); + + let y: Simd = simd_shuffle(a, b, I2); + assert_eq!(y.0, [1, 5]); + } +} diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed new file mode 100644 index 0000000000000..0a3086a345dda --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + (a.unwrap()) //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs new file mode 100644 index 0000000000000..83617e035e9ef --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + (a.unwrap) //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr new file mode 100644 index 0000000000000..6fa0915dcaf9a --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr @@ -0,0 +1,14 @@ +error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>` + --> $DIR/issue-89044-wrapped-expr-method.rs:7:12 + | +LL | (a.unwrap) + | ^^^^^^ method, not a field + | +help: use parentheses to call the method + | +LL | (a.unwrap()) + | ++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0615`.