diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index fdb6ab8f59b95..64f52ea7ac196 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -144,6 +144,9 @@ infer_fps_items_are_distinct = fn items are distinct from fn pointers infer_fps_remove_ref = consider removing the reference infer_fps_use_ref = consider using a reference infer_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime + +infer_full_type_written = the full type name has been written to '{$path}' + infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement infer_label_bad = {$bad_kind -> diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 6192eaf3c3a43..4593108edac03 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -18,6 +18,8 @@ use crate::infer::error_reporting::{ ObligationCauseAsDiagArg, }; +use std::path::PathBuf; + pub mod note_and_explain; #[derive(Diagnostic)] @@ -47,6 +49,9 @@ pub struct AnnotationRequired<'a> { pub infer_subdiags: Vec>, #[subdiagnostic] pub multi_suggestions: Vec>, + #[note(infer_full_type_written)] + pub was_written: Option<()>, + pub path: PathBuf, } // Copy of `AnnotationRequired` for E0283 @@ -65,6 +70,9 @@ pub struct AmbiguousImpl<'a> { pub infer_subdiags: Vec>, #[subdiagnostic] pub multi_suggestions: Vec>, + #[note(infer_full_type_written)] + pub was_written: Option<()>, + pub path: PathBuf, } // Copy of `AnnotationRequired` for E0284 @@ -83,6 +91,9 @@ pub struct AmbiguousReturn<'a> { pub infer_subdiags: Vec>, #[subdiagnostic] pub multi_suggestions: Vec>, + #[note(infer_full_type_written)] + pub was_written: Option<()>, + pub path: PathBuf, } // Used when a better one isn't available diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index f89ed256a08c2..3b5658ed0ee64 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -18,13 +18,15 @@ use rustc_middle::infer::unify_key::{ }; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; -use rustc_middle::ty::{self, InferConst}; -use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef}; -use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; +use rustc_middle::ty::{ + self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt, + TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults, +}; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, Span, DUMMY_SP}; use std::borrow::Cow; use std::iter; +use std::path::PathBuf; pub enum TypeAnnotationNeeded { /// ```compile_fail,E0282 @@ -153,6 +155,29 @@ impl UnderspecifiedArgKind { } } +struct ClosureEraser<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> TypeFolder> for ClosureEraser<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.kind() { + ty::Closure(_, args) => { + let closure_sig = args.as_closure().sig(); + Ty::new_fn_ptr( + self.tcx, + self.tcx.signature_unclosure(closure_sig, hir::Unsafety::Normal), + ) + } + _ => ty.super_fold_with(self), + } + } +} + fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> { let mut printer = FmtPrinter::new(infcx.tcx, ns); let ty_getter = move |ty_vid| { @@ -209,6 +234,10 @@ fn ty_to_string<'tcx>( ) -> String { let mut printer = fmt_printer(infcx, Namespace::TypeNS); let ty = infcx.resolve_vars_if_possible(ty); + // We use `fn` ptr syntax for closures, but this only works when the closure + // does not capture anything. + let ty = ty.fold_with(&mut ClosureEraser { tcx: infcx.tcx }); + match (ty.kind(), called_method_def_id) { // We don't want the regular output for `fn`s because it includes its path in // invalid pseudo-syntax, we want the `fn`-pointer output instead. @@ -223,11 +252,6 @@ fn ty_to_string<'tcx>( "Vec<_>".to_string() } _ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(), - // FIXME: The same thing for closures, but this only works when the closure - // does not capture anything. - // - // We do have to hide the `extern "rust-call"` ABI in that case though, - // which is too much of a bother for now. _ => { ty.print(&mut printer).unwrap(); printer.into_buffer() @@ -387,6 +411,8 @@ impl<'tcx> InferCtxt<'tcx> { infer_subdiags, multi_suggestions, bad_label, + was_written: None, + path: Default::default(), }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -396,6 +422,8 @@ impl<'tcx> InferCtxt<'tcx> { infer_subdiags, multi_suggestions, bad_label, + was_written: None, + path: Default::default(), }), TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn { span, @@ -405,6 +433,8 @@ impl<'tcx> InferCtxt<'tcx> { infer_subdiags, multi_suggestions, bad_label, + was_written: None, + path: Default::default(), }), } } @@ -442,7 +472,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return self.bad_inference_failure_err(failure_span, arg_data, error_code); }; - let (source_kind, name) = kind.ty_localized_msg(self); + let (source_kind, name, path) = kind.ty_localized_msg(self); let failure_span = if should_label_span && !failure_span.overlaps(span) { Some(failure_span) } else { @@ -518,7 +548,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"), GenericArgKind::Type(_) => self .next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, }) .into(), @@ -526,7 +556,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .next_const_var( arg.ty(), ConstVariableOrigin { - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, kind: ConstVariableOriginKind::MiscVariable, }, ) @@ -547,7 +577,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => { let placeholder = Some(self.next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, })); if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) { @@ -584,7 +614,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { let placeholder = Some(self.next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, })); if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) { @@ -606,6 +636,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer_subdiags, multi_suggestions, bad_label: None, + was_written: path.as_ref().map(|_| ()), + path: path.unwrap_or_default(), }), TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl { span, @@ -615,6 +647,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer_subdiags, multi_suggestions, bad_label: None, + was_written: path.as_ref().map(|_| ()), + path: path.unwrap_or_default(), }), TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn { span, @@ -624,6 +658,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer_subdiags, multi_suggestions, bad_label: None, + was_written: path.as_ref().map(|_| ()), + path: path.unwrap_or_default(), }), } } @@ -688,22 +724,23 @@ impl<'tcx> InferSource<'tcx> { } impl<'tcx> InferSourceKind<'tcx> { - fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String) { + fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option) { + let mut path = None; match *self { InferSourceKind::LetBinding { ty, .. } | InferSourceKind::ClosureArg { ty, .. } | InferSourceKind::ClosureReturn { ty, .. } => { if ty.is_closure() { - ("closure", closure_as_fn_str(infcx, ty)) + ("closure", closure_as_fn_str(infcx, ty), path) } else if !ty.is_ty_or_numeric_infer() { - ("normal", ty_to_string(infcx, ty, None)) + ("normal", infcx.tcx.short_ty_string(ty, &mut path), path) } else { - ("other", String::new()) + ("other", String::new(), path) } } // FIXME: We should be able to add some additional info here. InferSourceKind::GenericArg { .. } - | InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()), + | InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new(), path), } } } diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 16e3b8c11c133..b2403836397a1 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -105,7 +105,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di BuiltinLintDiag::RedundantImport(spans, ident) => { for (span, is_imported) in spans { let introduced = if is_imported { "imported" } else { "defined" }; - let span_msg = if span.is_dummy() { "by prelude" } else { "here" }; + let span_msg = if span.is_dummy() { "by the extern prelude" } else { "here" }; diag.span_label( span, format!("the item `{ident}` is already {introduced} {span_msg}"), diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 111a4fdcea174..503caa35358ab 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1074,10 +1074,14 @@ impl UnusedParens { // Otherwise proceed with linting. _ => {} } - let spans = inner - .span - .find_ancestor_inside(value.span) - .map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi()))); + let spans = if !value.span.from_expansion() { + inner + .span + .find_ancestor_inside(value.span) + .map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi()))) + } else { + None + }; self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space, false); } } @@ -1233,11 +1237,13 @@ impl EarlyLintPass for UnusedParens { if self.with_self_ty_parens && b.generic_params.len() > 0 => {} ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {} _ => { - let spans = r - .span - .find_ancestor_inside(ty.span) - .map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi()))); - + let spans = if !ty.span.from_expansion() { + r.span + .find_ancestor_inside(ty.span) + .map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi()))) + } else { + None + }; self.emit_unused_delims(cx, ty.span, spans, "type", (false, false), false); } } diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 44ae72bcd26bf..d448c5338fc46 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -227,13 +227,10 @@ mod impls { impl_clone! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 - f32 f64 + f16 f32 f64 f128 bool char } - #[cfg(not(bootstrap))] - impl_clone! { f16 f128 } - #[unstable(feature = "never_type", issue = "35121")] impl Clone for ! { #[inline] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 81bba927554a4..fa218600ed925 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1497,12 +1497,9 @@ mod impls { } partial_eq_impl! { - bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 + bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } - #[cfg(not(bootstrap))] - partial_eq_impl! { f16 f128 } - macro_rules! eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] @@ -1553,10 +1550,7 @@ mod impls { } } - partial_ord_impl! { f32 f64 } - - #[cfg(not(bootstrap))] - partial_ord_impl! { f16 f128 } + partial_ord_impl! { f16 f32 f64 f128 } macro_rules! ord_impl { ($($t:ty)*) => ($( diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 0167d04c413fe..1737c631f0bd0 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -34,8 +34,10 @@ macro_rules! impl_float_to_int { } } +impl_float_to_int!(f16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); +impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize); // Conversion traits for primitive integer and float types // Conversions T -> T are covered by a blanket impl and therefore excluded @@ -163,7 +165,12 @@ impl_from!(u16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0" impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); // float -> float +impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); +impl_from!(f64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); macro_rules! impl_float_from_bool { ($float:ty) => { diff --git a/library/core/src/fmt/nofloat.rs b/library/core/src/fmt/nofloat.rs index cfb94cd9de530..a36e7efcd95c7 100644 --- a/library/core/src/fmt/nofloat.rs +++ b/library/core/src/fmt/nofloat.rs @@ -11,5 +11,7 @@ macro_rules! floating { }; } +floating! { f16 } floating! { f32 } floating! { f64 } +floating! { f128 } diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 0ba3a557a035a..10d2698c5dd1b 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -200,8 +200,6 @@ // // Language features: // tidy-alphabetical-start -#![cfg_attr(not(bootstrap), feature(f128))] -#![cfg_attr(not(bootstrap), feature(f16))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] @@ -226,6 +224,8 @@ #![feature(doc_notable_trait)] #![feature(effects)] #![feature(extern_types)] +#![feature(f128)] +#![feature(f16)] #![feature(freeze_impls)] #![feature(fundamental)] #![feature(generic_arg_infer)] @@ -347,6 +347,10 @@ pub mod u8; #[path = "num/shells/usize.rs"] pub mod usize; +#[path = "num/f128.rs"] +pub mod f128; +#[path = "num/f16.rs"] +pub mod f16; #[path = "num/f32.rs"] pub mod f32; #[path = "num/f64.rs"] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index fb97b3bfa0926..1d073a6d649b8 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -422,17 +422,11 @@ marker_impls! { Copy for usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, - f32, f64, + f16, f32, f64, f128, bool, char, {T: ?Sized} *const T, {T: ?Sized} *mut T, -} -#[cfg(not(bootstrap))] -marker_impls! { - #[stable(feature = "rust1", since = "1.0.0")] - Copy for - f16, f128, } #[unstable(feature = "never_type", issue = "35121")] diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs new file mode 100644 index 0000000000000..3bc3e2dbf1242 --- /dev/null +++ b/library/core/src/num/f128.rs @@ -0,0 +1,16 @@ +//! Constants for the `f128` quadruple-precision floating point type. +//! +//! *[See also the `f128` primitive type][f128].* +//! +//! Mathematically significant numbers are provided in the `consts` sub-module. +//! +//! For the constants defined directly in this module +//! (as distinct from those defined in the `consts` sub-module), +//! new code should instead use the associated constants +//! defined directly on the `f128` type. + +#![unstable(feature = "f128", issue = "116909")] + +/// Basic mathematical constants. +#[unstable(feature = "f128", issue = "116909")] +pub mod consts {} diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs new file mode 100644 index 0000000000000..969ebdc5690c1 --- /dev/null +++ b/library/core/src/num/f16.rs @@ -0,0 +1,16 @@ +//! Constants for the `f16` half-precision floating point type. +//! +//! *[See also the `f16` primitive type][f16].* +//! +//! Mathematically significant numbers are provided in the `consts` sub-module. +//! +//! For the constants defined directly in this module +//! (as distinct from those defined in the `consts` sub-module), +//! new code should instead use the associated constants +//! defined directly on the `f16` type. + +#![unstable(feature = "f16", issue = "116909")] + +/// Basic mathematical constants. +#[unstable(feature = "f16", issue = "116909")] +pub mod consts {} diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index fd50f80474833..5e77788d8ea36 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -109,7 +109,7 @@ macro_rules! add_impl { )*) } -add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The subtraction operator `-`. /// @@ -218,7 +218,7 @@ macro_rules! sub_impl { )*) } -sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The multiplication operator `*`. /// @@ -348,7 +348,7 @@ macro_rules! mul_impl { )*) } -mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The division operator `/`. /// @@ -506,7 +506,7 @@ macro_rules! div_impl_float { )*) } -div_impl_float! { f32 f64 } +div_impl_float! { f16 f32 f64 f128 } /// The remainder operator `%`. /// @@ -623,7 +623,7 @@ macro_rules! rem_impl_float { )*) } -rem_impl_float! { f32 f64 } +rem_impl_float! { f16 f32 f64 f128 } /// The unary negation operator `-`. /// @@ -698,7 +698,7 @@ macro_rules! neg_impl { )*) } -neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 } +neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The addition assignment operator `+=`. /// @@ -765,7 +765,7 @@ macro_rules! add_assign_impl { )+) } -add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The subtraction assignment operator `-=`. /// @@ -832,7 +832,7 @@ macro_rules! sub_assign_impl { )+) } -sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The multiplication assignment operator `*=`. /// @@ -890,7 +890,7 @@ macro_rules! mul_assign_impl { )+) } -mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The division assignment operator `/=`. /// @@ -947,7 +947,7 @@ macro_rules! div_assign_impl { )+) } -div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } /// The remainder assignment operator `%=`. /// @@ -1008,4 +1008,4 @@ macro_rules! rem_assign_impl { )+) } -rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } +rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 } diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 15da4171bda21..e8e23f2a7ecc5 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1074,7 +1074,22 @@ mod prim_tuple {} #[doc(hidden)] impl (T,) {} +#[rustc_doc_primitive = "f16"] +#[doc(alias = "half")] +/// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008). +/// +/// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many +/// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on +/// half-precision values][wikipedia] for more information. +/// +/// *[See also the `std::f16::consts` module](crate::f16::consts).* +/// +/// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format +#[unstable(feature = "f16", issue = "116909")] +mod prim_f16 {} + #[rustc_doc_primitive = "f32"] +#[doc(alias = "single")] /// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008). /// /// This type can represent a wide range of decimal numbers, like `3.5`, `27`, @@ -1143,6 +1158,7 @@ impl (T,) {} mod prim_f32 {} #[rustc_doc_primitive = "f64"] +#[doc(alias = "double")] /// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008). /// /// This type is very similar to [`f32`], but has increased @@ -1157,6 +1173,20 @@ mod prim_f32 {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_f64 {} +#[rustc_doc_primitive = "f128"] +#[doc(alias = "quad")] +/// A 128-bit floating point type (specifically, the "binary128" type defined in IEEE 754-2008). +/// +/// This type is very similar to [`prim@f32`] and [`prim@f64`], but has increased precision by using twice +/// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on +/// quad-precision values][wikipedia] for more information. +/// +/// *[See also the `std::f128::consts` module](crate::f128::consts).* +/// +/// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format +#[unstable(feature = "f128", issue = "116909")] +mod prim_f128 {} + #[rustc_doc_primitive = "i8"] // /// The 8-bit signed integer type. diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs new file mode 100644 index 0000000000000..4710d7c50b444 --- /dev/null +++ b/library/std/src/f128.rs @@ -0,0 +1,11 @@ +//! Constants for the `f128` double-precision floating point type. +//! +//! *[See also the `f128` primitive type](primitive@f128).* +//! +//! Mathematically significant numbers are provided in the `consts` sub-module. + +#[cfg(test)] +mod tests; + +#[unstable(feature = "f128", issue = "116909")] +pub use core::f128::consts; diff --git a/library/std/src/f128/tests.rs b/library/std/src/f128/tests.rs new file mode 100644 index 0000000000000..b64c7f856a15f --- /dev/null +++ b/library/std/src/f128/tests.rs @@ -0,0 +1,40 @@ +#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used + +/// Smallest number +const TINY_BITS: u128 = 0x1; +/// Next smallest number +const TINY_UP_BITS: u128 = 0x2; +/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0 +const MAX_DOWN_BITS: u128 = 0x7ffeffffffffffffffffffffffffffff; +/// Zeroed exponent, full significant +const LARGEST_SUBNORMAL_BITS: u128 = 0x0000ffffffffffffffffffffffffffff; +/// Exponent = 0b1, zeroed significand +const SMALLEST_NORMAL_BITS: u128 = 0x00010000000000000000000000000000; +/// First pattern over the mantissa +const NAN_MASK1: u128 = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa; +/// Second pattern over the mantissa +const NAN_MASK2: u128 = 0x00005555555555555555555555555555; + +/// Compare by value +#[allow(unused_macros)] +macro_rules! assert_f128_eq { + ($a:expr, $b:expr) => { + let (l, r): (&f128, &f128) = (&$a, &$b); + assert_eq!(*l, *r, "\na: {:#0130x}\nb: {:#0130x}", l.to_bits(), r.to_bits()) + }; +} + +/// Compare by representation +#[allow(unused_macros)] +macro_rules! assert_f128_biteq { + ($a:expr, $b:expr) => { + let (l, r): (&f128, &f128) = (&$a, &$b); + let lb = l.to_bits(); + let rb = r.to_bits(); + assert_eq!( + lb, rb, + "float {:?} is not bitequal to {:?}.\na: {:#0130x}\nb: {:#0130x}", + *l, *r, lb, rb + ); + }; +} diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs new file mode 100644 index 0000000000000..c36f9f5d4c6a8 --- /dev/null +++ b/library/std/src/f16.rs @@ -0,0 +1,11 @@ +//! Constants for the `f16` double-precision floating point type. +//! +//! *[See also the `f16` primitive type](primitive@f16).* +//! +//! Mathematically significant numbers are provided in the `consts` sub-module. + +#[cfg(test)] +mod tests; + +#[unstable(feature = "f16", issue = "116909")] +pub use core::f16::consts; diff --git a/library/std/src/f16/tests.rs b/library/std/src/f16/tests.rs new file mode 100644 index 0000000000000..d65c43eca4bb8 --- /dev/null +++ b/library/std/src/f16/tests.rs @@ -0,0 +1,46 @@ +#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used + +// We run out of precision pretty quickly with f16 +const F16_APPROX_L1: f16 = 0.001; +const F16_APPROX_L2: f16 = 0.01; +const F16_APPROX_L3: f16 = 0.1; +const F16_APPROX_L4: f16 = 0.5; + +/// Smallest number +const TINY_BITS: u16 = 0x1; +/// Next smallest number +const TINY_UP_BITS: u16 = 0x2; +/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0 +const MAX_DOWN_BITS: u16 = 0x7bfe; +/// Zeroed exponent, full significant +const LARGEST_SUBNORMAL_BITS: u16 = 0x03ff; +/// Exponent = 0b1, zeroed significand +const SMALLEST_NORMAL_BITS: u16 = 0x0400; +/// First pattern over the mantissa +const NAN_MASK1: u16 = 0x02aa; +/// Second pattern over the mantissa +const NAN_MASK2: u16 = 0x0155; + +/// Compare by value +#[allow(unused_macros)] +macro_rules! assert_f16_eq { + ($a:expr, $b:expr) => { + let (l, r): (&f16, &f16) = (&$a, &$b); + assert_eq!(*l, *r, "\na: {:#018x}\nb: {:#018x}", l.to_bits(), r.to_bits()) + }; +} + +/// Compare by representation +#[allow(unused_macros)] +macro_rules! assert_f16_biteq { + ($a:expr, $b:expr) => { + let (l, r): (&f16, &f16) = (&$a, &$b); + let lb = l.to_bits(); + let rb = r.to_bits(); + assert_eq!( + lb, rb, + "float {:?} is not bitequal to {:?}.\na: {:#018x}\nb: {:#018x}", + *l, *r, lb, rb + ); + }; +} diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index 250cd58369614..0cdc49c87d8fc 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -383,12 +383,7 @@ impl Read for BufReader { // buffer. let mut bytes = Vec::new(); self.read_to_end(&mut bytes)?; - let string = crate::str::from_utf8(&bytes).map_err(|_| { - io::const_io_error!( - io::ErrorKind::InvalidData, - "stream did not contain valid UTF-8", - ) - })?; + let string = crate::str::from_utf8(&bytes).map_err(|_| io::Error::INVALID_UTF8)?; *buf += string; Ok(string.len()) } diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 85625116d025a..19f57bff3e31d 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -75,6 +75,25 @@ impl fmt::Debug for Error { } } +/// Common errors constants for use in std +impl Error { + pub(crate) const INVALID_UTF8: Self = + const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8"); + + pub(crate) const READ_EXACT_EOF: Self = + const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer"); + + #[allow(dead_code)] + pub(crate) const UNSUPPORTED_PLATFORM: Self = + const_io_error!(ErrorKind::Unsupported, "operation not supported on this platform"); + + pub(crate) const WRITE_ALL_EOF: Self = + const_io_error!(ErrorKind::WriteZero, "failed to write whole buffer"); + + pub(crate) const ZERO_TIMEOUT: Self = + const_io_error!(ErrorKind::InvalidInput, "cannot set a 0 duration timeout"); +} + #[stable(feature = "rust1", since = "1.0.0")] impl From for Error { /// Converts a [`alloc::ffi::NulError`] into a [`Error`]. diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index ee7ed4bcc9ab5..dd7e0725176e8 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -5,9 +5,7 @@ use crate::alloc::Allocator; use crate::cmp; use crate::collections::VecDeque; use crate::fmt; -use crate::io::{ - self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write, -}; +use crate::io::{self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write}; use crate::mem; use crate::str; @@ -289,10 +287,7 @@ impl Read for &[u8] { #[inline] fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { if buf.len() > self.len() { - return Err(io::const_io_error!( - ErrorKind::UnexpectedEof, - "failed to fill whole buffer" - )); + return Err(io::Error::READ_EXACT_EOF); } let (a, b) = self.split_at(buf.len()); @@ -312,10 +307,7 @@ impl Read for &[u8] { #[inline] fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { if cursor.capacity() > self.len() { - return Err(io::const_io_error!( - ErrorKind::UnexpectedEof, - "failed to fill whole buffer" - )); + return Err(io::Error::READ_EXACT_EOF); } let (a, b) = self.split_at(cursor.capacity()); @@ -336,9 +328,7 @@ impl Read for &[u8] { #[inline] fn read_to_string(&mut self, buf: &mut String) -> io::Result { - let content = str::from_utf8(self).map_err(|_| { - io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8") - })?; + let content = str::from_utf8(self).map_err(|_| io::Error::INVALID_UTF8)?; buf.push_str(content); let len = self.len(); *self = &self[len..]; @@ -399,11 +389,7 @@ impl Write for &mut [u8] { #[inline] fn write_all(&mut self, data: &[u8]) -> io::Result<()> { - if self.write(data)? == data.len() { - Ok(()) - } else { - Err(io::const_io_error!(ErrorKind::WriteZero, "failed to write whole buffer")) - } + if self.write(data)? == data.len() { Ok(()) } else { Err(io::Error::WRITE_ALL_EOF) } } #[inline] @@ -491,9 +477,7 @@ impl Read for VecDeque { // middle of an UTF-8 character. let len = self.len(); let content = self.make_contiguous(); - let string = str::from_utf8(content).map_err(|_| { - io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8") - })?; + let string = str::from_utf8(content).map_err(|_| io::Error::INVALID_UTF8)?; buf.push_str(string); self.clear(); Ok(len) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 980b3e7aa48d0..fb1bf53ddc782 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -385,12 +385,7 @@ where let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() }; let ret = f(g.buf); if str::from_utf8(&g.buf[g.len..]).is_err() { - ret.and_then(|_| { - Err(error::const_io_error!( - ErrorKind::InvalidData, - "stream did not contain valid UTF-8" - )) - }) + ret.and_then(|_| Err(Error::INVALID_UTF8)) } else { g.len = g.buf.len(); ret @@ -566,11 +561,7 @@ pub(crate) fn default_read_exact(this: &mut R, mut buf: &mut [ Err(e) => return Err(e), } } - if !buf.is_empty() { - Err(error::const_io_error!(ErrorKind::UnexpectedEof, "failed to fill whole buffer")) - } else { - Ok(()) - } + if !buf.is_empty() { Err(Error::READ_EXACT_EOF) } else { Ok(()) } } pub(crate) fn default_read_buf(read: F, mut cursor: BorrowedCursor<'_>) -> Result<()> @@ -595,10 +586,7 @@ pub(crate) fn default_read_buf_exact( } if cursor.written() == prev_written { - return Err(error::const_io_error!( - ErrorKind::UnexpectedEof, - "failed to fill whole buffer" - )); + return Err(Error::READ_EXACT_EOF); } } @@ -1709,10 +1697,7 @@ pub trait Write { while !buf.is_empty() { match self.write(buf) { Ok(0) => { - return Err(error::const_io_error!( - ErrorKind::WriteZero, - "failed to write whole buffer", - )); + return Err(Error::WRITE_ALL_EOF); } Ok(n) => buf = &buf[n..], Err(ref e) if e.is_interrupted() => {} @@ -1777,10 +1762,7 @@ pub trait Write { while !bufs.is_empty() { match self.write_vectored(bufs) { Ok(0) => { - return Err(error::const_io_error!( - ErrorKind::WriteZero, - "failed to write whole buffer", - )); + return Err(Error::WRITE_ALL_EOF); } Ok(n) => IoSlice::advance_slices(&mut bufs, n), Err(ref e) if e.is_interrupted() => {} diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c713eefc72c93..ac475b5530a78 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -214,7 +214,16 @@ //! [slice]: prim@slice #![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))] -#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))] +#![cfg_attr( + feature = "restricted-std", + unstable( + feature = "restricted_std", + issue = "none", + reason = "You have attempted to use a standard library built for a platform that it doesn't \ + know how to support. Consider building it for a known environment, disabling it with \ + `#![no_std]` or overriding this warning by enabling this feature". + ) +)] #![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)] #![doc( html_playground_url = "https://play.rust-lang.org/", @@ -283,6 +292,8 @@ #![feature(doc_masked)] #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] +#![feature(f128)] +#![feature(f16)] #![feature(if_let_guard)] #![feature(intra_doc_pointers)] #![feature(lang_items)] @@ -558,6 +569,10 @@ pub use core::u8; #[allow(deprecated, deprecated_in_future)] pub use core::usize; +#[unstable(feature = "f128", issue = "116909")] +pub mod f128; +#[unstable(feature = "f16", issue = "116909")] +pub mod f16; pub mod f32; pub mod f64; diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 0b3c51538718d..010ce4e5076ba 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -117,10 +117,7 @@ impl BorrowedFd<'_> { #[cfg(any(target_arch = "wasm32", target_os = "hermit"))] #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> crate::io::Result { - Err(crate::io::const_io_error!( - crate::io::ErrorKind::Unsupported, - "operation not supported on this platform", - )) + Err(crate::io::Error::UNSUPPORTED_PLATFORM) } } diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs index 058e9b90cc7a1..970023d8cf19e 100644 --- a/library/std/src/os/unix/fs.rs +++ b/library/std/src/os/unix/fs.rs @@ -127,11 +127,7 @@ pub trait FileExt { Err(e) => return Err(e), } } - if !buf.is_empty() { - Err(io::const_io_error!(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer",)) - } else { - Ok(()) - } + if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } } /// Writes a number of bytes starting from a given offset. @@ -249,10 +245,7 @@ pub trait FileExt { while !buf.is_empty() { match self.write_at(buf, offset) { Ok(0) => { - return Err(io::const_io_error!( - io::ErrorKind::WriteZero, - "failed to write whole buffer", - )); + return Err(io::Error::WRITE_ALL_EOF); } Ok(n) => { buf = &buf[n..]; diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index 4525c3aa91477..46fc2a50de911 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -86,11 +86,7 @@ pub trait FileExt { Err(e) => return Err(e), } } - if !buf.is_empty() { - Err(io::const_io_error!(io::ErrorKind::UnexpectedEof, "failed to fill whole buffer")) - } else { - Ok(()) - } + if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } } /// Writes a number of bytes starting from a given offset. @@ -153,10 +149,7 @@ pub trait FileExt { while !buf.is_empty() { match self.write_at(buf, offset) { Ok(0) => { - return Err(io::const_io_error!( - io::ErrorKind::WriteZero, - "failed to write whole buffer", - )); + return Err(io::Error::WRITE_ALL_EOF); } Ok(n) => { buf = &buf[n..]; diff --git a/library/std/src/sys/pal/hermit/net.rs b/library/std/src/sys/pal/hermit/net.rs index 1c53796f5d49c..23ac71cb9f29e 100644 --- a/library/std/src/sys/pal/hermit/net.rs +++ b/library/std/src/sys/pal/hermit/net.rs @@ -80,10 +80,7 @@ impl Socket { let mut pollfd = netc::pollfd { fd: self.as_raw_fd(), events: netc::POLLOUT, revents: 0 }; if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } let start = Instant::now(); @@ -245,10 +242,7 @@ impl Socket { let timeout = match dur { Some(dur) => { if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } let secs = if dur.as_secs() > netc::time_t::MAX as u64 { diff --git a/library/std/src/sys/pal/sgx/net.rs b/library/std/src/sys/pal/sgx/net.rs index edb28e2300f47..68a2d5eded2da 100644 --- a/library/std/src/sys/pal/sgx/net.rs +++ b/library/std/src/sys/pal/sgx/net.rs @@ -97,10 +97,7 @@ impl TcpStream { pub fn connect_timeout(addr: &SocketAddr, dur: Duration) -> io::Result { if dur == Duration::default() { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } Self::connect(Ok(addr)) // FIXME: ignoring timeout } @@ -108,10 +105,7 @@ impl TcpStream { pub fn set_read_timeout(&self, dur: Option) -> io::Result<()> { match dur { Some(dur) if dur == Duration::default() => { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } _ => sgx_ineffective(()), } @@ -120,10 +114,7 @@ impl TcpStream { pub fn set_write_timeout(&self, dur: Option) -> io::Result<()> { match dur { Some(dur) if dur == Duration::default() => { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } _ => sgx_ineffective(()), } diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index 109ee1a0ab666..3f6ff37903ac6 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -50,10 +50,7 @@ pub fn unsupported() -> crate::io::Result { } pub fn unsupported_err() -> crate::io::Error { - crate::io::const_io_error!( - crate::io::ErrorKind::Unsupported, - "operation not supported on this platform", - ) + crate::io::Error::UNSUPPORTED_PLATFORM } #[inline] diff --git a/library/std/src/sys/pal/solid/net.rs b/library/std/src/sys/pal/solid/net.rs index 6ea874e509e20..5bd339849e9dc 100644 --- a/library/std/src/sys/pal/solid/net.rs +++ b/library/std/src/sys/pal/solid/net.rs @@ -154,10 +154,7 @@ impl Socket { } if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } let mut timeout = @@ -306,10 +303,7 @@ impl Socket { let timeout = match dur { Some(dur) => { if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } let secs = if dur.as_secs() > netc::c_long::MAX as u64 { diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 4ae76518c4f62..3ef43a923a377 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -433,6 +433,6 @@ mod unsupported { } pub fn unsupported_err() -> io::Error { - io::const_io_error!(io::ErrorKind::Unsupported, "operation not supported on this platform",) + io::Error::UNSUPPORTED_PLATFORM } } diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs index 9a0a1b18aee0d..7237989c9059b 100644 --- a/library/std/src/sys/pal/unix/net.rs +++ b/library/std/src/sys/pal/unix/net.rs @@ -175,10 +175,7 @@ impl Socket { let mut pollfd = libc::pollfd { fd: self.as_raw_fd(), events: libc::POLLOUT, revents: 0 }; if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } let start = Instant::now(); @@ -360,10 +357,7 @@ impl Socket { let timeout = match dur { Some(dur) => { if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } let secs = if dur.as_secs() > libc::time_t::MAX as u64 { diff --git a/library/std/src/sys/pal/unsupported/common.rs b/library/std/src/sys/pal/unsupported/common.rs index 4f44db610af15..76f80291f0ea8 100644 --- a/library/std/src/sys/pal/unsupported/common.rs +++ b/library/std/src/sys/pal/unsupported/common.rs @@ -13,10 +13,7 @@ pub fn unsupported() -> std_io::Result { } pub fn unsupported_err() -> std_io::Error { - std_io::const_io_error!( - std_io::ErrorKind::Unsupported, - "operation not supported on this platform", - ) + std_io::Error::UNSUPPORTED_PLATFORM } pub fn is_interrupted(_code: i32) -> bool { diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs index 1e6169ea8ece0..9e15b15a3513a 100644 --- a/library/std/src/sys/pal/windows/net.rs +++ b/library/std/src/sys/pal/windows/net.rs @@ -154,10 +154,7 @@ impl Socket { match result { Err(ref error) if error.kind() == io::ErrorKind::WouldBlock => { if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } let mut timeout = c::timeval { @@ -364,10 +361,7 @@ impl Socket { Some(dur) => { let timeout = sys::dur2timeout(dur); if timeout == 0 { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - "cannot set a 0 duration timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } timeout } diff --git a/library/std/src/sys/pal/xous/net/tcpstream.rs b/library/std/src/sys/pal/xous/net/tcpstream.rs index aebef02acdad5..0ad8811071111 100644 --- a/library/std/src/sys/pal/xous/net/tcpstream.rs +++ b/library/std/src/sys/pal/xous/net/tcpstream.rs @@ -140,10 +140,7 @@ impl TcpStream { pub fn set_read_timeout(&self, timeout: Option) -> io::Result<()> { if let Some(to) = timeout { if to.is_zero() { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - &"Zero is an invalid timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } } self.read_timeout.store( @@ -156,10 +153,7 @@ impl TcpStream { pub fn set_write_timeout(&self, timeout: Option) -> io::Result<()> { if let Some(to) = timeout { if to.is_zero() { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - &"Zero is an invalid timeout", - )); + return Err(io::Error::ZERO_TIMEOUT); } } self.write_timeout.store( diff --git a/library/std/src/sys/pal/xous/net/udp.rs b/library/std/src/sys/pal/xous/net/udp.rs index cafa5b3bde829..3d0522b25f3fb 100644 --- a/library/std/src/sys/pal/xous/net/udp.rs +++ b/library/std/src/sys/pal/xous/net/udp.rs @@ -331,10 +331,7 @@ impl UdpSocket { pub fn set_read_timeout(&self, timeout: Option) -> io::Result<()> { if let Some(d) = timeout { if d.is_zero() { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - &"Zero duration is invalid" - )); + return Err(io::Error::ZERO_TIMEOUT); } } self.read_timeout @@ -345,10 +342,7 @@ impl UdpSocket { pub fn set_write_timeout(&self, timeout: Option) -> io::Result<()> { if let Some(d) = timeout { if d.is_zero() { - return Err(io::const_io_error!( - io::ErrorKind::InvalidInput, - &"Zero duration is invalid" - )); + return Err(io::Error::ZERO_TIMEOUT); } } self.write_timeout diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 228a976dbabc3..62f0a2c7b1c18 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -54,10 +54,7 @@ pub fn unsupported() -> std_io::Result { } pub fn unsupported_err() -> std_io::Error { - std_io::const_io_error!( - std_io::ErrorKind::Unsupported, - "operation not supported on this platform", - ) + std_io::Error::UNSUPPORTED_PLATFORM } pub fn is_interrupted(_code: i32) -> bool { diff --git a/tests/codegen/float/f128.rs b/tests/codegen/float/f128.rs new file mode 100644 index 0000000000000..97d545e028307 --- /dev/null +++ b/tests/codegen/float/f128.rs @@ -0,0 +1,129 @@ +// Verify that our intrinsics generate the correct LLVM calls for f128 + +#![crate_type = "lib"] +#![feature(f128)] +#![feature(core_intrinsics)] + +// CHECK-LABEL: i1 @f128_eq( +#[no_mangle] +pub fn f128_eq(a: f128, b: f128) -> bool { + // CHECK: fcmp oeq fp128 %{{.+}}, %{{.+}} + a == b +} + +// CHECK-LABEL: i1 @f128_ne( +#[no_mangle] +pub fn f128_ne(a: f128, b: f128) -> bool { + // CHECK: fcmp une fp128 %{{.+}}, %{{.+}} + a != b +} + +// CHECK-LABEL: i1 @f128_gt( +#[no_mangle] +pub fn f128_gt(a: f128, b: f128) -> bool { + // CHECK: fcmp ogt fp128 %{{.+}}, %{{.+}} + a > b +} + +// CHECK-LABEL: i1 @f128_ge( +#[no_mangle] +pub fn f128_ge(a: f128, b: f128) -> bool { + // CHECK: fcmp oge fp128 %{{.+}}, %{{.+}} + a >= b +} + +// CHECK-LABEL: i1 @f128_lt( +#[no_mangle] +pub fn f128_lt(a: f128, b: f128) -> bool { + // CHECK: fcmp olt fp128 %{{.+}}, %{{.+}} + a < b +} + +// CHECK-LABEL: i1 @f128_le( +#[no_mangle] +pub fn f128_le(a: f128, b: f128) -> bool { + // CHECK: fcmp ole fp128 %{{.+}}, %{{.+}} + a <= b +} + +// CHECK-LABEL: fp128 @f128_neg( +#[no_mangle] +pub fn f128_neg(a: f128) -> f128 { + // CHECK: fneg fp128 + -a +} + +// CHECK-LABEL: fp128 @f128_add( +#[no_mangle] +pub fn f128_add(a: f128, b: f128) -> f128 { + // CHECK: fadd fp128 %{{.+}}, %{{.+}} + a + b +} + +// CHECK-LABEL: fp128 @f128_sub( +#[no_mangle] +pub fn f128_sub(a: f128, b: f128) -> f128 { + // CHECK: fsub fp128 %{{.+}}, %{{.+}} + a - b +} + +// CHECK-LABEL: fp128 @f128_mul( +#[no_mangle] +pub fn f128_mul(a: f128, b: f128) -> f128 { + // CHECK: fmul fp128 %{{.+}}, %{{.+}} + a * b +} + +// CHECK-LABEL: fp128 @f128_div( +#[no_mangle] +pub fn f128_div(a: f128, b: f128) -> f128 { + // CHECK: fdiv fp128 %{{.+}}, %{{.+}} + a / b +} + +// CHECK-LABEL: fp128 @f128_rem( +#[no_mangle] +pub fn f128_rem(a: f128, b: f128) -> f128 { + // CHECK: frem fp128 %{{.+}}, %{{.+}} + a % b +} + +// CHECK-LABEL: void @f128_add_assign( +#[no_mangle] +pub fn f128_add_assign(a: &mut f128, b: f128) { + // CHECK: fadd fp128 %{{.+}}, %{{.+}} + // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}} + *a += b; +} + +// CHECK-LABEL: void @f128_sub_assign( +#[no_mangle] +pub fn f128_sub_assign(a: &mut f128, b: f128) { + // CHECK: fsub fp128 %{{.+}}, %{{.+}} + // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}} + *a -= b; +} + +// CHECK-LABEL: void @f128_mul_assign( +#[no_mangle] +pub fn f128_mul_assign(a: &mut f128, b: f128) { + // CHECK: fmul fp128 %{{.+}}, %{{.+}} + // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}} + *a *= b +} + +// CHECK-LABEL: void @f128_div_assign( +#[no_mangle] +pub fn f128_div_assign(a: &mut f128, b: f128) { + // CHECK: fdiv fp128 %{{.+}}, %{{.+}} + // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}} + *a /= b +} + +// CHECK-LABEL: void @f128_rem_assign( +#[no_mangle] +pub fn f128_rem_assign(a: &mut f128, b: f128) { + // CHECK: frem fp128 %{{.+}}, %{{.+}} + // CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}} + *a %= b +} diff --git a/tests/codegen/float/f16.rs b/tests/codegen/float/f16.rs new file mode 100644 index 0000000000000..d1f75cc3b6851 --- /dev/null +++ b/tests/codegen/float/f16.rs @@ -0,0 +1,129 @@ +// Verify that our intrinsics generate the correct LLVM calls for f16 + +#![crate_type = "lib"] +#![feature(f16)] +#![feature(core_intrinsics)] + +// CHECK-LABEL: i1 @f16_eq( +#[no_mangle] +pub fn f16_eq(a: f16, b: f16) -> bool { + // CHECK: fcmp oeq half %{{.+}}, %{{.+}} + a == b +} + +// CHECK-LABEL: i1 @f16_ne( +#[no_mangle] +pub fn f16_ne(a: f16, b: f16) -> bool { + // CHECK: fcmp une half %{{.+}}, %{{.+}} + a != b +} + +// CHECK-LABEL: i1 @f16_gt( +#[no_mangle] +pub fn f16_gt(a: f16, b: f16) -> bool { + // CHECK: fcmp ogt half %{{.+}}, %{{.+}} + a > b +} + +// CHECK-LABEL: i1 @f16_ge( +#[no_mangle] +pub fn f16_ge(a: f16, b: f16) -> bool { + // CHECK: fcmp oge half %{{.+}}, %{{.+}} + a >= b +} + +// CHECK-LABEL: i1 @f16_lt( +#[no_mangle] +pub fn f16_lt(a: f16, b: f16) -> bool { + // CHECK: fcmp olt half %{{.+}}, %{{.+}} + a < b +} + +// CHECK-LABEL: i1 @f16_le( +#[no_mangle] +pub fn f16_le(a: f16, b: f16) -> bool { + // CHECK: fcmp ole half %{{.+}}, %{{.+}} + a <= b +} + +// CHECK-LABEL: half @f16_neg( +#[no_mangle] +pub fn f16_neg(a: f16) -> f16 { + // CHECK: fneg half %{{.+}} + -a +} + +// CHECK-LABEL: half @f16_add( +#[no_mangle] +pub fn f16_add(a: f16, b: f16) -> f16 { + // CHECK: fadd half %{{.+}}, %{{.+}} + a + b +} + +// CHECK-LABEL: half @f16_sub( +#[no_mangle] +pub fn f16_sub(a: f16, b: f16) -> f16 { + // CHECK: fsub half %{{.+}}, %{{.+}} + a - b +} + +// CHECK-LABEL: half @f16_mul( +#[no_mangle] +pub fn f16_mul(a: f16, b: f16) -> f16 { + // CHECK: fmul half %{{.+}}, %{{.+}} + a * b +} + +// CHECK-LABEL: half @f16_div( +#[no_mangle] +pub fn f16_div(a: f16, b: f16) -> f16 { + // CHECK: fdiv half %{{.+}}, %{{.+}} + a / b +} + +// CHECK-LABEL: half @f16_rem( +#[no_mangle] +pub fn f16_rem(a: f16, b: f16) -> f16 { + // CHECK: frem half %{{.+}}, %{{.+}} + a % b +} + +// CHECK-LABEL: void @f16_add_assign( +#[no_mangle] +pub fn f16_add_assign(a: &mut f16, b: f16) { + // CHECK: fadd half %{{.+}}, %{{.+}} + // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}} + *a += b; +} + +// CHECK-LABEL: void @f16_sub_assign( +#[no_mangle] +pub fn f16_sub_assign(a: &mut f16, b: f16) { + // CHECK: fsub half %{{.+}}, %{{.+}} + // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}} + *a -= b; +} + +// CHECK-LABEL: void @f16_mul_assign( +#[no_mangle] +pub fn f16_mul_assign(a: &mut f16, b: f16) { + // CHECK: fmul half %{{.+}}, %{{.+}} + // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}} + *a *= b +} + +// CHECK-LABEL: void @f16_div_assign( +#[no_mangle] +pub fn f16_div_assign(a: &mut f16, b: f16) { + // CHECK: fdiv half %{{.+}}, %{{.+}} + // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}} + *a /= b +} + +// CHECK-LABEL: void @f16_rem_assign( +#[no_mangle] +pub fn f16_rem_assign(a: &mut f16, b: f16) { + // CHECK: frem half %{{.+}}, %{{.+}} + // CHECK-NEXT: store half %{{.+}}, ptr %{{.+}} + *a %= b +} diff --git a/tests/ui/array-slice-vec/vector-no-ann.stderr b/tests/ui/array-slice-vec/vector-no-ann.stderr index 24b6abfb34260..716971eb12045 100644 --- a/tests/ui/array-slice-vec/vector-no-ann.stderr +++ b/tests/ui/array-slice-vec/vector-no-ann.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Vec` +error[E0282]: type annotations needed for `Vec<_>` --> $DIR/vector-no-ann.rs:2:9 | LL | let _foo = Vec::new(); diff --git a/tests/ui/const-generics/defaults/doesnt_infer.rs b/tests/ui/const-generics/defaults/doesnt_infer.rs index 9c59e672d8e4c..e14c08fc1487d 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.rs +++ b/tests/ui/const-generics/defaults/doesnt_infer.rs @@ -9,5 +9,5 @@ impl Foo { fn main() { let foo = Foo::<1>::foo(); let foo = Foo::foo(); - //~^ error: type annotations needed for `Foo` + //~^ ERROR type annotations needed for `Foo<_>` } diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index 65ee0ecfdc5a4..93d5860339712 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Foo` +error[E0282]: type annotations needed for `Foo<_>` --> $DIR/doesnt_infer.rs:11:9 | LL | let foo = Foo::foo(); diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index 5b296a14869fe..5ee42c19dd3db 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations needed for `Mask<_, N>` +error[E0283]: type annotations needed for `Mask<_, _>` --> $DIR/issue-91614.rs:6:9 | LL | let y = Mask::<_, _>::splat(false); diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index f27d52a1437f5..5cda4681b5c8b 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -18,7 +18,7 @@ help: try adding a `where` bound LL | pub const fn new() -> Self where [(); Self::SIZE]: { | +++++++++++++++++++++++ -error[E0282]: type annotations needed for `ArrayHolder` +error[E0282]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index 1664669eee05a..beb159779ff5c 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -22,7 +22,7 @@ note: tuple struct defined here LL | struct ArrayHolder([u32; X]); | ^^^^^^^^^^^ -error[E0282]: type annotations needed for `ArrayHolder` +error[E0282]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); diff --git a/tests/ui/generic-const-items/inference-failure.stderr b/tests/ui/generic-const-items/inference-failure.stderr index 10ecd83ec53c4..594743a47f424 100644 --- a/tests/ui/generic-const-items/inference-failure.stderr +++ b/tests/ui/generic-const-items/inference-failure.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Option` +error[E0282]: type annotations needed for `Option<_>` --> $DIR/inference-failure.rs:8:9 | LL | let _ = NONE; diff --git a/tests/ui/generic-const-items/parameter-defaults.stderr b/tests/ui/generic-const-items/parameter-defaults.stderr index b8220af5d0e93..13562c98f6d96 100644 --- a/tests/ui/generic-const-items/parameter-defaults.stderr +++ b/tests/ui/generic-const-items/parameter-defaults.stderr @@ -4,7 +4,7 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type` LL | const NONE: Option = None::; | ^^^^^^ -error[E0282]: type annotations needed for `Option` +error[E0282]: type annotations needed for `Option<_>` --> $DIR/parameter-defaults.rs:13:9 | LL | let _ = NONE; diff --git a/tests/ui/imports/redundant-import-extern-prelude.rs b/tests/ui/imports/redundant-import-extern-prelude.rs new file mode 100644 index 0000000000000..acf59b09a1dec --- /dev/null +++ b/tests/ui/imports/redundant-import-extern-prelude.rs @@ -0,0 +1,17 @@ +// Check that we detect imports that are redundant due to the extern prelude +// and that we emit a reasonable diagnostic. +// issue: rust-lang/rust#121915 +//~^^^ NOTE the item `aux_issue_121915` is already defined by the extern prelude + +// See also the discussion in . + +//@ compile-flags: --extern aux_issue_121915 --edition 2018 +//@ aux-build: aux-issue-121915.rs + +#[deny(unused_imports)] +//~^ NOTE the lint level is defined here +fn main() { + use aux_issue_121915; + //~^ ERROR the item `aux_issue_121915` is imported redundantly + aux_issue_121915::item(); +} diff --git a/tests/ui/imports/redundant-import-issue-121915.stderr b/tests/ui/imports/redundant-import-extern-prelude.stderr similarity index 68% rename from tests/ui/imports/redundant-import-issue-121915.stderr rename to tests/ui/imports/redundant-import-extern-prelude.stderr index 0047d7c34207c..d49e013c3d34d 100644 --- a/tests/ui/imports/redundant-import-issue-121915.stderr +++ b/tests/ui/imports/redundant-import-extern-prelude.stderr @@ -1,11 +1,11 @@ error: the item `aux_issue_121915` is imported redundantly - --> $DIR/redundant-import-issue-121915.rs:6:9 + --> $DIR/redundant-import-extern-prelude.rs:14:9 | LL | use aux_issue_121915; - | ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by prelude + | ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by the extern prelude | note: the lint level is defined here - --> $DIR/redundant-import-issue-121915.rs:4:8 + --> $DIR/redundant-import-extern-prelude.rs:11:8 | LL | #[deny(unused_imports)] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/imports/redundant-import-issue-121915.rs b/tests/ui/imports/redundant-import-issue-121915.rs deleted file mode 100644 index 237acc4af2565..0000000000000 --- a/tests/ui/imports/redundant-import-issue-121915.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ compile-flags: --extern aux_issue_121915 --edition 2018 -//@ aux-build: aux-issue-121915.rs - -#[deny(unused_imports)] -fn main() { - use aux_issue_121915; - //~^ ERROR the item `aux_issue_121915` is imported redundantly - aux_issue_121915::item(); -} diff --git a/tests/ui/imports/redundant-import-lang-prelude-attr.rs b/tests/ui/imports/redundant-import-lang-prelude-attr.rs new file mode 100644 index 0000000000000..18d0e688206b0 --- /dev/null +++ b/tests/ui/imports/redundant-import-lang-prelude-attr.rs @@ -0,0 +1,18 @@ +// Check that we detect imports (of built-in attributes) that are redundant due to +// the language prelude and that we emit a reasonable diagnostic. +//~^^ NOTE the item `allow` is already defined by the extern prelude + +// Note that we use the term "extern prelude" in the label even though "language prelude" +// would be more correct. However, it's not worth special-casing this. + +// See also the discussion in . + +//@ edition: 2018 + +#![deny(unused_imports)] +//~^ NOTE the lint level is defined here + +use allow; //~ ERROR the item `allow` is imported redundantly + +#[allow(unused)] +fn main() {} diff --git a/tests/ui/imports/redundant-import-lang-prelude-attr.stderr b/tests/ui/imports/redundant-import-lang-prelude-attr.stderr new file mode 100644 index 0000000000000..a3ca7ce24ed0b --- /dev/null +++ b/tests/ui/imports/redundant-import-lang-prelude-attr.stderr @@ -0,0 +1,14 @@ +error: the item `allow` is imported redundantly + --> $DIR/redundant-import-lang-prelude-attr.rs:15:5 + | +LL | use allow; + | ^^^^^ the item `allow` is already defined by the extern prelude + | +note: the lint level is defined here + --> $DIR/redundant-import-lang-prelude-attr.rs:12:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/redundant-import-lang-prelude.rs b/tests/ui/imports/redundant-import-lang-prelude.rs new file mode 100644 index 0000000000000..3faf9423c37f8 --- /dev/null +++ b/tests/ui/imports/redundant-import-lang-prelude.rs @@ -0,0 +1,18 @@ +// Check that we detect imports that are redundant due to the language prelude +// and that we emit a reasonable diagnostic. +//~^^ NOTE the item `u8` is already defined by the extern prelude + +// Note that we use the term "extern prelude" in the label even though "language prelude" +// would be more correct. However, it's not worth special-casing this. + +// See also the discussion in . + +#![deny(unused_imports)] +//~^ NOTE the lint level is defined here + +use std::primitive::u8; +//~^ ERROR the item `u8` is imported redundantly + +const _: u8 = 0; + +fn main() {} diff --git a/tests/ui/imports/redundant-import-lang-prelude.stderr b/tests/ui/imports/redundant-import-lang-prelude.stderr new file mode 100644 index 0000000000000..e6a4535f9802d --- /dev/null +++ b/tests/ui/imports/redundant-import-lang-prelude.stderr @@ -0,0 +1,14 @@ +error: the item `u8` is imported redundantly + --> $DIR/redundant-import-lang-prelude.rs:13:5 + | +LL | use std::primitive::u8; + | ^^^^^^^^^^^^^^^^^^ the item `u8` is already defined by the extern prelude + | +note: the lint level is defined here + --> $DIR/redundant-import-lang-prelude.rs:10:9 + | +LL | #![deny(unused_imports)] + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/redundant-import-undetected-macro-use-prelude.rs b/tests/ui/imports/redundant-import-undetected-macro-use-prelude.rs new file mode 100644 index 0000000000000..4a79cb2c208f9 --- /dev/null +++ b/tests/ui/imports/redundant-import-undetected-macro-use-prelude.rs @@ -0,0 +1,23 @@ +// This test demonstrates that we currently don't make an effort to detect +// imports made redundant by the `#[macro_use]` prelude. +// See also the discussion in . + +//@ check-pass +//@ aux-build:two_macros.rs +#![deny(unused_imports)] + +#[macro_use] +extern crate two_macros; + +// This import is actually redundant due to the `#[macro_use]` above. +use two_macros::n; + +// We intentionally reference two items from the `#[macro_use]`'d crate because +// if we were to reference only item `n`, we would flag the `#[macro_use]` +// attribute as redundant which would be correct of course. +// That's interesting on its own -- we prefer "blaming" the `#[macro_use]` +// over the import (here, `use two_macros::n`) when it comes to redundancy. +n!(); +m!(); + +fn main() {} diff --git a/tests/ui/inference/cannot-infer-closure-circular.rs b/tests/ui/inference/cannot-infer-closure-circular.rs index affb481496d02..1b41171e74a76 100644 --- a/tests/ui/inference/cannot-infer-closure-circular.rs +++ b/tests/ui/inference/cannot-infer-closure-circular.rs @@ -4,7 +4,7 @@ fn main() { // error handles this gracefully, and in particular doesn't generate an extra // note about the `?` operator in the closure body, which isn't relevant to // the inference. - let x = |r| { //~ ERROR type annotations needed for `Result<(), E>` + let x = |r| { //~ ERROR type annotations needed for `Result<(), _>` let v = r?; Ok(v) }; diff --git a/tests/ui/inference/cannot-infer-closure-circular.stderr b/tests/ui/inference/cannot-infer-closure-circular.stderr index e3cf0cca83711..a16e832f8ef91 100644 --- a/tests/ui/inference/cannot-infer-closure-circular.stderr +++ b/tests/ui/inference/cannot-infer-closure-circular.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Result<(), E>` +error[E0282]: type annotations needed for `Result<(), _>` --> $DIR/cannot-infer-closure-circular.rs:7:14 | LL | let x = |r| { diff --git a/tests/ui/inference/erase-type-params-in-label.stderr b/tests/ui/inference/erase-type-params-in-label.stderr index 546e679f2d0bc..4e9a74c1e403d 100644 --- a/tests/ui/inference/erase-type-params-in-label.stderr +++ b/tests/ui/inference/erase-type-params-in-label.stderr @@ -1,4 +1,4 @@ -error[E0283]: type annotations needed for `Foo` +error[E0283]: type annotations needed for `Foo` --> $DIR/erase-type-params-in-label.rs:2:9 | LL | let foo = foo(1, ""); @@ -15,7 +15,7 @@ help: consider giving `foo` an explicit type, where the type for type parameter LL | let foo: Foo = foo(1, ""); | ++++++++++++++++++++++ -error[E0283]: type annotations needed for `Bar` +error[E0283]: type annotations needed for `Bar` --> $DIR/erase-type-params-in-label.rs:5:9 | LL | let bar = bar(1, ""); diff --git a/tests/ui/inference/issue-104649.stderr b/tests/ui/inference/issue-104649.stderr index afece960914da..391ed16f349d7 100644 --- a/tests/ui/inference/issue-104649.stderr +++ b/tests/ui/inference/issue-104649.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `A, Error>>` +error[E0282]: type annotations needed for `A, Error>>` --> $DIR/issue-104649.rs:24:9 | LL | let a = A(Result::Ok(Result::Ok(()))); diff --git a/tests/ui/inference/issue-72690.stderr b/tests/ui/inference/issue-72690.stderr index 6c93241ea07cd..6391672f8617d 100644 --- a/tests/ui/inference/issue-72690.stderr +++ b/tests/ui/inference/issue-72690.stderr @@ -50,7 +50,7 @@ help: try using a fully qualified path to specify the expected types LL | |x| String::from(>::as_ref("x")); | ++++++++++++++++++++++++++ ~ -error[E0283]: type annotations needed for `&T` +error[E0283]: type annotations needed for `&_` --> $DIR/issue-72690.rs:17:9 | LL | let _ = "x".as_ref(); diff --git a/tests/ui/inference/issue-83606.rs b/tests/ui/inference/issue-83606.rs index c387046e91008..4454b5e60f069 100644 --- a/tests/ui/inference/issue-83606.rs +++ b/tests/ui/inference/issue-83606.rs @@ -6,5 +6,5 @@ fn foo(_: impl std::fmt::Display) -> [usize; N] { fn main() { let _ = foo("foo"); - //~^ ERROR: type annotations needed for `[usize; N]` + //~^ ERROR type annotations needed for `[usize; _]` } diff --git a/tests/ui/inference/issue-83606.stderr b/tests/ui/inference/issue-83606.stderr index 00de4029e4281..8e6ff6d568de7 100644 --- a/tests/ui/inference/issue-83606.stderr +++ b/tests/ui/inference/issue-83606.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `[usize; N]` +error[E0282]: type annotations needed for `[usize; _]` --> $DIR/issue-83606.rs:8:9 | LL | let _ = foo("foo"); diff --git a/tests/ui/issues/issue-11771.stderr b/tests/ui/issues/issue-11771.stderr index 161fce4b0315c..d4a4647f6a10d 100644 --- a/tests/ui/issues/issue-11771.stderr +++ b/tests/ui/issues/issue-11771.stderr @@ -6,15 +6,15 @@ LL | 1 + | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: + <&'a f128 as Add> + <&'a f16 as Add> <&'a f32 as Add> <&'a f64 as Add> <&'a i128 as Add> <&'a i16 as Add> <&'a i32 as Add> <&'a i64 as Add> - <&'a i8 as Add> - <&'a isize as Add> - and 48 others + and 56 others error[E0277]: cannot add `()` to `{integer}` --> $DIR/issue-11771.rs:8:7 @@ -24,15 +24,15 @@ LL | 1 + | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: + <&'a f128 as Add> + <&'a f16 as Add> <&'a f32 as Add> <&'a f64 as Add> <&'a i128 as Add> <&'a i16 as Add> <&'a i32 as Add> <&'a i64 as Add> - <&'a i8 as Add> - <&'a isize as Add> - and 48 others + and 56 others error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-12187-1.stderr b/tests/ui/issues/issue-12187-1.stderr index 93dc1df8f6342..704854fe58581 100644 --- a/tests/ui/issues/issue-12187-1.stderr +++ b/tests/ui/issues/issue-12187-1.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `&T` +error[E0282]: type annotations needed for `&_` --> $DIR/issue-12187-1.rs:6:9 | LL | let &v = new(); diff --git a/tests/ui/issues/issue-12187-2.stderr b/tests/ui/issues/issue-12187-2.stderr index e9ba52ff4fde2..eeef63a1d0bd2 100644 --- a/tests/ui/issues/issue-12187-2.stderr +++ b/tests/ui/issues/issue-12187-2.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `&T` +error[E0282]: type annotations needed for `&_` --> $DIR/issue-12187-2.rs:6:9 | LL | let &v = new(); diff --git a/tests/ui/issues/issue-17551.stderr b/tests/ui/issues/issue-17551.stderr index 68f54a310844b..b9cb76fc298d9 100644 --- a/tests/ui/issues/issue-17551.stderr +++ b/tests/ui/issues/issue-17551.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `B` +error[E0282]: type annotations needed for `B<_>` --> $DIR/issue-17551.rs:6:9 | LL | let foo = B(marker::PhantomData); diff --git a/tests/ui/issues/issue-23046.stderr b/tests/ui/issues/issue-23046.stderr index b6e23814543f3..f70ac0c9f388a 100644 --- a/tests/ui/issues/issue-23046.stderr +++ b/tests/ui/issues/issue-23046.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Expr<'_, VAR>` +error[E0282]: type annotations needed for `Expr<'_, _>` --> $DIR/issue-23046.rs:17:15 | LL | let ex = |x| { diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr index 1967b51128f61..b765d2f087d0a 100644 --- a/tests/ui/issues/issue-50582.stderr +++ b/tests/ui/issues/issue-50582.stderr @@ -16,15 +16,15 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); | = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: + <&'a f128 as Add> + <&'a f16 as Add> <&'a f32 as Add> <&'a f64 as Add> <&'a i128 as Add> <&'a i16 as Add> <&'a i32 as Add> <&'a i64 as Add> - <&'a i8 as Add> - <&'a isize as Add> - and 48 others + and 56 others error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-98299.stderr b/tests/ui/issues/issue-98299.stderr index e99d8e5cc80a0..becf16d1db91b 100644 --- a/tests/ui/issues/issue-98299.stderr +++ b/tests/ui/issues/issue-98299.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `SmallCString` +error[E0282]: type annotations needed for `SmallCString<_>` --> $DIR/issue-98299.rs:4:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); diff --git a/tests/ui/lint/unused/unused_parens/unused-parens-in-macro-issue-120642.rs b/tests/ui/lint/unused/unused_parens/unused-parens-in-macro-issue-120642.rs new file mode 100644 index 0000000000000..59bb65a357bae --- /dev/null +++ b/tests/ui/lint/unused/unused_parens/unused-parens-in-macro-issue-120642.rs @@ -0,0 +1,39 @@ +//@ run-pass + +#![warn(unused_parens)] +#![allow(dead_code)] + +trait Foo { + fn bar(); + fn tar(); +} + +macro_rules! unused_parens { + ($ty:ident) => { + impl<$ty: Foo> Foo for ($ty,) { + fn bar() { <$ty>::bar() } + fn tar() {} + } + }; + + ($ty:ident $(, $rest:ident)*) => { + impl<$ty: Foo, $($rest: Foo),*> Foo for ($ty, $($rest),*) { + fn bar() { + <$ty>::bar(); + <($($rest),*)>::bar() //~WARN unnecessary parentheses around type + } + fn tar() { + let (_t) = 1; //~WARN unnecessary parentheses around pattern + //~| WARN unnecessary parentheses around pattern + let (_t1,) = (1,); + let (_t2, _t3) = (1, 2); + } + } + + unused_parens!($($rest),*); + } +} + +unused_parens!(T1, T2, T3); + +fn main() {} diff --git a/tests/ui/lint/unused/unused_parens/unused-parens-in-macro-issue-120642.stderr b/tests/ui/lint/unused/unused_parens/unused-parens-in-macro-issue-120642.stderr new file mode 100644 index 0000000000000..b1390debec73b --- /dev/null +++ b/tests/ui/lint/unused/unused_parens/unused-parens-in-macro-issue-120642.stderr @@ -0,0 +1,40 @@ +warning: unnecessary parentheses around pattern + --> $DIR/unused-parens-in-macro-issue-120642.rs:26:19 + | +LL | let (_t) = 1; + | ^^^^ +... +LL | unused_parens!(T1, T2, T3); + | -------------------------- in this macro invocation + | +note: the lint level is defined here + --> $DIR/unused-parens-in-macro-issue-120642.rs:3:9 + | +LL | #![warn(unused_parens)] + | ^^^^^^^^^^^^^ + = note: this warning originates in the macro `unused_parens` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: unnecessary parentheses around type + --> $DIR/unused-parens-in-macro-issue-120642.rs:23:18 + | +LL | <($($rest),*)>::bar() + | ^^^^^^^^^^^^ +... +LL | unused_parens!(T1, T2, T3); + | -------------------------- in this macro invocation + | + = note: this warning originates in the macro `unused_parens` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: unnecessary parentheses around pattern + --> $DIR/unused-parens-in-macro-issue-120642.rs:26:19 + | +LL | let (_t) = 1; + | ^^^^ +... +LL | unused_parens!(T1, T2, T3); + | -------------------------- in this macro invocation + | + = note: this warning originates in the macro `unused_parens` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 3 warnings emitted + diff --git a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 0a022dc3984f5..b2d2d039ff6a2 100644 --- a/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/tests/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Vec` +error[E0282]: type annotations needed for `Vec<_>` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:9 | LL | let mut x = Vec::new(); diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr index f8047c8e2d449..099c580a0565e 100644 --- a/tests/ui/mismatched_types/binops.stderr +++ b/tests/ui/mismatched_types/binops.stderr @@ -6,15 +6,15 @@ LL | 1 + Some(1); | = help: the trait `Add>` is not implemented for `{integer}` = help: the following other types implement trait `Add`: + <&'a f128 as Add> + <&'a f16 as Add> <&'a f32 as Add> <&'a f64 as Add> <&'a i128 as Add> <&'a i16 as Add> <&'a i32 as Add> <&'a i64 as Add> - <&'a i8 as Add> - <&'a isize as Add> - and 48 others + and 56 others error[E0277]: cannot subtract `Option<{integer}>` from `usize` --> $DIR/binops.rs:3:16 @@ -37,15 +37,15 @@ LL | 3 * (); | = help: the trait `Mul<()>` is not implemented for `{integer}` = help: the following other types implement trait `Mul`: + <&'a f128 as Mul> + <&'a f16 as Mul> <&'a f32 as Mul> <&'a f64 as Mul> <&'a i128 as Mul> <&'a i16 as Mul> <&'a i32 as Mul> <&'a i64 as Mul> - <&'a i8 as Mul> - <&'a isize as Mul> - and 49 others + and 57 others error[E0277]: cannot divide `{integer}` by `&str` --> $DIR/binops.rs:5:7 @@ -55,15 +55,15 @@ LL | 4 / ""; | = help: the trait `Div<&str>` is not implemented for `{integer}` = help: the following other types implement trait `Div`: + <&'a f128 as Div> + <&'a f16 as Div> <&'a f32 as Div> <&'a f64 as Div> <&'a i128 as Div> <&'a i16 as Div> <&'a i32 as Div> <&'a i64 as Div> - <&'a i8 as Div> - <&'a isize as Div> - and 54 others + and 62 others error[E0277]: can't compare `{integer}` with `String` --> $DIR/binops.rs:6:7 diff --git a/tests/ui/traits/copy-guessing.rs b/tests/ui/traits/copy-guessing.rs index af25010e3bd28..0ffa82497899a 100644 --- a/tests/ui/traits/copy-guessing.rs +++ b/tests/ui/traits/copy-guessing.rs @@ -18,7 +18,7 @@ fn assert_impls_fnR>(_: &T){} fn main() { let n = None; - //~^ ERROR type annotations needed for `Option` + //~^ ERROR type annotations needed for `Option<_>` let e = S(&n); let f = || { // S being copy is critical for this to work diff --git a/tests/ui/traits/copy-guessing.stderr b/tests/ui/traits/copy-guessing.stderr index 750140c017c25..cae91579ee0eb 100644 --- a/tests/ui/traits/copy-guessing.stderr +++ b/tests/ui/traits/copy-guessing.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Option` +error[E0282]: type annotations needed for `Option<_>` --> $DIR/copy-guessing.rs:20:9 | LL | let n = None; diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index 5be8d2f4b325e..0f4b3c3c877c9 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -55,7 +55,7 @@ help: try using a fully qualified path to specify the expected types LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(>::into(0u32))).collect(); | +++++++++++++++++++++++ ~ -error[E0283]: type annotations needed for `Box` +error[E0283]: type annotations needed for `Box<_>` --> $DIR/issue-77982.rs:37:9 | LL | let _ = ().foo(); @@ -73,7 +73,7 @@ help: consider giving this pattern a type, where the type for type parameter `T` LL | let _: Box = ().foo(); | ++++++++ -error[E0283]: type annotations needed for `Box` +error[E0283]: type annotations needed for `Box<_>` --> $DIR/issue-77982.rs:41:9 | LL | let _ = (&()).bar(); diff --git a/tests/ui/type-inference/or_else-multiple-type-params.stderr b/tests/ui/type-inference/or_else-multiple-type-params.stderr index d1bbe308ed3dd..3176a2d490ebc 100644 --- a/tests/ui/type-inference/or_else-multiple-type-params.stderr +++ b/tests/ui/type-inference/or_else-multiple-type-params.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Result` +error[E0282]: type annotations needed for `Result` --> $DIR/or_else-multiple-type-params.rs:7:18 | LL | .or_else(|err| { diff --git a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index 5a76ef3e87587..058dbb1e220f6 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Option` +error[E0282]: type annotations needed for `Option<_>` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:8:9 | LL | let mut closure0 = None;