From fc60282daea83a5deff651e6c5a93dbad4437be7 Mon Sep 17 00:00:00 2001 From: Solomon Ucko Date: Tue, 28 Apr 2020 22:40:18 -0400 Subject: [PATCH 1/8] impl PartialEq> for &[A], &mut [A] --- src/liballoc/tests/vec.rs | 54 +++++++++++++++++++++++++++++++++++++++ src/liballoc/vec.rs | 5 ++++ 2 files changed, 59 insertions(+) diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index a9813a8704f30..62a252c8be2e0 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::collections::TryReserveError::*; +use std::fmt::Debug; use std::mem::size_of; use std::panic::{catch_unwind, AssertUnwindSafe}; use std::vec::{Drain, IntoIter}; @@ -1588,3 +1589,56 @@ fn test_push_growth_strategy() { } } } + +macro_rules! generate_assert_eq_vec_and_prim { + ($name:ident<$B:ident>($type:ty)) => { + fn $name + Debug, $B: Debug>(a: Vec, b: $type) { + assert!(a == b); + assert_eq!(a, b); + } + }; +} + +generate_assert_eq_vec_and_prim! { assert_eq_vec_and_slice (&[B]) } +generate_assert_eq_vec_and_prim! { assert_eq_vec_and_array_3([B; 3]) } + +#[test] +fn partialeq_vec_and_prim() { + assert_eq_vec_and_slice(vec![1, 2, 3], &[1, 2, 3]); + assert_eq_vec_and_array_3(vec![1, 2, 3], [1, 2, 3]); +} + +macro_rules! assert_partial_eq_valid { + ($a2:ident, $a3:ident; $b2:ident, $b3: ident) => { + assert!($a2 == $b2); + assert!($a2 != $b3); + assert!($a3 != $b2); + assert!($a3 == $b3); + assert_eq!($a2, $b2); + assert_ne!($a2, $b3); + assert_ne!($a3, $b2); + assert_eq!($a3, $b3); + }; +} + +#[test] +fn partialeq_vec_full() { + let vec2: Vec<_> = vec![1, 2]; + let vec3: Vec<_> = vec![1, 2, 3]; + let slice2: &[_] = &[1, 2]; + let slice3: &[_] = &[1, 2, 3]; + let slicemut2: &[_] = &mut [1, 2]; + let slicemut3: &[_] = &mut [1, 2, 3]; + let array2: [_; 2] = [1, 2]; + let array3: [_; 3] = [1, 2, 3]; + let arrayref2: &[_; 2] = &[1, 2]; + let arrayref3: &[_; 3] = &[1, 2, 3]; + + assert_partial_eq_valid!(vec2,vec3; vec2,vec3); + assert_partial_eq_valid!(vec2,vec3; slice2,slice3); + assert_partial_eq_valid!(vec2,vec3; slicemut2,slicemut3); + assert_partial_eq_valid!(slice2,slice3; vec2,vec3); + assert_partial_eq_valid!(slicemut2,slicemut3; vec2,vec3); + assert_partial_eq_valid!(vec2,vec3; array2,array3); + assert_partial_eq_valid!(vec2,vec3; arrayref2,arrayref3); +} diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index f16cac05ea039..c886fa4092752 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2362,6 +2362,8 @@ macro_rules! __impl_slice_eq1 { __impl_slice_eq1! { [] Vec, Vec, } __impl_slice_eq1! { [] Vec, &[B], } __impl_slice_eq1! { [] Vec, &mut [B], } +__impl_slice_eq1! { [] &[A], Vec, } +__impl_slice_eq1! { [] &mut [A], Vec, } __impl_slice_eq1! { [] Cow<'_, [A]>, Vec, A: Clone } __impl_slice_eq1! { [] Cow<'_, [A]>, &[B], A: Clone } __impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B], A: Clone } @@ -2371,6 +2373,9 @@ __impl_slice_eq1! { [const N: usize] Vec, &[B; N], [B; N]: LengthAtMost32 } // NOTE: some less important impls are omitted to reduce code bloat // FIXME(Centril): Reconsider this? //__impl_slice_eq1! { [const N: usize] Vec, &mut [B; N], [B; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] [A; N], Vec, [A; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] &[A; N], Vec, [A; N]: LengthAtMost32 } +//__impl_slice_eq1! { [const N: usize] &mut [A; N], Vec, [A; N]: LengthAtMost32 } //__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, [B; N], [B; N]: LengthAtMost32 } //__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], [B; N]: LengthAtMost32 } //__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], [B; N]: LengthAtMost32 } From 4896a06667ae8d2df4b55822f98c90e6a6965fbc Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 20 Jun 2020 16:02:21 -0700 Subject: [PATCH 2/8] Update stability attribute of new Vec PartialEq impls --- src/liballoc/vec.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index c886fa4092752..e245204751f0b 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -2344,12 +2344,12 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for Vec { } macro_rules! __impl_slice_eq1 { - ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => { - #[stable(feature = "rust1", since = "1.0.0")] + ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?, #[$stability:meta]) => { + #[$stability] impl PartialEq<$rhs> for $lhs where A: PartialEq, - $($constraints)* + $($ty: $bound)? { #[inline] fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] } @@ -2359,16 +2359,16 @@ macro_rules! __impl_slice_eq1 { } } -__impl_slice_eq1! { [] Vec, Vec, } -__impl_slice_eq1! { [] Vec, &[B], } -__impl_slice_eq1! { [] Vec, &mut [B], } -__impl_slice_eq1! { [] &[A], Vec, } -__impl_slice_eq1! { [] &mut [A], Vec, } -__impl_slice_eq1! { [] Cow<'_, [A]>, Vec, A: Clone } -__impl_slice_eq1! { [] Cow<'_, [A]>, &[B], A: Clone } -__impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B], A: Clone } -__impl_slice_eq1! { [const N: usize] Vec, [B; N], [B; N]: LengthAtMost32 } -__impl_slice_eq1! { [const N: usize] Vec, &[B; N], [B; N]: LengthAtMost32 } +__impl_slice_eq1! { [] Vec, Vec, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Vec, &[B], #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Vec, &mut [B], #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] &[A], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } +__impl_slice_eq1! { [] &mut [A], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } +__impl_slice_eq1! { [] Cow<'_, [A]>, Vec where A: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Cow<'_, [A]>, &[B] where A: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B] where A: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [const N: usize] Vec, [B; N] where [B; N]: LengthAtMost32, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [const N: usize] Vec, &[B; N] where [B; N]: LengthAtMost32, #[stable(feature = "rust1", since = "1.0.0")] } // NOTE: some less important impls are omitted to reduce code bloat // FIXME(Centril): Reconsider this? From 467415d50cdf8a0d15ec19dc63251443b35d4cee Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jun 2020 12:28:33 +0200 Subject: [PATCH 3/8] deprecate wrapping_offset_from --- src/libcore/ptr/const_ptr.rs | 6 ++++++ src/libcore/ptr/mut_ptr.rs | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs index e39d18d7733a2..acc09ddc014e6 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -330,6 +330,12 @@ impl *const T { /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2); /// ``` #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")] + #[rustc_deprecated( + since = "1.46.0", + reason = "Pointer distances across allocation \ + boundaries are not typically meaningful. \ + Use integer subtraction if you really need this." + )] #[inline] pub fn wrapping_offset_from(self, origin: *const T) -> isize where diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index 40b5e4e22340e..2bbeb95965e7e 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -380,11 +380,18 @@ impl *mut T { /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2); /// ``` #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")] + #[rustc_deprecated( + since = "1.46.0", + reason = "Pointer distances across allocation \ + boundaries are not typically meaningful. \ + Use integer subtraction if you really need this." + )] #[inline] pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized, { + #[allow(deprecated_in_future, deprecated)] (self as *const T).wrapping_offset_from(origin) } From a657be42b1a7550c071bcccfc66dee22a55a96d1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 21 Jun 2020 11:24:35 +0200 Subject: [PATCH 4/8] Create E0765 error for unterminated double quote strings --- src/librustc_error_codes/error_codes.rs | 1 + src/librustc_error_codes/error_codes/E0765.md | 13 +++++++++++++ src/librustc_parse/lexer/mod.rs | 11 +++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0765.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 738b3bc7539a6..6a5e23adafa53 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -445,6 +445,7 @@ E0761: include_str!("./error_codes/E0761.md"), E0762: include_str!("./error_codes/E0762.md"), E0763: include_str!("./error_codes/E0763.md"), E0764: include_str!("./error_codes/E0764.md"), +E0765: include_str!("./error_codes/E0765.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0765.md b/src/librustc_error_codes/error_codes/E0765.md new file mode 100644 index 0000000000000..456e3f3e9e408 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0765.md @@ -0,0 +1,13 @@ +A double quote string (`"`) was not terminated. + +Erroneous code example: + +```compile_fail,E0765 +let s = "; // error! +``` + +To fix this error, add the missing double quote at the end of the string: + +``` +let s = ""; // ok! +``` diff --git a/src/librustc_parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs index 2e3cf4e746ae9..8e74c3847bc90 100644 --- a/src/librustc_parse/lexer/mod.rs +++ b/src/librustc_parse/lexer/mod.rs @@ -353,8 +353,15 @@ impl<'a> StringReader<'a> { } rustc_lexer::LiteralKind::Str { terminated } => { if !terminated { - self.fatal_span_(start, suffix_start, "unterminated double quote string") - .raise() + self.sess + .span_diagnostic + .struct_span_fatal_with_code( + self.mk_sp(start, suffix_start), + "unterminated double quote string", + error_code!(E0765), + ) + .emit(); + FatalError.raise(); } (token::Str, Mode::Str, 1, 1) // " " } From 726b6f4a69a129ebf97d55f8cde1b3735b6df6aa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Jun 2020 16:13:31 +0200 Subject: [PATCH 5/8] Miri: replace many bug! by span_bug! --- src/librustc_mir/interpret/cast.rs | 36 ++++++++++++++++------ src/librustc_mir/interpret/eval_context.rs | 7 +++-- src/librustc_mir/interpret/intrinsics.rs | 7 ++++- src/librustc_mir/interpret/operand.rs | 15 +++++---- src/librustc_mir/interpret/operator.rs | 22 ++++++++----- src/librustc_mir/interpret/terminator.rs | 2 +- 6 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index cfe856abe36dd..60cf21552e9e9 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -52,7 +52,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } if self.tcx.has_attr(def_id, sym::rustc_args_required_const) { - bug!("reifying a fn ptr that requires const arguments"); + span_bug!( + self.cur_span(), + "reifying a fn ptr that requires const arguments" + ); } let instance = ty::Instance::resolve_for_fn_ptr( @@ -66,7 +69,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); self.write_scalar(fn_ptr, dest)?; } - _ => bug!("reify fn pointer on {:?}", src.layout.ty), + _ => span_bug!(self.cur_span(), "reify fn pointer on {:?}", src.layout.ty), } } @@ -77,7 +80,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // No change to value self.write_immediate(*src, dest)?; } - _ => bug!("fn to unsafe fn cast on {:?}", cast_ty), + _ => span_bug!(self.cur_span(), "fn to unsafe fn cast on {:?}", cast_ty), } } @@ -99,7 +102,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); self.write_scalar(fn_ptr, dest)?; } - _ => bug!("closure fn pointer on {:?}", src.layout.ty), + _ => span_bug!(self.cur_span(), "closure fn pointer on {:?}", src.layout.ty), } } } @@ -162,7 +165,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!(src.layout.ty.is_unsafe_ptr()); return match *src { Immediate::ScalarPair(data, _) => Ok(data.into()), - Immediate::Scalar(..) => bug!( + Immediate::Scalar(..) => span_bug!( + self.cur_span(), "{:?} input to a fat-to-thin cast ({:?} -> {:?})", *src, src.layout.ty, @@ -216,7 +220,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Casts to bool are not permitted by rustc, no need to handle them here. - _ => bug!("invalid int to {:?} cast", cast_ty), + _ => span_bug!(self.cur_span(), "invalid int to {:?} cast", cast_ty), } } @@ -248,7 +252,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // float -> f64 Float(FloatTy::F64) => Scalar::from_f64(f.convert(&mut false).value), // That's it. - _ => bug!("invalid float to {:?} cast", dest_ty), + _ => span_bug!(self.cur_span(), "invalid float to {:?} cast", dest_ty), } } @@ -287,7 +291,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_immediate(val, dest) } - _ => bug!("invalid unsizing {:?} -> {:?}", src.layout.ty, cast_ty), + _ => { + span_bug!(self.cur_span(), "invalid unsizing {:?} -> {:?}", src.layout.ty, cast_ty) + } } } @@ -307,7 +313,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert_eq!(def_a, def_b); if def_a.is_box() || def_b.is_box() { if !def_a.is_box() || !def_b.is_box() { - bug!("invalid unsizing between {:?} -> {:?}", src.layout.ty, cast_ty.ty); + span_bug!( + self.cur_span(), + "invalid unsizing between {:?} -> {:?}", + src.layout.ty, + cast_ty.ty + ); } return self.unsize_into_ptr( src, @@ -335,7 +346,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Ok(()) } - _ => bug!("unsize_into: invalid conversion: {:?} -> {:?}", src.layout, dest.layout), + _ => span_bug!( + self.cur_span(), + "unsize_into: invalid conversion: {:?} -> {:?}", + src.layout, + dest.layout + ), } } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 22f4691c22b3d..ceacbbe5139bf 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -536,7 +536,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if sized_size == Size::ZERO { return Ok(None); } else { - bug!("Fields cannot be extern types, unless they are at offset 0") + span_bug!( + self.cur_span(), + "Fields cannot be extern types, unless they are at offset 0" + ) } } }; @@ -584,7 +587,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::Foreign(_) => Ok(None), - _ => bug!("size_and_align_of::<{:?}> not supported", layout.ty), + _ => span_bug!(self.cur_span(), "size_and_align_of::<{:?}> not supported", layout.ty), } } #[inline] diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index ac28ccd181520..31bdc45a2eab9 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -135,7 +135,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits = self.force_bits(val, layout_of.size)?; let kind = match layout_of.abi { Abi::Scalar(ref scalar) => scalar.value, - _ => bug!("{} called on invalid type {:?}", intrinsic_name, ty), + _ => span_bug!( + self.cur_span(), + "{} called on invalid type {:?}", + intrinsic_name, + ty + ), }; let (nonzero, intrinsic_name) = match intrinsic_name { sym::cttz_nonzero => (true, sym::cttz), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 35e433c4bd5cd..38948ee53846a 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -311,7 +311,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if let Ok(imm) = self.try_read_immediate(op)? { Ok(imm) } else { - bug!("primitive read failed for type: {:?}", op.layout.ty); + span_bug!(self.cur_span(), "primitive read failed for type: {:?}", op.layout.ty); } } @@ -360,9 +360,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = if offset.bytes() == 0 { a } else { b }; Immediate::from(val) } - Immediate::Scalar(val) => { - bug!("field access on non aggregate {:#?}, {:#?}", val, op.layout) - } + Immediate::Scalar(val) => span_bug!( + self.cur_span(), + "field access on non aggregate {:#?}, {:#?}", + val, + op.layout + ), }; Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout }) } @@ -545,7 +548,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::ConstKind::Infer(..) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => { - bug!("eval_const_to_op: Unexpected ConstKind {:?}", val) + span_bug!(self.cur_span(), "eval_const_to_op: Unexpected ConstKind {:?}", val) } ty::ConstKind::Value(val_val) => val_val, }; @@ -656,7 +659,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .discriminants(def_id, *self.tcx) .find(|(_, var)| var.val == discr_bits) } - _ => bug!("tagged layout for non-adt non-generator"), + _ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"), } .ok_or_else(|| err_ub!(InvalidTag(tag_val.erase_tag())))?; // Return the cast value, and the index. diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index d651267f82b79..607122935347e 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -61,7 +61,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Le => l <= r, Gt => l > r, Ge => l >= r, - _ => bug!("Invalid operation on char: {:?}", bin_op), + _ => span_bug!(self.cur_span(), "Invalid operation on char: {:?}", bin_op), }; (Scalar::from_bool(res), false, self.tcx.types.bool) } @@ -84,7 +84,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { BitAnd => l & r, BitOr => l | r, BitXor => l ^ r, - _ => bug!("Invalid operation on bool: {:?}", bin_op), + _ => span_bug!(self.cur_span(), "Invalid operation on bool: {:?}", bin_op), }; (Scalar::from_bool(res), false, self.tcx.types.bool) } @@ -110,7 +110,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Mul => ((l * r).value.into(), ty), Div => ((l / r).value.into(), ty), Rem => ((l % r).value.into(), ty), - _ => bug!("invalid float op: `{:?}`", bin_op), + _ => span_bug!(self.cur_span(), "invalid float op: `{:?}`", bin_op), }; (val, false, ty) } @@ -154,7 +154,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // For the remaining ops, the types must be the same on both sides if left_layout.ty != right_layout.ty { - bug!( + span_bug!( + self.cur_span(), "invalid asymmetric binary op {:?}: {:?} ({:?}), {:?} ({:?})", bin_op, l, @@ -251,7 +252,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { )); } - _ => bug!( + _ => span_bug!( + self.cur_span(), "invalid binary op {:?}: {:?}, {:?} (both {:?})", bin_op, l, @@ -333,7 +335,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { M::binary_ptr_op(self, bin_op, left, right) } - _ => bug!("Invalid MIR: bad LHS type for binop: {:?}", left.layout.ty), + _ => span_bug!( + self.cur_span(), + "Invalid MIR: bad LHS type for binop: {:?}", + left.layout.ty + ), } } @@ -367,7 +373,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = val.to_bool()?; let res = match un_op { Not => !val, - _ => bug!("Invalid bool op {:?}", un_op), + _ => span_bug!(self.cur_span(), "Invalid bool op {:?}", un_op), }; Ok((Scalar::from_bool(res), false, self.tcx.types.bool)) } @@ -375,7 +381,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let res = match (un_op, fty) { (Neg, FloatTy::F32) => Scalar::from_f32(-val.to_f32()?), (Neg, FloatTy::F64) => Scalar::from_f64(-val.to_f64()?), - _ => bug!("Invalid float op {:?}", un_op), + _ => span_bug!(self.cur_span(), "Invalid float op {:?}", un_op), }; Ok((res, false, layout.ty)) } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 1d57fce39734e..0f3fbcf819574 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -232,7 +232,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(), ty::Closure(..) => Abi::RustCall, ty::Generator(..) => Abi::Rust, - _ => bug!("unexpected callee ty: {:?}", instance_ty), + _ => span_bug!(self.cur_span(), "unexpected callee ty: {:?}", instance_ty), } }; let normalize_abi = |abi| match abi { From c14d85fd33934765fcf33122200cecca2d878061 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 21 Jun 2020 11:24:45 +0200 Subject: [PATCH 6/8] Update UI tests --- src/test/rustdoc-ui/test-compile-fail3.stderr | 3 ++- src/test/rustdoc-ui/unparseable-doc-test.stdout | 3 ++- src/test/ui/codemap_tests/tab_2.stderr | 3 ++- src/test/ui/issues/issue-44078.stderr | 3 ++- src/test/ui/parser/unbalanced-doublequote.stderr | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/test/rustdoc-ui/test-compile-fail3.stderr b/src/test/rustdoc-ui/test-compile-fail3.stderr index 7a2f1815ed8e5..fab801b3beaea 100644 --- a/src/test/rustdoc-ui/test-compile-fail3.stderr +++ b/src/test/rustdoc-ui/test-compile-fail3.stderr @@ -1,4 +1,4 @@ -error: unterminated double quote string +error[E0765]: unterminated double quote string --> $DIR/test-compile-fail3.rs:3:1 | 3 | "fail @@ -6,3 +6,4 @@ error: unterminated double quote string error: aborting due to previous error +For more information about this error, try `rustc --explain E0765`. diff --git a/src/test/rustdoc-ui/unparseable-doc-test.stdout b/src/test/rustdoc-ui/unparseable-doc-test.stdout index 4ea6455d3aa4c..29cb22e2e4b09 100644 --- a/src/test/rustdoc-ui/unparseable-doc-test.stdout +++ b/src/test/rustdoc-ui/unparseable-doc-test.stdout @@ -5,7 +5,7 @@ test $DIR/unparseable-doc-test.rs - foo (line 6) ... FAILED failures: ---- $DIR/unparseable-doc-test.rs - foo (line 6) stdout ---- -error: unterminated double quote string +error[E0765]: unterminated double quote string --> $DIR/unparseable-doc-test.rs:8:1 | LL | "unterminated @@ -13,6 +13,7 @@ LL | "unterminated error: aborting due to previous error +For more information about this error, try `rustc --explain E0765`. Couldn't compile the test. failures: diff --git a/src/test/ui/codemap_tests/tab_2.stderr b/src/test/ui/codemap_tests/tab_2.stderr index 70414bbd953d6..0bfdc3ac2651d 100644 --- a/src/test/ui/codemap_tests/tab_2.stderr +++ b/src/test/ui/codemap_tests/tab_2.stderr @@ -1,4 +1,4 @@ -error: unterminated double quote string +error[E0765]: unterminated double quote string --> $DIR/tab_2.rs:4:7 | LL | """; @@ -8,3 +8,4 @@ LL | | } error: aborting due to previous error +For more information about this error, try `rustc --explain E0765`. diff --git a/src/test/ui/issues/issue-44078.stderr b/src/test/ui/issues/issue-44078.stderr index 43b49e463128f..daf67219f4d0a 100644 --- a/src/test/ui/issues/issue-44078.stderr +++ b/src/test/ui/issues/issue-44078.stderr @@ -1,4 +1,4 @@ -error: unterminated double quote string +error[E0765]: unterminated double quote string --> $DIR/issue-44078.rs:2:8 | LL | "😊""; @@ -8,3 +8,4 @@ LL | | } error: aborting due to previous error +For more information about this error, try `rustc --explain E0765`. diff --git a/src/test/ui/parser/unbalanced-doublequote.stderr b/src/test/ui/parser/unbalanced-doublequote.stderr index 4d98515c224ad..94b300a7bd765 100644 --- a/src/test/ui/parser/unbalanced-doublequote.stderr +++ b/src/test/ui/parser/unbalanced-doublequote.stderr @@ -1,4 +1,4 @@ -error: unterminated double quote string +error[E0765]: unterminated double quote string --> $DIR/unbalanced-doublequote.rs:5:5 | LL | / " @@ -7,3 +7,4 @@ LL | | } error: aborting due to previous error +For more information about this error, try `rustc --explain E0765`. From fea5ab12c269bd816b828d3ceea6bb90e4f72825 Mon Sep 17 00:00:00 2001 From: Dan Aloni Date: Sat, 13 Jun 2020 20:58:46 +0300 Subject: [PATCH 7/8] Prefer accessible paths in 'use' suggestions This fixes an issue with the following sample: mod foo { mod inaccessible { pub struct X; } pub mod avail { pub struct X; } } fn main() { X; } Instead of suggesting both `use crate::foo::inaccessible::X;` and `use crate::foo::avail::X;`, it should only suggest the latter. It is done by trimming the list of suggestions from inaccessible paths if accessible paths are present. Visibility is checked with `is_accessible_from` now instead of being hard-coded. - Some tests fixes are trivial, and others require a bit more explaining, here are my comments: src/test/ui/issues/issue-35675.stderr: Only needs to make the enum public to have the suggestion make sense. src/test/ui/issues/issue-42944.stderr: Importing the tuple struct won't help because its constructor is not visible, so the attempted constructor does not work. In that case, it's better not to suggest it. The case where the constructor is public is covered in `issue-26545.rs`. --- src/librustc_resolve/diagnostics.rs | 65 ++++++++++++++++-------- src/librustc_resolve/late/diagnostics.rs | 7 ++- src/test/ui/hygiene/globs.stderr | 6 +-- src/test/ui/issues/issue-26545.rs | 12 +++++ src/test/ui/issues/issue-26545.stderr | 14 +++++ src/test/ui/issues/issue-35675.rs | 2 +- src/test/ui/issues/issue-42944.rs | 12 ++--- src/test/ui/issues/issue-42944.stderr | 14 ++--- src/test/ui/issues/issue-4366-2.stderr | 4 +- src/test/ui/issues/issue-4366.stderr | 4 +- src/test/ui/privacy/privacy-ns1.stderr | 18 ++----- src/test/ui/privacy/privacy-ns2.stderr | 18 ++----- src/test/ui/resolve/issue-21221-1.stderr | 5 +- 13 files changed, 99 insertions(+), 82 deletions(-) create mode 100644 src/test/ui/issues/issue-26545.rs create mode 100644 src/test/ui/issues/issue-26545.stderr diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index bd2ce5a72e8d9..bb88b8191f1ad 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -49,6 +49,7 @@ crate struct ImportSuggestion { pub did: Option, pub descr: &'static str, pub path: Path, + pub accessible: bool, } /// Adjust the impl span so that just the `impl` keyword is taken by removing @@ -640,9 +641,11 @@ impl<'a> Resolver<'a> { let mut candidates = Vec::new(); let mut seen_modules = FxHashSet::default(); let not_local_module = crate_name.name != kw::Crate; - let mut worklist = vec![(start_module, Vec::::new(), not_local_module)]; + let mut worklist = + vec![(start_module, Vec::::new(), true, not_local_module)]; - while let Some((in_module, path_segments, in_module_is_extern)) = worklist.pop() { + while let Some((in_module, path_segments, accessible, in_module_is_extern)) = worklist.pop() + { // We have to visit module children in deterministic order to avoid // instabilities in reported imports (#43552). in_module.for_each_child(self, |this, ident, ns, name_binding| { @@ -650,11 +653,20 @@ impl<'a> Resolver<'a> { if name_binding.is_import() && !name_binding.is_extern_crate() { return; } + // avoid non-importable candidates as well if !name_binding.is_importable() { return; } + let child_accessible = + accessible && this.is_accessible_from(name_binding.vis, parent_scope.module); + + // do not venture inside inaccessible items of other crates + if in_module_is_extern && !child_accessible { + return; + } + // collect results based on the filter function // avoid suggesting anything from the same module in which we are resolving if ident.name == lookup_ident.name @@ -673,22 +685,29 @@ impl<'a> Resolver<'a> { segms.push(ast::PathSegment::from_ident(ident)); let path = Path { span: name_binding.span, segments: segms }; - // the entity is accessible in the following cases: - // 1. if it's defined in the same crate, it's always - // accessible (since private entities can be made public) - // 2. if it's defined in another crate, it's accessible - // only if both the module is public and the entity is - // declared as public (due to pruning, we don't explore - // outside crate private modules => no need to check this) - if !in_module_is_extern || name_binding.vis == ty::Visibility::Public { - let did = match res { - Res::Def(DefKind::Ctor(..), did) => this.parent(did), - _ => res.opt_def_id(), - }; - if candidates.iter().all(|v: &ImportSuggestion| v.did != did) { - candidates.push(ImportSuggestion { did, descr: res.descr(), path }); + let did = match res { + Res::Def(DefKind::Ctor(..), did) => this.parent(did), + _ => res.opt_def_id(), + }; + + if child_accessible { + // Remove invisible match if exists + if let Some(idx) = candidates + .iter() + .position(|v: &ImportSuggestion| v.did == did && !v.accessible) + { + candidates.remove(idx); } } + + if candidates.iter().all(|v: &ImportSuggestion| v.did != did) { + candidates.push(ImportSuggestion { + did, + descr: res.descr(), + path, + accessible: child_accessible, + }); + } } } @@ -701,20 +720,22 @@ impl<'a> Resolver<'a> { let is_extern_crate_that_also_appears_in_prelude = name_binding.is_extern_crate() && lookup_ident.span.rust_2018(); - let is_visible_to_user = - !in_module_is_extern || name_binding.vis == ty::Visibility::Public; - - if !is_extern_crate_that_also_appears_in_prelude && is_visible_to_user { - // add the module to the lookup + if !is_extern_crate_that_also_appears_in_prelude { let is_extern = in_module_is_extern || name_binding.is_extern_crate(); + // add the module to the lookup if seen_modules.insert(module.def_id().unwrap()) { - worklist.push((module, path_segments, is_extern)); + worklist.push((module, path_segments, child_accessible, is_extern)); } } } }) } + // If only some candidates are accessible, take just them + if !candidates.iter().all(|v: &ImportSuggestion| !v.accessible) { + candidates = candidates.into_iter().filter(|x| x.accessible).collect(); + } + candidates } diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 05ef0aa0bb689..478698ba20c70 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -887,7 +887,12 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { let path = Path { span: name_binding.span, segments: path_segments }; result = Some(( module, - ImportSuggestion { did: Some(def_id), descr: "module", path }, + ImportSuggestion { + did: Some(def_id), + descr: "module", + path, + accessible: true, + }, )); } else { // add the module to the lookup diff --git a/src/test/ui/hygiene/globs.stderr b/src/test/ui/hygiene/globs.stderr index 8f6b7aca8fda8..6dcbf055a8bb7 100644 --- a/src/test/ui/hygiene/globs.stderr +++ b/src/test/ui/hygiene/globs.stderr @@ -23,14 +23,10 @@ LL | | } | |_____- in this macro invocation | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider importing one of these items +help: consider importing this function | LL | use bar::g; | -LL | use foo::test2::test::g; - | -LL | use foo::test::g; - | error[E0425]: cannot find function `f` in this scope --> $DIR/globs.rs:61:12 diff --git a/src/test/ui/issues/issue-26545.rs b/src/test/ui/issues/issue-26545.rs new file mode 100644 index 0000000000000..5652ee7470605 --- /dev/null +++ b/src/test/ui/issues/issue-26545.rs @@ -0,0 +1,12 @@ +mod foo { + pub struct B(pub ()); +} + +mod baz { + fn foo() { + B(()); + //~^ ERROR cannot find function, tuple struct or tuple variant `B` in this scope [E0425] + } +} + +fn main() {} diff --git a/src/test/ui/issues/issue-26545.stderr b/src/test/ui/issues/issue-26545.stderr new file mode 100644 index 0000000000000..d3c86692501d6 --- /dev/null +++ b/src/test/ui/issues/issue-26545.stderr @@ -0,0 +1,14 @@ +error[E0425]: cannot find function, tuple struct or tuple variant `B` in this scope + --> $DIR/issue-26545.rs:7:9 + | +LL | B(()); + | ^ not found in this scope + | +help: consider importing this tuple struct + | +LL | use foo::B; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/issues/issue-35675.rs b/src/test/ui/issues/issue-35675.rs index 7876811a9ac39..683761667d40a 100644 --- a/src/test/ui/issues/issue-35675.rs +++ b/src/test/ui/issues/issue-35675.rs @@ -33,7 +33,7 @@ fn qux() -> Some { fn main() {} mod x { - enum Enum { + pub enum Enum { Variant1, Variant2(), Variant3(usize), diff --git a/src/test/ui/issues/issue-42944.rs b/src/test/ui/issues/issue-42944.rs index cc365dc4c938e..a088f91554dfb 100644 --- a/src/test/ui/issues/issue-42944.rs +++ b/src/test/ui/issues/issue-42944.rs @@ -1,20 +1,20 @@ mod foo { - pub struct B(()); + pub struct Bx(()); } mod bar { - use foo::B; + use foo::Bx; fn foo() { - B(()); - //~^ ERROR expected function, tuple struct or tuple variant, found struct `B` [E0423] + Bx(()); + //~^ ERROR expected function, tuple struct or tuple variant, found struct `Bx` [E0423] } } mod baz { fn foo() { - B(()); - //~^ ERROR cannot find function, tuple struct or tuple variant `B` in this scope [E0425] + Bx(()); + //~^ ERROR cannot find function, tuple struct or tuple variant `Bx` in this scope [E0425] } } diff --git a/src/test/ui/issues/issue-42944.stderr b/src/test/ui/issues/issue-42944.stderr index e7e251e39c04f..9fad43757ba62 100644 --- a/src/test/ui/issues/issue-42944.stderr +++ b/src/test/ui/issues/issue-42944.stderr @@ -1,18 +1,18 @@ -error[E0423]: expected function, tuple struct or tuple variant, found struct `B` +error[E0423]: expected function, tuple struct or tuple variant, found struct `Bx` --> $DIR/issue-42944.rs:9:9 | -LL | B(()); - | ^ constructor is not visible here due to private fields +LL | Bx(()); + | ^^ constructor is not visible here due to private fields -error[E0425]: cannot find function, tuple struct or tuple variant `B` in this scope +error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this scope --> $DIR/issue-42944.rs:16:9 | -LL | B(()); - | ^ not found in this scope +LL | Bx(()); + | ^^ not found in this scope | help: consider importing this tuple struct | -LL | use foo::B; +LL | use foo::Bx; | error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-4366-2.stderr b/src/test/ui/issues/issue-4366-2.stderr index ecee595d4ab6a..a86ec7fabea4b 100644 --- a/src/test/ui/issues/issue-4366-2.stderr +++ b/src/test/ui/issues/issue-4366-2.stderr @@ -15,12 +15,10 @@ error[E0423]: expected function, found module `foo` LL | foo(); | ^^^ not a function | -help: consider importing one of these items instead +help: consider importing this function instead | LL | use foo::foo; | -LL | use m1::foo; - | error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-4366.stderr b/src/test/ui/issues/issue-4366.stderr index a094180572daa..469ea93e90468 100644 --- a/src/test/ui/issues/issue-4366.stderr +++ b/src/test/ui/issues/issue-4366.stderr @@ -4,12 +4,10 @@ error[E0425]: cannot find function `foo` in this scope LL | fn sub() -> isize { foo(); 1 } | ^^^ not found in this scope | -help: consider importing one of these items +help: consider importing this function | LL | use foo::foo; | -LL | use m1::foo; - | error: aborting due to previous error diff --git a/src/test/ui/privacy/privacy-ns1.stderr b/src/test/ui/privacy/privacy-ns1.stderr index 4d2af735fa6b9..eda9d4c128d81 100644 --- a/src/test/ui/privacy/privacy-ns1.stderr +++ b/src/test/ui/privacy/privacy-ns1.stderr @@ -11,14 +11,10 @@ help: a unit struct with a similar name exists | LL | Baz(); | ^^^ -help: consider importing one of these items instead - | -LL | use foo1::Bar; +help: consider importing this function instead | LL | use foo2::Bar; | -LL | use foo3::Bar; - | error[E0425]: cannot find function, tuple struct or tuple variant `Bar` in this scope --> $DIR/privacy-ns1.rs:51:5 @@ -33,14 +29,10 @@ help: a unit struct with a similar name exists | LL | Baz(); | ^^^ -help: consider importing one of these items - | -LL | use foo1::Bar; +help: consider importing this function | LL | use foo2::Bar; | -LL | use foo3::Bar; - | error[E0412]: cannot find type `Bar` in this scope --> $DIR/privacy-ns1.rs:52:17 @@ -55,14 +47,10 @@ help: a struct with a similar name exists | LL | let _x: Box; | ^^^ -help: consider importing one of these items +help: consider importing this trait | LL | use foo1::Bar; | -LL | use foo2::Bar; - | -LL | use foo3::Bar; - | error[E0107]: wrong number of const arguments: expected 0, found 1 --> $DIR/privacy-ns1.rs:35:17 diff --git a/src/test/ui/privacy/privacy-ns2.stderr b/src/test/ui/privacy/privacy-ns2.stderr index f1aa523742ae4..d7d9b83527509 100644 --- a/src/test/ui/privacy/privacy-ns2.stderr +++ b/src/test/ui/privacy/privacy-ns2.stderr @@ -4,14 +4,10 @@ error[E0423]: expected function, tuple struct or tuple variant, found trait `Bar LL | Bar(); | ^^^ not a function, tuple struct or tuple variant | -help: consider importing one of these items instead - | -LL | use foo1::Bar; +help: consider importing this function instead | LL | use foo2::Bar; | -LL | use foo3::Bar; - | error[E0423]: expected function, tuple struct or tuple variant, found trait `Bar` --> $DIR/privacy-ns2.rs:26:5 @@ -26,14 +22,10 @@ help: a unit struct with a similar name exists | LL | Baz(); | ^^^ -help: consider importing one of these items instead - | -LL | use foo1::Bar; +help: consider importing this function instead | LL | use foo2::Bar; | -LL | use foo3::Bar; - | error[E0573]: expected type, found function `Bar` --> $DIR/privacy-ns2.rs:43:14 @@ -45,14 +37,10 @@ help: use `=` if you meant to assign | LL | let _x = Bar(); | ^ -help: consider importing one of these items instead +help: consider importing this trait instead | LL | use foo1::Bar; | -LL | use foo2::Bar; - | -LL | use foo3::Bar; - | error[E0603]: trait `Bar` is private --> $DIR/privacy-ns2.rs:63:15 diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index d3e1953435359..538eeead9fc9d 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -25,11 +25,8 @@ LL | use mul1::Mul; | LL | use mul2::Mul; | -LL | use mul3::Mul; - | -LL | use mul4::Mul; +LL | use std::ops::Mul; | - and 2 other candidates error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope --> $DIR/issue-21221-1.rs:63:6 From ae71e965dcc5b5b4c4b0ac94d22852968fbf085d Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 21 Jun 2020 18:09:58 +0200 Subject: [PATCH 8/8] Do not send a notification for P-high stable regressions Add comment to clarify the pattern --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index fc2dbb8d4402d..5361a618d4e85 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -113,7 +113,7 @@ topic = "P-critical #{number} {title}" message_on_add = "@*WG-prioritization* issue #{number} has been assigned `P-critical`." [notify-zulip."P-high"] -required_labels = ["regression-from-stable-to-*"] +required_labels = ["regression-from-stable-to-[bn]*"] # only nightly and beta regressions zulip_stream = 227806 # #t-compiler/wg-prioritization topic = "P-high regression #{number} {title}" message_on_add = "@*WG-prioritization* issue #{number} has been assigned `P-high` and is a regression."