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 9 pull requests #73643

Merged
merged 39 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1d08b1b
Clean up E0689 explanation
GuillaumeGomez Jun 18, 2020
9245ba8
Remove the const_raw_ptr_comparison feature gate.
oli-obk Jun 12, 2020
e09b620
Add fuzzy pointer comparison intrinsics
oli-obk Jun 16, 2020
84f1d73
Tidy got confused on `rustc_const_unstable` `issue`s
oli-obk Jun 18, 2020
e75fbae
add second message for livedrop errors
pvdrz Jun 19, 2020
562f496
Account for multiple impl/dyn Trait in return type when suggesting `'_`
estebank Jun 9, 2020
0624a5a
Squashed all commits
rakshith-ravi Jun 20, 2020
9e88b48
Refer just to the issue in the raw ptr cmp diagnostic instead of expl…
oli-obk Jun 20, 2020
53686b9
Satisfy tidy
oli-obk Jun 20, 2020
98e97a4
Address review comments
oli-obk Jun 20, 2020
9355168
update tests
Jun 20, 2020
a63eb3c
Clarify --extern documentation.
adetaylor Jun 21, 2020
6374054
Fix typos in doc comments
JOE1994 Jun 21, 2020
e465b22
`icmp` can handle raw pointers just fine, there's no need to cast to …
oli-obk Jun 21, 2020
893077c
Update src/librustc_mir/monomorphize/collector.rs
JOE1994 Jun 21, 2020
b60ec47
bootstrap: no `config.toml` exists regression
davidtwco Jun 21, 2020
bcc0a9c
modify leak-check to track only outgoing edges from placeholders
nikomatsakis May 18, 2020
4199b3a
Revert "modify leak-check to track only outgoing edges from placehold…
nikomatsakis May 18, 2020
f2cf994
rewrite leak check to be based on universes
nikomatsakis May 19, 2020
5a7a850
move leak-check to during coherence, candidate eval
nikomatsakis May 20, 2020
1e00e1b
upcasting traits requires only that things become more general
nikomatsakis May 20, 2020
70cf33f
remove snapshot calls from "match" operations during select
nikomatsakis May 22, 2020
6873a76
remove leak-check from project
nikomatsakis May 22, 2020
3a68d56
remove `leak_check` from the outlives predicate evaluations
nikomatsakis May 22, 2020
be0d10f
add new tests from MCP and the tracking issue
nikomatsakis May 22, 2020
93e2982
add new coherence tests and update the documentation
nikomatsakis Jun 5, 2020
c88a76e
WIP bless test and compare-mode=nll
nikomatsakis Jun 6, 2020
6929013
fix subtle bug in NLL type checker
nikomatsakis Jun 8, 2020
d57689f
cite issue 73154
nikomatsakis Jun 8, 2020
3eb8eb9
review comments
estebank Jun 22, 2020
59e87c0
Rollup merge of #72271 - rakshith-ravi:master, r=varkor
Manishearth Jun 23, 2020
903823c
Rollup merge of #72493 - nikomatsakis:move-leak-check, r=matthewjasper
Manishearth Jun 23, 2020
ae38698
Rollup merge of #73398 - oli-obk:const_raw_ptr_cmp, r=varkor,RalfJung…
Manishearth Jun 23, 2020
98aa34c
Rollup merge of #73472 - GuillaumeGomez:cleanup-e0689, r=Dylan-DPC
Manishearth Jun 23, 2020
cd18ac1
Rollup merge of #73496 - estebank:opaque-missing-lts-in-fn-3, r=nikom…
Manishearth Jun 23, 2020
0f9a6ed
Rollup merge of #73515 - christianpoveda:livedrop-diagnostics, r=oli-obk
Manishearth Jun 23, 2020
0560151
Rollup merge of #73567 - adetaylor:extern-doc-fix, r=dtolnay
Manishearth Jun 23, 2020
84bd1e7
Rollup merge of #73572 - JOE1994:patch-4, r=jonas-schievink
Manishearth Jun 23, 2020
44900f8
Rollup merge of #73590 - davidtwco:bootstrap-fix-config-env-var, r=Ma…
Manishearth Jun 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
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