From 492826ac144666c75d68bc0a0121453ecc08561f Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Sat, 5 Sep 2020 22:37:36 +0200 Subject: [PATCH 01/15] Add a note about the panic behavior of math operations on time objects --- library/std/src/time.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 73c0a7b403a7b..42f1cde3e1c8f 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -100,6 +100,11 @@ pub use core::time::Duration; /// [clock_time_get (Monotonic Clock)]: https://nuxi.nl/cloudabi/#clock_time_get /// /// **Disclaimer:** These system calls might change over time. +/// +/// > Note: mathematical operations like [`add`] may panic if the underlying +/// > structure cannot represent the new point in time. +/// +/// [`add`]: Instant::add #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[stable(feature = "time2", since = "1.8.0")] pub struct Instant(time::Instant); @@ -174,6 +179,11 @@ pub struct Instant(time::Instant); /// [GetSystemTimeAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime /// /// **Disclaimer:** These system calls might change over time. +/// +/// > Note: mathematical operations like [`add`] may panic if the underlying +/// > structure cannot represent the new point in time. +/// +/// [`add`]: SystemTime::add #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[stable(feature = "time2", since = "1.8.0")] pub struct SystemTime(time::SystemTime); From a6ff925f8b5598a1f6d84964525baa1d4a08fd63 Mon Sep 17 00:00:00 2001 From: LingMan Date: Mon, 21 Sep 2020 04:53:44 +0200 Subject: [PATCH 02/15] Reduce boilerplate with the matches! macro Replaces simple bool `match`es of the form match $expr { $pattern => true _ => false } and their inverse with invocations of the matches! macro. --- compiler/rustc_middle/src/hir/map/mod.rs | 16 +- .../rustc_middle/src/mir/interpret/mod.rs | 8 +- .../rustc_middle/src/mir/interpret/value.rs | 10 +- compiler/rustc_middle/src/mir/mod.rs | 73 ++++----- compiler/rustc_middle/src/mir/visit.rs | 63 +++----- .../src/traits/specialization_graph.rs | 5 +- compiler/rustc_middle/src/ty/adjustment.rs | 5 +- compiler/rustc_middle/src/ty/context.rs | 5 +- compiler/rustc_middle/src/ty/diagnostics.rs | 32 ++-- compiler/rustc_middle/src/ty/instance.rs | 8 +- compiler/rustc_middle/src/ty/layout.rs | 5 +- compiler/rustc_middle/src/ty/mod.rs | 34 ++-- compiler/rustc_middle/src/ty/sty.rs | 145 ++++-------------- 13 files changed, 140 insertions(+), 269 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 1e57411f9c54f..9ef1dd038d170 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -535,15 +535,15 @@ impl<'hir> Map<'hir> { Some(Node::Binding(_)) => (), _ => return false, } - match self.find(self.get_parent_node(id)) { + matches!( + self.find(self.get_parent_node(id)), Some( Node::Item(_) | Node::TraitItem(_) | Node::ImplItem(_) | Node::Expr(Expr { kind: ExprKind::Closure(..), .. }), - ) => true, - _ => false, - } + ) + ) } /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context. @@ -554,10 +554,10 @@ impl<'hir> Map<'hir> { /// Whether `hir_id` corresponds to a `mod` or a crate. pub fn is_hir_id_module(&self, hir_id: HirId) -> bool { - match self.get_entry(hir_id).node { - Node::Item(Item { kind: ItemKind::Mod(_), .. }) | Node::Crate(..) => true, - _ => false, - } + matches!( + self.get_entry(hir_id).node, + Node::Item(Item { kind: ItemKind::Mod(_), .. }) | Node::Crate(..) + ) } /// Retrieves the `HirId` for `id`'s enclosing method, unless there's a diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 20363625e42b6..b5beb3babe239 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -486,10 +486,10 @@ impl<'tcx> TyCtxt<'tcx> { // `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true. // However, formatting code relies on function identity (see #58320), so we only do // this for generic functions. Lifetime parameters are ignored. - let is_generic = instance.substs.into_iter().any(|kind| match kind.unpack() { - GenericArgKind::Lifetime(_) => false, - _ => true, - }); + let is_generic = instance + .substs + .into_iter() + .any(|kind| !matches!(kind.unpack(), GenericArgKind::Lifetime(_))); if is_generic { // Get a fresh ID. let mut alloc_map = self.alloc_map.lock(); diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 1f547d9dc3a43..e5c7d496bacad 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -445,19 +445,13 @@ impl<'tcx, Tag> Scalar { /// Do not call this method! Dispatch based on the type instead. #[inline] pub fn is_bits(self) -> bool { - match self { - Scalar::Raw { .. } => true, - _ => false, - } + matches!(self, Scalar::Raw { .. }) } /// Do not call this method! Dispatch based on the type instead. #[inline] pub fn is_ptr(self) -> bool { - match self { - Scalar::Ptr(_) => true, - _ => false, - } + matches!(self, Scalar::Ptr(_)) } pub fn to_bool(self) -> InterpResult<'tcx, bool> { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 8ff75bf392e69..03071e716e8f2 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -935,67 +935,59 @@ impl<'tcx> LocalDecl<'tcx> { /// - `let x = ...`, /// - or `match ... { C(x) => ... }` pub fn can_be_made_mutable(&self) -> bool { - match self.local_info { - Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { - binding_mode: ty::BindingMode::BindByValue(_), - opt_ty_info: _, - opt_match_place: _, - pat_span: _, - })))) => true, - - Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf( - ImplicitSelfKind::Imm, - )))) => true, - - _ => false, - } + matches!( + self.local_info, + Some(box LocalInfo::User(ClearCrossCrate::Set( + BindingForm::Var(VarBindingForm { + binding_mode: ty::BindingMode::BindByValue(_), + opt_ty_info: _, + opt_match_place: _, + pat_span: _, + }) + | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm), + ))) + ) } /// Returns `true` if local is definitely not a `ref ident` or /// `ref mut ident` binding. (Such bindings cannot be made into /// mutable bindings, but the inverse does not necessarily hold). pub fn is_nonref_binding(&self) -> bool { - match self.local_info { - Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { - binding_mode: ty::BindingMode::BindByValue(_), - opt_ty_info: _, - opt_match_place: _, - pat_span: _, - })))) => true, - - Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_)))) => true, - - _ => false, - } + matches!( + self.local_info, + Some(box LocalInfo::User(ClearCrossCrate::Set( + BindingForm::Var(VarBindingForm { + binding_mode: ty::BindingMode::BindByValue(_), + opt_ty_info: _, + opt_match_place: _, + pat_span: _, + }) + | BindingForm::ImplicitSelf(_), + ))) + ) } /// Returns `true` if this variable is a named variable or function /// parameter declared by the user. #[inline] pub fn is_user_variable(&self) -> bool { - match self.local_info { - Some(box LocalInfo::User(_)) => true, - _ => false, - } + matches!(self.local_info, Some(box LocalInfo::User(_))) } /// Returns `true` if this is a reference to a variable bound in a `match` /// expression that is used to access said variable for the guard of the /// match arm. pub fn is_ref_for_guard(&self) -> bool { - match self.local_info { - Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard))) => true, - _ => false, - } + matches!( + self.local_info, + Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard))) + ) } /// Returns `Some` if this is a reference to a static item that is used to /// access that static pub fn is_ref_to_static(&self) -> bool { - match self.local_info { - Some(box LocalInfo::StaticRef { .. }) => true, - _ => false, - } + matches!(self.local_info, Some(box LocalInfo::StaticRef { .. })) } /// Returns `Some` if this is a reference to a static item that is used to @@ -2124,10 +2116,7 @@ pub enum BinOp { impl BinOp { pub fn is_checkable(self) -> bool { use self::BinOp::*; - match self { - Add | Sub | Mul | Shl | Shr => true, - _ => false, - } + matches!(self, Add | Sub | Mul | Shl | Shr) } } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index a008bd5f75fa0..f4d57dffacf0c 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1164,82 +1164,63 @@ pub enum PlaceContext { impl PlaceContext { /// Returns `true` if this place context represents a drop. pub fn is_drop(&self) -> bool { - match *self { - PlaceContext::MutatingUse(MutatingUseContext::Drop) => true, - _ => false, - } + matches!(self, PlaceContext::MutatingUse(MutatingUseContext::Drop)) } /// Returns `true` if this place context represents a borrow. pub fn is_borrow(&self) -> bool { - match *self { + matches!( + self, PlaceContext::NonMutatingUse( NonMutatingUseContext::SharedBorrow - | NonMutatingUseContext::ShallowBorrow - | NonMutatingUseContext::UniqueBorrow, - ) - | PlaceContext::MutatingUse(MutatingUseContext::Borrow) => true, - _ => false, - } + | NonMutatingUseContext::ShallowBorrow + | NonMutatingUseContext::UniqueBorrow + ) | PlaceContext::MutatingUse(MutatingUseContext::Borrow) + ) } /// Returns `true` if this place context represents a storage live or storage dead marker. pub fn is_storage_marker(&self) -> bool { - match *self { - PlaceContext::NonUse(NonUseContext::StorageLive | NonUseContext::StorageDead) => true, - _ => false, - } + matches!( + self, + PlaceContext::NonUse(NonUseContext::StorageLive | NonUseContext::StorageDead) + ) } /// Returns `true` if this place context represents a storage live marker. pub fn is_storage_live_marker(&self) -> bool { - match *self { - PlaceContext::NonUse(NonUseContext::StorageLive) => true, - _ => false, - } + matches!(self, PlaceContext::NonUse(NonUseContext::StorageLive)) } /// Returns `true` if this place context represents a storage dead marker. pub fn is_storage_dead_marker(&self) -> bool { - match *self { - PlaceContext::NonUse(NonUseContext::StorageDead) => true, - _ => false, - } + matches!(self, PlaceContext::NonUse(NonUseContext::StorageDead)) } /// Returns `true` if this place context represents a use that potentially changes the value. pub fn is_mutating_use(&self) -> bool { - match *self { - PlaceContext::MutatingUse(..) => true, - _ => false, - } + matches!(self, PlaceContext::MutatingUse(..)) } /// Returns `true` if this place context represents a use that does not change the value. pub fn is_nonmutating_use(&self) -> bool { - match *self { - PlaceContext::NonMutatingUse(..) => true, - _ => false, - } + matches!(self, PlaceContext::NonMutatingUse(..)) } /// Returns `true` if this place context represents a use. pub fn is_use(&self) -> bool { - match *self { - PlaceContext::NonUse(..) => false, - _ => true, - } + !matches!(self, PlaceContext::NonUse(..)) } /// Returns `true` if this place context represents an assignment statement. pub fn is_place_assignment(&self) -> bool { - match *self { + matches!( + self, PlaceContext::MutatingUse( MutatingUseContext::Store - | MutatingUseContext::Call - | MutatingUseContext::AsmOutput, - ) => true, - _ => false, - } + | MutatingUseContext::Call + | MutatingUseContext::AsmOutput, + ) + ) } } diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 969404c68cab7..ec6010e6eecf4 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -79,10 +79,7 @@ pub enum Node { impl<'tcx> Node { pub fn is_from_trait(&self) -> bool { - match *self { - Node::Trait(..) => true, - _ => false, - } + matches!(self, Node::Trait(..)) } /// Iterate over the items defined directly by the given (impl or trait) node. diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 46ef5ff7dd8c5..89d0e13955122 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -85,10 +85,7 @@ pub struct Adjustment<'tcx> { impl Adjustment<'tcx> { pub fn is_region_borrow(&self) -> bool { - match self.kind { - Adjust::Borrow(AutoBorrow::Ref(..)) => true, - _ => false, - } + matches!(self.kind, Adjust::Borrow(AutoBorrow::Ref(..))) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index cd8f12a4f3576..d2c7d6e328f71 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -588,10 +588,7 @@ impl<'tcx> TypeckResults<'tcx> { return false; } - match self.type_dependent_defs().get(expr.hir_id) { - Some(Ok((DefKind::AssocFn, _))) => true, - _ => false, - } + matches!(self.type_dependent_defs().get(expr.hir_id), Some(Ok((DefKind::AssocFn, _)))) } pub fn extract_binding_mode(&self, s: &Session, id: HirId, sp: Span) -> Option { diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 715319747e390..65703d04c7040 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -11,21 +11,16 @@ use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate}; impl<'tcx> TyS<'tcx> { /// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive. pub fn is_primitive_ty(&self) -> bool { - match self.kind() { - Bool - | Char - | Str - | Int(_) - | Uint(_) - | Float(_) + matches!( + self.kind(), + Bool | Char | Str | Int(_) | Uint(_) | Float(_) | Infer( InferTy::IntVar(_) | InferTy::FloatVar(_) | InferTy::FreshIntTy(_) - | InferTy::FreshFloatTy(_), - ) => true, - _ => false, - } + | InferTy::FreshFloatTy(_) + ) + ) } /// Whether the type is succinctly representable as a type instead of just referred to with a @@ -64,11 +59,16 @@ impl<'tcx> TyS<'tcx> { /// Whether the type can be safely suggested during error recovery. pub fn is_suggestable(&self) -> bool { - match self.kind() { - Opaque(..) | FnDef(..) | FnPtr(..) | Dynamic(..) | Closure(..) | Infer(..) - | Projection(..) => false, - _ => true, - } + !matches!( + self.kind(), + Opaque(..) + | FnDef(..) + | FnPtr(..) + | Dynamic(..) + | Closure(..) + | Infer(..) + | Projection(..) + ) } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index a6b62097d5b18..e527d6dc34cf1 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -183,10 +183,10 @@ impl<'tcx> InstanceDef<'tcx> { ty::InstanceDef::DropGlue(_, Some(_)) => return false, _ => return true, }; - match tcx.def_key(def_id).disambiguated_data.data { - DefPathData::Ctor | DefPathData::ClosureExpr => true, - _ => false, - } + matches!( + tcx.def_key(def_id).disambiguated_data.data, + DefPathData::Ctor | DefPathData::ClosureExpr + ) } /// Returns `true` if the machine code for this instance is instantiated in diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index b0a1413a9d62f..4e2dac0fd8c9c 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2628,10 +2628,7 @@ where target.target_os == "linux" && target.arch == "sparc64" && target_env_gnu_like; let linux_powerpc_gnu_like = target.target_os == "linux" && target.arch == "powerpc" && target_env_gnu_like; - let rust_abi = match sig.abi { - RustIntrinsic | PlatformIntrinsic | Rust | RustCall => true, - _ => false, - }; + let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall); // Handle safe Rust thin and fat pointers. let adjust_for_rust_scalar = |attrs: &mut ArgAttributes, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f23d666cfcfdd..eaf8037d6099e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2675,15 +2675,15 @@ impl<'tcx> ClosureKind { /// Returns `true` if this a type that impls this closure kind /// must also implement `other`. pub fn extends(self, other: ty::ClosureKind) -> bool { - match (self, other) { - (ClosureKind::Fn, ClosureKind::Fn) => true, - (ClosureKind::Fn, ClosureKind::FnMut) => true, - (ClosureKind::Fn, ClosureKind::FnOnce) => true, - (ClosureKind::FnMut, ClosureKind::FnMut) => true, - (ClosureKind::FnMut, ClosureKind::FnOnce) => true, - (ClosureKind::FnOnce, ClosureKind::FnOnce) => true, - _ => false, - } + matches!( + (self, other), + (ClosureKind::Fn, ClosureKind::Fn) + | (ClosureKind::Fn, ClosureKind::FnMut) + | (ClosureKind::Fn, ClosureKind::FnOnce) + | (ClosureKind::FnMut, ClosureKind::FnMut) + | (ClosureKind::FnMut, ClosureKind::FnOnce) + | (ClosureKind::FnOnce, ClosureKind::FnOnce) + ) } /// Returns the representative scalar type for this closure kind. @@ -2809,15 +2809,15 @@ impl<'tcx> TyCtxt<'tcx> { pub fn opt_associated_item(self, def_id: DefId) -> Option<&'tcx AssocItem> { let is_associated_item = if let Some(def_id) = def_id.as_local() { - match self.hir().get(self.hir().local_def_id_to_hir_id(def_id)) { - Node::TraitItem(_) | Node::ImplItem(_) => true, - _ => false, - } + matches!( + self.hir().get(self.hir().local_def_id_to_hir_id(def_id)), + Node::TraitItem(_) | Node::ImplItem(_) + ) } else { - match self.def_kind(def_id) { - DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy => true, - _ => false, - } + matches!( + self.def_kind(def_id), + DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy + ) }; is_associated_item.then(|| self.associated_item(def_id)) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 724ec101b23b7..5cba451ea6e3c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1763,10 +1763,7 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_never(&self) -> bool { - match self.kind() { - Never => true, - _ => false, - } + matches!(self.kind(), Never) } /// Checks whether a type is definitely uninhabited. This is @@ -1823,34 +1820,22 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_adt(&self) -> bool { - match self.kind() { - Adt(..) => true, - _ => false, - } + matches!(self.kind(), Adt(..)) } #[inline] pub fn is_ref(&self) -> bool { - match self.kind() { - Ref(..) => true, - _ => false, - } + matches!(self.kind(), Ref(..)) } #[inline] pub fn is_ty_var(&self) -> bool { - match self.kind() { - Infer(TyVar(_)) => true, - _ => false, - } + matches!(self.kind(), Infer(TyVar(_))) } #[inline] pub fn is_ty_infer(&self) -> bool { - match self.kind() { - Infer(_) => true, - _ => false, - } + matches!(self.kind(), Infer(_)) } #[inline] @@ -1880,20 +1865,14 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_slice(&self) -> bool { match self.kind() { - RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => match ty.kind() { - Slice(_) | Str => true, - _ => false, - }, + RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => matches!(ty.kind(), Slice(_) | Str), _ => false, } } #[inline] pub fn is_array(&self) -> bool { - match self.kind() { - Array(..) => true, - _ => false, - } + matches!(self.kind(), Array(..)) } #[inline] @@ -1940,27 +1919,21 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_region_ptr(&self) -> bool { - match self.kind() { - Ref(..) => true, - _ => false, - } + matches!(self.kind(), Ref(..)) } #[inline] pub fn is_mutable_ptr(&self) -> bool { - match self.kind() { + matches!( + self.kind(), RawPtr(TypeAndMut { mutbl: hir::Mutability::Mut, .. }) - | Ref(_, _, hir::Mutability::Mut) => true, - _ => false, - } + | Ref(_, _, hir::Mutability::Mut) + ) } #[inline] pub fn is_unsafe_ptr(&self) -> bool { - match self.kind() { - RawPtr(_) => true, - _ => false, - } + matches!(self.kind(), RawPtr(_)) } /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer). @@ -1990,35 +1963,22 @@ impl<'tcx> TyS<'tcx> { /// contents are abstract to rustc.) #[inline] pub fn is_scalar(&self) -> bool { - match self.kind() { - Bool - | Char - | Int(_) - | Float(_) - | Uint(_) + matches!( + self.kind(), + Bool | Char | Int(_) | Float(_) | Uint(_) | FnDef(..) | FnPtr(_) | RawPtr(_) | Infer(IntVar(_) | FloatVar(_)) - | FnDef(..) - | FnPtr(_) - | RawPtr(_) => true, - _ => false, - } + ) } /// Returns `true` if this type is a floating point type. #[inline] pub fn is_floating_point(&self) -> bool { - match self.kind() { - Float(_) | Infer(FloatVar(_)) => true, - _ => false, - } + matches!(self.kind(), Float(_) | Infer(FloatVar(_))) } #[inline] pub fn is_trait(&self) -> bool { - match self.kind() { - Dynamic(..) => true, - _ => false, - } + matches!(self.kind(), Dynamic(..)) } #[inline] @@ -2031,52 +1991,32 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_closure(&self) -> bool { - match self.kind() { - Closure(..) => true, - _ => false, - } + matches!(self.kind(), Closure(..)) } #[inline] pub fn is_generator(&self) -> bool { - match self.kind() { - Generator(..) => true, - _ => false, - } + matches!(self.kind(), Generator(..)) } #[inline] pub fn is_integral(&self) -> bool { - match self.kind() { - Infer(IntVar(_)) | Int(_) | Uint(_) => true, - _ => false, - } + matches!(self.kind(), Infer(IntVar(_)) | Int(_) | Uint(_)) } #[inline] pub fn is_fresh_ty(&self) -> bool { - match self.kind() { - Infer(FreshTy(_)) => true, - _ => false, - } + matches!(self.kind(), Infer(FreshTy(_))) } #[inline] pub fn is_fresh(&self) -> bool { - match self.kind() { - Infer(FreshTy(_)) => true, - Infer(FreshIntTy(_)) => true, - Infer(FreshFloatTy(_)) => true, - _ => false, - } + matches!(self.kind(), Infer(FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_))) } #[inline] pub fn is_char(&self) -> bool { - match self.kind() { - Char => true, - _ => false, - } + matches!(self.kind(), Char) } #[inline] @@ -2086,34 +2026,22 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_signed(&self) -> bool { - match self.kind() { - Int(_) => true, - _ => false, - } + matches!(self.kind(), Int(_)) } #[inline] pub fn is_ptr_sized_integral(&self) -> bool { - match self.kind() { - Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true, - _ => false, - } + matches!(self.kind(), Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize)) } #[inline] pub fn is_machine(&self) -> bool { - match self.kind() { - Int(..) | Uint(..) | Float(..) => true, - _ => false, - } + matches!(self.kind(), Int(..) | Uint(..) | Float(..)) } #[inline] pub fn has_concrete_skeleton(&self) -> bool { - match self.kind() { - Param(_) | Infer(_) | Error(_) => false, - _ => true, - } + !matches!(self.kind(), Param(_) | Infer(_) | Error(_)) } /// Returns the type and mutability of `*ty`. @@ -2156,26 +2084,17 @@ impl<'tcx> TyS<'tcx> { #[inline] pub fn is_fn(&self) -> bool { - match self.kind() { - FnDef(..) | FnPtr(_) => true, - _ => false, - } + matches!(self.kind(), FnDef(..) | FnPtr(_)) } #[inline] pub fn is_fn_ptr(&self) -> bool { - match self.kind() { - FnPtr(_) => true, - _ => false, - } + matches!(self.kind(), FnPtr(_)) } #[inline] pub fn is_impl_trait(&self) -> bool { - match self.kind() { - Opaque(..) => true, - _ => false, - } + matches!(self.kind(), Opaque(..)) } #[inline] From b4e77d21bcf8b15ef7d873005382ba8ca309faf5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 15 Jun 2020 11:50:58 -0400 Subject: [PATCH 03/15] rewrite old test so that its attributes are consistent with what we want in the language. (Note that the fact this test existed is a slight sign that we may need a crater run on this bugfix...) --- .../ui/rfc-2565-param-attrs/param-attrs-allowed.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs index 1217f89cb3168..a547d09d04822 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs @@ -8,8 +8,8 @@ extern "C" { #[allow(unused_mut)] a: i32, #[cfg(something)] b: i32, #[cfg_attr(something, cfg(nothing))] c: i32, - #[deny(unused_mut)] d: i32, - #[forbid(unused_mut)] #[warn(unused_mut)] ... + #[forbid(unused_mut)] d: i32, + #[deny(unused_mut)] #[warn(unused_mut)] ... ); } @@ -17,16 +17,16 @@ type FnType = fn( #[allow(unused_mut)] a: i32, #[cfg(something)] b: i32, #[cfg_attr(something, cfg(nothing))] c: i32, - #[deny(unused_mut)] d: i32, - #[forbid(unused_mut)] #[warn(unused_mut)] e: i32 + #[forbid(unused_mut)] d: i32, + #[deny(unused_mut)] #[warn(unused_mut)] e: i32 ); pub fn foo( #[allow(unused_mut)] a: i32, #[cfg(something)] b: i32, #[cfg_attr(something, cfg(nothing))] c: i32, - #[deny(unused_mut)] d: i32, - #[forbid(unused_mut)] #[warn(unused_mut)] _e: i32 + #[forbid(unused_mut)] d: i32, + #[deny(unused_mut)] #[warn(unused_mut)] _e: i32 ) {} // self From 9601724b11bbd9081b1bee6f7e478a5d2b9ace41 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sun, 4 Oct 2020 12:39:39 +0000 Subject: [PATCH 04/15] Avoid unchecked casts in net parser --- library/std/src/net/parser.rs | 69 +++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index 0570a7c41bfe6..da94a5735034f 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -6,11 +6,34 @@ #[cfg(test)] mod tests; +use crate::convert::TryInto as _; use crate::error::Error; use crate::fmt; use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use crate::str::FromStr; +trait ReadNumberHelper: crate::marker::Sized { + const ZERO: Self; + fn checked_mul(&self, other: u32) -> Option; + fn checked_add(&self, other: u32) -> Option; +} + +macro_rules! impl_helper { + ($($t:ty)*) => ($(impl ReadNumberHelper for $t { + const ZERO: Self = 0; + #[inline] + fn checked_mul(&self, other: u32) -> Option { + Self::checked_mul(*self, other.try_into().ok()?) + } + #[inline] + fn checked_add(&self, other: u32) -> Option { + Self::checked_add(*self, other.try_into().ok()?) + } + })*) +} + +impl_helper! { u8 u16 } + struct Parser<'a> { // parsing as ASCII, so can use byte array state: &'a [u8], @@ -59,7 +82,7 @@ impl<'a> Parser<'a> { fn read_char(&mut self) -> Option { self.state.split_first().map(|(&b, tail)| { self.state = tail; - b as char + char::from(b) }) } @@ -84,25 +107,26 @@ impl<'a> Parser<'a> { }) } - // Read a single digit in the given radix. For instance, 0-9 in radix 10; - // 0-9A-F in radix 16. - fn read_digit(&mut self, radix: u32) -> Option { - self.read_atomically(move |p| p.read_char()?.to_digit(radix)) - } - // Read a number off the front of the input in the given radix, stopping // at the first non-digit character or eof. Fails if the number has more - // digits than max_digits, or the value is >= upto, or if there is no number. - fn read_number(&mut self, radix: u32, max_digits: u32, upto: u32) -> Option { + // digits than max_digits or if there is no number. + fn read_number( + &mut self, + radix: u32, + max_digits: Option, + ) -> Option { self.read_atomically(move |p| { - let mut result = 0; + let mut result = T::ZERO; let mut digit_count = 0; - while let Some(digit) = p.read_digit(radix) { - result = (result * radix) + digit; + while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { + result = result.checked_mul(radix)?; + result = result.checked_add(digit)?; digit_count += 1; - if digit_count > max_digits || result >= upto { - return None; + if let Some(max_digits) = max_digits { + if digit_count > max_digits { + return None; + } } } @@ -116,7 +140,7 @@ impl<'a> Parser<'a> { let mut groups = [0; 4]; for (i, slot) in groups.iter_mut().enumerate() { - *slot = p.read_separator('.', i, |p| p.read_number(10, 3, 0x100))? as u8; + *slot = p.read_separator('.', i, |p| p.read_number(10, None))?; } Some(groups.into()) @@ -140,17 +164,17 @@ impl<'a> Parser<'a> { let ipv4 = p.read_separator(':', i, |p| p.read_ipv4_addr()); if let Some(v4_addr) = ipv4 { - let octets = v4_addr.octets(); - groups[i + 0] = ((octets[0] as u16) << 8) | (octets[1] as u16); - groups[i + 1] = ((octets[2] as u16) << 8) | (octets[3] as u16); + let [one, two, three, four] = v4_addr.octets(); + groups[i + 0] = u16::from_be_bytes([one, two]); + groups[i + 1] = u16::from_be_bytes([three, four]); return (i + 2, true); } } - let group = p.read_separator(':', i, |p| p.read_number(16, 4, 0x10000)); + let group = p.read_separator(':', i, |p| p.read_number(16, Some(4))); match group { - Some(g) => *slot = g as u16, + Some(g) => *slot = g, None => return (i, false), } } @@ -195,12 +219,11 @@ impl<'a> Parser<'a> { self.read_ipv4_addr().map(IpAddr::V4).or_else(move || self.read_ipv6_addr().map(IpAddr::V6)) } - /// Read a : followed by a port in base 10 + /// Read a : followed by a port in base 10. fn read_port(&mut self) -> Option { self.read_atomically(|p| { let _ = p.read_given_char(':')?; - let port = p.read_number(10, 5, 0x10000)?; - Some(port as u16) + p.read_number(10, None) }) } From f78a7ade61c1c218eead76854abb7d83bb6c6f75 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sun, 4 Oct 2020 17:07:30 +0000 Subject: [PATCH 05/15] Inline "eof" methods --- library/std/src/net/parser.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index da94a5735034f..3a5fd8f6f5d0e 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -44,10 +44,6 @@ impl<'a> Parser<'a> { Parser { state: input.as_bytes() } } - fn is_eof(&self) -> bool { - self.state.is_empty() - } - /// Run a parser, and restore the pre-parse state if it fails fn read_atomically(&mut self, inner: F) -> Option where @@ -63,19 +59,12 @@ impl<'a> Parser<'a> { /// Run a parser, but fail if the entire input wasn't consumed. /// Doesn't run atomically. - fn read_till_eof(&mut self, inner: F) -> Option - where - F: FnOnce(&mut Parser<'_>) -> Option, - { - inner(self).filter(|_| self.is_eof()) - } - - /// Same as read_till_eof, but returns a Result on failure fn parse_with(&mut self, inner: F) -> Result where F: FnOnce(&mut Parser<'_>) -> Option, { - self.read_till_eof(inner).ok_or(AddrParseError(())) + let result = inner(self); + if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(())) } /// Read the next character from the input From afa2a675453091773eb9dd1b19389725526224b9 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Mon, 15 Jun 2020 14:17:35 -0400 Subject: [PATCH 06/15] Prevent forbid from being ignored if overriden at the same level. That is, this changes `#[forbid(foo)] #[allow(foo)]` from allowing foo to forbidding foo. --- compiler/rustc_lint/src/levels.rs | 47 ++++++++++++++++-- compiler/rustc_middle/src/lint.rs | 20 +++++++- ...0819-dont-override-forbid-in-same-scope.rs | 49 +++++++++++++++++++ ...-dont-override-forbid-in-same-scope.stderr | 29 +++++++++++ src/tools/clippy/tests/ui/attrs.rs | 1 - src/tools/clippy/tests/ui/attrs.stderr | 16 ++---- 6 files changed, 144 insertions(+), 18 deletions(-) create mode 100644 src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs create mode 100644 src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 48254dcee82fe..222333a578b7d 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -10,6 +10,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::{intravisit, HirId}; use rustc_middle::hir::map::Map; +use rustc_middle::lint::LevelSource; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::lint::{struct_lint_level, LintLevelMap, LintLevelSets, LintSet, LintSource}; use rustc_middle::ty::query::Providers; @@ -95,6 +96,44 @@ impl<'s> LintLevelsBuilder<'s> { self.sets.list.push(LintSet::CommandLine { specs }); } + /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful + /// (e.g. if a forbid was already inserted on the same scope), then emits a + /// diagnostic with no change to `specs`. + fn insert_spec( + &mut self, + specs: &mut FxHashMap, + id: LintId, + (level, src): LevelSource, + ) { + if let Some((old_level, old_src)) = specs.get(&id) { + if old_level == &Level::Forbid && level != Level::Forbid { + let mut diag_builder = struct_span_err!( + self.sess, + src.span(), + E0453, + "{}({}) incompatible with previous forbid in same scope", + level.as_str(), + src.name(), + ); + match *old_src { + LintSource::Default => {} + LintSource::Node(_, forbid_source_span, reason) => { + diag_builder.span_label(forbid_source_span, "`forbid` level set here"); + if let Some(rationale) = reason { + diag_builder.note(&rationale.as_str()); + } + } + LintSource::CommandLine(_) => { + diag_builder.note("`forbid` lint level was set on command line"); + } + } + diag_builder.emit(); + return; + } + } + specs.insert(id, (level, src)); + } + /// Pushes a list of AST lint attributes onto this context. /// /// This function will return a `BuilderPush` object which should be passed @@ -109,7 +148,7 @@ impl<'s> LintLevelsBuilder<'s> { /// `#[allow]` /// /// Don't forget to call `pop`! - pub fn push( + pub(crate) fn push( &mut self, attrs: &[ast::Attribute], store: &LintStore, @@ -221,7 +260,7 @@ impl<'s> LintLevelsBuilder<'s> { let src = LintSource::Node(name, li.span(), reason); for &id in ids { self.check_gated_lint(id, attr.span); - specs.insert(id, (level, src)); + self.insert_spec(&mut specs, id, (level, src)); } } @@ -235,7 +274,7 @@ impl<'s> LintLevelsBuilder<'s> { reason, ); for id in ids { - specs.insert(*id, (level, src)); + self.insert_spec(&mut specs, *id, (level, src)); } } Err((Some(ids), new_lint_name)) => { @@ -272,7 +311,7 @@ impl<'s> LintLevelsBuilder<'s> { reason, ); for id in ids { - specs.insert(*id, (level, src)); + self.insert_spec(&mut specs, *id, (level, src)); } } Err((None, _)) => { diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 25e5379881e70..91e1d6e0b0b72 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -9,7 +9,7 @@ use rustc_session::lint::{builtin, Level, Lint, LintId}; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; -use rustc_span::{Span, Symbol}; +use rustc_span::{symbol, Span, Symbol, DUMMY_SP}; /// How a lint level was set. #[derive(Clone, Copy, PartialEq, Eq, HashStable)] @@ -25,6 +25,24 @@ pub enum LintSource { CommandLine(Symbol), } +impl LintSource { + pub fn name(&self) -> Symbol { + match *self { + LintSource::Default => symbol::kw::Default, + LintSource::Node(name, _, _) => name, + LintSource::CommandLine(name) => name, + } + } + + pub fn span(&self) -> Span { + match *self { + LintSource::Default => DUMMY_SP, + LintSource::Node(_, span, _) => span, + LintSource::CommandLine(_) => DUMMY_SP, + } + } +} + pub type LevelSource = (Level, LintSource); pub struct LintLevelSets { diff --git a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs new file mode 100644 index 0000000000000..8e25227b59e63 --- /dev/null +++ b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs @@ -0,0 +1,49 @@ +// This test is checking that you cannot override a `forbid` by adding in other +// attributes later in the same scope. (We already ensure that you cannot +// override it in nested scopes). + +// If you turn off deduplicate diagnostics (which rustc turns on by default but +// compiletest turns off when it runs ui tests), then the errors are +// (unfortunately) repeated here because the checking is done as we read in the +// errors, and curretly that happens two or three different times, depending on +// compiler flags. +// +// I decided avoiding the redundant output was not worth the time in engineering +// effort for bug like this, which 1. end users are unlikely to run into in the +// first place, and 2. they won't see the redundant output anyway. + +// compile-flags: -Z deduplicate-diagnostics=yes + +fn forbid_first(num: i32) -> i32 { + #![forbid(unused)] + #![deny(unused)] + //~^ ERROR: deny(unused) incompatible with previous forbid in same scope [E0453] + #![warn(unused)] + //~^ ERROR: warn(unused) incompatible with previous forbid in same scope [E0453] + #![allow(unused)] + //~^ ERROR: allow(unused) incompatible with previous forbid in same scope [E0453] + + num * num +} + +fn forbid_last(num: i32) -> i32 { + #![deny(unused)] + #![warn(unused)] + #![allow(unused)] + #![forbid(unused)] + + num * num +} + +fn forbid_multiple(num: i32) -> i32 { + #![forbid(unused)] + #![forbid(unused)] + + num * num +} + +fn main() { + forbid_first(10); + forbid_last(10); + forbid_multiple(10); +} diff --git a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr new file mode 100644 index 0000000000000..3951c511bf432 --- /dev/null +++ b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr @@ -0,0 +1,29 @@ +error[E0453]: deny(unused) incompatible with previous forbid in same scope + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:19:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] + | ^^^^^^ + +error[E0453]: warn(unused) incompatible with previous forbid in same scope + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:21:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +... +LL | #![warn(unused)] + | ^^^^^^ + +error[E0453]: allow(unused) incompatible with previous forbid in same scope + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:23:14 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +... +LL | #![allow(unused)] + | ^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0453`. diff --git a/src/tools/clippy/tests/ui/attrs.rs b/src/tools/clippy/tests/ui/attrs.rs index 908d063729f45..32685038067d6 100644 --- a/src/tools/clippy/tests/ui/attrs.rs +++ b/src/tools/clippy/tests/ui/attrs.rs @@ -3,7 +3,6 @@ // Test that the whole restriction group is not enabled #![warn(clippy::restriction)] #![deny(clippy::restriction)] -#![forbid(clippy::restriction)] #![allow(clippy::missing_docs_in_private_items, clippy::panic, clippy::unreachable)] #[inline(always)] diff --git a/src/tools/clippy/tests/ui/attrs.stderr b/src/tools/clippy/tests/ui/attrs.stderr index ef4b89eaa6dee..4324984dd60eb 100644 --- a/src/tools/clippy/tests/ui/attrs.stderr +++ b/src/tools/clippy/tests/ui/attrs.stderr @@ -1,5 +1,5 @@ error: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea - --> $DIR/attrs.rs:9:1 + --> $DIR/attrs.rs:8:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[inline(always)] = note: `-D clippy::inline-always` implied by `-D warnings` error: the since field must contain a semver-compliant version - --> $DIR/attrs.rs:29:14 + --> $DIR/attrs.rs:28:14 | LL | #[deprecated(since = "forever")] | ^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | #[deprecated(since = "forever")] = note: `-D clippy::deprecated-semver` implied by `-D warnings` error: the since field must contain a semver-compliant version - --> $DIR/attrs.rs:32:14 + --> $DIR/attrs.rs:31:14 | LL | #[deprecated(since = "1")] | ^^^^^^^^^^^ @@ -37,13 +37,5 @@ LL | #![deny(clippy::restriction)] | = help: try enabling only the lints you really need -error: restriction lints are not meant to be all enabled - --> $DIR/attrs.rs:6:11 - | -LL | #![forbid(clippy::restriction)] - | ^^^^^^^^^^^^^^^^^^^ - | - = help: try enabling only the lints you really need - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors From 5ab19676ed25ce52769b06a2fc7319b93d6c64dd Mon Sep 17 00:00:00 2001 From: Robin Schoonover Date: Wed, 16 Sep 2020 19:41:22 -0600 Subject: [PATCH 07/15] Remove extra indirection in LitKind::ByteStr --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/util/literal.rs | 5 ++--- compiler/rustc_builtin_macros/src/source_util.rs | 4 +--- compiler/rustc_mir_build/src/thir/constant.rs | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 95abf55291506..492d5788fc04f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1606,7 +1606,7 @@ pub enum LitKind { /// A string literal (`"foo"`). Str(Symbol, StrStyle), /// A byte string (`b"foo"`). - ByteStr(Lrc>), + ByteStr(Lrc<[u8]>), /// A byte char (`b'f'`). Byte(u8), /// A character literal (`'a'`). diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 597e5b437fcb1..f6f1ad0a9c3f2 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -4,7 +4,6 @@ use crate::ast::{self, Lit, LitKind}; use crate::token::{self, Token}; use crate::tokenstream::TokenTree; -use rustc_data_structures::sync::Lrc; use rustc_lexer::unescape::{unescape_byte, unescape_char}; use rustc_lexer::unescape::{unescape_byte_literal, unescape_literal, Mode}; use rustc_span::symbol::{kw, sym, Symbol}; @@ -108,7 +107,7 @@ impl LitKind { }); error?; buf.shrink_to_fit(); - LitKind::ByteStr(Lrc::new(buf)) + LitKind::ByteStr(buf.into()) } token::ByteStrRaw(_) => { let s = symbol.as_str(); @@ -128,7 +127,7 @@ impl LitKind { symbol.to_string().into_bytes() }; - LitKind::ByteStr(Lrc::new(bytes)) + LitKind::ByteStr(bytes.into()) } token::Err => LitKind::Err(symbol), }) diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 70753208af310..f76bbd8381940 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -13,8 +13,6 @@ use rustc_span::{self, Pos, Span}; use smallvec::SmallVec; use std::rc::Rc; -use rustc_data_structures::sync::Lrc; - // These macros all relate to the file system; they either return // the column/row/filename of the expression, or they include // a given file into the current one. @@ -216,7 +214,7 @@ pub fn expand_include_bytes( } }; match cx.source_map().load_binary_file(&file) { - Ok(bytes) => base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes)))), + Ok(bytes) => base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(bytes.into()))), Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); DummyResult::any(sp) diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index a7bb2864dafa0..b71ff6e755749 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -31,7 +31,7 @@ crate fn lit_to_const<'tcx>( (ast::LitKind::ByteStr(data), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => { - let allocation = Allocation::from_byte_aligned_bytes(data as &Vec); + let allocation = Allocation::from_byte_aligned_bytes(data as &[u8]); let allocation = tcx.intern_const_alloc(allocation); ConstValue::Slice { data: allocation, start: 0, end: data.len() } } From 62f7712a1fd500604f76442f627ea35ce7217177 Mon Sep 17 00:00:00 2001 From: Robin Schoonover Date: Sun, 4 Oct 2020 15:53:37 -0600 Subject: [PATCH 08/15] Change clippy's Constant back to refcount clone byte strings --- src/tools/clippy/clippy_lints/src/consts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_lints/src/consts.rs b/src/tools/clippy/clippy_lints/src/consts.rs index 0000d39263ed3..062c9bd2d9e6c 100644 --- a/src/tools/clippy/clippy_lints/src/consts.rs +++ b/src/tools/clippy/clippy_lints/src/consts.rs @@ -155,7 +155,7 @@ pub fn lit_to_constant(lit: &LitKind, ty: Option>) -> Constant { match *lit { LitKind::Str(ref is, _) => Constant::Str(is.to_string()), LitKind::Byte(b) => Constant::Int(u128::from(b)), - LitKind::ByteStr(ref s) => Constant::Binary(Lrc::from(s.as_slice())), + LitKind::ByteStr(ref s) => Constant::Binary(Lrc::clone(s)), LitKind::Char(c) => Constant::Char(c), LitKind::Int(n, _) => Constant::Int(n), LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty { From b205436ff66db720cb4b0c503d14ff0a571b14c7 Mon Sep 17 00:00:00 2001 From: Camelid <37223377+camelid@users.noreply.github.com> Date: Sun, 4 Oct 2020 16:57:32 -0700 Subject: [PATCH 09/15] Allow anyone to set regression labels --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index bcdc40017b526..8b7b536bcbf3c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -3,6 +3,7 @@ allow-unauthenticated = [ "C-*", "A-*", "E-*", "NLL-*", "O-*", "S-*", "T-*", "WG-*", "F-*", "D-*", "requires-nightly", + "regression-*", # I-* without I-nominated "I-*", "!I-nominated", "AsyncAwait-OnDeck", From afe83d4c1ca70149b463ac7548cf5d204d3d5844 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Oct 2020 18:35:16 -0700 Subject: [PATCH 10/15] Rename bootstrap/defaults/{config.toml.PROFILE => config.PROFILE.toml} --- src/bootstrap/config.rs | 2 +- .../defaults/{config.toml.codegen => config.codegen.toml} | 0 .../defaults/{config.toml.compiler => config.compiler.toml} | 0 .../defaults/{config.toml.library => config.library.toml} | 0 src/bootstrap/defaults/{config.toml.user => config.user.toml} | 0 src/bootstrap/setup.rs | 4 ++-- 6 files changed, 3 insertions(+), 3 deletions(-) rename src/bootstrap/defaults/{config.toml.codegen => config.codegen.toml} (100%) rename src/bootstrap/defaults/{config.toml.compiler => config.compiler.toml} (100%) rename src/bootstrap/defaults/{config.toml.library => config.library.toml} (100%) rename src/bootstrap/defaults/{config.toml.user => config.user.toml} (100%) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 5314398ce9a22..6265bbaf5c22c 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -574,7 +574,7 @@ impl Config { include_path.push("src"); include_path.push("bootstrap"); include_path.push("defaults"); - include_path.push(format!("config.toml.{}", include)); + include_path.push(format!("config.{}.toml", include)); let included_toml = get_toml(&include_path); toml.merge(included_toml); } diff --git a/src/bootstrap/defaults/config.toml.codegen b/src/bootstrap/defaults/config.codegen.toml similarity index 100% rename from src/bootstrap/defaults/config.toml.codegen rename to src/bootstrap/defaults/config.codegen.toml diff --git a/src/bootstrap/defaults/config.toml.compiler b/src/bootstrap/defaults/config.compiler.toml similarity index 100% rename from src/bootstrap/defaults/config.toml.compiler rename to src/bootstrap/defaults/config.compiler.toml diff --git a/src/bootstrap/defaults/config.toml.library b/src/bootstrap/defaults/config.library.toml similarity index 100% rename from src/bootstrap/defaults/config.toml.library rename to src/bootstrap/defaults/config.library.toml diff --git a/src/bootstrap/defaults/config.toml.user b/src/bootstrap/defaults/config.user.toml similarity index 100% rename from src/bootstrap/defaults/config.toml.user rename to src/bootstrap/defaults/config.user.toml diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 9d3a889aa008e..8a77641fbfefb 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -20,7 +20,7 @@ pub fn setup(src_path: &Path, include_name: &str) { file.display() ); println!( - "note: this will use the configuration in {}/src/bootstrap/defaults/config.toml.{}", + "note: this will use the configuration in {}/src/bootstrap/defaults/config.{}.toml", src_path.display(), include_name ); @@ -36,7 +36,7 @@ pub fn setup(src_path: &Path, include_name: &str) { t!(fs::write(path, settings)); let include_path = - format!("{}/src/bootstrap/defaults/config.toml.{}", src_path.display(), include_name); + format!("{}/src/bootstrap/defaults/config.{}.toml", src_path.display(), include_name); println!("`x.py` will now use the configuration at {}", include_path); let suggestions = match include_name { From 5388eb41e940cddaf8ae4ea812c4e04a3e9d9401 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 4 Oct 2020 18:39:59 -0700 Subject: [PATCH 11/15] Add changelog entry mentioning the renamed profile files --- src/bootstrap/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index d8c704f451bfc..7c12642da3551 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Non-breaking changes since the last major version] - `x.py check` needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473) +- The default bootstrap profiles are now located at `bootstrap/defaults/config.$PROFILE.toml` (previously they were located at `bootstrap/defaults/config.toml.$PROFILE`) [#77558](https://github.com/rust-lang/rust/pull/77558) + ## [Version 2] - 2020-09-25 From daf48b82abd87b6f2016881528be2e978fd5def7 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 5 Oct 2020 11:04:25 +0200 Subject: [PATCH 12/15] inliner: use caller param_env --- compiler/rustc_mir/src/transform/inline.rs | 32 ++++++++-------- .../ui/mir/mir-inlining/ice-issue-77564.rs | 38 +++++++++++++++++++ 2 files changed, 53 insertions(+), 17 deletions(-) create mode 100644 src/test/ui/mir/mir-inlining/ice-issue-77564.rs diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index ced8a2289d577..bec1eb790478c 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -45,8 +45,12 @@ impl<'tcx> MirPass<'tcx> for Inline { // based function. debug!("function inlining is disabled when compiling with `instrument_coverage`"); } else { - Inliner { tcx, codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()) } - .run_pass(body); + Inliner { + tcx, + param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()), + codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()), + } + .run_pass(body); } } } @@ -54,6 +58,7 @@ impl<'tcx> MirPass<'tcx> for Inline { struct Inliner<'tcx> { tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, codegen_fn_attrs: &'tcx CodegenFnAttrs, } @@ -75,17 +80,13 @@ impl Inliner<'tcx> { let def_id = caller_body.source.def_id(); - let param_env = self.tcx.param_env_reveal_all_normalized(def_id); - // Only do inlining into fn bodies. let self_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); if self.tcx.hir().body_owner_kind(self_hir_id).is_fn_or_closure() && caller_body.source.promoted.is_none() { for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated() { - if let Some(callsite) = - self.get_valid_function_call(bb, bb_data, caller_body, param_env) - { + if let Some(callsite) = self.get_valid_function_call(bb, bb_data, caller_body) { callsites.push_back(callsite); } } @@ -131,7 +132,7 @@ impl Inliner<'tcx> { let callee_body = if self.consider_optimizing(callsite, callee_body) { self.tcx.subst_and_normalize_erasing_regions( &callsite.substs, - param_env, + self.param_env, callee_body, ) } else { @@ -159,7 +160,7 @@ impl Inliner<'tcx> { // Add callsites from inlined function for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) { if let Some(new_callsite) = - self.get_valid_function_call(bb, bb_data, caller_body, param_env) + self.get_valid_function_call(bb, bb_data, caller_body) { // Don't inline the same function multiple times. if callsite.callee != new_callsite.callee { @@ -190,7 +191,6 @@ impl Inliner<'tcx> { bb: BasicBlock, bb_data: &BasicBlockData<'tcx>, caller_body: &Body<'tcx>, - param_env: ParamEnv<'tcx>, ) -> Option> { // Don't inline calls that are in cleanup blocks. if bb_data.is_cleanup { @@ -201,8 +201,9 @@ impl Inliner<'tcx> { let terminator = bb_data.terminator(); if let TerminatorKind::Call { func: ref op, .. } = terminator.kind { if let ty::FnDef(callee_def_id, substs) = *op.ty(caller_body, self.tcx).kind() { - let instance = - Instance::resolve(self.tcx, param_env, callee_def_id, substs).ok().flatten()?; + let instance = Instance::resolve(self.tcx, self.param_env, callee_def_id, substs) + .ok() + .flatten()?; if let InstanceDef::Virtual(..) = instance.def { return None; @@ -300,9 +301,6 @@ impl Inliner<'tcx> { debug!(" final inline threshold = {}", threshold); // FIXME: Give a bonus to functions with only a single caller - - let param_env = tcx.param_env(callee_body.source.def_id()); - let mut first_block = true; let mut cost = 0; @@ -335,7 +333,7 @@ impl Inliner<'tcx> { // If the place doesn't actually need dropping, treat it like // a regular goto. let ty = place.ty(callee_body, tcx).subst(tcx, callsite.substs).ty; - if ty.needs_drop(tcx, param_env) { + if ty.needs_drop(tcx, self.param_env) { cost += CALL_PENALTY; if let Some(unwind) = unwind { cost += LANDINGPAD_PENALTY; @@ -400,7 +398,7 @@ impl Inliner<'tcx> { let ty = v.ty.subst(tcx, callsite.substs); // Cost of the var is the size in machine-words, if we know // it. - if let Some(size) = type_size_of(tcx, param_env, ty) { + if let Some(size) = type_size_of(tcx, self.param_env, ty) { cost += (size / ptr_size) as usize; } else { cost += UNKNOWN_SIZE_COST; diff --git a/src/test/ui/mir/mir-inlining/ice-issue-77564.rs b/src/test/ui/mir/mir-inlining/ice-issue-77564.rs new file mode 100644 index 0000000000000..262402df2cc5a --- /dev/null +++ b/src/test/ui/mir/mir-inlining/ice-issue-77564.rs @@ -0,0 +1,38 @@ +// run-pass +// compile-flags:-Zmir-opt-level=2 + +use std::mem::MaybeUninit; +const N: usize = 2; + +trait CollectArray: Iterator { + fn inner_array(&mut self) -> [A; N]; + fn collect_array(&mut self) -> [A; N] { + let result = self.inner_array(); + assert!(self.next().is_none()); + result + } +} + +impl CollectArray for I +where + I: Iterator, +{ + fn inner_array(&mut self) -> [A; N] { + let mut result: [MaybeUninit; N] = unsafe { MaybeUninit::uninit().assume_init() }; + for (dest, item) in result.iter_mut().zip(self) { + *dest = MaybeUninit::new(item); + } + let temp_ptr: *const [MaybeUninit; N] = &result; + unsafe { std::ptr::read(temp_ptr as *const [A; N]) } + } +} + +fn main() { + assert_eq!( + [[1, 2], [3, 4]] + .iter() + .map(|row| row.iter().collect_array()) + .collect_array(), + [[&1, &2], [&3, &4]] + ); +} From b1ce6190ae4cb412c21207932924889e7201d4df Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 26 Sep 2020 15:31:30 +0200 Subject: [PATCH 13/15] Add missing examples for MaybeUninit --- library/core/src/mem/maybe_uninit.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index e629d28eae163..862c452a43480 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -246,6 +246,14 @@ impl MaybeUninit { /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. /// + /// # Example + /// + /// ``` + /// use std::mem::MaybeUninit; + /// + /// let v: MaybeUninit> = MaybeUninit::new(vec![42]); + /// ``` + /// /// [`assume_init`]: MaybeUninit::assume_init #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")] @@ -259,9 +267,15 @@ impl MaybeUninit { /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. /// - /// See the [type-level documentation][type] for some examples. + /// See the [type-level documentation][MaybeUninit] for some examples. /// - /// [type]: union.MaybeUninit.html + /// # Example + /// + /// ``` + /// use std::mem::MaybeUninit; + /// + /// let v: MaybeUninit = MaybeUninit::uninit(); + /// ``` #[stable(feature = "maybe_uninit", since = "1.36.0")] #[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")] #[inline(always)] From 9704911ecbea92f3a883d77f355af11be39626c0 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Mon, 5 Oct 2020 22:29:07 +0800 Subject: [PATCH 14/15] Use matches! for core::char methods --- library/core/src/char/methods.rs | 50 +++++++------------------------- 1 file changed, 10 insertions(+), 40 deletions(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 2603ecf428c7d..1b847addcf806 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1229,10 +1229,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_alphabetic(&self) -> bool { - match *self { - 'A'..='Z' | 'a'..='z' => true, - _ => false, - } + matches!(*self, 'A'..='Z' | 'a'..='z') } /// Checks if the value is an ASCII uppercase character: @@ -1265,10 +1262,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_uppercase(&self) -> bool { - match *self { - 'A'..='Z' => true, - _ => false, - } + matches!(*self, 'A'..='Z') } /// Checks if the value is an ASCII lowercase character: @@ -1301,10 +1295,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_lowercase(&self) -> bool { - match *self { - 'a'..='z' => true, - _ => false, - } + matches!(*self, 'a'..='z') } /// Checks if the value is an ASCII alphanumeric character: @@ -1340,10 +1331,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_alphanumeric(&self) -> bool { - match *self { - '0'..='9' | 'A'..='Z' | 'a'..='z' => true, - _ => false, - } + matches!(*self, '0'..='9' | 'A'..='Z' | 'a'..='z') } /// Checks if the value is an ASCII decimal digit: @@ -1376,10 +1364,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_digit(&self) -> bool { - match *self { - '0'..='9' => true, - _ => false, - } + matches!(*self, '0'..='9') } /// Checks if the value is an ASCII hexadecimal digit: @@ -1415,10 +1400,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_hexdigit(&self) -> bool { - match *self { - '0'..='9' | 'A'..='F' | 'a'..='f' => true, - _ => false, - } + matches!(*self, '0'..='9' | 'A'..='F' | 'a'..='f') } /// Checks if the value is an ASCII punctuation character: @@ -1455,10 +1437,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_punctuation(&self) -> bool { - match *self { - '!'..='/' | ':'..='@' | '['..='`' | '{'..='~' => true, - _ => false, - } + matches!(*self, '!'..='/' | ':'..='@' | '['..='`' | '{'..='~') } /// Checks if the value is an ASCII graphic character: @@ -1491,10 +1470,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_graphic(&self) -> bool { - match *self { - '!'..='~' => true, - _ => false, - } + matches!(*self, '!'..='~') } /// Checks if the value is an ASCII whitespace character: @@ -1544,10 +1520,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_whitespace(&self) -> bool { - match *self { - '\t' | '\n' | '\x0C' | '\r' | ' ' => true, - _ => false, - } + matches!(*self, '\t' | '\n' | '\x0C' | '\r' | ' ') } /// Checks if the value is an ASCII control character: @@ -1582,10 +1555,7 @@ impl char { #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")] #[inline] pub const fn is_ascii_control(&self) -> bool { - match *self { - '\0'..='\x1F' | '\x7F' => true, - _ => false, - } + matches!(*self, '\0'..='\x1F' | '\x7F') } } From 35192ff574c3706646e2f4be16d5c22c4f8b60b1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 5 Oct 2020 11:19:08 -0700 Subject: [PATCH 15/15] Fix span for unicode escape suggestion. --- compiler/rustc_parse/src/lexer/unescape_error_reporting.rs | 5 ++--- src/test/ui/fmt/format-string-error-2.stderr | 4 +--- src/test/ui/parser/issue-23620-invalid-escapes.stderr | 6 +++--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 6f249f491a647..47d317f918865 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -181,10 +181,9 @@ pub(crate) fn emit_unescape_error( if suggestion_len > 0 { suggestion.push('}'); - let lo = char_span.lo(); - let hi = lo + BytePos(suggestion_len as u32); + let hi = char_span.lo() + BytePos(suggestion_len as u32); diag.span_suggestion( - span.with_lo(lo).with_hi(hi), + span.with_hi(hi), "format of unicode escape sequences uses braces", suggestion, Applicability::MaybeIncorrect, diff --git a/src/test/ui/fmt/format-string-error-2.stderr b/src/test/ui/fmt/format-string-error-2.stderr index d202044a2bb97..c421fe49ef0a4 100644 --- a/src/test/ui/fmt/format-string-error-2.stderr +++ b/src/test/ui/fmt/format-string-error-2.stderr @@ -2,9 +2,7 @@ error: incorrect unicode escape sequence --> $DIR/format-string-error-2.rs:77:20 | LL | println!("\x7B}\u8 {", 1); - | ^^- - | | - | help: format of unicode escape sequences uses braces: `\u{8}` + | ^^^ help: format of unicode escape sequences uses braces: `\u{8}` error: invalid format string: expected `'}'`, found `'a'` --> $DIR/format-string-error-2.rs:5:5 diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issue-23620-invalid-escapes.stderr index b391ac75bf8d1..8c924ad0330e9 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.stderr +++ b/src/test/ui/parser/issue-23620-invalid-escapes.stderr @@ -80,9 +80,9 @@ error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:32:14 | LL | let _ = "\u8f"; - | ^^-- - | | - | help: format of unicode escape sequences uses braces: `\u{8f}` + | ^^^- + | | + | help: format of unicode escape sequences uses braces: `\u{8f}` error: aborting due to 13 previous errors