diff --git a/RELEASES.md b/RELEASES.md index d634feba33ac5..ecf49278f4b52 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -68,6 +68,13 @@ Misc - [`rustc` will now warn about some incorrect uses of `mem::{uninitialized, zeroed}` that are known to cause undefined behaviour.][63346] +Compatibility Notes +------------------- +- Unfortunately the [`x86_64-unknown-uefi` platform can not be built][62785] + with rustc 1.39.0. +- The [`armv7-unknown-linux-gnueabihf` platform is also known to have + issues][62896] for certain crates such as libc. + [60260]: https://github.com/rust-lang/rust/pull/60260/ [61457]: https://github.com/rust-lang/rust/pull/61457/ [61491]: https://github.com/rust-lang/rust/pull/61491/ @@ -79,7 +86,9 @@ Misc [62735]: https://github.com/rust-lang/rust/pull/62735/ [62766]: https://github.com/rust-lang/rust/pull/62766/ [62784]: https://github.com/rust-lang/rust/pull/62784/ +[62785]: https://github.com/rust-lang/rust/issues/62785/ [62814]: https://github.com/rust-lang/rust/pull/62814/ +[62896]: https://github.com/rust-lang/rust/issues/62896/ [63000]: https://github.com/rust-lang/rust/pull/63000/ [63056]: https://github.com/rust-lang/rust/pull/63056/ [63107]: https://github.com/rust-lang/rust/pull/63107/ diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs index dc7fd1adc2958..a39fcd5ad4c58 100644 --- a/src/liballoc/alloc.rs +++ b/src/liballoc/alloc.rs @@ -240,7 +240,7 @@ pub(crate) unsafe fn box_free(ptr: Unique) { #[stable(feature = "global_alloc", since = "1.28.0")] #[rustc_allocator_nounwind] pub fn handle_alloc_error(layout: Layout) -> ! { - #[allow(improper_ctypes)] + #[cfg_attr(bootstrap, allow(improper_ctypes))] extern "Rust" { #[lang = "oom"] fn oom_impl(layout: Layout) -> !; diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 15b7d69c58d24..3d2bc24bf24a5 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -71,7 +71,7 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3 } // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call - #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe + #[cfg_attr(boostrap_stdarch_ignore_this, allow(improper_ctypes))] extern "Rust" { #[lang = "panic_impl"] fn panic_impl(pi: &PanicInfo<'_>) -> !; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index dd290572d7bb7..5906a6388a8bd 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -7,7 +7,7 @@ use crate::lint::{LintPass, LateLintPass, LintArray}; use crate::middle::stability; use crate::session::Session; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use syntax::ast; use syntax::source_map::Span; use syntax::symbol::Symbol; @@ -524,7 +524,7 @@ pub(crate) fn add_elided_lifetime_in_path_suggestion( }; db.span_suggestion( replace_span, - &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }), + &format!("indicate the anonymous lifetime{}", pluralise!(n)), suggestion, Applicability::MachineApplicable ); diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8836a632a7ca8..d833a34385b2d 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -17,7 +17,7 @@ use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use crate::rustc::lint; use crate::session::Session; use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet}; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; @@ -3047,7 +3047,7 @@ pub fn report_missing_lifetime_specifiers( span, E0106, "missing lifetime specifier{}", - if count > 1 { "s" } else { "" } + pluralise!(count) ) } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 1d87484ef09be..c9018f1c290d2 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -33,7 +33,7 @@ use crate::ty::subst::Subst; use crate::ty::SubtypePredicate; use crate::util::nodemap::{FxHashMap, FxHashSet}; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use std::fmt; use syntax::ast; use syntax::symbol::{sym, kw}; @@ -1214,7 +1214,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => format!("{} {}argument{}", arg_length, if distinct && arg_length > 1 { "distinct " } else { "" }, - if arg_length == 1 { "" } else { "s" }), + pluralise!(arg_length)) } }; diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 62910ec320494..5409cbc4129f0 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -196,7 +196,7 @@ impl<'tcx> ty::TyS<'tcx> { let n = tcx.lift_to_global(&n).unwrap(); match n.try_eval_usize(tcx, ty::ParamEnv::empty()) { Some(n) => { - format!("array of {} element{}", n, if n != 1 { "s" } else { "" }).into() + format!("array of {} element{}", n, pluralise!(n)).into() } None => "array".into(), } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 3b8c06ba154c6..40261f6d13739 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -975,7 +975,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes { fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) { let mut vis = ImproperCTypesVisitor { cx }; let abi = cx.tcx.hir().get_foreign_abi(it.hir_id); - if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic { + if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi { + // Don't worry about types in internal ABIs. + } else { match it.node { hir::ForeignItemKind::Fn(ref decl, _, _) => { vis.check_foreign_fn(it.hir_id, decl); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index c3975098351af..2d4af2f606a2c 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -9,7 +9,7 @@ use lint::{LintPass, EarlyLintPass, LateLintPass}; use syntax::ast; use syntax::attr; -use syntax::errors::Applicability; +use syntax::errors::{Applicability, pluralise}; use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use syntax::print::pprust; use syntax::symbol::{kw, sym}; @@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } let ty = cx.tables.expr_ty(&expr); - let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false); + let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", 1); let mut fn_warned = false; let mut op_warned = false; @@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { span: Span, descr_pre: &str, descr_post: &str, - plural: bool, + plural_len: usize, ) -> bool { if ty.is_unit() || cx.tcx.is_ty_uninhabited_from( cx.tcx.hir().get_module_parent(expr.hir_id), ty) @@ -143,13 +143,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { return true; } - let plural_suffix = if plural { "s" } else { "" }; + let plural_suffix = pluralise!(plural_len); match ty.sty { ty::Adt(..) if ty.is_box() => { let boxed_ty = ty.boxed_ty(); let descr_pre = &format!("{}boxed ", descr_pre); - check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural) + check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len) } ty::Adt(def, _) => { check_must_use_def(cx, def.did, span, descr_pre, descr_post) @@ -202,7 +202,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() { let descr_post = &format!(" in tuple element {}", i); let span = *spans.get(i).unwrap_or(&span); - if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) { + if check_must_use_ty( + cx, + ty, + expr, + span, + descr_pre, + descr_post, + plural_len + ) { has_emitted = true; } } @@ -216,7 +224,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { descr_pre, plural_suffix, ); - check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true) + check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, n as usize + 1) } // Otherwise, we don't lint, to avoid false positives. _ => false, diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index 81359c6a46e99..599a0ad0d0c52 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -180,7 +180,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } if Some(DesugaringKind::ForLoop) == move_span.desugaring_kind() { - if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { + let sess = self.infcx.tcx.sess; + if let Ok(snippet) = sess.source_map().span_to_snippet(move_span) { err.span_suggestion( move_span, "consider borrowing to avoid moving into the for loop", diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 96d44b4b4c0dc..0d85be83e12e0 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -26,6 +26,8 @@ use crate::Resolver; use crate::resolve_imports::ImportDirectiveSubclass; +use errors::pluralise; + use rustc::util::nodemap::NodeMap; use rustc::{lint, ty}; use rustc_data_structures::fx::FxHashSet; @@ -295,7 +297,7 @@ impl Resolver<'_> { }).collect::>(); span_snippets.sort(); let msg = format!("unused import{}{}", - if len > 1 { "s" } else { "" }, + pluralise!(len), if !span_snippets.is_empty() { format!(": {}", span_snippets.join(", ")) } else { diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 0c86d8494fde8..df8bd3fa75e14 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -424,7 +424,7 @@ impl<'a> LateResolutionVisitor<'a, '_> { } else { err.note("did you mean to use one of the enum's variants?"); } - }, + } (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => { if let Some((ctor_def, ctor_vis)) = self.r.struct_constructors.get(&def_id).cloned() { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index e77e8290f1faa..360343169bc3d 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -11,7 +11,7 @@ use crate::{Resolver, ResolutionError, Segment, ModuleKind}; use crate::{names_to_string, module_to_string}; use crate::diagnostics::Suggestion; -use errors::Applicability; +use errors::{Applicability, pluralise}; use rustc_data_structures::ptr_key::PtrKey; use rustc::ty; @@ -728,7 +728,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let msg = format!( "unresolved import{} {}", - if paths.len() > 1 { "s" } else { "" }, + pluralise!(paths.len()), paths.join(", "), ); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 09e6b76900396..718d12484f741 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1346,7 +1346,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { span, E0191, "the value of the associated type{} {} must be specified", - if associated_types.len() == 1 { "" } else { "s" }, + pluralise!(associated_types.len()), names, ); let (suggest, potential_assoc_types_spans) = diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 049f2eb16bb00..1ae50b8cb2883 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -17,7 +17,7 @@ use crate::util::common::ErrorReported; use crate::util::nodemap::FxHashMap; use crate::astconv::AstConv as _; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use syntax::ast; use syntax::symbol::{Symbol, kw, sym}; use syntax::source_map::Span; @@ -1178,7 +1178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { struct_span_err!(tcx.sess, span, E0063, "missing field{} {}{} in initializer of `{}`", - if remaining_fields.len() == 1 { "" } else { "s" }, + pluralise!(remaining_fields.len()), remaining_fields_names, truncated_fields_error, adt_ty) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 3e45b1e98d4ec..74e4f28255b16 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -5,7 +5,7 @@ use crate::check::FnCtxt; use crate::middle::lang_items::FnOnceTraitLangItem; use crate::namespace::Namespace; use crate::util::nodemap::FxHashSet; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use rustc::hir::{self, ExprKind, Node, QPath}; use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; @@ -560,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let help = format!("{an}other candidate{s} {were} found in the following \ trait{s}, perhaps add a `use` for {one_of_them}:", an = if candidates.len() == 1 {"an" } else { "" }, - s = if candidates.len() == 1 { "" } else { "s" }, + s = pluralise!(candidates.len()), were = if candidates.len() == 1 { "was" } else { "were" }, one_of_them = if candidates.len() == 1 { "it" diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0eeeee01c82f1..7ff8f9c95c89c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -88,7 +88,7 @@ pub mod intrinsic; mod op; use crate::astconv::{AstConv, PathSeg}; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise}; use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath}; use rustc::hir::def::{CtorOf, Res, DefKind}; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; @@ -4935,5 +4935,5 @@ fn fatally_break_rust(sess: &Session) { } fn potentially_plural_count(count: usize, word: &str) -> String { - format!("{} {}{}", count, word, if count == 1 { "" } else { "s" }) + format!("{} {}{}", count, word, pluralise!(count)) } diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 8502b89de1469..d93a4052cd393 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -1,6 +1,6 @@ use crate::check::FnCtxt; use crate::util::nodemap::FxHashMap; -use errors::{Applicability, DiagnosticBuilder}; +use errors::{Applicability, DiagnosticBuilder, pluralise}; use rustc::hir::{self, PatKind, Pat, HirId}; use rustc::hir::def::{Res, DefKind, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; @@ -684,8 +684,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P], fields: &[ty::FieldDef]) { - let subpats_ending = if subpats.len() == 1 { "" } else { "s" }; - let fields_ending = if fields.len() == 1 { "" } else { "s" }; + let subpats_ending = pluralise!(subpats.len()); + let fields_ending = pluralise!(fields.len()); let res_span = self.tcx.def_span(res.def_id()); struct_span_err!( self.tcx.sess, @@ -1103,10 +1103,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0527, "pattern requires {} element{} but array has {}", min_len, - if min_len != 1 { "s" } else { "" }, + pluralise!(min_len), size, ) - .span_label(span, format!("expected {} element{}", size, if size != 1 { "s" } else { "" })) + .span_label(span, format!("expected {} element{}", size, pluralise!(size))) .emit(); } @@ -1117,14 +1117,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { E0528, "pattern requires at least {} element{} but array has {}", min_len, - if min_len != 1 { "s" } else { "" }, + pluralise!(min_len), size, ).span_label( span, format!( "pattern cannot match array of {} element{}", size, - if size != 1 { "s" } else { "" }, + pluralise!(size), ), ).emit(); } diff --git a/src/libstd/sys/vxworks/fs.rs b/src/libstd/sys/vxworks/fs.rs index d537d2258fda7..51fdb1c0e55ec 100644 --- a/src/libstd/sys/vxworks/fs.rs +++ b/src/libstd/sys/vxworks/fs.rs @@ -529,7 +529,7 @@ pub fn stat(p: &Path) -> io::Result { let p = cstr(p)?; let mut stat: stat64 = unsafe { mem::zeroed() }; cvt(unsafe { - libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _) + libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _) })?; Ok(FileAttr { stat }) } diff --git a/src/libstd/sys/vxworks/os.rs b/src/libstd/sys/vxworks/os.rs index 5dc35a6176bce..f4798da1876cf 100644 --- a/src/libstd/sys/vxworks/os.rs +++ b/src/libstd/sys/vxworks/os.rs @@ -287,28 +287,7 @@ pub fn temp_dir() -> PathBuf { } pub fn home_dir() -> Option { - return crate::env::var_os("HOME").or_else(|| unsafe { - fallback() - }).map(PathBuf::from); - - unsafe fn fallback() -> Option { - let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) { - n if n < 0 => 512 as usize, - n => n as usize, - }; - let mut buf = Vec::with_capacity(amt); - let mut passwd: libc::passwd = mem::zeroed(); - let mut result = ptr::null_mut(); - match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(), - buf.capacity(), &mut result) { - 0 if !result.is_null() => { - let ptr = passwd.pw_dir as *const _; - let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); - Some(OsStringExt::from_vec(bytes)) - }, - _ => None, - } - } + None } pub fn exit(code: i32) -> ! { diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 23735727fe8cf..f9c07e3a2e4ff 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -8,6 +8,7 @@ use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; use smallvec::{smallvec, SmallVec}; +use errors::pluralise; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use syntax_pos::hygiene::{ExpnId, Transparency}; @@ -348,10 +349,10 @@ impl LockstepIterSize { "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}", l_id, l_len, - if l_len != 1 { "s" } else { "" }, + pluralise!(l_len), r_id, r_len, - if r_len != 1 { "s" } else { "" }, + pluralise!(r_len), ); LockstepIterSize::Contradiction(msg) } diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index b74f2492c351f..2d7f4f71ca4ee 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -11,7 +11,7 @@ use crate::ptr::P; use crate::symbol::{kw, sym}; use crate::ThinVec; use crate::util::parser::AssocOp; -use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; +use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise}; use rustc_data_structures::fx::FxHashSet; use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError}; use log::{debug, trace}; @@ -532,15 +532,15 @@ impl<'a> Parser<'a> { self.eat_to_tokens(&[&end]); let span = lo.until(self.token.span); - let plural = number_of_gt > 1 || number_of_shr >= 1; + let total_num_of_gt = number_of_gt + number_of_shr * 2; self.diagnostic() .struct_span_err( span, - &format!("unmatched angle bracket{}", if plural { "s" } else { "" }), + &format!("unmatched angle bracket{}", pluralise!(total_num_of_gt)), ) .span_suggestion( span, - &format!("remove extra angle bracket{}", if plural { "s" } else { "" }), + &format!("remove extra angle bracket{}", pluralise!(total_num_of_gt)), String::new(), Applicability::MachineApplicable, ) diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index 31b28443abbc3..14a93d986b305 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -66,6 +66,10 @@ pub(super) enum LhsExpr { } impl From>> for LhsExpr { + /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)` + /// and `None` into `LhsExpr::NotYetParsed`. + /// + /// This conversion does not allocate. fn from(o: Option>) -> Self { if let Some(attrs) = o { LhsExpr::AttributesParsed(attrs) @@ -76,6 +80,9 @@ impl From>> for LhsExpr { } impl From> for LhsExpr { + /// Converts the `expr: P` into `LhsExpr::AlreadyParsed(expr)`. + /// + /// This conversion does not allocate. fn from(expr: P) -> Self { LhsExpr::AlreadyParsed(expr) } diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs index d4b13cc2e0121..dcd3c64801742 100644 --- a/src/libsyntax/parse/parser/path.rs +++ b/src/libsyntax/parse/parser/path.rs @@ -9,7 +9,7 @@ use crate::symbol::kw; use std::mem; use log::debug; -use errors::{Applicability}; +use errors::{Applicability, pluralise}; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -347,20 +347,19 @@ impl<'a> Parser<'a> { let span = lo.with_hi( lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count) ); - let plural = snapshot.unmatched_angle_bracket_count > 1; self.diagnostic() .struct_span_err( span, &format!( "unmatched angle bracket{}", - if plural { "s" } else { "" } + pluralise!(snapshot.unmatched_angle_bracket_count) ), ) .span_suggestion( span, &format!( "remove extra angle bracket{}", - if plural { "s" } else { "" } + pluralise!(snapshot.unmatched_angle_bracket_count) ), String::new(), Applicability::MachineApplicable, diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs index 465e31ac57e64..5697edd8e4867 100644 --- a/src/libsyntax/parse/parser/ty.rs +++ b/src/libsyntax/parse/parser/ty.rs @@ -11,7 +11,7 @@ use crate::symbol::{kw}; use rustc_target::spec::abi::Abi; -use errors::{Applicability}; +use errors::{Applicability, pluralise}; /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT`, /// `IDENT<::AssocTy>`. @@ -397,7 +397,7 @@ impl<'a> Parser<'a> { } if !negative_bounds.is_empty() || was_negative { - let plural = negative_bounds.len() > 1; + let negative_bounds_len = negative_bounds.len(); let last_span = negative_bounds.last().map(|sp| *sp); let mut err = self.struct_span_err( negative_bounds, @@ -420,7 +420,7 @@ impl<'a> Parser<'a> { } err.span_suggestion_hidden( bound_list, - &format!("remove the trait bound{}", if plural { "s" } else { "" }), + &format!("remove the trait bound{}", pluralise!(negative_bounds_len)), new_bound_list, Applicability::MachineApplicable, ); diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 46c7cbb83de90..26455df17b896 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -5,6 +5,7 @@ use fmt_macros as parse; use errors::DiagnosticBuilder; use errors::Applicability; +use errors::pluralise; use syntax::ast; use syntax::ext::base::{self, *}; @@ -299,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> { &format!( "{} positional argument{} in format string, but {}", count, - if count != 1 { "s" } else { "" }, + pluralise!(count), self.describe_num_args(), ), ); diff --git a/src/test/ui/issues/issue-64559.rs b/src/test/ui/issues/issue-64559.rs new file mode 100644 index 0000000000000..71e054b5d9876 --- /dev/null +++ b/src/test/ui/issues/issue-64559.rs @@ -0,0 +1,6 @@ +fn main() { + let orig = vec![true]; + for _val in orig {} + let _closure = || orig; + //~^ ERROR use of moved value: `orig` +} diff --git a/src/test/ui/issues/issue-64559.stderr b/src/test/ui/issues/issue-64559.stderr new file mode 100644 index 0000000000000..3c685dc8d089a --- /dev/null +++ b/src/test/ui/issues/issue-64559.stderr @@ -0,0 +1,18 @@ +error[E0382]: use of moved value: `orig` + --> $DIR/issue-64559.rs:4:20 + | +LL | let orig = vec![true]; + | ---- move occurs because `orig` has type `std::vec::Vec`, which does not implement the `Copy` trait +LL | for _val in orig {} + | ---- + | | + | value moved here + | help: consider borrowing to avoid moving into the for loop: `&orig` +LL | let _closure = || orig; + | ^^ ---- use occurs due to use in closure + | | + | value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/issues/issue-64593.rs b/src/test/ui/issues/issue-64593.rs new file mode 100644 index 0000000000000..9e787f638a998 --- /dev/null +++ b/src/test/ui/issues/issue-64593.rs @@ -0,0 +1,12 @@ +// check-pass +#![deny(improper_ctypes)] + +pub struct Error(std::num::NonZeroU32); + +extern "Rust" { + fn foo(dest: &mut [u8]) -> Result<(), Error>; +} + +fn main() { + let _ = unsafe { foo(&mut []) }; +}