diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 62e16d445c63f..272fb6c608c06 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -652,6 +652,68 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err } + fn ty_kind_suggestion(&self, ty: Ty<'tcx>) -> Option { + // Keep in sync with `rustc_hir_analysis/src/check/mod.rs:ty_kind_suggestion`. + // FIXME: deduplicate the above. + let tcx = self.infcx.tcx; + let implements_default = |ty| { + let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { + return false; + }; + self.infcx + .type_implements_trait(default_trait, [ty], self.param_env) + .must_apply_modulo_regions() + }; + + Some(match ty.kind() { + ty::Never | ty::Error(_) => return None, + ty::Bool => "false".to_string(), + ty::Char => "\'x\'".to_string(), + ty::Int(_) | ty::Uint(_) => "42".into(), + ty::Float(_) => "3.14159".into(), + ty::Slice(_) => "[]".to_string(), + ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => { + "vec![]".to_string() + } + ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => { + "String::new()".to_string() + } + ty::Adt(def, args) if def.is_box() => { + format!("Box::new({})", self.ty_kind_suggestion(args[0].expect_ty())?) + } + ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => { + "None".to_string() + } + ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => { + format!("Ok({})", self.ty_kind_suggestion(args[0].expect_ty())?) + } + ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(), + ty::Ref(_, ty, mutability) => { + if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) { + "\"\"".to_string() + } else { + let Some(ty) = self.ty_kind_suggestion(*ty) else { + return None; + }; + format!("&{}{ty}", mutability.prefix_str()) + } + } + ty::Array(ty, len) => format!( + "[{}; {}]", + self.ty_kind_suggestion(*ty)?, + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), + ), + ty::Tuple(tys) => format!( + "({})", + tys.iter() + .map(|ty| self.ty_kind_suggestion(ty)) + .collect::>>()? + .join(", ") + ), + _ => "value".to_string(), + }) + } + fn suggest_assign_value( &self, err: &mut Diag<'_>, @@ -661,34 +723,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let ty = moved_place.ty(self.body, self.infcx.tcx).ty; debug!("ty: {:?}, kind: {:?}", ty, ty.kind()); - let tcx = self.infcx.tcx; - let implements_default = |ty, param_env| { - let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { - return false; - }; - self.infcx - .type_implements_trait(default_trait, [ty], param_env) - .must_apply_modulo_regions() - }; - - let assign_value = match ty.kind() { - ty::Bool => "false", - ty::Float(_) => "0.0", - ty::Int(_) | ty::Uint(_) => "0", - ty::Never | ty::Error(_) => "", - ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => "vec![]", - ty::Adt(_, _) if implements_default(ty, self.param_env) => "Default::default()", - _ => "todo!()", + let Some(assign_value) = self.ty_kind_suggestion(ty) else { + return; }; - if !assign_value.is_empty() { - err.span_suggestion_verbose( - sugg_span.shrink_to_hi(), - "consider assigning a value", - format!(" = {assign_value}"), - Applicability::MaybeIncorrect, - ); - } + err.span_suggestion_verbose( + sugg_span.shrink_to_hi(), + "consider assigning a value", + format!(" = {assign_value}"), + Applicability::MaybeIncorrect, + ); } fn suggest_borrow_fn_like( diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8d4ae10d4bfe6..961b643fa2510 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -22,7 +22,6 @@ use rustc_middle::ty::{ AdtDef, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; -use rustc_span::symbol::sym; use rustc_target::abi::FieldIdx; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 8760901b71bad..938c0a19e338f 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -81,6 +81,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_errors::{pluralize, struct_span_code_err, Diag}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; +use rustc_hir::Mutability; use rustc_index::bit_set::BitSet; use rustc_infer::infer::error_reporting::ObligationCauseExt as _; use rustc_infer::infer::outlives::env::OutlivesEnvironment; @@ -91,10 +92,11 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::parse::feature_err; -use rustc_span::symbol::{kw, Ident}; -use rustc_span::{self, def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; +use rustc_span::symbol::{kw, sym, Ident}; +use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; @@ -466,14 +468,64 @@ fn fn_sig_suggestion<'tcx>( ) } -pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { +pub fn ty_kind_suggestion<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option { + // Keep in sync with `rustc_borrowck/src/diagnostics/conflict_errors.rs:ty_kind_suggestion`. + // FIXME: deduplicate the above. + let implements_default = |ty| { + let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { + return false; + }; + let infcx = tcx.infer_ctxt().build(); + infcx + .type_implements_trait(default_trait, [ty], ty::ParamEnv::reveal_all()) + .must_apply_modulo_regions() + }; Some(match ty.kind() { - ty::Bool => "true", - ty::Char => "'a'", - ty::Int(_) | ty::Uint(_) => "42", - ty::Float(_) => "3.14159", - ty::Error(_) | ty::Never => return None, - _ => "value", + ty::Never | ty::Error(_) => return None, + ty::Bool => "false".to_string(), + ty::Char => "\'x\'".to_string(), + ty::Int(_) | ty::Uint(_) => "42".into(), + ty::Float(_) => "3.14159".into(), + ty::Slice(_) => "[]".to_string(), + ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => { + "vec![]".to_string() + } + ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => { + "String::new()".to_string() + } + ty::Adt(def, args) if def.is_box() => { + format!("Box::new({})", ty_kind_suggestion(args[0].expect_ty(), tcx)?) + } + ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => { + "None".to_string() + } + ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => { + format!("Ok({})", ty_kind_suggestion(args[0].expect_ty(), tcx)?) + } + ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(), + ty::Ref(_, ty, mutability) => { + if let (ty::Str, Mutability::Not) = (ty.kind(), mutability) { + "\"\"".to_string() + } else { + let Some(ty) = ty_kind_suggestion(*ty, tcx) else { + return None; + }; + format!("&{}{ty}", mutability.prefix_str()) + } + } + ty::Array(ty, len) => format!( + "[{}; {}]", + ty_kind_suggestion(*ty, tcx)?, + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), + ), + ty::Tuple(tys) => format!( + "({})", + tys.iter() + .map(|ty| ty_kind_suggestion(ty, tcx)) + .collect::>>()? + .join(", ") + ), + _ => "value".to_string(), }) } @@ -511,7 +563,7 @@ fn suggestion_signature<'tcx>( } ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id).instantiate_identity(); - let val = ty_kind_suggestion(ty).unwrap_or("todo!()"); + let val = ty_kind_suggestion(ty, tcx).unwrap_or_else(|| "value".to_string()); format!("const {}: {} = {};", assoc.name, ty, val) } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7a1a2c498aa7d..8f30c3fd37743 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -694,10 +694,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty })); self.annotate_loop_expected_due_to_inference(err, expr, error); - if let Some(val) = ty_kind_suggestion(ty) { + if let Some(val) = ty_kind_suggestion(ty, tcx) { err.span_suggestion_verbose( expr.span.shrink_to_hi(), - "give it a value of the expected type", + "give the `break` a value of the expected type", format!(" {val}"), Applicability::HasPlaceholders, ); 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/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index dbdbaccb5353f..f4f33f8584bd0 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -517,8 +517,6 @@ impl CStr { /// # Examples /// /// ``` - /// #![feature(cstr_count_bytes)] - /// /// use std::ffi::CStr; /// /// let cstr = CStr::from_bytes_with_nul(b"foo\0").unwrap(); @@ -530,7 +528,7 @@ impl CStr { #[inline] #[must_use] #[doc(alias("len", "strlen"))] - #[unstable(feature = "cstr_count_bytes", issue = "114441")] + #[stable(feature = "cstr_count_bytes", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")] pub const fn count_bytes(&self) -> usize { self.inner.len() - 1 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/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/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/asm/x86_64/type-check-5.stderr b/tests/ui/asm/x86_64/type-check-5.stderr index 7970e76d6a1f4..4fb759934636d 100644 --- a/tests/ui/asm/x86_64/type-check-5.stderr +++ b/tests/ui/asm/x86_64/type-check-5.stderr @@ -8,8 +8,8 @@ LL | asm!("{}", in(reg) x); | help: consider assigning a value | -LL | let x: u64 = 0; - | +++ +LL | let x: u64 = 42; + | ++++ error[E0381]: used binding `y` isn't initialized --> $DIR/type-check-5.rs:18:9 @@ -21,8 +21,8 @@ LL | asm!("{}", inout(reg) y); | help: consider assigning a value | -LL | let mut y: u64 = 0; - | +++ +LL | let mut y: u64 = 42; + | ++++ error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable --> $DIR/type-check-5.rs:24:13 diff --git a/tests/ui/binop/issue-77910-1.stderr b/tests/ui/binop/issue-77910-1.stderr index 6402e5681884c..74deac900d424 100644 --- a/tests/ui/binop/issue-77910-1.stderr +++ b/tests/ui/binop/issue-77910-1.stderr @@ -32,8 +32,8 @@ LL | xs | help: consider assigning a value | -LL | let xs = todo!(); - | +++++++++ +LL | let xs = &42; + | +++++ error: aborting due to 3 previous errors diff --git a/tests/ui/binop/issue-77910-2.stderr b/tests/ui/binop/issue-77910-2.stderr index a14560ff188ee..7087f2cdf4197 100644 --- a/tests/ui/binop/issue-77910-2.stderr +++ b/tests/ui/binop/issue-77910-2.stderr @@ -21,8 +21,8 @@ LL | xs | help: consider assigning a value | -LL | let xs = todo!(); - | +++++++++ +LL | let xs = &42; + | +++++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/borrowck-block-uninit.stderr b/tests/ui/borrowck/borrowck-block-uninit.stderr index 07c09f1f443c5..4db98a7a0dce9 100644 --- a/tests/ui/borrowck/borrowck-block-uninit.stderr +++ b/tests/ui/borrowck/borrowck-block-uninit.stderr @@ -10,8 +10,8 @@ LL | println!("{}", x); | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-break-uninit-2.stderr b/tests/ui/borrowck/borrowck-break-uninit-2.stderr index 7c0cda31c9734..e23ca534e7454 100644 --- a/tests/ui/borrowck/borrowck-break-uninit-2.stderr +++ b/tests/ui/borrowck/borrowck-break-uninit-2.stderr @@ -10,8 +10,8 @@ LL | println!("{}", x); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-break-uninit.stderr b/tests/ui/borrowck/borrowck-break-uninit.stderr index 0d879c6fb7df2..0367d224f801d 100644 --- a/tests/ui/borrowck/borrowck-break-uninit.stderr +++ b/tests/ui/borrowck/borrowck-break-uninit.stderr @@ -10,8 +10,8 @@ LL | println!("{}", x); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-init-in-called-fn-expr.stderr b/tests/ui/borrowck/borrowck-init-in-called-fn-expr.stderr index a27b6956b305b..bfe3c60a84a6f 100644 --- a/tests/ui/borrowck/borrowck-init-in-called-fn-expr.stderr +++ b/tests/ui/borrowck/borrowck-init-in-called-fn-expr.stderr @@ -8,8 +8,8 @@ LL | i | help: consider assigning a value | -LL | let i: isize = 0; - | +++ +LL | let i: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-init-in-fn-expr.stderr b/tests/ui/borrowck/borrowck-init-in-fn-expr.stderr index 16f4c40f529c9..a248a6d85b67c 100644 --- a/tests/ui/borrowck/borrowck-init-in-fn-expr.stderr +++ b/tests/ui/borrowck/borrowck-init-in-fn-expr.stderr @@ -8,8 +8,8 @@ LL | i | help: consider assigning a value | -LL | let i: isize = 0; - | +++ +LL | let i: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-init-in-fru.stderr b/tests/ui/borrowck/borrowck-init-in-fru.stderr index f27993e10b44e..b5c332a90bcd1 100644 --- a/tests/ui/borrowck/borrowck-init-in-fru.stderr +++ b/tests/ui/borrowck/borrowck-init-in-fru.stderr @@ -8,8 +8,8 @@ LL | origin = Point { x: 10, ..origin }; | help: consider assigning a value | -LL | let mut origin: Point = todo!(); - | +++++++++ +LL | let mut origin: Point = value; + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-init-op-equal.stderr b/tests/ui/borrowck/borrowck-init-op-equal.stderr index 241d24341cb69..d621c4ab46e68 100644 --- a/tests/ui/borrowck/borrowck-init-op-equal.stderr +++ b/tests/ui/borrowck/borrowck-init-op-equal.stderr @@ -8,8 +8,8 @@ LL | v += 1; | help: consider assigning a value | -LL | let v: isize = 0; - | +++ +LL | let v: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-init-plus-equal.stderr b/tests/ui/borrowck/borrowck-init-plus-equal.stderr index 65de6e8bf5d3a..109321386ba21 100644 --- a/tests/ui/borrowck/borrowck-init-plus-equal.stderr +++ b/tests/ui/borrowck/borrowck-init-plus-equal.stderr @@ -8,8 +8,8 @@ LL | v = v + 1; | help: consider assigning a value | -LL | let mut v: isize = 0; - | +++ +LL | let mut v: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-return.stderr b/tests/ui/borrowck/borrowck-return.stderr index a1bc3008ea8cc..f680b9af4f01f 100644 --- a/tests/ui/borrowck/borrowck-return.stderr +++ b/tests/ui/borrowck/borrowck-return.stderr @@ -8,8 +8,8 @@ LL | return x; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-storage-dead.stderr b/tests/ui/borrowck/borrowck-storage-dead.stderr index a08e2a7b5352e..5f29c61c7ebe8 100644 --- a/tests/ui/borrowck/borrowck-storage-dead.stderr +++ b/tests/ui/borrowck/borrowck-storage-dead.stderr @@ -8,8 +8,8 @@ LL | let _ = x + 1; | help: consider assigning a value | -LL | let x: i32 = 0; - | +++ +LL | let x: i32 = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-uninit-after-item.stderr b/tests/ui/borrowck/borrowck-uninit-after-item.stderr index 06bb419aa3b38..c6d52a049d2b8 100644 --- a/tests/ui/borrowck/borrowck-uninit-after-item.stderr +++ b/tests/ui/borrowck/borrowck-uninit-after-item.stderr @@ -9,8 +9,8 @@ LL | baz(bar); | help: consider assigning a value | -LL | let bar = 0; - | +++ +LL | let bar = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-uninit-in-assignop.stderr b/tests/ui/borrowck/borrowck-uninit-in-assignop.stderr index fdbb451bde4e8..aaa33f08ff514 100644 --- a/tests/ui/borrowck/borrowck-uninit-in-assignop.stderr +++ b/tests/ui/borrowck/borrowck-uninit-in-assignop.stderr @@ -8,8 +8,8 @@ LL | x += 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:9:5 @@ -21,8 +21,8 @@ LL | x -= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:12:5 @@ -34,8 +34,8 @@ LL | x *= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:15:5 @@ -47,8 +47,8 @@ LL | x /= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:18:5 @@ -60,8 +60,8 @@ LL | x %= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:21:5 @@ -73,8 +73,8 @@ LL | x ^= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:24:5 @@ -86,8 +86,8 @@ LL | x &= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:27:5 @@ -99,8 +99,8 @@ LL | x |= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:30:5 @@ -112,8 +112,8 @@ LL | x <<= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:33:5 @@ -125,8 +125,8 @@ LL | x >>= 1; | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error: aborting due to 10 previous errors diff --git a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr index 73fded7545cc6..d6759b8e1cf45 100644 --- a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr +++ b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr @@ -8,8 +8,8 @@ LL | let _y = &**x; | help: consider assigning a value | -LL | let x: &&Box = todo!(); - | +++++++++ +LL | let x: &&Box = &&Box::new(42); + | ++++++++++++++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:11:14 @@ -21,7 +21,7 @@ LL | let _y = &**x; | help: consider assigning a value | -LL | let x: &&S = todo!(); +LL | let x: &&S = &&value; | +++++++++ error[E0381]: used binding `x` isn't initialized @@ -34,8 +34,8 @@ LL | let _y = &**x; | help: consider assigning a value | -LL | let x: &&i32 = todo!(); - | +++++++++ +LL | let x: &&i32 = &&42; + | ++++++ error[E0381]: partially assigned binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:18:5 diff --git a/tests/ui/borrowck/borrowck-uninit.stderr b/tests/ui/borrowck/borrowck-uninit.stderr index 1e004baa14302..9538baeafd171 100644 --- a/tests/ui/borrowck/borrowck-uninit.stderr +++ b/tests/ui/borrowck/borrowck-uninit.stderr @@ -8,8 +8,8 @@ LL | foo(x); | help: consider assigning a value | -LL | let x: isize = 0; - | +++ +LL | let x: isize = 42; + | ++++ error[E0381]: used binding `a` isn't initialized --> $DIR/borrowck-uninit.rs:14:32 diff --git a/tests/ui/borrowck/borrowck-use-in-index-lvalue.fixed b/tests/ui/borrowck/borrowck-use-in-index-lvalue.fixed new file mode 100644 index 0000000000000..947c7f5b7442a --- /dev/null +++ b/tests/ui/borrowck/borrowck-use-in-index-lvalue.fixed @@ -0,0 +1,11 @@ +//@ run-rustfix +#[allow(unused_mut)] +fn test() { + let w: &mut [isize] = &mut []; + w[5] = 0; //~ ERROR [E0381] + + let mut w: &mut [isize] = &mut []; + w[5] = 0; //~ ERROR [E0381] +} + +fn main() { test(); } diff --git a/tests/ui/borrowck/borrowck-use-in-index-lvalue.rs b/tests/ui/borrowck/borrowck-use-in-index-lvalue.rs index d30b1de5cd00f..a00fda60abbc0 100644 --- a/tests/ui/borrowck/borrowck-use-in-index-lvalue.rs +++ b/tests/ui/borrowck/borrowck-use-in-index-lvalue.rs @@ -1,3 +1,5 @@ +//@ run-rustfix +#[allow(unused_mut)] fn test() { let w: &mut [isize]; w[5] = 0; //~ ERROR [E0381] diff --git a/tests/ui/borrowck/borrowck-use-in-index-lvalue.stderr b/tests/ui/borrowck/borrowck-use-in-index-lvalue.stderr index 18e808f10d0c6..6ec4390ae8d78 100644 --- a/tests/ui/borrowck/borrowck-use-in-index-lvalue.stderr +++ b/tests/ui/borrowck/borrowck-use-in-index-lvalue.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `w` isn't initialized - --> $DIR/borrowck-use-in-index-lvalue.rs:3:5 + --> $DIR/borrowck-use-in-index-lvalue.rs:5:5 | LL | let w: &mut [isize]; | - binding declared here but left uninitialized @@ -8,11 +8,11 @@ LL | w[5] = 0; | help: consider assigning a value | -LL | let w: &mut [isize] = todo!(); +LL | let w: &mut [isize] = &mut []; | +++++++++ error[E0381]: used binding `w` isn't initialized - --> $DIR/borrowck-use-in-index-lvalue.rs:6:5 + --> $DIR/borrowck-use-in-index-lvalue.rs:8:5 | LL | let mut w: &mut [isize]; | ----- binding declared here but left uninitialized @@ -21,7 +21,7 @@ LL | w[5] = 0; | help: consider assigning a value | -LL | let mut w: &mut [isize] = todo!(); +LL | let mut w: &mut [isize] = &mut []; | +++++++++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.fixed b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.fixed new file mode 100644 index 0000000000000..f6ea5f0b6b8d7 --- /dev/null +++ b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.fixed @@ -0,0 +1,12 @@ +// Variation on `borrowck-use-uninitialized-in-cast` in which we do a +// trait cast from an uninitialized source. Issue #20791. +//@ run-rustfix +#![allow(unused_variables, dead_code)] + +trait Foo { fn dummy(&self) { } } +impl Foo for i32 { } + +fn main() { + let x: &i32 = &42; + let y = x as *const dyn Foo; //~ ERROR [E0381] +} diff --git a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs index 3ce7216181494..a384fdbf9504b 100644 --- a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs +++ b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.rs @@ -1,5 +1,7 @@ // Variation on `borrowck-use-uninitialized-in-cast` in which we do a // trait cast from an uninitialized source. Issue #20791. +//@ run-rustfix +#![allow(unused_variables, dead_code)] trait Foo { fn dummy(&self) { } } impl Foo for i32 { } diff --git a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr index dcbaa75333e01..ef04979f1cd45 100644 --- a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr +++ b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `x` isn't initialized - --> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:9:13 + --> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:11:13 | LL | let x: &i32; | - binding declared here but left uninitialized @@ -8,8 +8,8 @@ LL | let y = x as *const dyn Foo; | help: consider assigning a value | -LL | let x: &i32 = todo!(); - | +++++++++ +LL | let x: &i32 = &42; + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.fixed b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.fixed new file mode 100644 index 0000000000000..9c72015d747a4 --- /dev/null +++ b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.fixed @@ -0,0 +1,10 @@ +// Check that we detect unused values that are cast to other things. +// The problem was specified to casting to `*`, as creating unsafe +// pointers was not being fully checked. Issue #20791. +//@ run-rustfix +#![allow(unused_variables)] + +fn main() { + let x: &i32 = &42; + let y = x as *const i32; //~ ERROR [E0381] +} diff --git a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.rs b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.rs index a355a546dc6bf..290deb0f2576b 100644 --- a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.rs +++ b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.rs @@ -1,6 +1,8 @@ // Check that we detect unused values that are cast to other things. // The problem was specified to casting to `*`, as creating unsafe // pointers was not being fully checked. Issue #20791. +//@ run-rustfix +#![allow(unused_variables)] fn main() { let x: &i32; diff --git a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr index 7ccf6a4c3fc8a..22a3b72117980 100644 --- a/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr +++ b/tests/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `x` isn't initialized - --> $DIR/borrowck-use-uninitialized-in-cast.rs:7:13 + --> $DIR/borrowck-use-uninitialized-in-cast.rs:9:13 | LL | let x: &i32; | - binding declared here but left uninitialized @@ -8,8 +8,8 @@ LL | let y = x as *const i32; | help: consider assigning a value | -LL | let x: &i32 = todo!(); - | +++++++++ +LL | let x: &i32 = &42; + | +++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-103250.stderr b/tests/ui/borrowck/issue-103250.stderr index b7ece5d971d89..104bded5b0b53 100644 --- a/tests/ui/borrowck/issue-103250.stderr +++ b/tests/ui/borrowck/issue-103250.stderr @@ -9,8 +9,8 @@ LL | Err(last_error) | help: consider assigning a value | -LL | let mut last_error: Box = todo!(); - | +++++++++ +LL | let mut last_error: Box = Box::new(value); + | +++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-24267-flow-exit.stderr b/tests/ui/borrowck/issue-24267-flow-exit.stderr index 58d1c8c0f73ad..216f8d49b1b0e 100644 --- a/tests/ui/borrowck/issue-24267-flow-exit.stderr +++ b/tests/ui/borrowck/issue-24267-flow-exit.stderr @@ -10,8 +10,8 @@ LL | println!("{}", x); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let x: i32 = 0; - | +++ +LL | let x: i32 = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/issue-24267-flow-exit.rs:18:20 @@ -25,8 +25,8 @@ LL | println!("{}", x); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let x: i32 = 0; - | +++ +LL | let x: i32 = 42; + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr b/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr index e19f37538c16e..8705b8450fc9c 100644 --- a/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr +++ b/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr @@ -9,8 +9,8 @@ LL | ref u if true => {} | help: consider assigning a value | -LL | let e: i32 = 0; - | +++ +LL | let e: i32 = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/suggest-assign-rvalue.stderr b/tests/ui/borrowck/suggest-assign-rvalue.stderr index 92acba640d756..4305539f1b622 100644 --- a/tests/ui/borrowck/suggest-assign-rvalue.stderr +++ b/tests/ui/borrowck/suggest-assign-rvalue.stderr @@ -8,8 +8,8 @@ LL | apple(chaenomeles); | help: consider assigning a value | -LL | let chaenomeles = 0; - | +++ +LL | let chaenomeles = 42; + | ++++ error[E0381]: used binding `my_float` isn't initialized --> $DIR/suggest-assign-rvalue.rs:23:30 @@ -22,8 +22,8 @@ LL | println!("my_float: {}", my_float); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let my_float: f32 = 0.0; - | +++++ +LL | let my_float: f32 = 3.14159; + | +++++++++ error[E0381]: used binding `demo` isn't initialized --> $DIR/suggest-assign-rvalue.rs:26:28 @@ -50,8 +50,8 @@ LL | println!("demo_no: {:?}", demo_no); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let demo_no: DemoNoDef = todo!(); - | +++++++++ +LL | let demo_no: DemoNoDef = value; + | +++++++ error[E0381]: used binding `arr` isn't initialized --> $DIR/suggest-assign-rvalue.rs:34:27 @@ -64,7 +64,7 @@ LL | println!("arr: {:?}", arr); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let arr: [i32; 5] = todo!(); +LL | let arr: [i32; 5] = [42; 5]; | +++++++++ error[E0381]: used binding `foo` isn't initialized @@ -106,8 +106,8 @@ LL | println!("my_int: {}", *my_int); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let my_int: &i32 = todo!(); - | +++++++++ +LL | let my_int: &i32 = &42; + | +++++ error[E0381]: used binding `hello` isn't initialized --> $DIR/suggest-assign-rvalue.rs:49:27 @@ -120,8 +120,8 @@ LL | println!("hello: {}", hello); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let hello: &str = todo!(); - | +++++++++ +LL | let hello: &str = ""; + | ++++ error[E0381]: used binding `never` isn't initialized --> $DIR/suggest-assign-rvalue.rs:53:27 diff --git a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index 8a32f0d99e757..f8ed792e3c675 100644 --- a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -79,8 +79,8 @@ LL | let c1 = || match x { }; | help: consider assigning a value | -LL | let x: u8 = 0; - | +++ +LL | let x: u8 = 42; + | ++++ error: aborting due to 8 previous errors diff --git a/tests/ui/const-generics/const-generic-default-wont-borrowck.fixed b/tests/ui/const-generics/const-generic-default-wont-borrowck.fixed new file mode 100644 index 0000000000000..da48c62df2101 --- /dev/null +++ b/tests/ui/const-generics/const-generic-default-wont-borrowck.fixed @@ -0,0 +1,6 @@ +//@ run-rustfix +pub struct X; + +fn main() {} diff --git a/tests/ui/const-generics/const-generic-default-wont-borrowck.rs b/tests/ui/const-generics/const-generic-default-wont-borrowck.rs index e64adacac9fd2..0d7d87100b7f5 100644 --- a/tests/ui/const-generics/const-generic-default-wont-borrowck.rs +++ b/tests/ui/const-generics/const-generic-default-wont-borrowck.rs @@ -1,4 +1,5 @@ -struct X; diff --git a/tests/ui/const-generics/const-generic-default-wont-borrowck.stderr b/tests/ui/const-generics/const-generic-default-wont-borrowck.stderr index 4cea35f1c8eb9..83e7f88eda79b 100644 --- a/tests/ui/const-generics/const-generic-default-wont-borrowck.stderr +++ b/tests/ui/const-generics/const-generic-default-wont-borrowck.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `s` isn't initialized - --> $DIR/const-generic-default-wont-borrowck.rs:2:26 + --> $DIR/const-generic-default-wont-borrowck.rs:3:26 | LL | let s: &'static str; s.len() | - ^ `*s` used here but it isn't initialized @@ -8,8 +8,8 @@ LL | let s: &'static str; s.len() | help: consider assigning a value | -LL | let s: &'static str = todo!(); s.len() - | +++++++++ +LL | let s: &'static str = ""; s.len() + | ++++ error: aborting due to 1 previous error 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/consts/issue-78655.stderr b/tests/ui/consts/issue-78655.stderr index 5a38d023d6f16..ccaed03b4c1df 100644 --- a/tests/ui/consts/issue-78655.stderr +++ b/tests/ui/consts/issue-78655.stderr @@ -8,8 +8,8 @@ LL | &x | help: consider assigning a value | -LL | let x = 0; - | +++ +LL | let x = 42; + | ++++ error: could not evaluate constant pattern --> $DIR/issue-78655.rs:7:9 diff --git a/tests/ui/drop/repeat-drop-2.stderr b/tests/ui/drop/repeat-drop-2.stderr index 009a2057212f0..cea7baf697664 100644 --- a/tests/ui/drop/repeat-drop-2.stderr +++ b/tests/ui/drop/repeat-drop-2.stderr @@ -32,8 +32,8 @@ LL | let _ = [x; 0]; | help: consider assigning a value | -LL | let x: u8 = 0; - | +++ +LL | let x: u8 = 42; + | ++++ error: aborting due to 3 previous errors 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-27042.stderr b/tests/ui/issues/issue-27042.stderr index 01532de999e3b..ba39399e46eda 100644 --- a/tests/ui/issues/issue-27042.stderr +++ b/tests/ui/issues/issue-27042.stderr @@ -19,7 +19,7 @@ LL | loop { break }; | | | this loop is expected to be of type `i32` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | loop { break 42 }; | ++ 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/loops/loop-break-value.rs b/tests/ui/loops/loop-break-value.rs index c35200520cb5d..d509fc1657054 100644 --- a/tests/ui/loops/loop-break-value.rs +++ b/tests/ui/loops/loop-break-value.rs @@ -23,6 +23,10 @@ fn main() { }; }; + let _: Option = loop { + break; //~ ERROR mismatched types + }; + 'while_loop: while true { //~ WARN denote infinite loops with break; break (); //~ ERROR `break` with value from a `while` loop diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr index a691960f96257..0093182422e1b 100644 --- a/tests/ui/loops/loop-break-value.stderr +++ b/tests/ui/loops/loop-break-value.stderr @@ -1,5 +1,5 @@ warning: label name `'a` shadows a label name that is already in scope - --> $DIR/loop-break-value.rs:136:17 + --> $DIR/loop-break-value.rs:140:17 | LL | 'a: loop { | -- first declared here @@ -8,7 +8,7 @@ LL | let _ = 'a: loop { | ^^ label `'a` already in scope warning: label name `'a` shadows a label name that is already in scope - --> $DIR/loop-break-value.rs:148:17 + --> $DIR/loop-break-value.rs:152:17 | LL | 'a: loop { | -- first declared here @@ -17,7 +17,7 @@ LL | let _ = 'a: loop { | ^^ label `'a` already in scope error[E0425]: cannot find value `LOOP` in this scope - --> $DIR/loop-break-value.rs:95:15 + --> $DIR/loop-break-value.rs:99:15 | LL | 'LOOP: for _ in 0 .. 9 { | ----- a label with a similar name exists @@ -28,7 +28,7 @@ LL | break LOOP; | help: use the similarly named label: `'LOOP` warning: denote infinite loops with `loop { ... }` - --> $DIR/loop-break-value.rs:26:5 + --> $DIR/loop-break-value.rs:30:5 | LL | 'while_loop: while true { | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop` @@ -36,7 +36,7 @@ LL | 'while_loop: while true { = note: `#[warn(while_true)]` on by default error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:28:9 + --> $DIR/loop-break-value.rs:32:9 | LL | 'while_loop: while true { | ----------------------- you can't `break` with a value in a `while` loop @@ -54,7 +54,7 @@ LL | break 'while_loop; | ~~~~~~~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:30:13 + --> $DIR/loop-break-value.rs:34:13 | LL | 'while_loop: while true { | ----------------------- you can't `break` with a value in a `while` loop @@ -68,7 +68,7 @@ LL | break 'while_loop; | ~~~~~~~~~~~~~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:38:12 + --> $DIR/loop-break-value.rs:42:12 | LL | while let Some(_) = Some(()) { | ---------------------------- you can't `break` with a value in a `while` loop @@ -81,7 +81,7 @@ LL | if break { | ~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:43:9 + --> $DIR/loop-break-value.rs:47:9 | LL | while let Some(_) = Some(()) { | ---------------------------- you can't `break` with a value in a `while` loop @@ -94,7 +94,7 @@ LL | break; | ~~~~~ error[E0571]: `break` with value from a `while` loop - --> $DIR/loop-break-value.rs:49:13 + --> $DIR/loop-break-value.rs:53:13 | LL | 'while_let_loop: while let Some(_) = Some(()) { | --------------------------------------------- you can't `break` with a value in a `while` loop @@ -108,7 +108,7 @@ LL | break 'while_let_loop; | ~~~~~~~~~~~~~~~~~~~~~ error[E0571]: `break` with value from a `for` loop - --> $DIR/loop-break-value.rs:56:9 + --> $DIR/loop-break-value.rs:60:9 | LL | for _ in &[1,2,3] { | ----------------- you can't `break` with a value in a `for` loop @@ -121,7 +121,7 @@ LL | break; | ~~~~~ error[E0571]: `break` with value from a `for` loop - --> $DIR/loop-break-value.rs:57:9 + --> $DIR/loop-break-value.rs:61:9 | LL | for _ in &[1,2,3] { | ----------------- you can't `break` with a value in a `for` loop @@ -135,7 +135,7 @@ LL | break; | ~~~~~ error[E0571]: `break` with value from a `for` loop - --> $DIR/loop-break-value.rs:64:13 + --> $DIR/loop-break-value.rs:68:13 | LL | 'for_loop: for _ in &[1,2,3] { | ---------------------------- you can't `break` with a value in a `for` loop @@ -191,7 +191,24 @@ LL | break 'outer_loop "nope"; | ^^^^^^ expected `i32`, found `&str` error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:73:26 + --> $DIR/loop-break-value.rs:27:9 + | +LL | let _: Option = loop { + | - ---- this loop is expected to be of type `Option` + | | + | expected because of this assignment +LL | break; + | ^^^^^ expected `Option`, found `()` + | + = note: expected enum `Option` + found unit type `()` +help: give the `break` a value of the expected type + | +LL | break None; + | ++++ + +error[E0308]: mismatched types + --> $DIR/loop-break-value.rs:77:26 | LL | break; | ----- expected because of this `break` @@ -199,7 +216,7 @@ LL | break 'c 123; | ^^^ expected `()`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:80:15 + --> $DIR/loop-break-value.rs:84:15 | LL | break (break, break); | ^-----^^-----^ @@ -212,7 +229,7 @@ LL | break (break, break); found tuple `(!, !)` error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:85:15 + --> $DIR/loop-break-value.rs:89:15 | LL | break; | ----- expected because of this `break` @@ -220,20 +237,20 @@ LL | break 2; | ^ expected `()`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:90:9 + --> $DIR/loop-break-value.rs:94:9 | LL | break 2; | ------- expected because of this `break` LL | break; | ^^^^^ expected integer, found `()` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | break value; | +++++ error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:108:9 + --> $DIR/loop-break-value.rs:112:9 | LL | break 'a 1; | ---------- expected because of this `break` @@ -241,13 +258,13 @@ LL | break 'a 1; LL | break; | ^^^^^ expected integer, found `()` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | break value; | +++++ error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:120:9 + --> $DIR/loop-break-value.rs:124:9 | LL | break 'a 1; | ---------- expected because of this `break` @@ -255,13 +272,13 @@ LL | break 'a 1; LL | break 'a; | ^^^^^^^^ expected integer, found `()` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | break 'a value; | +++++ error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:131:15 + --> $DIR/loop-break-value.rs:135:15 | LL | break; | ----- expected because of this `break` @@ -270,7 +287,7 @@ LL | break 2; | ^ expected `()`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:140:17 + --> $DIR/loop-break-value.rs:144:17 | LL | break 2; | ------- expected because of this `break` @@ -278,13 +295,13 @@ LL | loop { LL | break 'a; | ^^^^^^^^ expected integer, found `()` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | break 'a value; | +++++ error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:143:15 + --> $DIR/loop-break-value.rs:147:15 | LL | break; | ----- expected because of this `break` @@ -293,7 +310,7 @@ LL | break 2; | ^ expected `()`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:152:17 + --> $DIR/loop-break-value.rs:156:17 | LL | break 'a 2; | ---------- expected because of this `break` @@ -301,13 +318,13 @@ LL | loop { LL | break 'a; | ^^^^^^^^ expected integer, found `()` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | break 'a value; | +++++ error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:155:15 + --> $DIR/loop-break-value.rs:159:15 | LL | break; | ----- expected because of this `break` @@ -316,7 +333,7 @@ LL | break 2; | ^ expected `()`, found integer error[E0308]: mismatched types - --> $DIR/loop-break-value.rs:159:15 + --> $DIR/loop-break-value.rs:163:15 | LL | fn main() { | - expected `()` because of this return type @@ -326,7 +343,7 @@ LL | loop { // point at the return type LL | break 2; | ^ expected `()`, found integer -error: aborting due to 25 previous errors; 3 warnings emitted +error: aborting due to 26 previous errors; 3 warnings emitted Some errors have detailed explanations: E0308, E0425, E0571. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/loops/loop-labeled-break-value.stderr b/tests/ui/loops/loop-labeled-break-value.stderr index 694d6c306f645..3be62316e34a6 100644 --- a/tests/ui/loops/loop-labeled-break-value.stderr +++ b/tests/ui/loops/loop-labeled-break-value.stderr @@ -7,7 +7,7 @@ LL | let _: i32 = loop { break }; | | this loop is expected to be of type `i32` | expected because of this assignment | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | let _: i32 = loop { break 42 }; | ++ @@ -21,7 +21,7 @@ LL | let _: i32 = 'inner: loop { break 'inner }; | | this loop is expected to be of type `i32` | expected because of this assignment | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | let _: i32 = 'inner: loop { break 'inner 42 }; | ++ @@ -35,7 +35,7 @@ LL | let _: i32 = 'inner2: loop { loop { break 'inner2 } }; | | this loop is expected to be of type `i32` | expected because of this assignment | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | let _: i32 = 'inner2: loop { loop { break 'inner2 42 } }; | ++ diff --git a/tests/ui/loops/loop-proper-liveness.stderr b/tests/ui/loops/loop-proper-liveness.stderr index bcd6eb353e525..cd4c064bcd19c 100644 --- a/tests/ui/loops/loop-proper-liveness.stderr +++ b/tests/ui/loops/loop-proper-liveness.stderr @@ -10,8 +10,8 @@ LL | println!("{:?}", x); = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let x: i32 = 0; - | +++ +LL | let x: i32 = 42; + | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/loops/loop-properly-diverging-2.stderr b/tests/ui/loops/loop-properly-diverging-2.stderr index c9f27a6a672c6..ba615f9ae4f1c 100644 --- a/tests/ui/loops/loop-properly-diverging-2.stderr +++ b/tests/ui/loops/loop-properly-diverging-2.stderr @@ -7,7 +7,7 @@ LL | let x: i32 = loop { break }; | | this loop is expected to be of type `i32` | expected because of this assignment | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | let x: i32 = loop { break 42 }; | ++ 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/moves/issue-72649-uninit-in-loop.stderr b/tests/ui/moves/issue-72649-uninit-in-loop.stderr index 7e119fe8cda64..49a5a188cde3b 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/tests/ui/moves/issue-72649-uninit-in-loop.stderr @@ -56,8 +56,8 @@ LL | let _used = value; | help: consider assigning a value | -LL | let value: NonCopy = todo!(); - | +++++++++ +LL | let value: NonCopy = value; + | +++++++ error[E0381]: used binding `value` isn't initialized --> $DIR/issue-72649-uninit-in-loop.rs:69:21 @@ -70,8 +70,8 @@ LL | let _used = value; | help: consider assigning a value | -LL | let mut value: NonCopy = todo!(); - | +++++++++ +LL | let mut value: NonCopy = value; + | +++++++ error: aborting due to 6 previous errors diff --git a/tests/ui/moves/move-into-dead-array-1.stderr b/tests/ui/moves/move-into-dead-array-1.stderr index 83779fb16edb3..d9b719730d692 100644 --- a/tests/ui/moves/move-into-dead-array-1.stderr +++ b/tests/ui/moves/move-into-dead-array-1.stderr @@ -8,8 +8,8 @@ LL | a[i] = d(); | help: consider assigning a value | -LL | let mut a: [D; 4] = todo!(); - | +++++++++ +LL | let mut a: [D; 4] = [value; 4]; + | ++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/moves/move-of-addr-of-mut.stderr b/tests/ui/moves/move-of-addr-of-mut.stderr index 706b52d3402b8..46f7d39a61af2 100644 --- a/tests/ui/moves/move-of-addr-of-mut.stderr +++ b/tests/ui/moves/move-of-addr-of-mut.stderr @@ -9,8 +9,8 @@ LL | std::ptr::addr_of_mut!(x); = note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let mut x: S = todo!(); - | +++++++++ +LL | let mut x: S = value; + | +++++++ error: aborting due to 1 previous error diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr index bab47064f6cdf..02cb9cb22a3f4 100644 --- a/tests/ui/never_type/issue-52443.stderr +++ b/tests/ui/never_type/issue-52443.stderr @@ -36,7 +36,7 @@ error[E0308]: mismatched types LL | [(); loop { break }]; | ^^^^^ expected `usize`, found `()` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | [(); loop { break 42 }]; | ++ diff --git a/tests/ui/nll/match-cfg-fake-edges.stderr b/tests/ui/nll/match-cfg-fake-edges.stderr index d692ded36fa49..066e77b17fc7b 100644 --- a/tests/ui/nll/match-cfg-fake-edges.stderr +++ b/tests/ui/nll/match-cfg-fake-edges.stderr @@ -126,8 +126,8 @@ LL | _ if { x; false } => 2, | help: consider assigning a value | -LL | let x = 0; - | +++ +LL | let x = 42; + | ++++ error[E0381]: used binding `x` isn't initialized --> $DIR/match-cfg-fake-edges.rs:86:31 @@ -142,8 +142,8 @@ LL | _ if let Some(()) = { x; None } => 2, | help: consider assigning a value | -LL | let x = 0; - | +++ +LL | let x = 42; + | ++++ error[E0382]: use of moved value: `x` --> $DIR/match-cfg-fake-edges.rs:99:22 diff --git a/tests/ui/nll/match-on-borrowed.stderr b/tests/ui/nll/match-on-borrowed.stderr index 9273484565a19..4e0b048fb4b5a 100644 --- a/tests/ui/nll/match-on-borrowed.stderr +++ b/tests/ui/nll/match-on-borrowed.stderr @@ -43,8 +43,8 @@ LL | match n {} | help: consider assigning a value | -LL | let n: Never = todo!(); - | +++++++++ +LL | let n: Never = value; + | +++++++ error: aborting due to 4 previous errors 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/type/type-error-break-tail.stderr b/tests/ui/type/type-error-break-tail.stderr index 5ef522fee2a88..81f8f52428d65 100644 --- a/tests/ui/type/type-error-break-tail.stderr +++ b/tests/ui/type/type-error-break-tail.stderr @@ -8,7 +8,7 @@ LL | loop { LL | if false { break; } | ^^^^^ expected `i32`, found `()` | -help: give it a value of the expected type +help: give the `break` a value of the expected type | LL | if false { break 42; } | ++ 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; diff --git a/tests/ui/uninhabited/privately-uninhabited-mir-call.fixed b/tests/ui/uninhabited/privately-uninhabited-mir-call.fixed new file mode 100644 index 0000000000000..76f4251daefbf --- /dev/null +++ b/tests/ui/uninhabited/privately-uninhabited-mir-call.fixed @@ -0,0 +1,31 @@ +// Verifies that MIR building for a call expression respects +// privacy when checking if a call return type is uninhabited. +//@ run-rustfix +#![allow(unreachable_code, unused_variables)] + +pub mod widget { + enum Unimplemented {} + pub struct Widget(Unimplemented); + + impl Widget { + pub fn new() -> Widget { + todo!(); + } + } + + pub fn f() { + let x: &mut u32; + Widget::new(); + // Ok. Widget type returned from new is known to be uninhabited + // and the following code is considered unreachable. + *x = 1; + } +} + +fn main() { + let y: &mut u32 = &mut 42; + widget::Widget::new(); + // Error. Widget type is not known to be uninhabited here, + // so the following code is considered reachable. + *y = 2; //~ ERROR E0381 +} diff --git a/tests/ui/uninhabited/privately-uninhabited-mir-call.rs b/tests/ui/uninhabited/privately-uninhabited-mir-call.rs index 2764bb563d307..1eec57ae04611 100644 --- a/tests/ui/uninhabited/privately-uninhabited-mir-call.rs +++ b/tests/ui/uninhabited/privately-uninhabited-mir-call.rs @@ -1,5 +1,7 @@ // Verifies that MIR building for a call expression respects // privacy when checking if a call return type is uninhabited. +//@ run-rustfix +#![allow(unreachable_code, unused_variables)] pub mod widget { enum Unimplemented {} diff --git a/tests/ui/uninhabited/privately-uninhabited-mir-call.stderr b/tests/ui/uninhabited/privately-uninhabited-mir-call.stderr index 5f2f02c99fb79..9d0771ad79e5a 100644 --- a/tests/ui/uninhabited/privately-uninhabited-mir-call.stderr +++ b/tests/ui/uninhabited/privately-uninhabited-mir-call.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `y` isn't initialized - --> $DIR/privately-uninhabited-mir-call.rs:28:5 + --> $DIR/privately-uninhabited-mir-call.rs:30:5 | LL | let y: &mut u32; | - binding declared here but left uninitialized @@ -9,7 +9,7 @@ LL | *y = 2; | help: consider assigning a value | -LL | let y: &mut u32 = todo!(); +LL | let y: &mut u32 = &mut 42; | +++++++++ error: aborting due to 1 previous error