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 7 pull requests #68423

Merged
merged 32 commits into from
Jan 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9e90840
Simplify NodeHeader by avoiding slices in BTreeMaps with shared roots
ssomers Dec 26, 2019
34878d7
Options IP_MULTICAST_TTL and IP_MULTICAST_LOOP are 1 byte on BSD and …
Jan 17, 2020
dda32e4
refactor fix using cfg_if!
Jan 17, 2020
239a7d9
refactor fix using cfg_if! (fix build)
Jan 17, 2020
766f6c5
Actually pass target LLVM args to LLVM
Jan 18, 2020
01cbe50
Add `constness` field to `ast::ItemKind::Impl`
ecstatic-morse Jan 14, 2020
a790f9b
Add `constness` field to `hir::ItemKind::Impl`
ecstatic-morse Jan 14, 2020
958b0bc
Store `impl const` in `ItemKind::Impl`
ecstatic-morse Jan 14, 2020
eb60346
Add `MaybeConst` variant to `{ast,hir}::TraitBoundModifier`
ecstatic-morse Jan 14, 2020
1a3bd57
Revert "Add a `constness` field to `ast::TraitRef`"
ecstatic-morse Jan 14, 2020
ab3081a
Add `constness` field to `ty::Predicate::Trait`
ecstatic-morse Jan 14, 2020
d2aefbb
Add `ConstnessAnd` that implements `ToPredicate`
ecstatic-morse Jan 14, 2020
adbd01e
Track constness while lowering bounds
ecstatic-morse Jan 14, 2020
3b1a9d3
Ignore filelength for `astconv`
ecstatic-morse Jan 14, 2020
0ac4ba0
Parse `?const ?Trait`
ecstatic-morse Jan 20, 2020
23ea42c
Update tests
ecstatic-morse Jan 14, 2020
71450c7
generalize bindings_with_variant_name lint
Centril Jan 20, 2020
5392442
refactor fix using cfg_if! (fix build on Solaris)
Jan 20, 2020
78f0c7f
check_match: unify some lowering code and fix some ICEs
Centril Jan 20, 2020
58eb03d
check_match: simplify check_arm
Centril Jan 20, 2020
1b800a5
trade in outdated comments for correct ones
ssomers Jan 21, 2020
6bd69a1
Add comment explaining `MaybeConstMaybe` lowering
ecstatic-morse Jan 21, 2020
14c002e
tidy: fix most clippy warnings
matthiaskrgr Jan 21, 2020
3e947ef
Declare unsafe functions that can no longer handle shared roots
ssomers Jan 21, 2020
32a81f7
lowering: cleanup some hofs
Centril Jan 21, 2020
d532a04
Rollup merge of #67686 - ssomers:keys_start_slasher, r=Mark-Simulacrum
Centril Jan 21, 2020
3484e2f
Rollup merge of #68140 - ecstatic-morse:const-trait-bound-opt-out, r=…
Centril Jan 21, 2020
dabd816
Rollup merge of #68313 - batrla:master, r=alexcrichton
Centril Jan 21, 2020
3fa8cc3
Rollup merge of #68328 - jethrogb:jb/target-llvm-args, r=alexcrichton
Centril Jan 21, 2020
5850482
Rollup merge of #68399 - Centril:check-match-unify, r=oli-obk
Centril Jan 21, 2020
b6d6391
Rollup merge of #68415 - matthiaskrgr:tidy_clippy, r=oli-obk
Centril Jan 21, 2020
c1b20b1
Rollup merge of #68416 - Centril:lowering-cleanup-hofs, r=pietroalbini
Centril Jan 21, 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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3763,6 +3763,7 @@ dependencies = [
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_session",
"rustc_span",
"rustc_target",
"serialize",
Expand Down
6 changes: 3 additions & 3 deletions src/liballoc/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1968,7 +1968,7 @@ where
(i, false) => i,
},
(_, Unbounded) => 0,
(true, Included(_)) => min_node.keys().len(),
(true, Included(_)) => min_node.len(),
(true, Excluded(_)) => 0,
};

Expand All @@ -1987,9 +1987,9 @@ where
}
(i, false) => i,
},
(_, Unbounded) => max_node.keys().len(),
(_, Unbounded) => max_node.len(),
(true, Included(_)) => 0,
(true, Excluded(_)) => max_node.keys().len(),
(true, Excluded(_)) => max_node.len(),
};

if !diverged {
Expand Down
65 changes: 11 additions & 54 deletions src/liballoc/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ pub const CAPACITY: usize = 2 * B - 1;
/// `NodeHeader` because we do not want unnecessary padding between `len` and the keys.
/// Crucially, `NodeHeader` can be safely transmuted to different K and V. (This is exploited
/// by `as_header`.)
/// See `into_key_slice` for an explanation of K2. K2 cannot be safely transmuted around
/// because the size of `NodeHeader` depends on its alignment!
#[repr(C)]
struct NodeHeader<K, V, K2 = ()> {
struct NodeHeader<K, V> {
/// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`.
/// This either points to an actual node or is null.
parent: *const InternalNode<K, V>,
Expand All @@ -72,9 +70,6 @@ struct NodeHeader<K, V, K2 = ()> {
/// This next to `parent_idx` to encourage the compiler to join `len` and
/// `parent_idx` into the same 32-bit word, reducing space overhead.
len: u16,

/// See `into_key_slice`.
keys_start: [K2; 0],
}
#[repr(C)]
struct LeafNode<K, V> {
Expand Down Expand Up @@ -128,7 +123,7 @@ unsafe impl Sync for NodeHeader<(), ()> {}
// We use just a header in order to save space, since no operation on an empty tree will
// ever take a pointer past the first key.
static EMPTY_ROOT_NODE: NodeHeader<(), ()> =
NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0, keys_start: [] };
NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0 };

/// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
/// behind `BoxedNode`s to prevent dropping uninitialized keys and values. Any pointer to an
Expand Down Expand Up @@ -390,14 +385,13 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
}

/// Borrows a view into the keys stored in the node.
/// Works on all possible nodes, including the shared root.
pub fn keys(&self) -> &[K] {
/// The caller must ensure that the node is not the shared root.
pub unsafe fn keys(&self) -> &[K] {
self.reborrow().into_key_slice()
}

/// Borrows a view into the values stored in the node.
/// The caller must ensure that the node is not the shared root.
/// This function is not public, so doesn't have to support shared roots like `keys` does.
fn vals(&self) -> &[V] {
self.reborrow().into_val_slice()
}
Expand Down Expand Up @@ -515,7 +509,6 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
}

/// The caller must ensure that the node is not the shared root.
/// This function is not public, so doesn't have to support shared roots like `keys` does.
fn keys_mut(&mut self) -> &mut [K] {
unsafe { self.reborrow_mut().into_key_slice_mut() }
}
Expand All @@ -527,48 +520,11 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
}

impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
fn into_key_slice(self) -> &'a [K] {
// We have to be careful here because we might be pointing to the shared root.
// In that case, we must not create an `&LeafNode`. We could just return
// an empty slice whenever the length is 0 (this includes the shared root),
// but we want to avoid that run-time check.
// Instead, we create a slice pointing into the node whenever possible.
// We can sometimes do this even for the shared root, as the slice will be
// empty and `NodeHeader` contains an empty `keys_start` array.
// We cannot *always* do this because:
// - `keys_start` is not correctly typed because we want `NodeHeader`'s size to
// not depend on the alignment of `K` (needed because `as_header` should be safe).
// For this reason, `NodeHeader` has this `K2` parameter (that's usually `()`
// and hence just adds a size-0-align-1 field, not affecting layout).
// If the correctly typed header is more highly aligned than the allocated header,
// we cannot transmute safely.
// - Even if we can transmute, the offset of a correctly typed `keys_start` might
// be different and outside the bounds of the allocated header!
// So we do an alignment check and a size check first, that will be evaluated
// at compile-time, and only do any run-time check in the rare case that
// the compile-time checks signal danger.
if (mem::align_of::<NodeHeader<K, V, K>>() > mem::align_of::<NodeHeader<K, V>>()
|| mem::size_of::<NodeHeader<K, V, K>>() != mem::size_of::<NodeHeader<K, V>>())
&& self.is_shared_root()
{
&[]
} else {
// If we are a `LeafNode<K, V>`, we can always transmute to
// `NodeHeader<K, V, K>` and `keys_start` always has the same offset
// as the actual `keys`.
// Thanks to the checks above, we know that we can transmute to
// `NodeHeader<K, V, K>` and that `keys_start` will be
// in-bounds of some allocation even if this is the shared root!
// (We might be one-past-the-end, but that is allowed by LLVM.)
// Thus we can use `NodeHeader<K, V, K>`
// to compute the pointer where the keys start.
// This entire hack will become unnecessary once
// <https://github.com/rust-lang/rfcs/pull/2582> lands, then we can just take a raw
// pointer to the `keys` field of `*const InternalNode<K, V>`.
let header = self.as_header() as *const _ as *const NodeHeader<K, V, K>;
let keys = unsafe { &(*header).keys_start as *const _ as *const K };
unsafe { slice::from_raw_parts(keys, self.len()) }
}
/// The caller must ensure that the node is not the shared root.
unsafe fn into_key_slice(self) -> &'a [K] {
debug_assert!(!self.is_shared_root());
// We cannot be the shared root, so `as_leaf` is okay.
slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len())
}

/// The caller must ensure that the node is not the shared root.
Expand All @@ -578,9 +534,10 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) }
}

/// The caller must ensure that the node is not the shared root.
fn into_slices(self) -> (&'a [K], &'a [V]) {
let k = unsafe { ptr::read(&self) };
(k.into_key_slice(), self.into_val_slice())
(unsafe { k.into_key_slice() }, self.into_val_slice())
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/liballoc/collections/btree/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,18 @@ where
{
// This function is defined over all borrow types (immutable, mutable, owned),
// and may be called on the shared root in each case.
// Crucially, we use `keys()` here, i.e., we work with immutable data.
// `keys_mut()` does not support the shared root, so we cannot use it.
// Using `keys()` is fine here even if BorrowType is mutable, as all we return
// is an index -- not a reference.
for (i, k) in node.keys().iter().enumerate() {
match key.cmp(k.borrow()) {
Ordering::Greater => {}
Ordering::Equal => return (i, true),
Ordering::Less => return (i, false),
let len = node.len();
if len > 0 {
let keys = unsafe { node.keys() }; // safe because a non-empty node cannot be the shared root
for (i, k) in keys.iter().enumerate() {
match key.cmp(k.borrow()) {
Ordering::Greater => {}
Ordering::Equal => return (i, true),
Ordering::Less => return (i, false),
}
}
}
(node.keys().len(), false)
(len, false)
}
9 changes: 6 additions & 3 deletions src/librustc/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,10 @@ impl AutoTraitFinder<'tcx> {
&Err(SelectionError::Unimplemented) => {
if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) {
already_visited.remove(&pred);
self.add_user_pred(&mut user_computed_preds, ty::Predicate::Trait(pred));
self.add_user_pred(
&mut user_computed_preds,
ty::Predicate::Trait(pred, ast::Constness::NotConst),
);
predicates.push_back(pred);
} else {
debug!(
Expand Down Expand Up @@ -405,7 +408,7 @@ impl AutoTraitFinder<'tcx> {
let mut should_add_new = true;
user_computed_preds.retain(|&old_pred| {
match (&new_pred, old_pred) {
(&ty::Predicate::Trait(new_trait), ty::Predicate::Trait(old_trait)) => {
(&ty::Predicate::Trait(new_trait, _), ty::Predicate::Trait(old_trait, _)) => {
if new_trait.def_id() == old_trait.def_id() {
let new_substs = new_trait.skip_binder().trait_ref.substs;
let old_substs = old_trait.skip_binder().trait_ref.substs;
Expand Down Expand Up @@ -627,7 +630,7 @@ impl AutoTraitFinder<'tcx> {
// We check this by calling is_of_param on the relevant types
// from the various possible predicates
match &predicate {
&ty::Predicate::Trait(p) => {
&ty::Predicate::Trait(p, _) => {
if self.is_param_no_infer(p.skip_binder().trait_ref.substs)
&& !only_projections
&& is_new_pred
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/traits/engine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::infer::InferCtxt;
use crate::traits::Obligation;
use crate::ty::{self, ToPredicate, Ty, TyCtxt};
use crate::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_hir::def_id::DefId;

use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError};
Expand Down Expand Up @@ -33,7 +33,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
cause,
recursion_depth: 0,
param_env,
predicate: trait_ref.to_predicate(),
predicate: trait_ref.without_const().to_predicate(),
},
);
}
Expand Down
28 changes: 18 additions & 10 deletions src/librustc/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ use crate::ty::error::ExpectedFound;
use crate::ty::fast_reject;
use crate::ty::fold::TypeFolder;
use crate::ty::SubtypePredicate;
use crate::ty::{self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
use crate::ty::{
self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
};

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
Expand Down Expand Up @@ -128,15 +130,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

let (cond, error) = match (cond, error) {
(&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error),
(&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error, _)) => (cond, error),
_ => {
// FIXME: make this work in other cases too.
return false;
}
};

for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) {
if let ty::Predicate::Trait(implication) = implication {
if let ty::Predicate::Trait(implication, _) = implication {
let error = error.to_poly_trait_ref();
let implication = implication.to_poly_trait_ref();
// FIXME: I'm just not taking associated types at all here.
Expand Down Expand Up @@ -528,7 +530,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
return;
}
match obligation.predicate {
ty::Predicate::Trait(ref trait_predicate) => {
ty::Predicate::Trait(ref trait_predicate, _) => {
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);

if self.tcx.sess.has_errors() && trait_predicate.references_error() {
Expand Down Expand Up @@ -581,7 +583,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"{}",
message.unwrap_or_else(|| format!(
"the trait bound `{}` is not satisfied{}",
trait_ref.to_predicate(),
trait_ref.without_const().to_predicate(),
post_message,
))
);
Expand Down Expand Up @@ -693,7 +695,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
trait_pred
});
let unit_obligation = Obligation {
predicate: ty::Predicate::Trait(predicate),
predicate: ty::Predicate::Trait(
predicate,
ast::Constness::NotConst,
),
..obligation.clone()
};
if self.predicate_may_hold(&unit_obligation) {
Expand Down Expand Up @@ -986,7 +991,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
) -> PredicateObligation<'tcx> {
let new_trait_ref =
ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) };
Obligation::new(cause, param_env, new_trait_ref.to_predicate())
Obligation::new(cause, param_env, new_trait_ref.without_const().to_predicate())
}
}

Expand Down Expand Up @@ -1074,7 +1079,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

let mut err = match predicate {
ty::Predicate::Trait(ref data) => {
ty::Predicate::Trait(ref data, _) => {
let trait_ref = data.to_poly_trait_ref();
let self_ty = trait_ref.self_ty();
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);
Expand Down Expand Up @@ -1267,8 +1272,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
)
.value;

let obligation =
Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate());
let obligation = Obligation::new(
ObligationCause::dummy(),
param_env,
cleaned_pred.without_const().to_predicate(),
);

self.predicate_may_hold(&obligation)
})
Expand Down
17 changes: 10 additions & 7 deletions src/librustc/traits/error_reporting/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::{
use crate::infer::InferCtxt;
use crate::traits::object_safety::object_safety_violations;
use crate::ty::TypeckTables;
use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};

use rustc_errors::{
error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style,
Expand Down Expand Up @@ -48,7 +48,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} else {
" where"
},
trait_ref.to_predicate(),
trait_ref.without_const().to_predicate(),
),
Applicability::MachineApplicable,
);
Expand Down Expand Up @@ -338,8 +338,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let new_self_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_static, self_ty);
let substs = self.tcx.mk_substs_trait(new_self_ty, &[]);
let new_trait_ref = ty::TraitRef::new(obligation.parent_trait_ref.def_id(), substs);
let new_obligation =
Obligation::new(ObligationCause::dummy(), param_env, new_trait_ref.to_predicate());
let new_obligation = Obligation::new(
ObligationCause::dummy(),
param_env,
new_trait_ref.without_const().to_predicate(),
);
if self.predicate_must_hold_modulo_regions(&new_obligation) {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
// We have a very specific type of error, where just borrowing this argument
Expand Down Expand Up @@ -1120,7 +1123,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// the type. The last generator has information about where the bound was introduced. At
// least one generator should be present for this diagnostic to be modified.
let (mut trait_ref, mut target_ty) = match obligation.predicate {
ty::Predicate::Trait(p) => {
ty::Predicate::Trait(p, _) => {
(Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty()))
}
_ => (None, None),
Expand Down Expand Up @@ -1543,7 +1546,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err.note(&format!("required because it appears within the type `{}`", ty));
obligated_types.push(ty);

let parent_predicate = parent_trait_ref.to_predicate();
let parent_predicate = parent_trait_ref.without_const().to_predicate();
if !self.is_recursive_obligation(obligated_types, &data.parent_code) {
self.note_obligation_cause_code(
err,
Expand All @@ -1560,7 +1563,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
parent_trait_ref.print_only_trait_path(),
parent_trait_ref.skip_binder().self_ty()
));
let parent_predicate = parent_trait_ref.to_predicate();
let parent_predicate = parent_trait_ref.without_const().to_predicate();
self.note_obligation_cause_code(
err,
&parent_predicate,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
}

match obligation.predicate {
ty::Predicate::Trait(ref data) => {
ty::Predicate::Trait(ref data, _) => {
let trait_obligation = obligation.with(data.clone());

if data.is_global() {
Expand Down
Loading