Use the constness from the param env instead of having a separate dimension for it
This breaks a ~const test that will be fixed in a follow up commit of this PR
This commit is contained in:
parent
19f2101272
commit
d51068ca28
12 changed files with 25 additions and 142 deletions
|
@ -4,7 +4,6 @@ use rustc_data_structures::obligation_forest::ProcessResult;
|
|||
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
|
||||
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation};
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::thir::abstract_const::NotConstEvaluatable;
|
||||
|
@ -231,21 +230,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||
self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
|
||||
}
|
||||
|
||||
fn select_all_with_constness_or_error(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
constness: rustc_hir::Constness,
|
||||
) -> Vec<FulfillmentError<'tcx>> {
|
||||
{
|
||||
let errors = self.select_with_constness_where_possible(infcx, constness);
|
||||
if !errors.is_empty() {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
self.predicates.to_errors(CodeAmbiguity).into_iter().map(to_fulfillment_error).collect()
|
||||
}
|
||||
|
||||
fn select_where_possible(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
|
@ -254,15 +238,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||
self.select(&mut selcx)
|
||||
}
|
||||
|
||||
fn select_with_constness_where_possible(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
constness: hir::Constness,
|
||||
) -> Vec<FulfillmentError<'tcx>> {
|
||||
let mut selcx = SelectionContext::with_constness(infcx, constness);
|
||||
self.select(&mut selcx)
|
||||
}
|
||||
|
||||
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
|
||||
self.predicates.map_pending_obligations(|o| o.obligation.clone())
|
||||
}
|
||||
|
@ -679,12 +654,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
if obligation.predicate.is_known_global() {
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
//
|
||||
// If the predicate is considered const, then we cannot use this because
|
||||
// it will cause false negatives in the ui tests.
|
||||
if !self.selcx.is_predicate_const(obligation.predicate)
|
||||
&& infcx.predicate_must_hold_considering_regions(obligation)
|
||||
{
|
||||
if infcx.predicate_must_hold_considering_regions(obligation) {
|
||||
debug!(
|
||||
"selecting trait at depth {} evaluated to holds",
|
||||
obligation.recursion_depth
|
||||
|
@ -738,12 +708,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
if obligation.predicate.is_global(tcx) {
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
//
|
||||
// If the predicate is considered const, then we cannot use this because
|
||||
// it will cause false negatives in the ui tests.
|
||||
if !self.selcx.is_predicate_const(obligation.predicate)
|
||||
&& self.selcx.infcx().predicate_must_hold_considering_regions(obligation)
|
||||
{
|
||||
if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) {
|
||||
return ProcessResult::Changed(vec![]);
|
||||
} else {
|
||||
tracing::debug!("Does NOT hold: {:?}", obligation);
|
||||
|
|
|
@ -303,7 +303,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
} else if lang_items.drop_trait() == Some(def_id)
|
||||
&& obligation.predicate.skip_binder().constness == ty::BoundConstness::ConstIfConst
|
||||
{
|
||||
if self.is_in_const_context {
|
||||
if obligation.param_env.constness() == hir::Constness::Const {
|
||||
self.assemble_const_drop_candidates(obligation, stack, &mut candidates)?;
|
||||
} else {
|
||||
debug!("passing ~const Drop bound; in non-const context");
|
||||
|
|
|
@ -128,9 +128,6 @@ pub struct SelectionContext<'cx, 'tcx> {
|
|||
/// and a negative impl
|
||||
allow_negative_impls: bool,
|
||||
|
||||
/// Are we in a const context that needs `~const` bounds to be const?
|
||||
is_in_const_context: bool,
|
||||
|
||||
/// The mode that trait queries run in, which informs our error handling
|
||||
/// policy. In essence, canonicalized queries need their errors propagated
|
||||
/// rather than immediately reported because we do not have accurate spans.
|
||||
|
@ -222,7 +219,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: false,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls: false,
|
||||
is_in_const_context: false,
|
||||
query_mode: TraitQueryMode::Standard,
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +230,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: true,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls: false,
|
||||
is_in_const_context: false,
|
||||
query_mode: TraitQueryMode::Standard,
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +245,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: false,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls,
|
||||
is_in_const_context: false,
|
||||
query_mode: TraitQueryMode::Standard,
|
||||
}
|
||||
}
|
||||
|
@ -266,26 +260,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: false,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls: false,
|
||||
is_in_const_context: false,
|
||||
query_mode,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_constness(
|
||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
constness: hir::Constness,
|
||||
) -> SelectionContext<'cx, 'tcx> {
|
||||
SelectionContext {
|
||||
infcx,
|
||||
freshener: infcx.freshener_keep_static(),
|
||||
intercrate: false,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls: false,
|
||||
is_in_const_context: matches!(constness, hir::Constness::Const),
|
||||
query_mode: TraitQueryMode::Standard,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables tracking of intercrate ambiguity causes. These are
|
||||
/// used in coherence to give improved diagnostics. We don't do
|
||||
/// this until we detect a coherence error because it can lead to
|
||||
|
@ -318,20 +296,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
self.intercrate
|
||||
}
|
||||
|
||||
/// Returns `true` if the trait predicate is considerd `const` to this selection context.
|
||||
pub fn is_trait_predicate_const(&self, pred: ty::TraitPredicate<'_>) -> bool {
|
||||
matches!(pred.constness, ty::BoundConstness::ConstIfConst) && self.is_in_const_context
|
||||
}
|
||||
|
||||
/// Returns `true` if the predicate is considered `const` to
|
||||
/// this selection context.
|
||||
pub fn is_predicate_const(&self, pred: ty::Predicate<'_>) -> bool {
|
||||
match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(pred) => self.is_trait_predicate_const(pred),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Selection
|
||||
//
|
||||
|
@ -1138,7 +1102,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
for candidate in candidates {
|
||||
// Respect const trait obligations
|
||||
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
|
||||
if obligation.is_const() {
|
||||
match candidate {
|
||||
// const impl
|
||||
ImplCandidate(def_id)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue