Skip to content
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

Rollup of 12 pull requests #66436

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7b9d50d
rename Error::iter_chain() and remove Error::iter_sources()
haraldh Oct 15, 2019
1aceaaa
Avoid hashing the key twice in `get_query()`.
nnethercote Oct 31, 2019
b941034
qualify-const remove cannot mutate statics in initializer of another …
spastorino Nov 11, 2019
695e91a
check-consts remove cannot mutate statics in initializer of another s…
spastorino Nov 12, 2019
139477d
Update mdbook.
ehuss Nov 12, 2019
32d1f47
Fix mdbook-linkcheck license checks.
ehuss Nov 12, 2019
bc1bd95
Do not ICE on recovery from unmet associated type bound obligation
estebank Nov 13, 2019
4137263
Fix ICE when trying to suggest `Type<>` instead of `Type()`
estebank Nov 13, 2019
7d61484
Do not ICE in `if` without `else` in `async fn`
estebank Nov 13, 2019
37de933
Fix spurious CI filures due to OOM
wesleywiser Nov 14, 2019
3fe7cfc
Remove some stack frames from `.async` calls
sfackler Nov 14, 2019
92154d0
[ConstProp] Avoid OOM crashes by not evaluating large Places
wesleywiser Nov 14, 2019
6c9ba97
miri: helper methods for max values of machine's usize/isize
RalfJung Nov 14, 2019
0c52c3e
Respond to review feedback
wesleywiser Nov 14, 2019
336e332
Link to tracking issue in HIR const-check error
ecstatic-morse Nov 14, 2019
4349228
Don't warn labels beginning with `_`
JohnTitor Nov 14, 2019
c0a0a7d
review comments
estebank Nov 14, 2019
b884205
review comments
estebank Nov 14, 2019
3bd5226
Use different size on 32bit
wesleywiser Nov 15, 2019
006c62d
Rollup merge of #65557 - haraldh:error_iter_rename, r=sfackler
JohnTitor Nov 15, 2019
c858c63
Rollup merge of #66013 - nnethercote:avoid-hashing-twice-in-get_query…
JohnTitor Nov 15, 2019
b3fec2b
Rollup merge of #66306 - spastorino:remove-error-handled-by-miri, r=o…
JohnTitor Nov 15, 2019
c5e6692
Rollup merge of #66338 - ehuss:update-mdbook, r=alexcrichton
JohnTitor Nov 15, 2019
180de59
Rollup merge of #66388 - estebank:melt-ice, r=Centril
JohnTitor Nov 15, 2019
1452a83
Rollup merge of #66390 - estebank:parenice, r=Centril
JohnTitor Nov 15, 2019
b13272f
Rollup merge of #66391 - estebank:if-else-async-ice, r=Centril
JohnTitor Nov 15, 2019
4081586
Rollup merge of #66394 - wesleywiser:fix_oom, r=oli-obk
JohnTitor Nov 15, 2019
134d248
Rollup merge of #66398 - sfackler:no-async-nesting, r=Centril
JohnTitor Nov 15, 2019
65873cc
Rollup merge of #66410 - RalfJung:miri-machine-max, r=oli-obk
JohnTitor Nov 15, 2019
fc8a76e
Rollup merge of #66418 - ecstatic-morse:hir-const-check-err-msg, r=es…
JohnTitor Nov 15, 2019
175f296
Rollup merge of #66419 - JohnTitor:ignore-underscore, r=varkor
JohnTitor Nov 15, 2019
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
347 changes: 172 additions & 175 deletions Cargo.lock

Large diffs are not rendered by default.

19 changes: 10 additions & 9 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1862,15 +1862,16 @@ impl<'a> LoweringContext<'a> {
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
// Do not suggest going from `Trait()` to `Trait<>`
if data.inputs.len() > 0 {
let split = snippet.find('(').unwrap();
let trait_name = &snippet[0..split];
let args = &snippet[split + 1 .. snippet.len() - 1];
err.span_suggestion(
data.span,
"use angle brackets instead",
format!("{}<{}>", trait_name, args),
Applicability::MaybeIncorrect,
);
if let Some(split) = snippet.find('(') {
let trait_name = &snippet[0..split];
let args = &snippet[split + 1 .. snippet.len() - 1];
err.span_suggestion(
data.span,
"use angle brackets instead",
format!("{}<{}>", trait_name, args),
Applicability::MaybeIncorrect,
);
}
}
};
err.emit();
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#![feature(log_syntax)]
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
#![feature(hash_raw_entry)]

#![recursion_limit="512"]

Expand Down
13 changes: 13 additions & 0 deletions src/librustc/mir/interpret/pointer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt::{self, Display};
use std::convert::TryFrom;

use crate::mir;
use crate::ty::layout::{self, HasDataLayout, Size};
Expand Down Expand Up @@ -40,6 +41,18 @@ pub trait PointerArithmetic: layout::HasDataLayout {
self.data_layout().pointer_size
}

#[inline]
fn usize_max(&self) -> u64 {
let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
u64::try_from(max_usize_plus_1-1).unwrap()
}

#[inline]
fn isize_max(&self) -> i64 {
let max_isize_plus_1 = 1u128 << (self.pointer_size().bits()-1);
i64::try_from(max_isize_plus_1-1).unwrap()
}

/// Helper function: truncate given value-"overflowed flag" pair to pointer size and
/// update "overflowed flag" if there was an overflow.
/// This should be called by all the other methods before returning!
Expand Down
16 changes: 13 additions & 3 deletions src/librustc/ty/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ use errors::Level;
use errors::Diagnostic;
use errors::FatalError;
use errors::Handler;
use rustc_data_structures::fx::{FxHashMap};
use rustc_data_structures::fx::{FxHasher, FxHashMap};
use rustc_data_structures::sync::{Lrc, Lock};
use rustc_data_structures::sharded::Sharded;
use rustc_data_structures::thin_vec::ThinVec;
#[cfg(not(parallel_compiler))]
use rustc_data_structures::cold_path;
use std::hash::{Hash, Hasher};
use std::mem;
use std::ptr;
use std::collections::hash_map::Entry;
Expand Down Expand Up @@ -82,8 +83,17 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
pub(super) fn try_get(tcx: TyCtxt<'tcx>, span: Span, key: &Q::Key) -> TryGetJob<'a, 'tcx, Q> {
let cache = Q::query_cache(tcx);
loop {
let mut lock = cache.get_shard_by_value(key).lock();
if let Some(value) = lock.results.get(key) {
// We compute the key's hash once and then use it for both the
// shard lookup and the hashmap lookup. This relies on the fact
// that both of them use `FxHasher`.
let mut state = FxHasher::default();
key.hash(&mut state);
let key_hash = state.finish();

let mut lock = cache.get_shard_by_hash(key_hash).lock();
if let Some((_, value)) =
lock.results.raw_entry().from_key_hashed_nocheck(key_hash, key)
{
tcx.prof.query_cache_hit(Q::NAME);
let result = (value.value.clone(), value.index);
#[cfg(debug_assertions)]
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_data_structures/sharded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ impl<T> Sharded<T> {
}
}

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

/// Get a shard with a pre-computed hash value. If `get_shard_by_value` is
/// ever used in combination with `get_shard_by_hash` on a single `Sharded`
/// instance, then `hash` must be computed with `FxHasher`. Otherwise,
/// `hash` can be computed with any hasher, so long as that hasher is used
/// consistently for each `Sharded` instance.
#[inline]
pub fn get_shard_by_hash(&self, hash: u64) -> &Lock<T> {
let hash_len = mem::size_of::<usize>();
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_error_codes/error_codes/E0744.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ const _: i32 = {
x
};
```

This will be allowed at some point in the future, but the implementation is not
yet complete. See the tracking issue for [conditionals] or [loops] in a const
context for the current status.

[conditionals]: https://github.com/rust-lang/rust/issues/49146
[loops]: https://github.com/rust-lang/rust/issues/52000
12 changes: 1 addition & 11 deletions src/librustc_mir/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,17 +326,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
let is_thread_local = self.tcx.has_attr(*def_id, sym::thread_local);
if is_thread_local {
self.check_op(ops::ThreadLocalAccess);
} else if self.const_kind() == ConstKind::Static && context.is_mutating_use() {
// this is not strictly necessary as miri will also bail out
// For interior mutability we can't really catch this statically as that
// goes through raw pointers and intermediate temporaries, so miri has
// to catch this anyway

self.tcx.sess.span_err(
self.span,
"cannot mutate statics in the initializer of another static",
);
} else {
} else if self.const_kind() != ConstKind::Static || !context.is_mutating_use() {
self.check_op(ops::StaticAccess);
}
}
Expand Down
16 changes: 13 additions & 3 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc::ty::subst::InternalSubsts;
use rustc_data_structures::fx::FxHashMap;
use rustc_index::vec::IndexVec;
use rustc::ty::layout::{
LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
};

use crate::rustc::ty::subst::Subst;
Expand All @@ -35,6 +35,9 @@ use crate::interpret::{
use crate::const_eval::error_to_const_error;
use crate::transform::{MirPass, MirSource};

/// The maximum number of bytes that we'll allocate space for a return value.
const MAX_ALLOC_LIMIT: u64 = 1024;

pub struct ConstProp;

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

ecx.push_stack_frame(
Expand Down Expand Up @@ -453,6 +458,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
) -> Option<()> {
let span = source_info.span;

// #66397: Don't try to eval into large places as that can cause an OOM
if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) {
return None;
}

let overflow_check = self.tcx.sess.overflow_checks();

// Perform any special handling for specific Rvalue types.
Expand Down
13 changes: 0 additions & 13 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,19 +787,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {

// Only allow statics (not consts) to refer to other statics.
if self.mode == Mode::Static || self.mode == Mode::StaticMut {
if self.mode == Mode::Static
&& context.is_mutating_use()
&& !self.suppress_errors
{
// this is not strictly necessary as miri will also bail out
// For interior mutability we can't really catch this statically as that
// goes through raw pointers and intermediate temporaries, so miri has
// to catch this anyway
self.tcx.sess.span_err(
self.span,
"cannot mutate statics in the initializer of another static",
);
}
return;
}
unleash_miri!(self);
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_resolve/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {

fn with_resolved_label(&mut self, label: Option<Label>, id: NodeId, f: impl FnOnce(&mut Self)) {
if let Some(label) = label {
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
if label.ident.as_str().as_bytes()[1] != b'_' {
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
}
self.with_label_rib(NormalRibKind, |this| {
let ident = label.ident.modern_and_legacy();
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
Expand Down
10 changes: 8 additions & 2 deletions src/librustc_typeck/check/generator_interior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
// can be reborrowed without needing to spill to a temporary.
// If this were not the case, then we could conceivably have
// to create intermediate temporaries.)
let ty = self.fcx.tables.borrow().expr_ty(expr);
self.record(ty, scope, Some(expr), expr.span);
//
// The type table might not have information for this expression
// if it is in a malformed scope. (#66387)
if let Some(ty) = self.fcx.tables.borrow().expr_ty_opt(expr) {
self.record(ty, scope, Some(expr), expr.span);
} else {
self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
}
}
}
3 changes: 2 additions & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3108,7 +3108,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fallback_has_occurred: bool,
mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
) {
if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
if let Err(mut errors) = result {
mutate_fullfillment_errors(&mut errors);
self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
}
Expand Down
92 changes: 12 additions & 80 deletions src/libstd/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,9 @@ impl dyn Error {
/// Returns an iterator starting with the current error and continuing with
/// recursively calling [`source`].
///
/// If you want to omit the current error and only use its sources,
/// use `skip(1)`.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -763,7 +766,7 @@ impl dyn Error {
/// // let err : Box<Error> = b.into(); // or
/// let err = &b as &(dyn Error);
///
/// let mut iter = err.iter_chain();
/// let mut iter = err.chain();
///
/// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
/// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
Expand All @@ -774,98 +777,27 @@ impl dyn Error {
/// [`source`]: trait.Error.html#method.source
#[unstable(feature = "error_iter", issue = "58520")]
#[inline]
pub fn iter_chain(&self) -> ErrorIter<'_> {
ErrorIter {
pub fn chain(&self) -> Chain<'_> {
Chain {
current: Some(self),
}
}

/// Returns an iterator starting with the [`source`] of this error
/// and continuing with recursively calling [`source`].
///
/// # Examples
///
/// ```
/// #![feature(error_iter)]
/// use std::error::Error;
/// use std::fmt;
///
/// #[derive(Debug)]
/// struct A;
///
/// #[derive(Debug)]
/// struct B(Option<Box<dyn Error + 'static>>);
///
/// #[derive(Debug)]
/// struct C(Option<Box<dyn Error + 'static>>);
///
/// impl fmt::Display for A {
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// write!(f, "A")
/// }
/// }
///
/// impl fmt::Display for B {
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// write!(f, "B")
/// }
/// }
///
/// impl fmt::Display for C {
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// write!(f, "C")
/// }
/// }
///
/// impl Error for A {}
///
/// impl Error for B {
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
/// self.0.as_ref().map(|e| e.as_ref())
/// }
/// }
///
/// impl Error for C {
/// fn source(&self) -> Option<&(dyn Error + 'static)> {
/// self.0.as_ref().map(|e| e.as_ref())
/// }
/// }
///
/// let b = B(Some(Box::new(A)));
/// let c = C(Some(Box::new(b)));
///
/// // let err : Box<Error> = c.into(); // or
/// let err = &c as &(dyn Error);
///
/// let mut iter = err.iter_sources();
///
/// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
/// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
/// assert!(iter.next().is_none());
/// assert!(iter.next().is_none());
/// ```
///
/// [`source`]: trait.Error.html#method.source
#[inline]
#[unstable(feature = "error_iter", issue = "58520")]
pub fn iter_sources(&self) -> ErrorIter<'_> {
ErrorIter {
current: self.source(),
}
}
}

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

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

fn next(&mut self) -> Option<Self::Item> {
Expand Down
Loading