Skip to content

Rollup of 8 pull requests #77470

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Oct 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a313abe
Manually implement Debug for BTreeMap::{IntoKeys,IntoValues} structs
canova Aug 8, 2020
456738e
Only print values in the Debug of HashMap::ValuesMut struct
canova Aug 10, 2020
c346e89
Manually implement Debug for BTreeMap::ValuesMut struct
canova Aug 10, 2020
8faf550
Remove the unused bounds from Debug impl of HashMap::{IntoKeys,IntoVa…
canova Aug 11, 2020
247b739
Move Wrapping<T> ui tests into library
workingjubilee Sep 15, 2020
797cb95
Fix to libstd test
workingjubilee Sep 15, 2020
980e1ff
Add missing examples for Fd traits
GuillaumeGomez Sep 24, 2020
07fd17f
Only use LOCAL_{STDOUT,STDERR} when set_{print/panic} is used.
m-ou-se Sep 27, 2020
ed3ead0
Relax memory ordering of LOCAL_STREAMS and document it.
m-ou-se Sep 27, 2020
de597fc
Optimize set_{panic,print}(None).
m-ou-se Sep 27, 2020
2033eb1
Write manifest for MAJOR.MINOR channel to enable rustup convenience
carols10cents Aug 30, 2020
17db1cb
Bypass const_item_mutation if const's type has Drop impl
dtolnay Sep 27, 2020
0dfe7b6
Add justification of the destructor filter
dtolnay Sep 27, 2020
bb760b5
Simplify defid destructor check
dtolnay Sep 27, 2020
0f6284c
Add test of const item mutation with Drop impl
dtolnay Sep 27, 2020
352ce8b
Test a type with drop glue but no Drop impl
dtolnay Sep 27, 2020
41baa09
Skip dropck::check_drop_impl in is_const_item_without_destructor
dtolnay Sep 27, 2020
eef5104
Add test of VEC.push on a const
dtolnay Oct 1, 2020
75c2fdf
Warn on method call mutating const, even if it has destructor
dtolnay Oct 1, 2020
a8fe654
Write MAJOR.MINOR manifest for stable channel only
carols10cents Oct 1, 2020
804d159
Fixme with link for re-enabling const mutation lint for Drop consts
dtolnay Oct 1, 2020
b20bce8
Revert "resolve: Avoid "self-confirming" import resolutions in one mo…
petrochenkov Oct 1, 2020
89fdfe6
Permit ty::Bool in const generics for v0 mangling
Mark-Simulacrum Oct 2, 2020
d6b838b
Simplify fd examples
GuillaumeGomez Oct 2, 2020
4e97396
Remove unnecessary mod-cfg
workingjubilee Oct 2, 2020
1118ab9
Rollup merge of #75377 - canova:map_debug_impl, r=dtolnay
jonas-schievink Oct 2, 2020
ca0ff93
Rollup merge of #76107 - integer32llc:manifest-alias, r=pietroalbini
jonas-schievink Oct 2, 2020
389f7cf
Rollup merge of #76745 - workingjubilee:move-wrapping-tests, r=matklad
jonas-schievink Oct 2, 2020
ccc020a
Rollup merge of #77182 - GuillaumeGomez:missing-examples-fd-traits, r…
jonas-schievink Oct 2, 2020
6522868
Rollup merge of #77251 - dtolnay:drop, r=Aaron1011
jonas-schievink Oct 2, 2020
01ca829
Rollup merge of #77264 - fusion-engineering-forks:skip-local-stdio, r…
jonas-schievink Oct 2, 2020
23408de
Rollup merge of #77421 - petrochenkov:globtravel, r=nagisa
jonas-schievink Oct 2, 2020
eff6398
Rollup merge of #77452 - Mark-Simulacrum:fix-symbol-v0, r=eddyb
jonas-schievink Oct 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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