Skip to content

Commit

Permalink
Auto merge of #73643 - Manishearth:rollup-68dr8fz, r=Manishearth
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - #72271 (Improve compiler error message for wrong generic parameter order)
 - #72493 ( move leak-check to during coherence, candidate eval)
 - #73398 (A way forward for pointer equality in const eval)
 - #73472 (Clean up E0689 explanation)
 - #73496 (Account for multiple impl/dyn Trait in return type when suggesting `'_`)
 - #73515 (Add second message for LiveDrop errors)
 - #73567 (Clarify --extern documentation.)
 - #73572 (Fix typos in doc comments)
 - #73590 (bootstrap: no `config.toml` exists regression)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Jun 23, 2020
2 parents 3b1c08c + 44900f8 commit 1557fb0
Show file tree
Hide file tree
Showing 206 changed files with 3,091 additions and 1,578 deletions.
14 changes: 9 additions & 5 deletions src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -893,15 +893,18 @@ def bootstrap(help_triggered):
build.verbose = args.verbose
build.clean = args.clean

try:
toml_path = os.getenv('RUST_BOOTSTRAP_CONFIG') or args.config or 'config.toml'
# Read from `RUST_BOOTSTRAP_CONFIG`, then `--config`, then fallback to `config.toml` (if it
# exists).
toml_path = os.getenv('RUST_BOOTSTRAP_CONFIG') or args.config
if not toml_path and os.path.exists('config.toml'):
toml_path = 'config.toml'

if toml_path:
if not os.path.exists(toml_path):
toml_path = os.path.join(build.rust_root, toml_path)

with open(toml_path) as config:
build.config_toml = config.read()
except (OSError, IOError):
pass

config_verbose = build.get_toml('verbose', 'build')
if config_verbose is not None:
Expand Down Expand Up @@ -947,11 +950,12 @@ def bootstrap(help_triggered):
env["SRC"] = build.rust_root
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
env["BOOTSTRAP_PYTHON"] = sys.executable
env["BOOTSTRAP_CONFIG"] = toml_path
env["BUILD_DIR"] = build.build_dir
env["RUSTC_BOOTSTRAP"] = '1'
env["CARGO"] = build.cargo()
env["RUSTC"] = build.rustc()
if toml_path:
env["BOOTSTRAP_CONFIG"] = toml_path
if build.rustfmt():
env["RUSTFMT"] = build.rustfmt()
run(args, env=env, verbose=build.verbose)
Expand Down
12 changes: 10 additions & 2 deletions src/doc/rustc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,18 @@ This flag, when combined with other flags, makes them produce extra output.
This flag allows you to pass the name and location for an external crate of a
direct dependency. Indirect dependencies (dependencies of dependencies) are
located using the [`-L` flag](#option-l-search-path). The given crate name is
added to the [extern prelude], which is the same as specifying `extern crate`
within the root module. The given crate name does not need to match the name
added to the [extern prelude], similar to specifying `extern crate` within the
root module. The given crate name does not need to match the name
the library was built with.

Specifying `--extern` has one behavior difference from `extern crate`:
`--extern` merely makes the crate a _candidate_ for being linked; it does not
actually link it unless it's actively used. In rare occasions you may wish
to ensure a crate is linked even if you don't actively use it from your
code: for example, if it changes the global allocator or if it contains
`#[no_mangle]` symbols for use by other programming languages. In such
cases you'll need to use `extern crate`.

This flag may be specified multiple times. This flag takes an argument with
either of the following formats:

Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<T> RawVec<T, Global> {
/// `#[rustc_force_min_const_fn]` attribute which requires conformance
/// with `min_const_fn` but does not necessarily allow calling it in
/// `stable(...) const fn` / user code not enabling `foo` when
/// `#[rustc_const_unstable(feature = "foo", ..)]` is present.
/// `#[rustc_const_unstable(feature = "foo", issue = "01234")]` is present.
pub const NEW: Self = Self::new();

/// Creates the biggest possible `RawVec` (on the system heap)
Expand Down
16 changes: 13 additions & 3 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ extern "rust-intrinsic" {
///
/// The stabilized version of this intrinsic is
/// [`std::any::type_name`](../../std/any/fn.type_name.html)
#[rustc_const_unstable(feature = "const_type_name", issue = "none")]
#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
pub fn type_name<T: ?Sized>() -> &'static str;

/// Gets an identifier which is globally unique to the specified type. This
Expand All @@ -1021,7 +1021,7 @@ extern "rust-intrinsic" {
///
/// The stabilized version of this intrinsic is
/// [`std::any::TypeId::of`](../../std/any/struct.TypeId.html#method.of)
#[rustc_const_unstable(feature = "const_type_id", issue = "none")]
#[rustc_const_unstable(feature = "const_type_id", issue = "41875")]
pub fn type_id<T: ?Sized + 'static>() -> u64;

/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
Expand Down Expand Up @@ -1931,7 +1931,7 @@ extern "rust-intrinsic" {
pub fn nontemporal_store<T>(ptr: *mut T, val: T);

/// See documentation of `<*const T>::offset_from` for details.
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "none")]
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;

/// Internal hook used by Miri to implement unwinding.
Expand All @@ -1948,6 +1948,16 @@ extern "rust-intrinsic" {
#[cfg(not(bootstrap))]
#[lang = "count_code_region"]
pub fn count_code_region(index: u32);

/// See documentation of `<*const T>::guaranteed_eq` for details.
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[cfg(not(bootstrap))]
pub fn ptr_guaranteed_eq<T>(ptr: *const T, other: *const T) -> bool;

/// See documentation of `<*const T>::guaranteed_ne` for details.
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[cfg(not(bootstrap))]
pub fn ptr_guaranteed_ne<T>(ptr: *const T, other: *const T) -> bool;
}

// Some functions are defined here because they accidentally got made
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
#![feature(const_generics)]
#![feature(const_ptr_offset)]
#![feature(const_ptr_offset_from)]
#![cfg_attr(not(bootstrap), feature(const_raw_ptr_comparison))]
#![feature(const_result)]
#![feature(const_slice_from_raw_parts)]
#![feature(const_slice_ptr_len)]
Expand Down
66 changes: 66 additions & 0 deletions src/libcore/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,72 @@ impl<T: ?Sized> *const T {
intrinsics::ptr_offset_from(self, origin)
}

/// Returns whether two pointers are guaranteed to be equal.
///
/// At runtime this function behaves like `self == other`.
/// However, in some contexts (e.g., compile-time evaluation),
/// it is not always possible to determine equality of two pointers, so this function may
/// spuriously return `false` for pointers that later actually turn out to be equal.
/// But when it returns `true`, the pointers are guaranteed to be equal.
///
/// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer
/// comparisons for which both functions return `false`.
///
/// [`guaranteed_ne`]: #method.guaranteed_ne
///
/// The return value may change depending on the compiler version and unsafe code may not
/// rely on the result of this function for soundness. It is suggested to only use this function
/// for performance optimizations where spurious `false` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
#[cfg(not(bootstrap))]
pub const fn guaranteed_eq(self, other: *const T) -> bool
where
T: Sized,
{
intrinsics::ptr_guaranteed_eq(self, other)
}

/// Returns whether two pointers are guaranteed to be inequal.
///
/// 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.
///
/// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
/// comparisons for which both functions return `false`.
///
/// [`guaranteed_eq`]: #method.guaranteed_eq
///
/// The return value may change depending on the compiler version and unsafe code may not
/// rely on the result of this function for soundness. It is suggested to only use this function
/// for performance optimizations where spurious `false` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
#[cfg(not(bootstrap))]
pub const fn guaranteed_ne(self, other: *const T) -> bool
where
T: Sized,
{
intrinsics::ptr_guaranteed_ne(self, other)
}

/// Calculates the distance between two pointers. The returned value is in
/// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
///
Expand Down
66 changes: 66 additions & 0 deletions src/libcore/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,72 @@ impl<T: ?Sized> *mut T {
if self.is_null() { None } else { Some(&mut *self) }
}

/// Returns whether two pointers are guaranteed to be equal.
///
/// At runtime this function behaves like `self == other`.
/// However, in some contexts (e.g., compile-time evaluation),
/// it is not always possible to determine equality of two pointers, so this function may
/// spuriously return `false` for pointers that later actually turn out to be equal.
/// But when it returns `true`, the pointers are guaranteed to be equal.
///
/// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer
/// comparisons for which both functions return `false`.
///
/// [`guaranteed_ne`]: #method.guaranteed_ne
///
/// The return value may change depending on the compiler version and unsafe code may not
/// rely on the result of this function for soundness. It is suggested to only use this function
/// for performance optimizations where spurious `false` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
#[cfg(not(bootstrap))]
pub const fn guaranteed_eq(self, other: *mut T) -> bool
where
T: Sized,
{
intrinsics::ptr_guaranteed_eq(self as *const _, other as *const _)
}

/// Returns whether two pointers are guaranteed to be inequal.
///
/// 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.
///
/// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
/// comparisons for which both functions return `false`.
///
/// [`guaranteed_eq`]: #method.guaranteed_eq
///
/// The return value may change depending on the compiler version and unsafe code may not
/// rely on the result of this function for soundness. It is suggested to only use this function
/// for performance optimizations where spurious `false` return values by this function do not
/// affect the outcome, but just the performance.
/// The consequences of using this method to make runtime and compile-time code behave
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
#[cfg(not(bootstrap))]
pub const unsafe fn guaranteed_ne(self, other: *mut T) -> bool
where
T: Sized,
{
intrinsics::ptr_guaranteed_ne(self as *const _, other as *const _)
}

/// Calculates the distance between two pointers. The returned value is in
/// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
///
Expand Down
17 changes: 17 additions & 0 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5956,10 +5956,18 @@ where
return false;
}

#[cfg(bootstrap)]
if self.as_ptr() == other.as_ptr() {
return true;
}

// While performance would suffer if `guaranteed_eq` just returned `false`
// for all arguments, correctness and return value of this function are not affected.
#[cfg(not(bootstrap))]
if self.as_ptr().guaranteed_eq(other.as_ptr()) {
return true;
}

self.iter().zip(other.iter()).all(|(x, y)| x == y)
}
}
Expand All @@ -5973,9 +5981,18 @@ where
if self.len() != other.len() {
return false;
}

#[cfg(bootstrap)]
if self.as_ptr() == other.as_ptr() {
return true;
}

// While performance would suffer if `guaranteed_eq` just returned `false`
// for all arguments, correctness and return value of this function are not affected.
#[cfg(not(bootstrap))]
if self.as_ptr().guaranteed_eq(other.as_ptr()) {
return true;
}
unsafe {
let size = mem::size_of_val(self);
memcmp(self.as_ptr() as *const u8, other.as_ptr() as *const u8, size) == 0
Expand Down
12 changes: 11 additions & 1 deletion src/librustc_codegen_llvm/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use log::debug;
use rustc_ast::ast;
use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh};
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_codegen_ssa::glue;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
Expand Down Expand Up @@ -731,6 +731,16 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
return;
}

"ptr_guaranteed_eq" | "ptr_guaranteed_ne" => {
let a = args[0].immediate();
let b = args[1].immediate();
if name == "ptr_guaranteed_eq" {
self.icmp(IntPredicate::IntEQ, a, b)
} else {
self.icmp(IntPredicate::IntNE, a, b)
}
}

"ptr_offset_from" => {
let ty = substs.type_at(0);
let pointee_size = self.size_of(ty);
Expand Down
19 changes: 11 additions & 8 deletions src/librustc_error_codes/error_codes/E0689.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
This error indicates that the numeric value for the method being passed exists
but the type of the numeric value or binding could not be identified.
A method was called on an ambiguous numeric type.

The error happens on numeric literals:
Erroneous code example:

```compile_fail,E0689
2.0.neg();
2.0.neg(); // error!
```

and on numeric bindings without an identified concrete type:
This error indicates that the numeric value for the method being passed exists
but the type of the numeric value or binding could not be identified.

The error happens on numeric literals and on numeric bindings without an
identified concrete type:

```compile_fail,E0689
let x = 2.0;
Expand All @@ -19,8 +22,8 @@ Because of this, you must give the numeric literal or binding a type:
```
use std::ops::Neg;
let _ = 2.0_f32.neg();
let _ = 2.0_f32.neg(); // ok!
let x: f32 = 2.0;
let _ = x.neg();
let _ = (2.0 as f32).neg();
let _ = x.neg(); // ok!
let _ = (2.0 as f32).neg(); // ok!
```
3 changes: 0 additions & 3 deletions src/librustc_feature/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,6 @@ declare_features! (
/// Allows dereferencing raw pointers during const eval.
(active, const_raw_ptr_deref, "1.27.0", Some(51911), None),

/// Allows comparing raw pointers during const eval.
(active, const_compare_raw_pointers, "1.27.0", Some(53020), None),

/// Allows `#[doc(alias = "...")]`.
(active, doc_alias, "1.27.0", Some(50146), None),

Expand Down
5 changes: 5 additions & 0 deletions src/librustc_feature/removed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ declare_features! (
Some("removed in favor of `#![feature(marker_trait_attr)]`")),
/// Allows `#[no_debug]`.
(removed, no_debug, "1.43.0", Some(29721), None, Some("removed due to lack of demand")),

/// Allows comparing raw pointers during const eval.
(removed, const_compare_raw_pointers, "1.46.0", Some(53020), None,
Some("cannot be allowed in const eval in any meaningful way")),

// -------------------------------------------------------------------------
// feature-group-end: removed features
// -------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
&self,
region: Region<'tcx>,
br: &ty::BoundRegion,
) -> Option<(&hir::Ty<'_>, &hir::FnDecl<'_>)> {
) -> Option<(&hir::Ty<'tcx>, &hir::FnDecl<'tcx>)> {
if let Some(anon_reg) = self.tcx().is_suitable_region(region) {
let def_id = anon_reg.def_id;
if let Some(def_id) = def_id.as_local() {
Expand Down
Loading

0 comments on commit 1557fb0

Please sign in to comment.