Skip to content

Commit dac7229

Browse files
committed
Auto merge of #66436 - JohnTitor:rollup-kphyb2i, r=JohnTitor
Rollup of 12 pull requests Successful merges: - #65557 (rename Error::iter_chain() and remove Error::iter_sources()) - #66013 (Avoid hashing the key twice in `get_query()`.) - #66306 (Remove cannot mutate statics in initializer of another static error) - #66338 (Update mdbook.) - #66388 (Do not ICE on recovery from unmet associated type bound obligation) - #66390 (Fix ICE when trying to suggest `Type<>` instead of `Type()`) - #66391 (Do not ICE in `if` without `else` in `async fn`) - #66394 (Fix two OOM issues related to `ConstProp`) - #66398 (Remove some stack frames from `.async` calls) - #66410 (miri: helper methods for max values of machine's usize/isize) - #66418 (Link to tracking issue in HIR const-check error code description) - #66419 (Don't warn labels beginning with `_` on unused_labels lint) Failed merges: r? @ghost
2 parents 9e8c4e6 + 175f296 commit dac7229

31 files changed

+392
-383
lines changed

Cargo.lock

+172-175
Large diffs are not rendered by default.

src/librustc/hir/lowering.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -1862,15 +1862,16 @@ impl<'a> LoweringContext<'a> {
18621862
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
18631863
// Do not suggest going from `Trait()` to `Trait<>`
18641864
if data.inputs.len() > 0 {
1865-
let split = snippet.find('(').unwrap();
1866-
let trait_name = &snippet[0..split];
1867-
let args = &snippet[split + 1 .. snippet.len() - 1];
1868-
err.span_suggestion(
1869-
data.span,
1870-
"use angle brackets instead",
1871-
format!("{}<{}>", trait_name, args),
1872-
Applicability::MaybeIncorrect,
1873-
);
1865+
if let Some(split) = snippet.find('(') {
1866+
let trait_name = &snippet[0..split];
1867+
let args = &snippet[split + 1 .. snippet.len() - 1];
1868+
err.span_suggestion(
1869+
data.span,
1870+
"use angle brackets instead",
1871+
format!("{}<{}>", trait_name, args),
1872+
Applicability::MaybeIncorrect,
1873+
);
1874+
}
18741875
}
18751876
};
18761877
err.emit();

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#![feature(log_syntax)]
6060
#![feature(associated_type_bounds)]
6161
#![feature(rustc_attrs)]
62+
#![feature(hash_raw_entry)]
6263

6364
#![recursion_limit="512"]
6465

src/librustc/mir/interpret/pointer.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::fmt::{self, Display};
2+
use std::convert::TryFrom;
23

34
use crate::mir;
45
use crate::ty::layout::{self, HasDataLayout, Size};
@@ -40,6 +41,18 @@ pub trait PointerArithmetic: layout::HasDataLayout {
4041
self.data_layout().pointer_size
4142
}
4243

44+
#[inline]
45+
fn usize_max(&self) -> u64 {
46+
let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
47+
u64::try_from(max_usize_plus_1-1).unwrap()
48+
}
49+
50+
#[inline]
51+
fn isize_max(&self) -> i64 {
52+
let max_isize_plus_1 = 1u128 << (self.pointer_size().bits()-1);
53+
i64::try_from(max_isize_plus_1-1).unwrap()
54+
}
55+
4356
/// Helper function: truncate given value-"overflowed flag" pair to pointer size and
4457
/// update "overflowed flag" if there was an overflow.
4558
/// This should be called by all the other methods before returning!

src/librustc/ty/query/plumbing.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ use errors::Level;
1414
use errors::Diagnostic;
1515
use errors::FatalError;
1616
use errors::Handler;
17-
use rustc_data_structures::fx::{FxHashMap};
17+
use rustc_data_structures::fx::{FxHasher, FxHashMap};
1818
use rustc_data_structures::sync::{Lrc, Lock};
1919
use rustc_data_structures::sharded::Sharded;
2020
use rustc_data_structures::thin_vec::ThinVec;
2121
#[cfg(not(parallel_compiler))]
2222
use rustc_data_structures::cold_path;
23+
use std::hash::{Hash, Hasher};
2324
use std::mem;
2425
use std::ptr;
2526
use std::collections::hash_map::Entry;
@@ -82,8 +83,17 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
8283
pub(super) fn try_get(tcx: TyCtxt<'tcx>, span: Span, key: &Q::Key) -> TryGetJob<'a, 'tcx, Q> {
8384
let cache = Q::query_cache(tcx);
8485
loop {
85-
let mut lock = cache.get_shard_by_value(key).lock();
86-
if let Some(value) = lock.results.get(key) {
86+
// We compute the key's hash once and then use it for both the
87+
// shard lookup and the hashmap lookup. This relies on the fact
88+
// that both of them use `FxHasher`.
89+
let mut state = FxHasher::default();
90+
key.hash(&mut state);
91+
let key_hash = state.finish();
92+
93+
let mut lock = cache.get_shard_by_hash(key_hash).lock();
94+
if let Some((_, value)) =
95+
lock.results.raw_entry().from_key_hashed_nocheck(key_hash, key)
96+
{
8797
tcx.prof.query_cache_hit(Q::NAME);
8898
let result = (value.value.clone(), value.index);
8999
#[cfg(debug_assertions)]

src/librustc_data_structures/sharded.rs

+6
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl<T> Sharded<T> {
6060
}
6161
}
6262

63+
/// The shard is selected by hashing `val` with `FxHasher`.
6364
#[inline]
6465
pub fn get_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> &Lock<T> {
6566
if SHARDS == 1 {
@@ -69,6 +70,11 @@ impl<T> Sharded<T> {
6970
}
7071
}
7172

73+
/// Get a shard with a pre-computed hash value. If `get_shard_by_value` is
74+
/// ever used in combination with `get_shard_by_hash` on a single `Sharded`
75+
/// instance, then `hash` must be computed with `FxHasher`. Otherwise,
76+
/// `hash` can be computed with any hasher, so long as that hasher is used
77+
/// consistently for each `Sharded` instance.
7278
#[inline]
7379
pub fn get_shard_by_hash(&self, hash: u64) -> &Lock<T> {
7480
let hash_len = mem::size_of::<usize>();

src/librustc_error_codes/error_codes/E0744.md

+7
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,10 @@ const _: i32 = {
1515
x
1616
};
1717
```
18+
19+
This will be allowed at some point in the future, but the implementation is not
20+
yet complete. See the tracking issue for [conditionals] or [loops] in a const
21+
context for the current status.
22+
23+
[conditionals]: https://github.com/rust-lang/rust/issues/49146
24+
[loops]: https://github.com/rust-lang/rust/issues/52000

src/librustc_mir/transform/check_consts/validation.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -326,17 +326,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
326326
let is_thread_local = self.tcx.has_attr(*def_id, sym::thread_local);
327327
if is_thread_local {
328328
self.check_op(ops::ThreadLocalAccess);
329-
} else if self.const_kind() == ConstKind::Static && context.is_mutating_use() {
330-
// this is not strictly necessary as miri will also bail out
331-
// For interior mutability we can't really catch this statically as that
332-
// goes through raw pointers and intermediate temporaries, so miri has
333-
// to catch this anyway
334-
335-
self.tcx.sess.span_err(
336-
self.span,
337-
"cannot mutate statics in the initializer of another static",
338-
);
339-
} else {
329+
} else if self.const_kind() != ConstKind::Static || !context.is_mutating_use() {
340330
self.check_op(ops::StaticAccess);
341331
}
342332
}

src/librustc_mir/transform/const_prop.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc::ty::subst::InternalSubsts;
2222
use rustc_data_structures::fx::FxHashMap;
2323
use rustc_index::vec::IndexVec;
2424
use rustc::ty::layout::{
25-
LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
25+
LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
2626
};
2727

2828
use crate::rustc::ty::subst::Subst;
@@ -35,6 +35,9 @@ use crate::interpret::{
3535
use crate::const_eval::error_to_const_error;
3636
use crate::transform::{MirPass, MirSource};
3737

38+
/// The maximum number of bytes that we'll allocate space for a return value.
39+
const MAX_ALLOC_LIMIT: u64 = 1024;
40+
3841
pub struct ConstProp;
3942

4043
impl<'tcx> MirPass<'tcx> for ConstProp {
@@ -313,8 +316,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
313316
ecx
314317
.layout_of(body.return_ty().subst(tcx, substs))
315318
.ok()
316-
// Don't bother allocating memory for ZST types which have no values.
317-
.filter(|ret_layout| !ret_layout.is_zst())
319+
// Don't bother allocating memory for ZST types which have no values
320+
// or for large values.
321+
.filter(|ret_layout| !ret_layout.is_zst() &&
322+
ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT))
318323
.map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack));
319324

320325
ecx.push_stack_frame(
@@ -453,6 +458,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
453458
) -> Option<()> {
454459
let span = source_info.span;
455460

461+
// #66397: Don't try to eval into large places as that can cause an OOM
462+
if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) {
463+
return None;
464+
}
465+
456466
let overflow_check = self.tcx.sess.overflow_checks();
457467

458468
// Perform any special handling for specific Rvalue types.

src/librustc_mir/transform/qualify_consts.rs

-13
Original file line numberDiff line numberDiff line change
@@ -787,19 +787,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
787787

788788
// Only allow statics (not consts) to refer to other statics.
789789
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
790-
if self.mode == Mode::Static
791-
&& context.is_mutating_use()
792-
&& !self.suppress_errors
793-
{
794-
// this is not strictly necessary as miri will also bail out
795-
// For interior mutability we can't really catch this statically as that
796-
// goes through raw pointers and intermediate temporaries, so miri has
797-
// to catch this anyway
798-
self.tcx.sess.span_err(
799-
self.span,
800-
"cannot mutate statics in the initializer of another static",
801-
);
802-
}
803790
return;
804791
}
805792
unleash_miri!(self);

src/librustc_resolve/late.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
17671767

17681768
fn with_resolved_label(&mut self, label: Option<Label>, id: NodeId, f: impl FnOnce(&mut Self)) {
17691769
if let Some(label) = label {
1770-
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
1770+
if label.ident.as_str().as_bytes()[1] != b'_' {
1771+
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
1772+
}
17711773
self.with_label_rib(NormalRibKind, |this| {
17721774
let ident = label.ident.modern_and_legacy();
17731775
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);

src/librustc_typeck/check/generator_interior.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
244244
// can be reborrowed without needing to spill to a temporary.
245245
// If this were not the case, then we could conceivably have
246246
// to create intermediate temporaries.)
247-
let ty = self.fcx.tables.borrow().expr_ty(expr);
248-
self.record(ty, scope, Some(expr), expr.span);
247+
//
248+
// The type table might not have information for this expression
249+
// if it is in a malformed scope. (#66387)
250+
if let Some(ty) = self.fcx.tables.borrow().expr_ty_opt(expr) {
251+
self.record(ty, scope, Some(expr), expr.span);
252+
} else {
253+
self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
254+
}
249255
}
250256
}

src/librustc_typeck/check/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3108,7 +3108,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31083108
fallback_has_occurred: bool,
31093109
mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
31103110
) {
3111-
if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
3111+
let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3112+
if let Err(mut errors) = result {
31123113
mutate_fullfillment_errors(&mut errors);
31133114
self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
31143115
}

src/libstd/error.rs

+12-80
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,9 @@ impl dyn Error {
725725
/// Returns an iterator starting with the current error and continuing with
726726
/// recursively calling [`source`].
727727
///
728+
/// If you want to omit the current error and only use its sources,
729+
/// use `skip(1)`.
730+
///
728731
/// # Examples
729732
///
730733
/// ```
@@ -763,7 +766,7 @@ impl dyn Error {
763766
/// // let err : Box<Error> = b.into(); // or
764767
/// let err = &b as &(dyn Error);
765768
///
766-
/// let mut iter = err.iter_chain();
769+
/// let mut iter = err.chain();
767770
///
768771
/// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
769772
/// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
@@ -774,98 +777,27 @@ impl dyn Error {
774777
/// [`source`]: trait.Error.html#method.source
775778
#[unstable(feature = "error_iter", issue = "58520")]
776779
#[inline]
777-
pub fn iter_chain(&self) -> ErrorIter<'_> {
778-
ErrorIter {
780+
pub fn chain(&self) -> Chain<'_> {
781+
Chain {
779782
current: Some(self),
780783
}
781784
}
782-
783-
/// Returns an iterator starting with the [`source`] of this error
784-
/// and continuing with recursively calling [`source`].
785-
///
786-
/// # Examples
787-
///
788-
/// ```
789-
/// #![feature(error_iter)]
790-
/// use std::error::Error;
791-
/// use std::fmt;
792-
///
793-
/// #[derive(Debug)]
794-
/// struct A;
795-
///
796-
/// #[derive(Debug)]
797-
/// struct B(Option<Box<dyn Error + 'static>>);
798-
///
799-
/// #[derive(Debug)]
800-
/// struct C(Option<Box<dyn Error + 'static>>);
801-
///
802-
/// impl fmt::Display for A {
803-
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
804-
/// write!(f, "A")
805-
/// }
806-
/// }
807-
///
808-
/// impl fmt::Display for B {
809-
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
810-
/// write!(f, "B")
811-
/// }
812-
/// }
813-
///
814-
/// impl fmt::Display for C {
815-
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
816-
/// write!(f, "C")
817-
/// }
818-
/// }
819-
///
820-
/// impl Error for A {}
821-
///
822-
/// impl Error for B {
823-
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
824-
/// self.0.as_ref().map(|e| e.as_ref())
825-
/// }
826-
/// }
827-
///
828-
/// impl Error for C {
829-
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
830-
/// self.0.as_ref().map(|e| e.as_ref())
831-
/// }
832-
/// }
833-
///
834-
/// let b = B(Some(Box::new(A)));
835-
/// let c = C(Some(Box::new(b)));
836-
///
837-
/// // let err : Box<Error> = c.into(); // or
838-
/// let err = &c as &(dyn Error);
839-
///
840-
/// let mut iter = err.iter_sources();
841-
///
842-
/// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
843-
/// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
844-
/// assert!(iter.next().is_none());
845-
/// assert!(iter.next().is_none());
846-
/// ```
847-
///
848-
/// [`source`]: trait.Error.html#method.source
849-
#[inline]
850-
#[unstable(feature = "error_iter", issue = "58520")]
851-
pub fn iter_sources(&self) -> ErrorIter<'_> {
852-
ErrorIter {
853-
current: self.source(),
854-
}
855-
}
856785
}
857786

858-
/// An iterator over [`Error`]
787+
/// An iterator over an [`Error`] and its sources.
788+
///
789+
/// If you want to omit the initial error and only process
790+
/// its sources, use `skip(1)`.
859791
///
860792
/// [`Error`]: trait.Error.html
861793
#[unstable(feature = "error_iter", issue = "58520")]
862794
#[derive(Copy, Clone, Debug)]
863-
pub struct ErrorIter<'a> {
795+
pub struct Chain<'a> {
864796
current: Option<&'a (dyn Error + 'static)>,
865797
}
866798

867799
#[unstable(feature = "error_iter", issue = "58520")]
868-
impl<'a> Iterator for ErrorIter<'a> {
800+
impl<'a> Iterator for Chain<'a> {
869801
type Item = &'a (dyn Error + 'static);
870802

871803
fn next(&mut self) -> Option<Self::Item> {

0 commit comments

Comments
 (0)