Skip to content

Commit

Permalink
Auto merge of #77470 - jonas-schievink:rollup-9a2hulp, r=jonas-schievink
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #75377 (Fix Debug implementations of some of the HashMap and BTreeMap iterator types)
 - #76107 (Write manifest for MAJOR.MINOR channel to enable rustup convenience)
 - #76745 (Move Wrapping<T> ui tests into library)
 - #77182 (Add missing examples for Fd traits)
 - #77251 (Bypass const_item_mutation if const's type has Drop impl)
 - #77264 (Only use LOCAL_{STDOUT,STDERR} when set_{print/panic} is used. )
 - #77421 (Revert "resolve: Avoid "self-confirming" import resolutions in one more case")
 - #77452 (Permit ty::Bool in const generics for v0 mangling)

Failed merges:

r? `@ghost`
  • Loading branch information
bors committed Oct 2, 2020
2 parents 8876ffc + eff6398 commit 6ebad43
Show file tree
Hide file tree
Showing 16 changed files with 398 additions and 145 deletions.
31 changes: 30 additions & 1 deletion compiler/rustc_mir/src/transform/check_const_item_mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,35 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> {
None
}
}

fn is_const_item_without_destructor(&self, local: Local) -> Option<DefId> {
let def_id = self.is_const_item(local)?;
let mut any_dtor = |_tcx, _def_id| Ok(());

// We avoid linting mutation of a const item if the const's type has a
// Drop impl. The Drop logic observes the mutation which was performed.
//
// pub struct Log { msg: &'static str }
// pub const LOG: Log = Log { msg: "" };
// impl Drop for Log {
// fn drop(&mut self) { println!("{}", self.msg); }
// }
//
// LOG.msg = "wow"; // prints "wow"
//
// FIXME(https://github.com/rust-lang/rust/issues/77425):
// Drop this exception once there is a stable attribute to suppress the
// const item mutation lint for a single specific const only. Something
// equivalent to:
//
// #[const_mutation_allowed]
// pub const LOG: Log = Log { msg: "" };
match self.tcx.calculate_dtor(def_id, &mut any_dtor) {
Some(_) => None,
None => Some(def_id),
}
}

fn lint_const_item_usage(
&self,
const_item: DefId,
Expand Down Expand Up @@ -59,7 +88,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
// Assigning directly to a constant (e.g. `FOO = true;`) is a hard error,
// so emitting a lint would be redundant.
if !lhs.projection.is_empty() {
if let Some(def_id) = self.is_const_item(lhs.local) {
if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) {
// Don't lint on writes through a pointer
// (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`)
if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) {
Expand Down
13 changes: 2 additions & 11 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,12 +875,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
/// consolidate multiple unresolved import errors into a single diagnostic.
fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> {
let orig_vis = import.vis.replace(ty::Visibility::Invisible);
let orig_unusable_binding = match &import.kind {
ImportKind::Single { target_bindings, .. } => {
Some(mem::replace(&mut self.r.unusable_binding, target_bindings[TypeNS].get()))
}
_ => None,
};
let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
let path_res = self.r.resolve_path(
&import.module_path,
Expand All @@ -891,9 +885,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
import.crate_lint(),
);
let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
if let Some(orig_unusable_binding) = orig_unusable_binding {
self.r.unusable_binding = orig_unusable_binding;
}
import.vis.set(orig_vis);
if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
// Consider erroneous imports used to avoid duplicate diagnostics.
Expand All @@ -904,7 +895,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
// Consistency checks, analogous to `finalize_macro_resolutions`.
if let Some(initial_module) = import.imported_module.get() {
if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
span_bug!(import.span, "inconsistent resolution for an import");
let msg = "inconsistent resolution for an import";
self.r.session.span_err(import.span, msg);
}
} else {
if self.r.privacy_errors.is_empty() {
Expand All @@ -926,7 +918,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
}
PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => {
if no_ambiguity {
assert!(import.imported_module.get().is_none());
let err = match self.make_path_suggestion(
span,
import.module_path.clone(),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_symbol_mangling/src/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {

match ct.ty.kind() {
ty::Uint(_) => {}
ty::Bool => {}
_ => {
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct);
}
Expand Down
58 changes: 51 additions & 7 deletions library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,14 +297,23 @@ pub struct IntoIter<K, V> {
length: usize,
}

#[stable(feature = "collection_debug", since = "1.17.0")]
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl<K, V> IntoIter<K, V> {
/// Returns an iterator of references over the remaining items.
#[inline]
pub(super) fn iter(&self) -> Iter<'_, K, V> {
let range = Range {
front: self.front.as_ref().map(|f| f.reborrow()),
back: self.back.as_ref().map(|b| b.reborrow()),
};
f.debug_list().entries(range).finish()

Iter { range: range, length: self.length }
}
}

#[stable(feature = "collection_debug", since = "1.17.0")]
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}

Expand Down Expand Up @@ -351,35 +360,53 @@ impl<K, V: fmt::Debug> fmt::Debug for Values<'_, K, V> {
///
/// [`values_mut`]: BTreeMap::values_mut
#[stable(feature = "map_values_mut", since = "1.10.0")]
#[derive(Debug)]
pub struct ValuesMut<'a, K: 'a, V: 'a> {
inner: IterMut<'a, K, V>,
}

#[stable(feature = "map_values_mut", since = "1.10.0")]
impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
}
}

/// An owning iterator over the keys of a `BTreeMap`.
///
/// This `struct` is created by the [`into_keys`] method on [`BTreeMap`].
/// See its documentation for more.
///
/// [`into_keys`]: BTreeMap::into_keys
#[unstable(feature = "map_into_keys_values", issue = "75294")]
#[derive(Debug)]
pub struct IntoKeys<K, V> {
inner: IntoIter<K, V>,
}

#[unstable(feature = "map_into_keys_values", issue = "75294")]
impl<K: fmt::Debug, V> fmt::Debug for IntoKeys<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter().map(|(key, _)| key)).finish()
}
}

/// An owning iterator over the values of a `BTreeMap`.
///
/// This `struct` is created by the [`into_values`] method on [`BTreeMap`].
/// See its documentation for more.
///
/// [`into_values`]: BTreeMap::into_values
#[unstable(feature = "map_into_keys_values", issue = "75294")]
#[derive(Debug)]
pub struct IntoValues<K, V> {
inner: IntoIter<K, V>,
}

#[unstable(feature = "map_into_keys_values", issue = "75294")]
impl<K, V: fmt::Debug> fmt::Debug for IntoValues<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
}
}

/// An iterator over a sub-range of entries in a `BTreeMap`.
///
/// This `struct` is created by the [`range`] method on [`BTreeMap`]. See its
Expand Down Expand Up @@ -1465,6 +1492,14 @@ impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
#[stable(feature = "fused", since = "1.26.0")]
impl<K, V> FusedIterator for IterMut<'_, K, V> {}

impl<'a, K, V> IterMut<'a, K, V> {
/// Returns an iterator of references over the remaining items.
#[inline]
pub(super) fn iter(&self) -> Iter<'_, K, V> {
Iter { range: self.range.iter(), length: self.length }
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> IntoIterator for BTreeMap<K, V> {
type Item = (K, V);
Expand Down Expand Up @@ -1949,6 +1984,15 @@ impl<'a, K, V> RangeMut<'a, K, V> {
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
unsafe { unwrap_unchecked(self.front.as_mut()).next_unchecked() }
}

/// Returns an iterator of references over the remaining items.
#[inline]
pub(super) fn iter(&self) -> Range<'_, K, V> {
Range {
front: self.front.as_ref().map(|f| f.reborrow()),
back: self.back.as_ref().map(|b| b.reborrow()),
}
}
}

#[stable(feature = "btree_range", since = "1.17.0")]
Expand Down
76 changes: 76 additions & 0 deletions library/core/tests/num/wrapping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use core::num::Wrapping;

macro_rules! wrapping_operation {
($result:expr, $lhs:ident $op:tt $rhs:expr) => {
assert_eq!($result, $lhs $op $rhs);
assert_eq!($result, &$lhs $op $rhs);
assert_eq!($result, $lhs $op &$rhs);
assert_eq!($result, &$lhs $op &$rhs);
};
($result:expr, $op:tt $expr:expr) => {
assert_eq!($result, $op $expr);
assert_eq!($result, $op &$expr);
};
}

macro_rules! wrapping_assignment {
($result:expr, $lhs:ident $op:tt $rhs:expr) => {
let mut lhs1 = $lhs;
lhs1 $op $rhs;
assert_eq!($result, lhs1);

let mut lhs2 = $lhs;
lhs2 $op &$rhs;
assert_eq!($result, lhs2);
};
}

macro_rules! wrapping_test {
($type:ty, $min:expr, $max:expr) => {
#[test]
fn wrapping_$type() {
let zero: Wrapping<$type> = Wrapping(0);
let one: Wrapping<$type> = Wrapping(1);
let min: Wrapping<$type> = Wrapping($min);
let max: Wrapping<$type> = Wrapping($max);

wrapping_operation!(min, max + one);
wrapping_assignment!(min, max += one);
wrapping_operation!(max, min - one);
wrapping_assignment!(max, min -= one);
wrapping_operation!(max, max * one);
wrapping_assignment!(max, max *= one);
wrapping_operation!(max, max / one);
wrapping_assignment!(max, max /= one);
wrapping_operation!(zero, max % one);
wrapping_assignment!(zero, max %= one);
wrapping_operation!(zero, zero & max);
wrapping_assignment!(zero, zero &= max);
wrapping_operation!(max, zero | max);
wrapping_assignment!(max, zero |= max);
wrapping_operation!(zero, max ^ max);
wrapping_assignment!(zero, max ^= max);
wrapping_operation!(zero, zero << 1usize);
wrapping_assignment!(zero, zero <<= 1usize);
wrapping_operation!(zero, zero >> 1usize);
wrapping_assignment!(zero, zero >>= 1usize);
wrapping_operation!(zero, -zero);
wrapping_operation!(max, !min);
}
};
}

wrapping_test!(i8, i8::MIN, i8::MAX);
wrapping_test!(i16, i16::MIN, i16::MAX);
wrapping_test!(i32, i32::MIN, i32::MAX);
wrapping_test!(i64, i64::MIN, i64::MAX);
#[cfg(not(target_os = "emscripten"))]
wrapping_test!(i128, i128::MIN, i128::MAX);
wrapping_test!(isize, isize::MIN, isize::MAX);
wrapping_test!(u8, u8::MIN, u8::MAX);
wrapping_test!(u16, u16::MIN, u16::MAX);
wrapping_test!(u32, u32::MIN, u32::MAX);
wrapping_test!(u64, u64::MIN, u64::MAX);
#[cfg(not(target_os = "emscripten"))]
wrapping_test!(u128, u128::MIN, u128::MAX);
wrapping_test!(usize, usize::MIN, usize::MAX);
12 changes: 4 additions & 8 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2042,13 +2042,9 @@ impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}

#[stable(feature = "std_debug", since = "1.16.0")]
impl<K, V> fmt::Debug for ValuesMut<'_, K, V>
where
K: fmt::Debug,
V: fmt::Debug,
{
impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter()).finish()
f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
}
}

Expand Down Expand Up @@ -2076,7 +2072,7 @@ impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
impl<K, V> FusedIterator for IntoKeys<K, V> {}

#[unstable(feature = "map_into_keys_values", issue = "75294")]
impl<K: Debug, V: Debug> fmt::Debug for IntoKeys<K, V> {
impl<K: Debug, V> fmt::Debug for IntoKeys<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter().map(|(k, _)| k)).finish()
}
Expand Down Expand Up @@ -2106,7 +2102,7 @@ impl<K, V> ExactSizeIterator for IntoValues<K, V> {
impl<K, V> FusedIterator for IntoValues<K, V> {}

#[unstable(feature = "map_into_keys_values", issue = "75294")]
impl<K: Debug, V: Debug> fmt::Debug for IntoValues<K, V> {
impl<K, V: Debug> fmt::Debug for IntoValues<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter().map(|(_, v)| v)).finish()
}
Expand Down
Loading

0 comments on commit 6ebad43

Please sign in to comment.