Add ConstnessAnd
that implements ToPredicate
This commit is contained in:
parent
ab3081a70e
commit
d2aefbb286
@ -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};
|
||||
@ -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(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -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};
|
||||
@ -130,7 +132,7 @@ 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;
|
||||
@ -138,7 +140,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
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.
|
||||
@ -530,7 +532,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() {
|
||||
@ -583,7 +585,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,
|
||||
))
|
||||
);
|
||||
@ -695,7 +697,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) {
|
||||
@ -988,7 +993,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())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1076,7 +1081,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);
|
||||
@ -1269,8 +1274,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)
|
||||
})
|
||||
|
@ -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,
|
||||
@ -50,7 +50,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
" where"
|
||||
},
|
||||
trait_ref.to_predicate(),
|
||||
trait_ref.without_const().to_predicate(),
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
@ -340,8 +340,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
|
||||
@ -1122,7 +1125,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),
|
||||
@ -1545,7 +1548,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,
|
||||
@ -1562,7 +1565,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,
|
||||
|
@ -29,7 +29,7 @@ use crate::mir::interpret::ErrorHandled;
|
||||
use crate::ty::error::{ExpectedFound, TypeError};
|
||||
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use crate::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt};
|
||||
use crate::ty::{self, AdtKind, GenericParamDefKind, List, ToPredicate, Ty, TyCtxt, WithConstness};
|
||||
use crate::util::common::ErrorReported;
|
||||
use chalk_engine;
|
||||
use rustc_hir as hir;
|
||||
@ -732,7 +732,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
|
||||
param_env,
|
||||
cause: ObligationCause::misc(span, hir::DUMMY_HIR_ID),
|
||||
recursion_depth: 0,
|
||||
predicate: trait_ref.to_predicate(),
|
||||
predicate: trait_ref.without_const().to_predicate(),
|
||||
};
|
||||
|
||||
let result = infcx.predicate_must_hold_modulo_regions(&obligation);
|
||||
|
@ -12,7 +12,7 @@ use super::elaborate_predicates;
|
||||
|
||||
use crate::traits::{self, Obligation, ObligationCause};
|
||||
use crate::ty::subst::{InternalSubsts, Subst};
|
||||
use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
|
||||
@ -585,6 +585,7 @@ fn receiver_is_dispatchable<'tcx>(
|
||||
def_id: unsize_did,
|
||||
substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]),
|
||||
}
|
||||
.without_const()
|
||||
.to_predicate();
|
||||
|
||||
// U: Trait<Arg1, ..., ArgN>
|
||||
@ -598,7 +599,7 @@ fn receiver_is_dispatchable<'tcx>(
|
||||
}
|
||||
});
|
||||
|
||||
ty::TraitRef { def_id: unsize_did, substs }.to_predicate()
|
||||
ty::TraitRef { def_id: unsize_did, substs }.without_const().to_predicate()
|
||||
};
|
||||
|
||||
let caller_bounds: Vec<Predicate<'tcx>> = param_env
|
||||
@ -620,6 +621,7 @@ fn receiver_is_dispatchable<'tcx>(
|
||||
def_id: dispatch_from_dyn_did,
|
||||
substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
|
||||
}
|
||||
.without_const()
|
||||
.to_predicate();
|
||||
|
||||
Obligation::new(ObligationCause::dummy(), param_env, predicate)
|
||||
|
@ -16,7 +16,7 @@ use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
|
||||
use crate::ty::fold::{TypeFoldable, TypeFolder};
|
||||
use crate::ty::subst::{InternalSubsts, Subst};
|
||||
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt};
|
||||
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
|
||||
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_macros::HashStable;
|
||||
@ -738,7 +738,12 @@ fn get_paranoid_cache_value_obligation<'a, 'tcx>(
|
||||
depth: usize,
|
||||
) -> PredicateObligation<'tcx> {
|
||||
let trait_ref = projection_ty.trait_ref(infcx.tcx).to_poly_trait_ref();
|
||||
Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.to_predicate() }
|
||||
Obligation {
|
||||
cause,
|
||||
recursion_depth: depth,
|
||||
param_env,
|
||||
predicate: trait_ref.without_const().to_predicate(),
|
||||
}
|
||||
}
|
||||
|
||||
/// If we are projecting `<T as Trait>::Item`, but `T: Trait` does not
|
||||
@ -772,7 +777,7 @@ fn normalize_to_error<'a, 'tcx>(
|
||||
cause,
|
||||
recursion_depth: depth,
|
||||
param_env,
|
||||
predicate: trait_ref.to_predicate(),
|
||||
predicate: trait_ref.without_const().to_predicate(),
|
||||
};
|
||||
let tcx = selcx.infcx().tcx;
|
||||
let def_id = projection_ty.item_def_id;
|
||||
|
@ -37,7 +37,7 @@ use crate::middle::lang_items;
|
||||
use crate::ty::fast_reject;
|
||||
use crate::ty::relate::TypeRelation;
|
||||
use crate::ty::subst::{Subst, SubstsRef};
|
||||
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
@ -3368,7 +3368,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
|
||||
tcx.mk_substs_trait(source, &[]),
|
||||
);
|
||||
nested.push(predicate_to_obligation(tr.to_predicate()));
|
||||
nested.push(predicate_to_obligation(tr.without_const().to_predicate()));
|
||||
|
||||
// If the type is `Foo + 'a`, ensure that the type
|
||||
// being cast to `Foo + 'a` outlives `'a`:
|
||||
|
@ -4,7 +4,7 @@ use smallvec::SmallVec;
|
||||
|
||||
use crate::ty::outlives::Component;
|
||||
use crate::ty::subst::{GenericArg, Subst, SubstsRef};
|
||||
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt};
|
||||
use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, WithConstness};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -99,14 +99,14 @@ pub fn elaborate_trait_ref<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> Elaborator<'tcx> {
|
||||
elaborate_predicates(tcx, vec![trait_ref.to_predicate()])
|
||||
elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
|
||||
}
|
||||
|
||||
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.to_predicate()).collect();
|
||||
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
|
||||
elaborate_predicates(tcx, predicates)
|
||||
}
|
||||
|
||||
@ -358,7 +358,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
||||
fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
|
||||
let tcx = self.tcx;
|
||||
let trait_ref = item.trait_ref();
|
||||
let pred = trait_ref.to_predicate();
|
||||
let pred = trait_ref.without_const().to_predicate();
|
||||
|
||||
debug!("expand_trait_aliases: trait_ref={:?}", trait_ref);
|
||||
|
||||
@ -370,13 +370,9 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
||||
|
||||
// Don't recurse if this trait alias is already on the stack for the DFS search.
|
||||
let anon_pred = anonymize_predicate(tcx, &pred);
|
||||
if item
|
||||
.path
|
||||
.iter()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.any(|(tr, _)| anonymize_predicate(tcx, &tr.to_predicate()) == anon_pred)
|
||||
{
|
||||
if item.path.iter().rev().skip(1).any(|(tr, _)| {
|
||||
anonymize_predicate(tcx, &tr.without_const().to_predicate()) == anon_pred
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -545,7 +541,12 @@ pub fn predicate_for_trait_ref<'tcx>(
|
||||
trait_ref: ty::TraitRef<'tcx>,
|
||||
recursion_depth: usize,
|
||||
) -> PredicateObligation<'tcx> {
|
||||
Obligation { cause, param_env, recursion_depth, predicate: trait_ref.to_predicate() }
|
||||
Obligation {
|
||||
cause,
|
||||
param_env,
|
||||
recursion_depth,
|
||||
predicate: trait_ref.without_const().to_predicate(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn predicate_for_trait_def(
|
||||
|
@ -3,7 +3,7 @@ use crate::infer::InferCtxt;
|
||||
use crate::middle::lang_items;
|
||||
use crate::traits::{self, AssocTypeBoundData};
|
||||
use crate::ty::subst::SubstsRef;
|
||||
use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
@ -350,7 +350,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
self.compute_trait_ref(&trait_ref, Elaborate::None);
|
||||
|
||||
if !data.has_escaping_bound_vars() {
|
||||
let predicate = trait_ref.to_predicate();
|
||||
let predicate = trait_ref.without_const().to_predicate();
|
||||
let cause = self.cause(traits::ProjectionWf(data));
|
||||
self.out.push(traits::Obligation::new(cause, self.param_env, predicate));
|
||||
}
|
||||
@ -378,7 +378,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
def_id: self.infcx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
|
||||
substs: self.infcx.tcx.mk_substs_trait(subty, &[]),
|
||||
};
|
||||
self.out.push(traits::Obligation::new(cause, self.param_env, trait_ref.to_predicate()));
|
||||
self.out.push(traits::Obligation::new(
|
||||
cause,
|
||||
self.param_env,
|
||||
trait_ref.without_const().to_predicate(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ use std::ops::Deref;
|
||||
use std::ops::Range;
|
||||
use std::slice;
|
||||
use std::{mem, ptr};
|
||||
use syntax::ast::{self, Ident, Name, NodeId};
|
||||
use syntax::ast::{self, Constness, Ident, Name, NodeId};
|
||||
use syntax::attr;
|
||||
|
||||
pub use self::sty::BoundRegion::*;
|
||||
@ -1072,7 +1072,7 @@ pub enum Predicate<'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),
|
||||
Trait(PolyTraitPredicate<'tcx>, Constness),
|
||||
|
||||
/// `where 'a: 'b`
|
||||
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
|
||||
@ -1340,18 +1340,33 @@ pub trait ToPredicate<'tcx> {
|
||||
fn to_predicate(&self) -> Predicate<'tcx>;
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
|
||||
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
|
||||
fn to_predicate(&self) -> Predicate<'tcx> {
|
||||
ty::Predicate::Trait(
|
||||
ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.clone() }),
|
||||
ast::Constness::NotConst,
|
||||
ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }),
|
||||
self.constness,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for PolyTraitRef<'tcx> {
|
||||
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&TraitRef<'tcx>> {
|
||||
fn to_predicate(&self) -> Predicate<'tcx> {
|
||||
ty::Predicate::Trait(self.to_poly_trait_predicate(), ast::Constness::NotConst)
|
||||
ty::Predicate::Trait(
|
||||
ty::Binder::dummy(ty::TraitPredicate { trait_ref: self.value.clone() }),
|
||||
self.constness,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
|
||||
fn to_predicate(&self) -> Predicate<'tcx> {
|
||||
ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<&PolyTraitRef<'tcx>> {
|
||||
fn to_predicate(&self) -> Predicate<'tcx> {
|
||||
ty::Predicate::Trait(self.value.to_poly_trait_predicate(), self.constness)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1707,6 +1722,33 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct ConstnessAnd<T> {
|
||||
pub constness: Constness,
|
||||
pub value: T,
|
||||
}
|
||||
|
||||
// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate()` to ensure that
|
||||
// the constness of trait bounds is being propagated correctly.
|
||||
pub trait WithConstness: Sized {
|
||||
#[inline]
|
||||
fn with_constness(self, constness: Constness) -> ConstnessAnd<Self> {
|
||||
ConstnessAnd { constness, value: self }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_const(self) -> ConstnessAnd<Self> {
|
||||
self.with_constness(Constness::Const)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn without_const(self) -> ConstnessAnd<Self> {
|
||||
self.with_constness(Constness::NotConst)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> WithConstness for T {}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
|
||||
pub struct ParamEnvAnd<'tcx, T> {
|
||||
pub param_env: ParamEnv<'tcx>,
|
||||
|
@ -12,7 +12,9 @@ use crate::mir::interpret::Scalar;
|
||||
use crate::mir::Promoted;
|
||||
use crate::ty::layout::VariantIdx;
|
||||
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
||||
use crate::ty::{self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable};
|
||||
use crate::ty::{
|
||||
self, AdtDef, DefIdTree, Discr, Ty, TyCtxt, TypeFlags, TypeFoldable, WithConstness,
|
||||
};
|
||||
use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS};
|
||||
use polonius_engine::Atom;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
@ -665,14 +667,16 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
|
||||
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
|
||||
use crate::ty::ToPredicate;
|
||||
match *self.skip_binder() {
|
||||
ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(),
|
||||
ExistentialPredicate::Trait(tr) => {
|
||||
Binder(tr).with_self_ty(tcx, self_ty).without_const().to_predicate()
|
||||
}
|
||||
ExistentialPredicate::Projection(p) => {
|
||||
ty::Predicate::Projection(Binder(p.with_self_ty(tcx, self_ty)))
|
||||
}
|
||||
ExistentialPredicate::AutoTrait(did) => {
|
||||
let trait_ref =
|
||||
Binder(ty::TraitRef { def_id: did, substs: tcx.mk_substs_trait(self_ty, &[]) });
|
||||
trait_ref.to_predicate()
|
||||
trait_ref.without_const().to_predicate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use rustc::hir::map as hir_map;
|
||||
use rustc::session::CrateDisambiguator;
|
||||
use rustc::traits::{self};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::{self, ToPredicate, Ty, TyCtxt};
|
||||
use rustc::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
@ -58,6 +58,7 @@ fn sized_constraint_for_ty(tcx: TyCtxt<'tcx>, adtdef: &ty::AdtDef, ty: Ty<'tcx>)
|
||||
def_id: sized_trait,
|
||||
substs: tcx.mk_substs_trait(ty, &[]),
|
||||
})
|
||||
.without_const()
|
||||
.to_predicate();
|
||||
let predicates = tcx.predicates_of(adtdef.did).predicates;
|
||||
if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
|
||||
|
@ -17,7 +17,7 @@ use rustc::traits::astconv_object_safety_violations;
|
||||
use rustc::traits::error_reporting::report_object_safety_error;
|
||||
use rustc::traits::wf::object_region_bounds;
|
||||
use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
|
||||
use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
|
||||
use rustc::ty::{GenericParamDef, GenericParamDefKind};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId};
|
||||
@ -2980,7 +2980,7 @@ impl<'tcx> Bounds<'tcx> {
|
||||
def_id: sized,
|
||||
substs: tcx.mk_substs_trait(param_ty, &[]),
|
||||
});
|
||||
(trait_ref.to_predicate(), span)
|
||||
(trait_ref.without_const().to_predicate(), span)
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -5,7 +5,7 @@ use rustc::infer::{InferCtxt, InferOk};
|
||||
use rustc::session::DiagnosticMessageId;
|
||||
use rustc::traits::{self, TraitEngine};
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
|
||||
use rustc::ty::{self, TraitRef, Ty, TyCtxt};
|
||||
use rustc::ty::{self, TraitRef, Ty, TyCtxt, WithConstness};
|
||||
use rustc::ty::{ToPredicate, TypeFoldable};
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
@ -124,8 +124,11 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
|
||||
let obligation =
|
||||
traits::Obligation::new(cause.clone(), self.param_env, trait_ref.to_predicate());
|
||||
let obligation = traits::Obligation::new(
|
||||
cause.clone(),
|
||||
self.param_env,
|
||||
trait_ref.without_const().to_predicate(),
|
||||
);
|
||||
if !self.infcx.predicate_may_hold(&obligation) {
|
||||
debug!("overloaded_deref_ty: cannot match obligation");
|
||||
return None;
|
||||
|
@ -17,7 +17,7 @@ use rustc::traits;
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use rustc::ty::GenericParamDefKind;
|
||||
use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable};
|
||||
use rustc::ty::{self, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TypeFoldable, WithConstness};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
@ -322,7 +322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span,
|
||||
self.body_id,
|
||||
self.param_env,
|
||||
poly_trait_ref.to_predicate(),
|
||||
poly_trait_ref.without_const().to_predicate(),
|
||||
);
|
||||
|
||||
// Now we want to know if this can be matched
|
||||
|
@ -25,6 +25,7 @@ use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
|
||||
use rustc::ty::GenericParamDefKind;
|
||||
use rustc::ty::{
|
||||
self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable,
|
||||
WithConstness,
|
||||
};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
@ -1396,7 +1397,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
TraitCandidate(trait_ref) => {
|
||||
let predicate = trait_ref.to_predicate();
|
||||
let predicate = trait_ref.without_const().to_predicate();
|
||||
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
|
||||
if !self.predicate_may_hold(&obligation) {
|
||||
if self.probe(|_| self.select_trait_candidate(trait_ref).is_err()) {
|
||||
|
@ -9,7 +9,7 @@ use rustc::hir::map::Map;
|
||||
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc::traits::Obligation;
|
||||
use rustc::ty::print::with_crate_prefix;
|
||||
use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
@ -59,7 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span,
|
||||
self.body_id,
|
||||
self.param_env,
|
||||
poly_trait_ref.to_predicate(),
|
||||
poly_trait_ref.without_const().to_predicate(),
|
||||
);
|
||||
self.predicate_may_hold(&obligation)
|
||||
})
|
||||
|
@ -112,7 +112,7 @@ use rustc::ty::subst::{GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSel
|
||||
use rustc::ty::util::{Discr, IntTypeExt, Representability};
|
||||
use rustc::ty::{
|
||||
self, AdtKind, CanonicalUserType, Const, GenericParamDefKind, RegionKind, ToPolyTraitRef,
|
||||
ToPredicate, Ty, TyCtxt, UserType,
|
||||
ToPredicate, Ty, TyCtxt, UserType, WithConstness,
|
||||
};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
@ -1423,7 +1423,7 @@ fn check_fn<'a, 'tcx>(
|
||||
inherited.register_predicate(traits::Obligation::new(
|
||||
cause,
|
||||
param_env,
|
||||
trait_ref.to_predicate(),
|
||||
trait_ref.without_const().to_predicate(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ use rustc::middle::lang_items;
|
||||
use rustc::session::parse::feature_err;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc::ty::{self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::{
|
||||
self, AdtKind, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
|
||||
};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -955,7 +957,8 @@ fn receiver_is_implemented(
|
||||
substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
|
||||
};
|
||||
|
||||
let obligation = traits::Obligation::new(cause, fcx.param_env, trait_ref.to_predicate());
|
||||
let obligation =
|
||||
traits::Obligation::new(cause, fcx.param_env, trait_ref.without_const().to_predicate());
|
||||
|
||||
if fcx.predicate_must_hold_modulo_regions(&obligation) {
|
||||
true
|
||||
|
@ -30,7 +30,7 @@ use rustc::ty::subst::GenericArgKind;
|
||||
use rustc::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc::ty::util::Discr;
|
||||
use rustc::ty::util::IntTypeExt;
|
||||
use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
|
||||
use rustc::ty::{self, AdtKind, Const, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, WithConstness};
|
||||
use rustc::ty::{ReprOptions, ToPredicate};
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
@ -411,7 +411,8 @@ fn type_param_predicates(
|
||||
// Implied `Self: Trait` and supertrait bounds.
|
||||
if param_id == item_hir_id {
|
||||
let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
|
||||
extend = Some((identity_trait_ref.to_predicate(), item.span));
|
||||
extend =
|
||||
Some((identity_trait_ref.without_const().to_predicate(), item.span));
|
||||
}
|
||||
generics
|
||||
}
|
||||
@ -2056,7 +2057,7 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
|
||||
let span = tcx.def_span(def_id);
|
||||
result.predicates =
|
||||
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
|
||||
ty::TraitRef::identity(tcx, def_id).to_predicate(),
|
||||
ty::TraitRef::identity(tcx, def_id).without_const().to_predicate(),
|
||||
span,
|
||||
))));
|
||||
}
|
||||
@ -2230,7 +2231,10 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
|
||||
// (see below). Recall that a default impl is not itself an impl, but rather a
|
||||
// set of defaults that can be incorporated into another impl.
|
||||
if let Some(trait_ref) = is_default_impl_trait {
|
||||
predicates.push((trait_ref.to_poly_trait_ref().to_predicate(), tcx.def_span(def_id)));
|
||||
predicates.push((
|
||||
trait_ref.to_poly_trait_ref().without_const().to_predicate(),
|
||||
tcx.def_span(def_id),
|
||||
));
|
||||
}
|
||||
|
||||
// Collect the region predicates that were declared inline as
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc::infer::InferOk;
|
||||
use rustc::traits;
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::ToPredicate;
|
||||
use rustc::ty::{ToPredicate, WithConstness};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_span::DUMMY_SP;
|
||||
@ -64,7 +64,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||
match infcx.evaluate_obligation(&traits::Obligation::new(
|
||||
cause,
|
||||
param_env,
|
||||
trait_ref.to_predicate(),
|
||||
trait_ref.without_const().to_predicate(),
|
||||
)) {
|
||||
Ok(eval_result) => eval_result.may_apply(),
|
||||
Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no
|
||||
|
Loading…
Reference in New Issue
Block a user