Skip to content

Commit

Permalink
Auto merge of rust-lang#70747 - Centril:rollup-2vx9bve, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - rust-lang#69860 (Use associated numeric consts in documentation)
 - rust-lang#70576 (Update the description of the ticket to point at RFC 1721)
 - rust-lang#70597 (Fix double-free and undefined behaviour in libstd::syn::unix::Thread::new)
 - rust-lang#70640 (Hide `task_context` when lowering body)
 - rust-lang#70641 (Remove duplicated code in trait selection)
 - rust-lang#70707 (Remove unused graphviz emitter)
 - rust-lang#70720 (Place TLS initializers with relocations in .tdata)
 - rust-lang#70735 (Clean up E0502 explanation)
 - rust-lang#70741 (Add test for rust-lang#59023)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Apr 3, 2020
2 parents f6fe99c + 4c41ea3 commit 74bd074
Show file tree
Hide file tree
Showing 41 changed files with 283 additions and 709 deletions.
2 changes: 1 addition & 1 deletion src/liballoc/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ impl<T> [T] {
///
/// ```should_panic
/// // this will panic at runtime
/// b"0123456789abcdef".repeat(usize::max_value());
/// b"0123456789abcdef".repeat(usize::MAX);
/// ```
#[stable(feature = "repeat_generic_slice", since = "1.40.0")]
pub fn repeat(&self, n: usize) -> Vec<T>
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ impl str {
///
/// ```should_panic
/// // this will panic at runtime
/// "0123456789abcdef".repeat(usize::max_value());
/// "0123456789abcdef".repeat(usize::MAX);
/// ```
#[stable(feature = "repeat_str", since = "1.16.0")]
pub fn repeat(&self, n: usize) -> String {
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
/// When comparison is impossible:
///
/// ```
/// let result = std::f64::NAN.partial_cmp(&1.0);
/// let result = f64::NAN.partial_cmp(&1.0);
/// assert_eq!(result, None);
/// ```
#[must_use]
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,7 @@ pub trait LowerHex {
/// }
/// }
///
/// let l = Length(i32::max_value());
/// let l = Length(i32::MAX);
///
/// assert_eq!(format!("l as hex is: {:X}", l), "l as hex is: 7FFFFFFF");
///
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use crate::intrinsics;
///
/// assert_eq!(div_1(7, 0), 7);
/// assert_eq!(div_1(9, 1), 4);
/// assert_eq!(div_1(11, std::u32::MAX), 0);
/// assert_eq!(div_1(11, u32::MAX), 0);
/// ```
#[inline]
#[stable(feature = "unreachable", since = "1.27.0")]
Expand Down
12 changes: 6 additions & 6 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1739,19 +1739,19 @@ extern "rust-intrinsic" {
pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);

/// Performs an exact division, resulting in undefined behavior where
/// `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`
/// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
pub fn exact_div<T: Copy>(x: T, y: T) -> T;

/// Performs an unchecked division, resulting in undefined behavior
/// where y = 0 or x = `T::min_value()` and y = -1
/// where y = 0 or x = `T::MIN` and y = -1
///
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `checked_div` method. For example,
/// [`std::u32::checked_div`](../../std/primitive.u32.html#method.checked_div)
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
/// Returns the remainder of an unchecked division, resulting in
/// undefined behavior where y = 0 or x = `T::min_value()` and y = -1
/// undefined behavior where y = 0 or x = `T::MIN` and y = -1
///
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `checked_rem` method. For example,
Expand All @@ -1777,17 +1777,17 @@ extern "rust-intrinsic" {
pub fn unchecked_shr<T: Copy>(x: T, y: T) -> T;

/// Returns the result of an unchecked addition, resulting in
/// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
/// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;

/// Returns the result of an unchecked subtraction, resulting in
/// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
/// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;

/// Returns the result of an unchecked multiplication, resulting in
/// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
/// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
#[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;

Expand Down
8 changes: 4 additions & 4 deletions src/libcore/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ pub trait Iterator {
/// // and the maximum possible lower bound
/// let iter = 0..;
///
/// assert_eq!((usize::max_value(), None), iter.size_hint());
/// assert_eq!((usize::MAX, None), iter.size_hint());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -2920,7 +2920,7 @@ pub trait Iterator {
/// assert_eq!([1.].iter().partial_cmp([1., 2.].iter()), Some(Ordering::Less));
/// assert_eq!([1., 2.].iter().partial_cmp([1.].iter()), Some(Ordering::Greater));
///
/// assert_eq!([std::f64::NAN].iter().partial_cmp([1.].iter()), None);
/// assert_eq!([f64::NAN].iter().partial_cmp([1.].iter()), None);
/// ```
#[stable(feature = "iter_order", since = "1.5.0")]
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
Expand Down Expand Up @@ -3170,7 +3170,7 @@ pub trait Iterator {
/// assert!(![1, 3, 2, 4].iter().is_sorted());
/// assert!([0].iter().is_sorted());
/// assert!(std::iter::empty::<i32>().is_sorted());
/// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted());
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted());
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
Expand All @@ -3197,7 +3197,7 @@ pub trait Iterator {
/// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
/// ```
///
/// [`is_sorted`]: trait.Iterator.html#method.is_sorted
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ impl f32 {
///
/// let value = -128.9_f32;
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
/// assert_eq!(rounded, std::i8::MIN);
/// assert_eq!(rounded, i8::MIN);
/// ```
///
/// # Safety
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ impl f64 {
///
/// let value = -128.9_f32;
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
/// assert_eq!(rounded, std::i8::MIN);
/// assert_eq!(rounded, i8::MIN);
/// ```
///
/// # Safety
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
/// let zero = Wrapping(0u32);
/// let one = Wrapping(1u32);
///
/// assert_eq!(std::u32::MAX, (zero - one).0);
/// assert_eq!(u32::MAX, (zero - one).0);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
Expand Down
10 changes: 4 additions & 6 deletions src/libcore/ops/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,9 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
/// ```
/// #![feature(range_is_empty)]
///
/// use std::f32::NAN;
/// assert!(!(3.0..5.0).is_empty());
/// assert!( (3.0..NAN).is_empty());
/// assert!( (NAN..5.0).is_empty());
/// assert!( (3.0..f32::NAN).is_empty());
/// assert!( (f32::NAN..5.0).is_empty());
/// ```
#[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")]
pub fn is_empty(&self) -> bool {
Expand Down Expand Up @@ -496,10 +495,9 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// ```
/// #![feature(range_is_empty)]
///
/// use std::f32::NAN;
/// assert!(!(3.0..=5.0).is_empty());
/// assert!( (3.0..=NAN).is_empty());
/// assert!( (NAN..=5.0).is_empty());
/// assert!( (3.0..=f32::NAN).is_empty());
/// assert!( (f32::NAN..=5.0).is_empty());
/// ```
///
/// This method returns `true` after iteration has finished:
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,8 @@ impl<T: ?Sized> *const T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`. It is permissible for the implementation to *always*
/// return `usize::max_value()`. Only your algorithm's performance can depend
/// `usize::MAX`. It is permissible for the implementation to *always*
/// return `usize::MAX`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,8 +847,8 @@ impl<T: ?Sized> *mut T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`. It is permissible for the implementation to *always*
/// return `usize::max_value()`. Only your algorithm's performance can depend
/// `usize::MAX`. It is permissible for the implementation to *always*
/// return `usize::MAX`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2588,7 +2588,7 @@ impl<T> [T] {
/// assert!(![1, 3, 2, 4].is_sorted());
/// assert!([0].is_sorted());
/// assert!(empty.is_sorted());
/// assert!(![0.0, 1.0, std::f32::NAN].is_sorted());
/// assert!(![0.0, 1.0, f32::NAN].is_sorted());
/// ```
#[inline]
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ impl Duration {
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
/// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(std::u64::MAX, 0)), None);
/// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
/// ```
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
#[inline]
Expand Down Expand Up @@ -460,7 +460,7 @@ impl Duration {
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 500_000_001).checked_mul(2), Some(Duration::new(1, 2)));
/// assert_eq!(Duration::new(std::u64::MAX - 1, 0).checked_mul(2), None);
/// assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
/// ```
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
#[inline]
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_ast_lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,8 +972,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
) -> hir::BodyId {
let prev_gen_kind = self.generator_kind.take();
let task_context = self.task_context.take();
let (parameters, result) = f(self);
let body_id = self.record_body(parameters, result);
self.task_context = task_context;
self.generator_kind = prev_gen_kind;
body_id
}
Expand Down
29 changes: 13 additions & 16 deletions src/librustc_codegen_llvm/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,24 +436,21 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
//
// We could remove this hack whenever we decide to drop macOS 10.10 support.
if self.tcx.sess.target.target.options.is_like_osx {
assert_eq!(alloc.relocations().len(), 0);

let is_zeroed = {
// Treats undefined bytes as if they were defined with the byte value that
// happens to be currently assigned in mir. This is valid since reading
// undef bytes may yield arbitrary values.
//
// FIXME: ignore undef bytes even with representation `!= 0`.
//
// The `inspect` method is okay here because we checked relocations, and
// because we are doing this access to inspect the final interpreter state
// (not as part of the interpreter execution).
alloc
// The `inspect` method is okay here because we checked relocations, and
// because we are doing this access to inspect the final interpreter state
// (not as part of the interpreter execution).
//
// FIXME: This check requires that the (arbitrary) value of undefined bytes
// happens to be zero. Instead, we should only check the value of defined bytes
// and set all undefined bytes to zero if this allocation is headed for the
// BSS.
let all_bytes_are_zero = alloc.relocations().is_empty()
&& alloc
.inspect_with_undef_and_ptr_outside_interpreter(0..alloc.len())
.iter()
.all(|b| *b == 0)
};
let sect_name = if is_zeroed {
.all(|&byte| byte == 0);

let sect_name = if all_bytes_are_zero {
CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_bss\0")
} else {
CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_data\0")
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_error_codes/error_codes/E0502.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
This error indicates that you are trying to borrow a variable as mutable when it
has already been borrowed as immutable.
A variable already borrowed as immutable was borrowed as mutable.

Erroneous code example:

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_infer/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod engine;
pub mod error_reporting;
mod project;
mod structural_impls;
mod util;
pub mod util;

use rustc_hir as hir;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
Expand Down
80 changes: 78 additions & 2 deletions src/librustc_infer/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ use smallvec::smallvec;

use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::outlives::Component;
use rustc_middle::ty::{self, ToPolyTraitRef, TyCtxt};
use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, TyCtxt, WithConstness};

fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
pub fn anonymize_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
pred: &ty::Predicate<'tcx>,
) -> ty::Predicate<'tcx> {
match *pred {
ty::Predicate::Trait(ref data, constness) => {
ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
Expand Down Expand Up @@ -88,6 +91,21 @@ pub struct Elaborator<'tcx> {
visited: PredicateSet<'tcx>,
}

pub fn elaborate_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Elaborator<'tcx> {
elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
}

pub fn elaborate_trait_refs<'tcx>(
tcx: TyCtxt<'tcx>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Elaborator<'tcx> {
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
elaborate_predicates(tcx, predicates)
}

pub fn elaborate_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
mut predicates: Vec<ty::Predicate<'tcx>>,
Expand All @@ -98,6 +116,10 @@ pub fn elaborate_predicates<'tcx>(
}

impl Elaborator<'tcx> {
pub fn filter_to_traits(self) -> FilterToTraits<Self> {
FilterToTraits::new(self)
}

fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
let tcx = self.visited.tcx;
match *predicate {
Expand Down Expand Up @@ -223,3 +245,57 @@ impl Iterator for Elaborator<'tcx> {
}
}
}

///////////////////////////////////////////////////////////////////////////
// Supertrait iterator
///////////////////////////////////////////////////////////////////////////

pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;

pub fn supertraits<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Supertraits<'tcx> {
elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
}

pub fn transitive_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Supertraits<'tcx> {
elaborate_trait_refs(tcx, bounds).filter_to_traits()
}

///////////////////////////////////////////////////////////////////////////
// Other
///////////////////////////////////////////////////////////////////////////

/// A filter around an iterator of predicates that makes it yield up
/// just trait references.
pub struct FilterToTraits<I> {
base_iterator: I,
}

impl<I> FilterToTraits<I> {
fn new(base: I) -> FilterToTraits<I> {
FilterToTraits { base_iterator: base }
}
}

impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
type Item = ty::PolyTraitRef<'tcx>;

fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(pred) = self.base_iterator.next() {
if let ty::Predicate::Trait(data, _) = pred {
return Some(data.to_poly_trait_ref());
}
}
None
}

fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.base_iterator.size_hint();
(0, upper)
}
}
Loading

0 comments on commit 74bd074

Please sign in to comment.