Skip to content

Commit 6ebad43

Browse files
committed
Auto merge of rust-lang#77470 - jonas-schievink:rollup-9a2hulp, r=jonas-schievink
Rollup of 8 pull requests Successful merges: - rust-lang#75377 (Fix Debug implementations of some of the HashMap and BTreeMap iterator types) - rust-lang#76107 (Write manifest for MAJOR.MINOR channel to enable rustup convenience) - rust-lang#76745 (Move Wrapping<T> ui tests into library) - rust-lang#77182 (Add missing examples for Fd traits) - rust-lang#77251 (Bypass const_item_mutation if const's type has Drop impl) - rust-lang#77264 (Only use LOCAL_{STDOUT,STDERR} when set_{print/panic} is used. ) - rust-lang#77421 (Revert "resolve: Avoid "self-confirming" import resolutions in one more case") - rust-lang#77452 (Permit ty::Bool in const generics for v0 mangling) Failed merges: r? `@ghost`
2 parents 8876ffc + eff6398 commit 6ebad43

File tree

16 files changed

+398
-145
lines changed

16 files changed

+398
-145
lines changed

compiler/rustc_mir/src/transform/check_const_item_mutation.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,35 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> {
3131
None
3232
}
3333
}
34+
35+
fn is_const_item_without_destructor(&self, local: Local) -> Option<DefId> {
36+
let def_id = self.is_const_item(local)?;
37+
let mut any_dtor = |_tcx, _def_id| Ok(());
38+
39+
// We avoid linting mutation of a const item if the const's type has a
40+
// Drop impl. The Drop logic observes the mutation which was performed.
41+
//
42+
// pub struct Log { msg: &'static str }
43+
// pub const LOG: Log = Log { msg: "" };
44+
// impl Drop for Log {
45+
// fn drop(&mut self) { println!("{}", self.msg); }
46+
// }
47+
//
48+
// LOG.msg = "wow"; // prints "wow"
49+
//
50+
// FIXME(https://github.com/rust-lang/rust/issues/77425):
51+
// Drop this exception once there is a stable attribute to suppress the
52+
// const item mutation lint for a single specific const only. Something
53+
// equivalent to:
54+
//
55+
// #[const_mutation_allowed]
56+
// pub const LOG: Log = Log { msg: "" };
57+
match self.tcx.calculate_dtor(def_id, &mut any_dtor) {
58+
Some(_) => None,
59+
None => Some(def_id),
60+
}
61+
}
62+
3463
fn lint_const_item_usage(
3564
&self,
3665
const_item: DefId,
@@ -59,7 +88,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> {
5988
// Assigning directly to a constant (e.g. `FOO = true;`) is a hard error,
6089
// so emitting a lint would be redundant.
6190
if !lhs.projection.is_empty() {
62-
if let Some(def_id) = self.is_const_item(lhs.local) {
91+
if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) {
6392
// Don't lint on writes through a pointer
6493
// (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`)
6594
if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) {

compiler/rustc_resolve/src/imports.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -875,12 +875,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
875875
/// consolidate multiple unresolved import errors into a single diagnostic.
876876
fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> {
877877
let orig_vis = import.vis.replace(ty::Visibility::Invisible);
878-
let orig_unusable_binding = match &import.kind {
879-
ImportKind::Single { target_bindings, .. } => {
880-
Some(mem::replace(&mut self.r.unusable_binding, target_bindings[TypeNS].get()))
881-
}
882-
_ => None,
883-
};
884878
let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
885879
let path_res = self.r.resolve_path(
886880
&import.module_path,
@@ -891,9 +885,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
891885
import.crate_lint(),
892886
);
893887
let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
894-
if let Some(orig_unusable_binding) = orig_unusable_binding {
895-
self.r.unusable_binding = orig_unusable_binding;
896-
}
897888
import.vis.set(orig_vis);
898889
if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
899890
// Consider erroneous imports used to avoid duplicate diagnostics.
@@ -904,7 +895,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
904895
// Consistency checks, analogous to `finalize_macro_resolutions`.
905896
if let Some(initial_module) = import.imported_module.get() {
906897
if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
907-
span_bug!(import.span, "inconsistent resolution for an import");
898+
let msg = "inconsistent resolution for an import";
899+
self.r.session.span_err(import.span, msg);
908900
}
909901
} else {
910902
if self.r.privacy_errors.is_empty() {
@@ -926,7 +918,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
926918
}
927919
PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => {
928920
if no_ambiguity {
929-
assert!(import.imported_module.get().is_none());
930921
let err = match self.make_path_suggestion(
931922
span,
932923
import.module_path.clone(),

compiler/rustc_symbol_mangling/src/v0.rs

+1
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
504504

505505
match ct.ty.kind() {
506506
ty::Uint(_) => {}
507+
ty::Bool => {}
507508
_ => {
508509
bug!("symbol_names: unsupported constant of type `{}` ({:?})", ct.ty, ct);
509510
}

library/alloc/src/collections/btree/map.rs

+51-7
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,23 @@ pub struct IntoIter<K, V> {
297297
length: usize,
298298
}
299299

300-
#[stable(feature = "collection_debug", since = "1.17.0")]
301-
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
302-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300+
impl<K, V> IntoIter<K, V> {
301+
/// Returns an iterator of references over the remaining items.
302+
#[inline]
303+
pub(super) fn iter(&self) -> Iter<'_, K, V> {
303304
let range = Range {
304305
front: self.front.as_ref().map(|f| f.reborrow()),
305306
back: self.back.as_ref().map(|b| b.reborrow()),
306307
};
307-
f.debug_list().entries(range).finish()
308+
309+
Iter { range: range, length: self.length }
310+
}
311+
}
312+
313+
#[stable(feature = "collection_debug", since = "1.17.0")]
314+
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
315+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316+
f.debug_list().entries(self.iter()).finish()
308317
}
309318
}
310319

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

367+
#[stable(feature = "map_values_mut", since = "1.10.0")]
368+
impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
369+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370+
f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
371+
}
372+
}
373+
359374
/// An owning iterator over the keys of a `BTreeMap`.
360375
///
361376
/// This `struct` is created by the [`into_keys`] method on [`BTreeMap`].
362377
/// See its documentation for more.
363378
///
364379
/// [`into_keys`]: BTreeMap::into_keys
365380
#[unstable(feature = "map_into_keys_values", issue = "75294")]
366-
#[derive(Debug)]
367381
pub struct IntoKeys<K, V> {
368382
inner: IntoIter<K, V>,
369383
}
370384

385+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
386+
impl<K: fmt::Debug, V> fmt::Debug for IntoKeys<K, V> {
387+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
388+
f.debug_list().entries(self.inner.iter().map(|(key, _)| key)).finish()
389+
}
390+
}
391+
371392
/// An owning iterator over the values of a `BTreeMap`.
372393
///
373394
/// This `struct` is created by the [`into_values`] method on [`BTreeMap`].
374395
/// See its documentation for more.
375396
///
376397
/// [`into_values`]: BTreeMap::into_values
377398
#[unstable(feature = "map_into_keys_values", issue = "75294")]
378-
#[derive(Debug)]
379399
pub struct IntoValues<K, V> {
380400
inner: IntoIter<K, V>,
381401
}
382402

403+
#[unstable(feature = "map_into_keys_values", issue = "75294")]
404+
impl<K, V: fmt::Debug> fmt::Debug for IntoValues<K, V> {
405+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406+
f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
407+
}
408+
}
409+
383410
/// An iterator over a sub-range of entries in a `BTreeMap`.
384411
///
385412
/// This `struct` is created by the [`range`] method on [`BTreeMap`]. See its
@@ -1465,6 +1492,14 @@ impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
14651492
#[stable(feature = "fused", since = "1.26.0")]
14661493
impl<K, V> FusedIterator for IterMut<'_, K, V> {}
14671494

1495+
impl<'a, K, V> IterMut<'a, K, V> {
1496+
/// Returns an iterator of references over the remaining items.
1497+
#[inline]
1498+
pub(super) fn iter(&self) -> Iter<'_, K, V> {
1499+
Iter { range: self.range.iter(), length: self.length }
1500+
}
1501+
}
1502+
14681503
#[stable(feature = "rust1", since = "1.0.0")]
14691504
impl<K, V> IntoIterator for BTreeMap<K, V> {
14701505
type Item = (K, V);
@@ -1949,6 +1984,15 @@ impl<'a, K, V> RangeMut<'a, K, V> {
19491984
unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
19501985
unsafe { unwrap_unchecked(self.front.as_mut()).next_unchecked() }
19511986
}
1987+
1988+
/// Returns an iterator of references over the remaining items.
1989+
#[inline]
1990+
pub(super) fn iter(&self) -> Range<'_, K, V> {
1991+
Range {
1992+
front: self.front.as_ref().map(|f| f.reborrow()),
1993+
back: self.back.as_ref().map(|b| b.reborrow()),
1994+
}
1995+
}
19521996
}
19531997

19541998
#[stable(feature = "btree_range", since = "1.17.0")]

library/core/tests/num/wrapping.rs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use core::num::Wrapping;
2+
3+
macro_rules! wrapping_operation {
4+
($result:expr, $lhs:ident $op:tt $rhs:expr) => {
5+
assert_eq!($result, $lhs $op $rhs);
6+
assert_eq!($result, &$lhs $op $rhs);
7+
assert_eq!($result, $lhs $op &$rhs);
8+
assert_eq!($result, &$lhs $op &$rhs);
9+
};
10+
($result:expr, $op:tt $expr:expr) => {
11+
assert_eq!($result, $op $expr);
12+
assert_eq!($result, $op &$expr);
13+
};
14+
}
15+
16+
macro_rules! wrapping_assignment {
17+
($result:expr, $lhs:ident $op:tt $rhs:expr) => {
18+
let mut lhs1 = $lhs;
19+
lhs1 $op $rhs;
20+
assert_eq!($result, lhs1);
21+
22+
let mut lhs2 = $lhs;
23+
lhs2 $op &$rhs;
24+
assert_eq!($result, lhs2);
25+
};
26+
}
27+
28+
macro_rules! wrapping_test {
29+
($type:ty, $min:expr, $max:expr) => {
30+
#[test]
31+
fn wrapping_$type() {
32+
let zero: Wrapping<$type> = Wrapping(0);
33+
let one: Wrapping<$type> = Wrapping(1);
34+
let min: Wrapping<$type> = Wrapping($min);
35+
let max: Wrapping<$type> = Wrapping($max);
36+
37+
wrapping_operation!(min, max + one);
38+
wrapping_assignment!(min, max += one);
39+
wrapping_operation!(max, min - one);
40+
wrapping_assignment!(max, min -= one);
41+
wrapping_operation!(max, max * one);
42+
wrapping_assignment!(max, max *= one);
43+
wrapping_operation!(max, max / one);
44+
wrapping_assignment!(max, max /= one);
45+
wrapping_operation!(zero, max % one);
46+
wrapping_assignment!(zero, max %= one);
47+
wrapping_operation!(zero, zero & max);
48+
wrapping_assignment!(zero, zero &= max);
49+
wrapping_operation!(max, zero | max);
50+
wrapping_assignment!(max, zero |= max);
51+
wrapping_operation!(zero, max ^ max);
52+
wrapping_assignment!(zero, max ^= max);
53+
wrapping_operation!(zero, zero << 1usize);
54+
wrapping_assignment!(zero, zero <<= 1usize);
55+
wrapping_operation!(zero, zero >> 1usize);
56+
wrapping_assignment!(zero, zero >>= 1usize);
57+
wrapping_operation!(zero, -zero);
58+
wrapping_operation!(max, !min);
59+
}
60+
};
61+
}
62+
63+
wrapping_test!(i8, i8::MIN, i8::MAX);
64+
wrapping_test!(i16, i16::MIN, i16::MAX);
65+
wrapping_test!(i32, i32::MIN, i32::MAX);
66+
wrapping_test!(i64, i64::MIN, i64::MAX);
67+
#[cfg(not(target_os = "emscripten"))]
68+
wrapping_test!(i128, i128::MIN, i128::MAX);
69+
wrapping_test!(isize, isize::MIN, isize::MAX);
70+
wrapping_test!(u8, u8::MIN, u8::MAX);
71+
wrapping_test!(u16, u16::MIN, u16::MAX);
72+
wrapping_test!(u32, u32::MIN, u32::MAX);
73+
wrapping_test!(u64, u64::MIN, u64::MAX);
74+
#[cfg(not(target_os = "emscripten"))]
75+
wrapping_test!(u128, u128::MIN, u128::MAX);
76+
wrapping_test!(usize, usize::MIN, usize::MAX);

library/std/src/collections/hash/map.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -2042,13 +2042,9 @@ impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
20422042
impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
20432043

20442044
#[stable(feature = "std_debug", since = "1.16.0")]
2045-
impl<K, V> fmt::Debug for ValuesMut<'_, K, V>
2046-
where
2047-
K: fmt::Debug,
2048-
V: fmt::Debug,
2049-
{
2045+
impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
20502046
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2051-
f.debug_list().entries(self.inner.iter()).finish()
2047+
f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
20522048
}
20532049
}
20542050

@@ -2076,7 +2072,7 @@ impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
20762072
impl<K, V> FusedIterator for IntoKeys<K, V> {}
20772073

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

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

0 commit comments

Comments
 (0)