Skip to content

Commit

Permalink
Auto merge of #72433 - RalfJung:rollup-srft8nx, r=RalfJung
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #72055 (Intern predicates)
 - #72149 (Don't `type_of` on trait assoc ty without default)
 - #72347 (Make intra-link resolve links for both trait and impl items)
 - #72350 (Improve documentation of `slice::from_raw_parts`)
 - #72382 (Show default values for debug-assertions & debug-assertions-std)
 - #72421 (Fix anchor display when hovering impl)
 - #72425 (fix discriminant_value sign extension)

Failed merges:

r? @ghost
  • Loading branch information
bors committed May 21, 2020
2 parents 9310e3b + 74b5c50 commit d9417b3
Show file tree
Hide file tree
Showing 72 changed files with 941 additions and 682 deletions.
4 changes: 2 additions & 2 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,11 @@

# Whether or not debug assertions are enabled for the compiler and standard
# library.
#debug-assertions = false
#debug-assertions = debug

# Whether or not debug assertions are enabled for the standard library.
# Overrides the `debug-assertions` option, if defined.
#debug-assertions-std = false
#debug-assertions-std = debug-assertions

# Debuginfo level for most of Rust code, corresponds to the `-C debuginfo=N` option of `rustc`.
# `0` - no debug info
Expand Down
31 changes: 30 additions & 1 deletion src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5740,7 +5740,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
/// and it must be properly aligned. This means in particular:
///
/// * The entire memory range of this slice must be contained within a single allocated object!
/// Slices can never span across multiple allocated objects.
/// Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
/// for an example incorrectly not taking this into account.
/// * `data` must be non-null and aligned even for zero-length slices. One
/// reason for this is that enum layout optimizations may rely on references
/// (including slices of any length) being aligned and non-null to distinguish
Expand Down Expand Up @@ -5773,6 +5774,34 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
/// assert_eq!(slice[0], 42);
/// ```
///
/// ### Incorrect usage
///
/// The following `join_slices` function is **unsound** ⚠️
///
/// ```rust,no_run
/// use std::slice;
///
/// fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
/// let fst_end = fst.as_ptr().wrapping_add(fst.len());
/// let snd_start = snd.as_ptr();
/// assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
/// unsafe {
/// // The assertion above ensures `fst` and `snd` are contiguous, but they might
/// // still be contained within _different allocated objects_, in which case
/// // creating this slice is undefined behavior.
/// slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
/// }
/// }
///
/// fn main() {
/// // `a` and `b` are different allocated objects...
/// let a = 42;
/// let b = 27;
/// // ... which may nevertheless be laid out contiguously in memory: | a | b |
/// let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
/// }
/// ```
///
/// [valid]: ../../std/ptr/index.html#safety
/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
Expand Down
19 changes: 11 additions & 8 deletions src/librustc_infer/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
use rustc_middle::ty::{self, BoundVar, Const, Ty, TyCtxt};
use rustc_middle::ty::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt};
use std::fmt::Debug;

impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
Expand Down Expand Up @@ -532,12 +532,14 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
cause.clone(),
param_env,
match k1.unpack() {
GenericArgKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
GenericArgKind::Lifetime(r1) => ty::PredicateKind::RegionOutlives(
ty::Binder::bind(ty::OutlivesPredicate(r1, r2)),
),
GenericArgKind::Type(t1) => {
ty::Predicate::TypeOutlives(ty::Binder::bind(ty::OutlivesPredicate(t1, r2)))
}
)
.to_predicate(self.tcx),
GenericArgKind::Type(t1) => ty::PredicateKind::TypeOutlives(ty::Binder::bind(
ty::OutlivesPredicate(t1, r2),
))
.to_predicate(self.tcx),
GenericArgKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
// ecounter this branch.
Expand Down Expand Up @@ -664,9 +666,10 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
self.obligations.push(Obligation {
cause: self.cause.clone(),
param_env: self.param_env,
predicate: ty::Predicate::RegionOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
predicate: ty::PredicateKind::RegionOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
sup, sub,
))),
)))
.to_predicate(self.infcx.tcx),
recursion_depth: 0,
});
}
Expand Down
14 changes: 9 additions & 5 deletions src/librustc_infer/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable};
use rustc_middle::ty::{IntType, UintType};
use rustc_span::{Span, DUMMY_SP};

Expand Down Expand Up @@ -307,7 +307,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
self.param_env,
ty::Predicate::WellFormed(b_ty),
ty::PredicateKind::WellFormed(b_ty).to_predicate(self.infcx.tcx),
));
}

Expand Down Expand Up @@ -398,11 +398,15 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
b: &'tcx ty::Const<'tcx>,
) {
let predicate = if a_is_expected {
ty::Predicate::ConstEquate(a, b)
ty::PredicateKind::ConstEquate(a, b)
} else {
ty::Predicate::ConstEquate(b, a)
ty::PredicateKind::ConstEquate(b, a)
};
self.obligations.push(Obligation::new(self.trace.cause.clone(), self.param_env, predicate));
self.obligations.push(Obligation::new(
self.trace.cause.clone(),
self.param_env,
predicate.to_predicate(self.tcx()),
));
}
}

Expand Down
22 changes: 11 additions & 11 deletions src/librustc_infer/infer/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ pub fn explicit_outlives_bounds<'tcx>(
param_env: ty::ParamEnv<'tcx>,
) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
debug!("explicit_outlives_bounds()");
param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate {
ty::Predicate::Projection(..)
| ty::Predicate::Trait(..)
| ty::Predicate::Subtype(..)
| ty::Predicate::WellFormed(..)
| ty::Predicate::ObjectSafe(..)
| ty::Predicate::ClosureKind(..)
| ty::Predicate::TypeOutlives(..)
| ty::Predicate::ConstEvaluatable(..)
| ty::Predicate::ConstEquate(..) => None,
ty::Predicate::RegionOutlives(ref data) => data
param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate.kind() {
ty::PredicateKind::Projection(..)
| ty::PredicateKind::Trait(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) => None,
ty::PredicateKind::RegionOutlives(ref data) => data
.no_bound_vars()
.map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)),
})
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_infer/infer/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::traits::Obligation;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::TyVar;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use std::mem;

/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
Expand Down Expand Up @@ -100,11 +100,12 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
self.fields.obligations.push(Obligation::new(
self.fields.trace.cause.clone(),
self.fields.param_env,
ty::Predicate::Subtype(ty::Binder::dummy(ty::SubtypePredicate {
ty::PredicateKind::Subtype(ty::Binder::dummy(ty::SubtypePredicate {
a_is_expected: self.a_is_expected,
a,
b,
})),
}))
.to_predicate(self.tcx()),
));

Ok(a)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_infer/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
cause,
recursion_depth: 0,
param_env,
predicate: trait_ref.without_const().to_predicate(),
predicate: trait_ref.without_const().to_predicate(infcx.tcx),
},
);
}
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 @@ -59,7 +59,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;

// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(PredicateObligation<'_>, 112);
static_assert_size!(PredicateObligation<'_>, 88);

pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
Expand Down
82 changes: 46 additions & 36 deletions src/librustc_infer/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,49 @@ 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)
match pred.kind() {
&ty::PredicateKind::Trait(ref data, constness) => {
ty::PredicateKind::Trait(tcx.anonymize_late_bound_regions(data), constness)
.to_predicate(tcx)
}

ty::Predicate::RegionOutlives(ref data) => {
ty::Predicate::RegionOutlives(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::RegionOutlives(data) => {
ty::PredicateKind::RegionOutlives(tcx.anonymize_late_bound_regions(data))
.to_predicate(tcx)
}

ty::Predicate::TypeOutlives(ref data) => {
ty::Predicate::TypeOutlives(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::TypeOutlives(data) => {
ty::PredicateKind::TypeOutlives(tcx.anonymize_late_bound_regions(data))
.to_predicate(tcx)
}

ty::Predicate::Projection(ref data) => {
ty::Predicate::Projection(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::Projection(data) => {
ty::PredicateKind::Projection(tcx.anonymize_late_bound_regions(data)).to_predicate(tcx)
}

ty::Predicate::WellFormed(data) => ty::Predicate::WellFormed(data),
&ty::PredicateKind::WellFormed(data) => {
ty::PredicateKind::WellFormed(data).to_predicate(tcx)
}

ty::Predicate::ObjectSafe(data) => ty::Predicate::ObjectSafe(data),
&ty::PredicateKind::ObjectSafe(data) => {
ty::PredicateKind::ObjectSafe(data).to_predicate(tcx)
}

ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind)
&ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind).to_predicate(tcx)
}

ty::Predicate::Subtype(ref data) => {
ty::Predicate::Subtype(tcx.anonymize_late_bound_regions(data))
ty::PredicateKind::Subtype(data) => {
ty::PredicateKind::Subtype(tcx.anonymize_late_bound_regions(data)).to_predicate(tcx)
}

ty::Predicate::ConstEvaluatable(def_id, substs) => {
ty::Predicate::ConstEvaluatable(def_id, substs)
&ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
ty::PredicateKind::ConstEvaluatable(def_id, substs).to_predicate(tcx)
}

ty::Predicate::ConstEquate(c1, c2) => ty::Predicate::ConstEquate(c1, c2),
ty::PredicateKind::ConstEquate(c1, c2) => {
ty::PredicateKind::ConstEquate(c1, c2).to_predicate(tcx)
}
}
}

Expand Down Expand Up @@ -99,14 +108,14 @@ pub fn elaborate_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Elaborator<'tcx> {
elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate()))
elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate(tcx)))
}

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());
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate(tcx));
elaborate_predicates(tcx, predicates)
}

Expand Down Expand Up @@ -145,8 +154,8 @@ impl Elaborator<'tcx> {

fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
let tcx = self.visited.tcx;
match obligation.predicate {
ty::Predicate::Trait(ref data, _) => {
match obligation.predicate.kind() {
ty::PredicateKind::Trait(ref data, _) => {
// Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id());

Expand All @@ -167,36 +176,36 @@ impl Elaborator<'tcx> {

self.stack.extend(obligations);
}
ty::Predicate::WellFormed(..) => {
ty::PredicateKind::WellFormed(..) => {
// Currently, we do not elaborate WF predicates,
// although we easily could.
}
ty::Predicate::ObjectSafe(..) => {
ty::PredicateKind::ObjectSafe(..) => {
// Currently, we do not elaborate object-safe
// predicates.
}
ty::Predicate::Subtype(..) => {
ty::PredicateKind::Subtype(..) => {
// Currently, we do not "elaborate" predicates like `X <: Y`,
// though conceivably we might.
}
ty::Predicate::Projection(..) => {
ty::PredicateKind::Projection(..) => {
// Nothing to elaborate in a projection predicate.
}
ty::Predicate::ClosureKind(..) => {
ty::PredicateKind::ClosureKind(..) => {
// Nothing to elaborate when waiting for a closure's kind to be inferred.
}
ty::Predicate::ConstEvaluatable(..) => {
ty::PredicateKind::ConstEvaluatable(..) => {
// Currently, we do not elaborate const-evaluatable
// predicates.
}
ty::Predicate::ConstEquate(..) => {
ty::PredicateKind::ConstEquate(..) => {
// Currently, we do not elaborate const-equate
// predicates.
}
ty::Predicate::RegionOutlives(..) => {
ty::PredicateKind::RegionOutlives(..) => {
// Nothing to elaborate from `'a: 'b`.
}
ty::Predicate::TypeOutlives(ref data) => {
ty::PredicateKind::TypeOutlives(ref data) => {
// We know that `T: 'a` for some type `T`. We can
// often elaborate this. For example, if we know that
// `[U]: 'a`, that implies that `U: 'a`. Similarly, if
Expand Down Expand Up @@ -228,15 +237,15 @@ impl Elaborator<'tcx> {
if r.is_late_bound() {
None
} else {
Some(ty::Predicate::RegionOutlives(ty::Binder::dummy(
Some(ty::PredicateKind::RegionOutlives(ty::Binder::dummy(
ty::OutlivesPredicate(r, r_min),
)))
}
}

Component::Param(p) => {
let ty = tcx.mk_ty_param(p.index, p.name);
Some(ty::Predicate::TypeOutlives(ty::Binder::dummy(
Some(ty::PredicateKind::TypeOutlives(ty::Binder::dummy(
ty::OutlivesPredicate(ty, r_min),
)))
}
Expand All @@ -250,8 +259,9 @@ impl Elaborator<'tcx> {
None
}
})
.filter(|p| visited.insert(p))
.map(|p| predicate_obligation(p, None)),
.map(|predicate_kind| predicate_kind.to_predicate(tcx))
.filter(|predicate| visited.insert(predicate))
.map(|predicate| predicate_obligation(predicate, None)),
);
}
}
Expand Down Expand Up @@ -317,7 +327,7 @@ impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToT

fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(obligation) = self.base_iterator.next() {
if let ty::Predicate::Trait(data, _) = obligation.predicate {
if let ty::PredicateKind::Trait(data, _) = obligation.predicate.kind() {
return Some(data.to_poly_trait_ref());
}
}
Expand Down
Loading

0 comments on commit d9417b3

Please sign in to comment.