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 14 pull requests #78311

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
16e10bf
Revert "Allow dynamic linking for iOS/tvOS targets."
francesca64 Oct 7, 2020
b62b352
Check for exhaustion in RangeInclusive::contains
cuviper Oct 19, 2020
9fd79a3
make exhausted RangeInclusive::end_bound return Excluded(end)
cuviper Oct 19, 2020
a9470d0
Simplify assert terminator only if condition evaluates to expected value
tmiasko Oct 21, 2020
9202fbd
Check for exhaustion in SliceIndex for RangeInclusive
cuviper Oct 21, 2020
40ab18d
improve const infer error
lcnr Oct 22, 2020
9775ac6
Document inline-const in the Unstable Book
camelid Oct 22, 2020
09135e4
Add regression test for issue-77475
JohnTitor Oct 23, 2020
e1c524c
review
lcnr Oct 23, 2020
50e34d6
Do not try to report on closures to avoid ICE
JohnTitor Oct 23, 2020
9b90e17
add `insert` and `insert_with` to `Option`
Canop Oct 1, 2020
e8df2a4
remove `option.insert_with`
Canop Oct 1, 2020
60a96ca
more tests in option.insert, code cleaning in option
Canop Oct 1, 2020
cc8b77a
fix naming unconsistency between function doc and prototype
Canop Oct 3, 2020
3955779
Update library/core/src/option.rs
Canop Oct 23, 2020
415a8e5
Update library/core/src/option.rs
Canop Oct 23, 2020
216d0fe
add tracking issue number to option_insert feature gate
Canop Oct 23, 2020
efedcb2
Update description of Empty Enum for accuracy
Enet4 Oct 23, 2020
972d9e8
move `visit_predicate` into `TypeVisitor`
lcnr Oct 23, 2020
a0ce1e0
Always store Rustdoc theme when it's changed
nasso Oct 23, 2020
c3cbaf6
x.py test --test-args flag description enhancement
njasm Oct 22, 2020
929f80e
Add a spin loop hint for Arc::downgrade
nicbn Sep 12, 2020
f3265fe
Fix Ubuntu download URL
jonas-schievink Oct 23, 2020
589537f
Rollup merge of #76649 - nicbn:arc-spin-loop-hint, r=m-ou-se
jonas-schievink Oct 23, 2020
2918e14
Rollup merge of #77392 - Canop:option_insert, r=m-ou-se
jonas-schievink Oct 23, 2020
b168abe
Rollup merge of #77716 - francesca64:revert-ios-dynamic-linking, r=jo…
jonas-schievink Oct 23, 2020
d2a6f8e
Rollup merge of #78109 - cuviper:exhausted-rangeinc, r=dtolnay
jonas-schievink Oct 23, 2020
47ff2ff
Rollup merge of #78198 - tmiasko:assert, r=davidtwco
jonas-schievink Oct 23, 2020
d3f33be
Rollup merge of #78243 - njasm:patch_test_args_description, r=jyn514
jonas-schievink Oct 23, 2020
02af194
Rollup merge of #78249 - lcnr:ct-infer-origin, r=varkor
jonas-schievink Oct 23, 2020
db148ad
Rollup merge of #78250 - camelid:document-inline-const, r=spastorino
jonas-schievink Oct 23, 2020
f94099a
Rollup merge of #78264 - JohnTitor:macro-test, r=petrochenkov
jonas-schievink Oct 23, 2020
90aa72b
Rollup merge of #78268 - JohnTitor:issue-78262, r=estebank
jonas-schievink Oct 23, 2020
0fee325
Rollup merge of #78274 - Enet4:patch-1, r=jonas-schievink
jonas-schievink Oct 23, 2020
f7a56d7
Rollup merge of #78278 - lcnr:predicate-visit, r=matthewjasper
jonas-schievink Oct 23, 2020
d48f449
Rollup merge of #78293 - nasso:master, r=GuillaumeGomez
jonas-schievink Oct 23, 2020
5f61b55
Rollup merge of #78309 - jonas-schievink:fix-ci, r=pietroalbini
jonas-schievink Oct 23, 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
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
) if **sub_r == RegionKind::ReStatic => {
// This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
if let ObligationCauseCode::UnifyReceiver(ctxt) = &cause.code {
// This may have a closure and it would cause ICE
// through `find_param_with_region` (#78262).
let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
if fn_returns.is_empty() {
return None;
}

let param = self.find_param_with_region(sup_r, sub_r)?;
let lifetime = if sup_r.has_name() {
format!("lifetime `{}`", sup_r)
Expand Down
25 changes: 8 additions & 17 deletions compiler/rustc_middle/src/infer/unify_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,19 +175,15 @@ impl<'tcx> UnifyKey for ty::ConstVid<'tcx> {
impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>);

fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
let (val, span) = match (value1.val, value2.val) {
fn unify_values(&value1: &Self, &value2: &Self) -> Result<Self, Self::Error> {
Ok(match (value1.val, value2.val) {
(ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
bug!("equating two const variables, both of which have known values")
}

// If one side is known, prefer that one.
(ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => {
(value1.val, value1.origin.span)
}
(ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => {
(value2.val, value2.origin.span)
}
(ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => value1,
(ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => value2,

// If both sides are *unknown*, it hardly matters, does it?
(
Expand All @@ -200,16 +196,11 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> {
// universe is the minimum of the two universes, because that is
// the one which contains the fewest names in scope.
let universe = cmp::min(universe1, universe2);
(ConstVariableValue::Unknown { universe }, value1.origin.span)
ConstVarValue {
val: ConstVariableValue::Unknown { universe },
origin: value1.origin,
}
}
};

Ok(ConstVarValue {
origin: ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstInference,
span: span,
},
val,
})
}
}
Expand Down
11 changes: 5 additions & 6 deletions compiler/rustc_middle/src/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
//!
//! These methods return true to indicate that the visitor has found what it is
//! looking for, and does not need to visit anything else.

use crate::ty::structural_impls::PredicateVisitor;
use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
Expand Down Expand Up @@ -211,6 +209,10 @@ pub trait TypeVisitor<'tcx>: Sized {
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
c.super_visit_with(self)
}

fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> bool {
p.super_visit_with(self)
}
}

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -868,9 +870,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
_ => ct.super_visit_with(self),
}
}
}

impl<'tcx> PredicateVisitor<'tcx> for HasEscapingVarsVisitor {
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
predicate.inner.outer_exclusive_binder > self.outer_index
}
Expand Down Expand Up @@ -903,9 +903,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
flags.intersects(self.flags)
}
}

impl<'tcx> PredicateVisitor<'tcx> for HasTypeFlagsVisitor {
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
debug!(
"HasTypeFlagsVisitor: predicate={:?} predicate.flags={:?} self.flags={:?}",
Expand All @@ -914,6 +912,7 @@ impl<'tcx> PredicateVisitor<'tcx> for HasTypeFlagsVisitor {
predicate.inner.flags.intersects(self.flags)
}
}

/// Collects all the late-bound regions at the innermost binding level
/// into a hash set.
struct LateBoundRegionsCollector {
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,16 +1040,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
}
}

pub(super) trait PredicateVisitor<'tcx>: TypeVisitor<'tcx> {
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool;
}

impl<T: TypeVisitor<'tcx>> PredicateVisitor<'tcx> for T {
default fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
predicate.super_visit_with(self)
}
}

impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
fold_list(*self, folder, |tcx, v| tcx.intern_predicates(v))
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_mir/src/transform/simplify_branches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches {
}
TerminatorKind::Assert {
target, cond: Operand::Constant(ref c), expected, ..
} if (c.literal.try_eval_bool(tcx, param_env) == Some(true)) == expected => {
TerminatorKind::Goto { target }
}
} => match c.literal.try_eval_bool(tcx, param_env) {
Some(v) if v == expected => TerminatorKind::Goto { target },
_ => continue,
},
TerminatorKind::FalseEdge { real_target, .. } => {
TerminatorKind::Goto { target: real_target }
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/apple_sdk_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ fn link_env_remove(arch: Arch) -> Vec<String> {
pub fn opts(arch: Arch) -> TargetOptions {
TargetOptions {
cpu: target_cpu(arch),
dynamic_linking: false,
executables: true,
link_env_remove: link_env_remove(arch),
has_elf_tls: false,
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
#![feature(raw_ref_op)]
#![feature(rustc_attrs)]
#![feature(receiver_trait)]
#![feature(renamed_spin_loop)]
#![feature(min_specialization)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use core::cmp::Ordering;
use core::convert::{From, TryFrom};
use core::fmt;
use core::hash::{Hash, Hasher};
use core::hint;
use core::intrinsics::abort;
use core::iter;
use core::marker::{PhantomData, Unpin, Unsize};
Expand Down Expand Up @@ -764,6 +765,7 @@ impl<T: ?Sized> Arc<T> {
loop {
// check if the weak counter is currently "locked"; if so, spin.
if cur == usize::MAX {
hint::spin_loop();
cur = this.inner().weak.load(Relaxed);
continue;
}
Expand Down
29 changes: 29 additions & 0 deletions library/alloc/tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,13 @@ mod slice_index {
message: "out of bounds";
}

in mod rangeinclusive_len {
data: "abcdef";
good: data[0..=5] == "abcdef";
bad: data[0..=6];
message: "out of bounds";
}

in mod range_len_len {
data: "abcdef";
good: data[6..6] == "";
Expand All @@ -544,6 +551,28 @@ mod slice_index {
}
}

panic_cases! {
in mod rangeinclusive_exhausted {
data: "abcdef";

good: data[0..=5] == "abcdef";
good: data[{
let mut iter = 0..=5;
iter.by_ref().count(); // exhaust it
iter
}] == "";

// 0..=6 is out of bounds before exhaustion, so it
// stands to reason that it still would be after.
bad: data[{
let mut iter = 0..=6;
iter.by_ref().count(); // exhaust it
iter
}];
message: "out of bounds";
}
}

panic_cases! {
in mod range_neg_width {
data: "abcdef";
Expand Down
32 changes: 31 additions & 1 deletion library/core/src/ops/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,20 @@ impl<Idx> RangeInclusive<Idx> {
}
}

impl RangeInclusive<usize> {
/// Converts to an exclusive `Range` for `SliceIndex` implementations.
/// The caller is responsible for dealing with `end == usize::MAX`.
#[inline]
pub(crate) fn into_slice_range(self) -> Range<usize> {
// If we're not exhausted, we want to simply slice `start..end + 1`.
// If we are exhausted, then slicing with `end + 1..end + 1` gives us an
// empty range that is still subject to bounds-checks for that endpoint.
let exclusive_end = self.end + 1;
let start = if self.exhausted { exclusive_end } else { self.start };
start..exclusive_end
}
}

#[stable(feature = "inclusive_range", since = "1.26.0")]
impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -479,6 +493,16 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// assert!(!(0.0..=f32::NAN).contains(&0.0));
/// assert!(!(f32::NAN..=1.0).contains(&1.0));
/// ```
///
/// This method always returns `false` after iteration has finished:
///
/// ```
/// let mut r = 3..=5;
/// assert!(r.contains(&3) && r.contains(&5));
/// for _ in r.by_ref() {}
/// // Precise field values are unspecified here
/// assert!(!r.contains(&3) && !r.contains(&5));
/// ```
#[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
Expand Down Expand Up @@ -881,7 +905,13 @@ impl<T> RangeBounds<T> for RangeInclusive<T> {
Included(&self.start)
}
fn end_bound(&self) -> Bound<&T> {
Included(&self.end)
if self.exhausted {
// When the iterator is exhausted, we usually have start == end,
// but we want the range to appear empty, containing nothing.
Excluded(&self.end)
} else {
Included(&self.end)
}
}
}

Expand Down
44 changes: 37 additions & 7 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,36 @@ impl<T> Option<T> {
}
}

/// Inserts `value` into the option then returns a mutable reference to it.
///
/// If the option already contains a value, the old value is dropped.
///
/// # Example
///
/// ```
/// #![feature(option_insert)]
///
/// let mut opt = None;
/// let val = opt.insert(1);
/// assert_eq!(*val, 1);
/// assert_eq!(opt.unwrap(), 1);
/// let val = opt.insert(2);
/// assert_eq!(*val, 2);
/// *val = 3;
/// assert_eq!(opt.unwrap(), 3);
/// ```
#[inline]
#[unstable(feature = "option_insert", reason = "newly added", issue = "78271")]
pub fn insert(&mut self, value: T) -> &mut T {
*self = Some(value);

match self {
Some(v) => v,
// SAFETY: the code above just filled the option
None => unsafe { hint::unreachable_unchecked() },
}
}

/////////////////////////////////////////////////////////////////////////
// Iterator constructors
/////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -792,7 +822,7 @@ impl<T> Option<T> {
// Entry-like operations to insert if None and return a reference
/////////////////////////////////////////////////////////////////////////

/// Inserts `v` into the option if it is [`None`], then
/// Inserts `value` into the option if it is [`None`], then
/// returns a mutable reference to the contained value.
///
/// # Examples
Expand All @@ -811,12 +841,12 @@ impl<T> Option<T> {
/// ```
#[inline]
#[stable(feature = "option_entry", since = "1.20.0")]
pub fn get_or_insert(&mut self, v: T) -> &mut T {
self.get_or_insert_with(|| v)
pub fn get_or_insert(&mut self, value: T) -> &mut T {
self.get_or_insert_with(|| value)
}

/// Inserts a value computed from `f` into the option if it is [`None`], then
/// returns a mutable reference to the contained value.
/// Inserts a value computed from `f` into the option if it is [`None`],
/// then returns a mutable reference to the contained value.
///
/// # Examples
///
Expand All @@ -839,8 +869,8 @@ impl<T> Option<T> {
*self = Some(f());
}

match *self {
Some(ref mut v) => v,
match self {
Some(v) => v,
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
// variant in the code above.
None => unsafe { hint::unreachable_unchecked() },
Expand Down
16 changes: 6 additions & 10 deletions library/core/src/slice/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,44 +376,40 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {

#[inline]
fn get(self, slice: &[T]) -> Option<&[T]> {
if *self.end() == usize::MAX { None } else { (*self.start()..self.end() + 1).get(slice) }
if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
}

#[inline]
fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
if *self.end() == usize::MAX {
None
} else {
(*self.start()..self.end() + 1).get_mut(slice)
}
if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
}

#[inline]
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
unsafe { (*self.start()..self.end() + 1).get_unchecked(slice) }
unsafe { self.into_slice_range().get_unchecked(slice) }
}

#[inline]
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
unsafe { (*self.start()..self.end() + 1).get_unchecked_mut(slice) }
unsafe { self.into_slice_range().get_unchecked_mut(slice) }
}

#[inline]
fn index(self, slice: &[T]) -> &[T] {
if *self.end() == usize::MAX {
slice_end_index_overflow_fail();
}
(*self.start()..self.end() + 1).index(slice)
self.into_slice_range().index(slice)
}

#[inline]
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
if *self.end() == usize::MAX {
slice_end_index_overflow_fail();
}
(*self.start()..self.end() + 1).index_mut(slice)
self.into_slice_range().index_mut(slice)
}
}

Expand Down
Loading