Add constness field to ty::Predicate::Trait

This commit is contained in:
Dylan MacKenzie 2020-01-13 20:30:31 -08:00
parent 1a3bd5775f
commit ab3081a70e
27 changed files with 104 additions and 55 deletions

View File

@ -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!(
@ -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;
@ -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

View File

@ -331,7 +331,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() {

View File

@ -234,7 +234,7 @@ fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_o
.map(|(predicate, _)| predicate.subst_supertrait(tcx, &trait_ref))
.any(|predicate| {
match predicate {
ty::Predicate::Trait(ref data) => {
ty::Predicate::Trait(ref data, _) => {
// In the case of a trait predicate, we can skip the "self" type.
data.skip_binder().input_types().skip(1).any(has_self_ty)
}
@ -285,7 +285,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
let predicates = tcx.predicates_of(def_id);
let predicates = predicates.instantiate_identity(tcx).predicates;
elaborate_predicates(tcx, predicates).any(|predicate| match predicate {
ty::Predicate::Trait(ref trait_pred) => {
ty::Predicate::Trait(ref trait_pred, _) => {
trait_pred.def_id() == sized_def_id && trait_pred.skip_binder().self_ty().is_param(0)
}
ty::Predicate::Projection(..)

View File

@ -24,7 +24,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
// `&T`, accounts for about 60% percentage of the predicates
// we have to prove. No need to canonicalize and all that for
// such cases.
if let Predicate::Trait(trait_ref) = key.value.predicate {
if let Predicate::Trait(trait_ref, _) = key.value.predicate {
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
if trait_ref.def_id() == sized_def_id {
if trait_ref.skip_binder().self_ty().is_trivially_sized(tcx) {

View File

@ -51,7 +51,7 @@ use std::cmp;
use std::fmt::{self, Display};
use std::iter;
use std::rc::Rc;
use syntax::attr;
use syntax::{ast, attr};
pub struct SelectionContext<'cx, 'tcx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
@ -718,7 +718,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
match obligation.predicate {
ty::Predicate::Trait(ref t) => {
ty::Predicate::Trait(ref t, _) => {
debug_assert!(!t.has_escaping_bound_vars());
let obligation = obligation.with(t.clone());
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
@ -945,7 +945,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// trait refs. This is important because it's only a cycle
// if the regions match exactly.
let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth);
let cycle = cycle.map(|stack| ty::Predicate::Trait(stack.obligation.predicate));
let cycle = cycle.map(|stack| {
ty::Predicate::Trait(stack.obligation.predicate, ast::Constness::NotConst)
});
if self.coinductive_match(cycle) {
debug!("evaluate_stack({:?}) --> recursive, coinductive", stack.fresh_trait_ref);
Some(EvaluatedToOk)
@ -1060,7 +1062,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
let result = match predicate {
ty::Predicate::Trait(ref data) => self.tcx().trait_is_auto(data.def_id()),
ty::Predicate::Trait(ref data, _) => self.tcx().trait_is_auto(data.def_id()),
_ => false,
};
debug!("coinductive_predicate({:?}) = {:?}", predicate, result);

View File

@ -13,8 +13,8 @@ use super::{Normalized, Obligation, ObligationCause, PredicateObligation, Select
fn anonymize_predicate<'tcx>(tcx: TyCtxt<'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
match *pred {
ty::Predicate::Trait(ref data) => {
ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data))
ty::Predicate::Trait(ref data, constness) => {
ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data), constness)
}
ty::Predicate::RegionOutlives(ref data) => {
@ -127,7 +127,7 @@ impl Elaborator<'tcx> {
fn elaborate(&mut self, predicate: &ty::Predicate<'tcx>) {
let tcx = self.visited.tcx;
match *predicate {
ty::Predicate::Trait(ref data) => {
ty::Predicate::Trait(ref data, _) => {
// Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id());
@ -471,7 +471,7 @@ impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(pred) = self.base_iterator.next() {
if let ty::Predicate::Trait(data) = pred {
if let ty::Predicate::Trait(data, _) = pred {
return Some(data.to_poly_trait_ref());
}
}

View File

@ -62,7 +62,7 @@ pub fn predicate_obligations<'a, 'tcx>(
// (*) ok to skip binders, because wf code is prepared for it
match *predicate {
ty::Predicate::Trait(ref t) => {
ty::Predicate::Trait(ref t, _) => {
wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*)
}
ty::Predicate::RegionOutlives(..) => {}
@ -245,7 +245,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
}
}
}
ty::Predicate::Trait(proj) => {
ty::Predicate::Trait(proj, _) => {
// An associated item obligation born out of the `trait` failed to be met.
// Point at the `impl` that failed the obligation, the associated item that
// needed to meet the obligation, and the definition of that associated item,

View File

@ -150,6 +150,15 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
}
}
impl TypeFoldable<'tcx> for syntax::ast::Constness {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
*self
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
false
}
}
/// The `TypeFolder` trait defines the actual *folding*. There is a
/// method defined for every foldable type. Each of these has a
/// default implementation that does an "identity" fold. Within each

View File

@ -1068,7 +1068,11 @@ pub enum Predicate<'tcx> {
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the type parameters.
Trait(PolyTraitPredicate<'tcx>),
///
/// A trait predicate will have `Constness::Const` if it originates
/// from a bound on a `const fn` without the `?const` opt-out (e.g.,
/// `const fn foobar<Foo: Bar>() {}`).
Trait(PolyTraitPredicate<'tcx>, ast::Constness),
/// `where 'a: 'b`
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
@ -1191,8 +1195,8 @@ impl<'tcx> Predicate<'tcx> {
let substs = &trait_ref.skip_binder().substs;
match *self {
Predicate::Trait(ref binder) => {
Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs)))
Predicate::Trait(ref binder, constness) => {
Predicate::Trait(binder.map_bound(|data| data.subst(tcx, substs)), constness)
}
Predicate::Subtype(ref binder) => {
Predicate::Subtype(binder.map_bound(|data| data.subst(tcx, substs)))
@ -1338,13 +1342,16 @@ pub trait ToPredicate<'tcx> {
impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
fn to_predicate(&self) -> Predicate<'tcx> {
ty::Predicate::Trait(ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() }))
ty::Predicate::Trait(
ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() }),
ast::Constness::NotConst,
)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
fn to_predicate(&self) -> Predicate<'tcx> {
ty::Predicate::Trait(self.to_poly_trait_predicate())
ty::Predicate::Trait(self.to_poly_trait_predicate(), ast::Constness::NotConst)
}
}
@ -1413,7 +1420,7 @@ impl<'tcx> Predicate<'tcx> {
/// with depth 0 are bound by the predicate.
pub fn walk_tys(&'a self) -> impl Iterator<Item = Ty<'tcx>> + 'a {
match *self {
ty::Predicate::Trait(ref data) => {
ty::Predicate::Trait(ref data, _) => {
WalkTysIter::InputTypes(data.skip_binder().input_types())
}
ty::Predicate::Subtype(binder) => {
@ -1439,7 +1446,7 @@ impl<'tcx> Predicate<'tcx> {
pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
match *self {
Predicate::Trait(ref t) => Some(t.to_poly_trait_ref()),
Predicate::Trait(ref t, _) => Some(t.to_poly_trait_ref()),
Predicate::Projection(..)
| Predicate::Subtype(..)
| Predicate::RegionOutlives(..)

View File

@ -1791,7 +1791,12 @@ define_print_and_forward_display! {
ty::Predicate<'tcx> {
match *self {
ty::Predicate::Trait(ref data) => p!(print(data)),
ty::Predicate::Trait(ref data, constness) => {
if let ast::Constness::Const = constness {
p!(write("const "));
}
p!(print(data))
}
ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),

View File

@ -15,6 +15,7 @@ use smallvec::SmallVec;
use std::fmt;
use std::rc::Rc;
use std::sync::Arc;
use syntax::ast;
impl fmt::Debug for ty::GenericParamDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -234,7 +235,12 @@ impl fmt::Debug for ty::ProjectionPredicate<'tcx> {
impl fmt::Debug for ty::Predicate<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::Predicate::Trait(ref a) => a.fmt(f),
ty::Predicate::Trait(ref a, constness) => {
if let ast::Constness::Const = constness {
write!(f, "const ")?;
}
a.fmt(f)
}
ty::Predicate::Subtype(ref pair) => pair.fmt(f),
ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f),
ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f),
@ -474,7 +480,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
type Lifted = ty::Predicate<'tcx>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
match *self {
ty::Predicate::Trait(ref binder) => tcx.lift(binder).map(ty::Predicate::Trait),
ty::Predicate::Trait(ref binder, constness) => {
tcx.lift(binder).map(|binder| ty::Predicate::Trait(binder, constness))
}
ty::Predicate::Subtype(ref binder) => tcx.lift(binder).map(ty::Predicate::Subtype),
ty::Predicate::RegionOutlives(ref binder) => {
tcx.lift(binder).map(ty::Predicate::RegionOutlives)

View File

@ -144,7 +144,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
ty::Opaque(def, _) => {
let mut has_emitted = false;
for (predicate, _) in cx.tcx.predicates_of(def).predicates {
if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
if let ty::Predicate::Trait(ref poly_trait_predicate, _) = predicate {
let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
let def_id = trait_ref.def_id;
let descr_pre =

View File

@ -33,6 +33,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::vec::{Idx, IndexVec};
use rustc_span::{Span, DUMMY_SP};
use syntax::ast;
use crate::dataflow::move_paths::MoveData;
use crate::dataflow::FlowAtLocation;
@ -1931,12 +1932,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
traits::ObligationCauseCode::RepeatVec(should_suggest),
),
self.param_env,
ty::Predicate::Trait(ty::Binder::bind(ty::TraitPredicate {
trait_ref: ty::TraitRef::new(
self.tcx().lang_items().copy_trait().unwrap(),
tcx.mk_substs_trait(ty, &[]),
),
})),
ty::Predicate::Trait(
ty::Binder::bind(ty::TraitPredicate {
trait_ref: ty::TraitRef::new(
self.tcx().lang_items().copy_trait().unwrap(),
tcx.mk_substs_trait(ty, &[]),
),
}),
ast::Constness::NotConst,
),
),
&traits::SelectionError::Unimplemented,
false,
@ -2574,7 +2578,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
category: ConstraintCategory,
) {
self.prove_predicates(
Some(ty::Predicate::Trait(trait_ref.to_poly_trait_ref().to_poly_trait_predicate())),
Some(ty::Predicate::Trait(
trait_ref.to_poly_trait_ref().to_poly_trait_predicate(),
ast::Constness::NotConst,
)),
locations,
category,
);

View File

@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use std::borrow::Cow;
use syntax::attr;
use syntax::{ast, attr};
type McfResult = Result<(), (Span, Cow<'static, str>)>;
@ -27,12 +27,19 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
bug!("closure kind predicate on function: {:#?}", predicate)
}
Predicate::Subtype(_) => bug!("subtype predicate on function: {:#?}", predicate),
Predicate::Trait(pred) => {
Predicate::Trait(pred, constness) => {
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
continue;
}
match pred.skip_binder().self_ty().kind {
ty::Param(ref p) => {
// Allow `T: ?const Trait`
if *constness == ast::Constness::NotConst
&& feature_allowed(tcx, def_id, sym::const_trait_bound_opt_out)
{
continue;
}
let generics = tcx.generics_of(current);
let def = generics.type_param(p, tcx);
let span = tcx.def_span(def.def_id);

View File

@ -93,7 +93,7 @@ where
let ty::GenericPredicates { parent: _, predicates } = predicates;
for (predicate, _span) in predicates {
match predicate {
ty::Predicate::Trait(poly_predicate) => {
ty::Predicate::Trait(poly_predicate, _) => {
let ty::TraitPredicate { trait_ref } = *poly_predicate.skip_binder();
if self.visit_trait(trait_ref) {
return true;

View File

@ -94,7 +94,7 @@ impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
use rustc::ty::Predicate;
match self {
Predicate::Trait(predicate) => predicate.lower(),
Predicate::Trait(predicate, _) => predicate.lower(),
Predicate::RegionOutlives(predicate) => predicate.lower(),
Predicate::TypeOutlives(predicate) => predicate.lower(),
Predicate::Projection(predicate) => predicate.lower(),

View File

@ -1490,7 +1490,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait_ref
);
match trait_ref {
ty::Predicate::Trait(pred) => {
ty::Predicate::Trait(pred, constness) => {
associated_types.entry(span).or_default().extend(
tcx.associated_items(pred.def_id())
.filter(|item| item.kind == ty::AssocKind::Type)

View File

@ -565,7 +565,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
let obligation = queue.remove(0);
debug!("coerce_unsized resolve step: {:?}", obligation);
let trait_ref = match obligation.predicate {
ty::Predicate::Trait(ref tr) if traits.contains(&tr.def_id()) => {
ty::Predicate::Trait(ref tr, _) if traits.contains(&tr.def_id()) => {
if unsize_did == tr.def_id() {
let sty = &tr.skip_binder().input_types().nth(1).unwrap().kind;
if let ty::Tuple(..) = sty {

View File

@ -234,7 +234,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
let predicate_matches_closure = |p: &'_ Predicate<'tcx>| {
let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env);
match (predicate, p) {
(Predicate::Trait(a), Predicate::Trait(b)) => relator.relate(a, b).is_ok(),
(Predicate::Trait(a, _), Predicate::Trait(b, _)) => relator.relate(a, b).is_ok(),
(Predicate::Projection(a), Predicate::Projection(b)) => {
relator.relate(a, b).is_ok()
}

View File

@ -569,7 +569,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
traits::elaborate_predicates(self.tcx, predicates.predicates.clone())
.filter_map(|predicate| match predicate {
ty::Predicate::Trait(trait_pred) if trait_pred.def_id() == sized_def_id => {
ty::Predicate::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => {
Some(trait_pred)
}
_ => None,

View File

@ -826,7 +826,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// FIXME: do we want to commit to this behavior for param bounds?
let bounds = self.param_env.caller_bounds.iter().filter_map(|predicate| match *predicate {
ty::Predicate::Trait(ref trait_predicate) => {
ty::Predicate::Trait(ref trait_predicate, _) => {
match trait_predicate.skip_binder().trait_ref.self_ty().kind {
ty::Param(ref p) if *p == param_ty => Some(trait_predicate.to_poly_trait_ref()),
_ => None,
@ -1430,7 +1430,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
let o = self.resolve_vars_if_possible(&o);
if !self.predicate_may_hold(&o) {
result = ProbeResult::NoMatch;
if let &ty::Predicate::Trait(ref pred) = &o.predicate {
if let &ty::Predicate::Trait(ref pred, _) = &o.predicate {
possibly_unsatisfied_predicates.push(pred.skip_binder().trait_ref);
}
}

View File

@ -2623,7 +2623,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
parent: None,
predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
|&predicate| match predicate {
ty::Predicate::Trait(ref data)
ty::Predicate::Trait(ref data, _)
if data.skip_binder().self_ty().is_param(index) =>
{
// HACK(eddyb) should get the original `Span`.
@ -3695,7 +3695,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Predicate::Projection(ref data) => {
Some((data.to_poly_trait_ref(self.tcx), obligation))
}
ty::Predicate::Trait(ref data) => Some((data.to_poly_trait_ref(), obligation)),
ty::Predicate::Trait(ref data, _) => Some((data.to_poly_trait_ref(), obligation)),
ty::Predicate::Subtype(..) => None,
ty::Predicate::RegionOutlives(..) => None,
ty::Predicate::TypeOutlives(..) => None,
@ -3998,7 +3998,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
continue;
}
if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
// Collect the argument position for all arguments that could have caused this
// `FulfillmentError`.
let mut referenced_in = final_arg_types
@ -4042,7 +4042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let hir::ExprKind::Path(qpath) = &path.kind {
if let hir::QPath::Resolved(_, path) = &qpath {
for error in errors {
if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
if let ty::Predicate::Trait(predicate, _) = error.obligation.predicate {
// If any of the type arguments in this path segment caused the
// `FullfillmentError`, point at its span (#61860).
for arg in path

View File

@ -432,7 +432,7 @@ fn type_param_predicates(
icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true))
.into_iter()
.filter(|(predicate, _)| match predicate {
ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index),
ty::Predicate::Trait(ref data, _) => data.skip_binder().self_ty().is_param(index),
_ => false,
}),
);
@ -857,7 +857,7 @@ fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredi
// which will, in turn, reach indirect supertraits.
for &(pred, span) in superbounds {
debug!("superbound: {:?}", pred);
if let ty::Predicate::Trait(bound) = pred {
if let ty::Predicate::Trait(bound, _) = pred {
tcx.at(span).super_predicates_of(bound.def_id());
}
}

View File

@ -462,7 +462,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
.filter(|p| {
!orig_bounds.contains(p)
|| match p {
&&ty::Predicate::Trait(pred) => pred.def_id() == sized_trait,
ty::Predicate::Trait(pred, _) => pred.def_id() == sized_trait,
_ => false,
}
})

View File

@ -482,7 +482,7 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
use rustc::ty::Predicate;
match *self {
Predicate::Trait(ref pred) => Some(pred.clean(cx)),
Predicate::Trait(ref pred, _) => Some(pred.clean(cx)),
Predicate::Subtype(ref pred) => Some(pred.clean(cx)),
Predicate::RegionOutlives(ref pred) => pred.clean(cx),
Predicate::TypeOutlives(ref pred) => pred.clean(cx),

View File

@ -141,7 +141,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId, trait_: DefId)
.predicates
.iter()
.filter_map(|(pred, _)| {
if let ty::Predicate::Trait(ref pred) = *pred {
if let ty::Predicate::Trait(ref pred, _) = *pred {
if pred.skip_binder().trait_ref.self_ty() == self_ty {
Some(pred.def_id())
} else {

View File

@ -2165,7 +2165,8 @@ impl IsAsync {
}
}
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
#[derive(HashStable_Generic)]
pub enum Constness {
Const,
NotConst,