Skip to content

Commit

Permalink
Auto merge of rust-lang#74667 - Manishearth:rollup-s6k59sw, r=Manishe…
Browse files Browse the repository at this point in the history
…arth

Rollup of 8 pull requests

Successful merges:

 - rust-lang#74141 (libstd/libcore: fix various typos)
 - rust-lang#74490 (add a Backtrace::disabled function)
 - rust-lang#74548 (one more Path::with_extension example, to demonstrate behavior)
 - rust-lang#74587 (Prefer constant over function)
 - rust-lang#74606 (Remove Linux workarounds for missing CLOEXEC support)
 - rust-lang#74637 (Make str point to primitive page)
 - rust-lang#74654 (require type defaults to be after const generic parameters)
 - rust-lang#74659 (Improve codegen for unchecked float casts on wasm)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Jul 23, 2020
2 parents fcac119 + 8f02f2c commit 2bbfa02
Show file tree
Hide file tree
Showing 36 changed files with 266 additions and 302 deletions.
5 changes: 3 additions & 2 deletions src/liballoc/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use crate::vec::Vec;
///
/// # Examples
///
/// You can create a `String` from [a literal string][str] with [`String::from`]:
/// You can create a `String` from [a literal string][`str`] with [`String::from`]:
///
/// [`String::from`]: From::from
///
Expand Down Expand Up @@ -268,7 +268,8 @@ use crate::vec::Vec;
///
/// Here, there's no need to allocate more memory inside the loop.
///
/// [`&str`]: str
/// [`str`]: type@str
/// [`&str`]: type@str
/// [`Deref`]: core::ops::Deref
/// [`as_str()`]: String::as_str
#[derive(PartialOrd, Eq, Ord)]
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ impl AsRef<str> for str {
///
///
/// However there is one case where `!` syntax can be used
/// before `!` is stabilized as a full-fleged type: in the position of a function’s return type.
/// before `!` is stabilized as a full-fledged type: in the position of a function’s return type.
/// Specifically, it is possible implementations for two different function pointer types:
///
/// ```
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/hash/sip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ struct SipHasher24 {
///
/// SipHash is a general-purpose hashing function: it runs at a good
/// speed (competitive with Spooky and City) and permits strong _keyed_
/// hashing. This lets you key your hashtables from a strong RNG, such as
/// hashing. This lets you key your hash tables from a strong RNG, such as
/// [`rand::os::OsRng`](https://doc.rust-lang.org/rand/rand/os/struct.OsRng.html).
///
/// Although the SipHash algorithm is considered to be generally strong,
Expand Down
8 changes: 4 additions & 4 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//!
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
//! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done
//! without T-lang consulation, because it bakes a feature into the language that cannot be
//! without T-lang consultation, because it bakes a feature into the language that cannot be
//! replicated in user code without compiler support.
//!
//! # Volatiles
Expand Down Expand Up @@ -994,7 +994,7 @@ extern "rust-intrinsic" {
/// [`std::mem::align_of`](../../std/mem/fn.align_of.html).
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
pub fn min_align_of<T>() -> usize;
/// The prefered alignment of a type.
/// The preferred alignment of a type.
///
/// This intrinsic does not have a stable counterpart.
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "none")]
Expand Down Expand Up @@ -1246,14 +1246,14 @@ extern "rust-intrinsic" {
/// assert!(mid <= len);
/// unsafe {
/// let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
/// // first: transmute is not typesafe; all it checks is that T and
/// // first: transmute is not type safe; all it checks is that T and
/// // U are of the same size. Second, right here, you have two
/// // mutable references pointing to the same memory.
/// (&mut slice[0..mid], &mut slice2[mid..len])
/// }
/// }
///
/// // This gets rid of the typesafety problems; `&mut *` will *only* give
/// // This gets rid of the type safety problems; `&mut *` will *only* give
/// // you an `&mut T` from an `&mut T` or `*mut T`.
/// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
/// -> (&mut [T], &mut [T]) {
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ pub trait Iterator {
/// let vec = iter.collect::<Vec<_>>();
///
/// // We have more elements which could fit in u32 (4, 5), but `map_while` returned `None` for `-3`
/// // (as the `predicate` returned `None`) and `collect` stops at the first `None` entcountered.
/// // (as the `predicate` returned `None`) and `collect` stops at the first `None` encountered.
/// assert_eq!(vec, vec![0, 1, 2]);
/// ```
///
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ pub(crate) mod builtin {
};
}

/// Includes a utf8-encoded file as a string.
/// Includes a UTF-8 encoded file as a string.
///
/// The file is located relative to the current file (similarly to how
/// modules are found). The provided path is interpreted in a platform-specific
Expand Down
8 changes: 4 additions & 4 deletions src/libcore/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,11 @@ pub fn size_of_val<T: ?Sized>(val: &T) -> usize {
///
/// - If `T` is `Sized`, this function is always safe to call.
/// - If the unsized tail of `T` is:
/// - a [slice], then the length of the slice tail must be an intialized
/// - a [slice], then the length of the slice tail must be an initialized
/// integer, and the size of the *entire value*
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
/// - a [trait object], then the vtable part of the pointer must point
/// to a valid vtable acquired by an unsizing coersion, and the size
/// to a valid vtable acquired by an unsizing coercion, and the size
/// of the *entire value* (dynamic tail length + statically sized prefix)
/// must fit in `isize`.
/// - an (unstable) [extern type], then this function is always safe to
Expand Down Expand Up @@ -483,11 +483,11 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
///
/// - If `T` is `Sized`, this function is always safe to call.
/// - If the unsized tail of `T` is:
/// - a [slice], then the length of the slice tail must be an intialized
/// - a [slice], then the length of the slice tail must be an initialized
/// integer, and the size of the *entire value*
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
/// - a [trait object], then the vtable part of the pointer must point
/// to a valid vtable acquired by an unsizing coersion, and the size
/// to a valid vtable acquired by an unsizing coercion, and the size
/// of the *entire value* (dynamic tail length + statically sized prefix)
/// must fit in `isize`.
/// - an (unstable) [extern type], then this function is always safe to
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ impl f64 {
/// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
///
/// Rather than trying to preserve signaling-ness cross-platform, this
/// implementation favours preserving the exact bits. This means that
/// implementation favors preserving the exact bits. This means that
/// any payloads encoded in NaNs will be preserved even if the result of
/// this method is sent over the network from an x86 machine to a MIPS one.
///
Expand All @@ -696,7 +696,7 @@ impl f64 {
///
/// If the input isn't NaN, then there is no portability concern.
///
/// If you don't care about signalingness (very likely), then there is no
/// If you don't care about signaling-ness (very likely), then there is no
/// portability concern.
///
/// Note that this function is distinct from `as` casting, which attempts to
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
//!
//! Crucially, we have to be able to rely on [`drop`] being called. If an element
//! could be deallocated or otherwise invalidated without calling [`drop`], the pointers into it
//! from its neighbouring elements would become invalid, which would break the data structure.
//! from its neighboring elements would become invalid, which would break the data structure.
//!
//! Therefore, pinning also comes with a [`drop`]-related guarantee.
//!
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,13 +331,13 @@ impl<T: ?Sized> *const T {
intrinsics::ptr_guaranteed_eq(self, other)
}

/// Returns whether two pointers are guaranteed to be inequal.
/// Returns whether two pointers are guaranteed to be unequal.
///
/// At runtime this function behaves like `self != other`.
/// However, in some contexts (e.g., compile-time evaluation),
/// it is not always possible to determine the inequality of two pointers, so this function may
/// spuriously return `false` for pointers that later actually turn out to be inequal.
/// But when it returns `true`, the pointers are guaranteed to be inequal.
/// spuriously return `false` for pointers that later actually turn out to be unequal.
/// But when it returns `true`, the pointers are guaranteed to be unequal.
///
/// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
/// comparisons for which both functions return `false`.
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,13 +317,13 @@ impl<T: ?Sized> *mut T {
intrinsics::ptr_guaranteed_eq(self as *const _, other as *const _)
}

/// Returns whether two pointers are guaranteed to be inequal.
/// Returns whether two pointers are guaranteed to be unequal.
///
/// At runtime this function behaves like `self != other`.
/// However, in some contexts (e.g., compile-time evaluation),
/// it is not always possible to determine the inequality of two pointers, so this function may
/// spuriously return `false` for pointers that later actually turn out to be inequal.
/// But when it returns `true`, the pointers are guaranteed to be inequal.
/// spuriously return `false` for pointers that later actually turn out to be unequal.
/// But when it returns `true`, the pointers are guaranteed to be unequal.
///
/// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
/// comparisons for which both functions return `false`.
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl<T> NonNull<[T]> {
/// assert_eq!(unsafe { slice.as_ref()[2] }, 7);
/// ```
///
/// (Note that this example artifically demonstrates a use of this method,
/// (Note that this example artificially demonstrates a use of this method,
/// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.)
#[unstable(feature = "nonnull_slice_from_raw_parts", issue = "71941")]
#[rustc_const_unstable(feature = "const_nonnull_slice_from_raw_parts", issue = "71941")]
Expand Down
25 changes: 19 additions & 6 deletions src/librustc_ast_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1118,13 +1118,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
fn visit_generics(&mut self, generics: &'a Generics) {
let mut prev_ty_default = None;
for param in &generics.params {
if let GenericParamKind::Type { ref default, .. } = param.kind {
if default.is_some() {
match param.kind {
GenericParamKind::Lifetime => (),
GenericParamKind::Type { default: Some(_), .. } => {
prev_ty_default = Some(param.ident.span);
} else if let Some(span) = prev_ty_default {
self.err_handler()
.span_err(span, "type parameters with a default must be trailing");
break;
}
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
if let Some(span) = prev_ty_default {
let mut err = self.err_handler().struct_span_err(
span,
"type parameters with a default must be trailing",
);
if matches!(param.kind, GenericParamKind::Const { .. }) {
err.note(
"using type defaults and const parameters \
in the same parameter list is currently not permitted",
);
}
err.emit();
break;
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/librustc_codegen_llvm/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,14 @@ impl CodegenCx<'b, 'tcx> {
ifn!("llvm.wasm.trunc.saturate.signed.i32.f64", fn(t_f64) -> t_i32);
ifn!("llvm.wasm.trunc.saturate.signed.i64.f32", fn(t_f32) -> t_i64);
ifn!("llvm.wasm.trunc.saturate.signed.i64.f64", fn(t_f64) -> t_i64);
ifn!("llvm.wasm.trunc.unsigned.i32.f32", fn(t_f32) -> t_i32);
ifn!("llvm.wasm.trunc.unsigned.i32.f64", fn(t_f64) -> t_i32);
ifn!("llvm.wasm.trunc.unsigned.i64.f32", fn(t_f32) -> t_i64);
ifn!("llvm.wasm.trunc.unsigned.i64.f64", fn(t_f64) -> t_i64);
ifn!("llvm.wasm.trunc.signed.i32.f32", fn(t_f32) -> t_i32);
ifn!("llvm.wasm.trunc.signed.i32.f64", fn(t_f64) -> t_i32);
ifn!("llvm.wasm.trunc.signed.i64.f32", fn(t_f32) -> t_i64);
ifn!("llvm.wasm.trunc.signed.i64.f64", fn(t_f64) -> t_i64);

ifn!("llvm.trap", fn() -> void);
ifn!("llvm.debugtrap", fn() -> void);
Expand Down
75 changes: 57 additions & 18 deletions src/librustc_codegen_llvm/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,27 +629,24 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
}

sym::float_to_int_unchecked => {
if float_type_width(arg_tys[0]).is_none() {
span_invalid_monomorphization_error(
tcx.sess,
span,
&format!(
"invalid monomorphization of `float_to_int_unchecked` \
let float_width = match float_type_width(arg_tys[0]) {
Some(width) => width,
None => {
span_invalid_monomorphization_error(
tcx.sess,
span,
&format!(
"invalid monomorphization of `float_to_int_unchecked` \
intrinsic: expected basic float type, \
found `{}`",
arg_tys[0]
),
);
return;
}
match int_type_width_signed(ret_ty, self.cx) {
Some((width, signed)) => {
if signed {
self.fptosi(args[0].immediate(), self.cx.type_ix(width))
} else {
self.fptoui(args[0].immediate(), self.cx.type_ix(width))
}
arg_tys[0]
),
);
return;
}
};
let (width, signed) = match int_type_width_signed(ret_ty, self.cx) {
Some(pair) => pair,
None => {
span_invalid_monomorphization_error(
tcx.sess,
Expand All @@ -663,7 +660,49 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
);
return;
}
};

// The LLVM backend can reorder and speculate `fptosi` and
// `fptoui`, so on WebAssembly the codegen for this instruction
// is quite heavyweight. To avoid this heavyweight codegen we
// instead use the raw wasm intrinsics which will lower to one
// instruction in WebAssembly (`iNN.trunc_fMM_{s,u}`). This one
// instruction will trap if the operand is out of bounds, but
// that's ok since this intrinsic is UB if the operands are out
// of bounds, so the behavior can be different on WebAssembly
// than other targets.
//
// Note, however, that when the `nontrapping-fptoint` feature is
// enabled in LLVM then LLVM will lower `fptosi` to
// `iNN.trunc_sat_fMM_{s,u}`, so if that's the case we don't
// bother with intrinsics.
let mut result = None;
if self.sess().target.target.arch == "wasm32"
&& !self.sess().target_features.contains(&sym::nontrapping_dash_fptoint)
{
let name = match (width, float_width, signed) {
(32, 32, true) => Some("llvm.wasm.trunc.signed.i32.f32"),
(32, 64, true) => Some("llvm.wasm.trunc.signed.i32.f64"),
(64, 32, true) => Some("llvm.wasm.trunc.signed.i64.f32"),
(64, 64, true) => Some("llvm.wasm.trunc.signed.i64.f64"),
(32, 32, false) => Some("llvm.wasm.trunc.unsigned.i32.f32"),
(32, 64, false) => Some("llvm.wasm.trunc.unsigned.i32.f64"),
(64, 32, false) => Some("llvm.wasm.trunc.unsigned.i64.f32"),
(64, 64, false) => Some("llvm.wasm.trunc.unsigned.i64.f64"),
_ => None,
};
if let Some(name) = name {
let intrinsic = self.get_intrinsic(name);
result = Some(self.call(intrinsic, &[args[0].immediate()], None));
}
}
result.unwrap_or_else(|| {
if signed {
self.fptosi(args[0].immediate(), self.cx.type_ix(width))
} else {
self.fptoui(args[0].immediate(), self.cx.type_ix(width))
}
})
}

sym::discriminant_value => {
Expand Down
6 changes: 6 additions & 0 deletions src/libstd/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ impl Backtrace {
Backtrace::create(Backtrace::force_capture as usize)
}

/// Forcibly captures a disabled backtrace, regardless of environment
/// variable configuration.
pub const fn disabled() -> Backtrace {
Backtrace { inner: Inner::Disabled }
}

// Capture a backtrace which start just before the function addressed by
// `ip`
fn create(ip: usize) -> Backtrace {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1500,7 +1500,7 @@ mod tests {
assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0);
assert_approx_eq!(f32::from_bits(0xc1640000), -14.25);

// Check that NaNs roundtrip their bits regardless of signalingness
// Check that NaNs roundtrip their bits regardless of signaling-ness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
let masked_nan1 = f32::NAN.to_bits() ^ 0x002A_AAAA;
let masked_nan2 = f32::NAN.to_bits() ^ 0x0055_5555;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ mod tests {
assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);

// Check that NaNs roundtrip their bits regardless of signalingness
// Check that NaNs roundtrip their bits regardless of signaling-ness
// 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/os/linux/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime_nsec(&self) -> i64;
/// Returns the "preferred" blocksize for efficient filesystem I/O.
/// Returns the "preferred" block size for efficient filesystem I/O.
///
/// # Examples
///
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/os/redox/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime_nsec(&self) -> i64;
/// Returns the "preferred" blocksize for efficient filesystem I/O.
/// Returns the "preferred" block size for efficient filesystem I/O.
///
/// # Examples
///
Expand Down
3 changes: 3 additions & 0 deletions src/libstd/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2244,6 +2244,9 @@ impl Path {
///
/// let path = Path::new("foo.rs");
/// assert_eq!(path.with_extension("txt"), PathBuf::from("foo.txt"));
///
/// let path = Path::new("foo.tar.gz");
/// assert_eq!(path.with_extension(""), PathBuf::from("foo.tar"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/sys/sgx/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl FileDesc {
self.fd
}

/// Extracts the actual filedescriptor without closing it.
/// Extracts the actual file descriptor without closing it.
pub fn into_raw(self) -> Fd {
let fd = self.fd;
mem::forget(self);
Expand Down
Loading

0 comments on commit 2bbfa02

Please sign in to comment.