Pass constness to SelectionContext
This commit is contained in:
parent
a00f2bcf5c
commit
01bb3710b5
5 changed files with 101 additions and 23 deletions
|
@ -3,6 +3,7 @@ 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::abstract_const::NotConstEvaluatable;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
|
@ -228,6 +229,22 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||
if errors.is_empty() { Ok(()) } else { Err(errors) }
|
||||
}
|
||||
|
||||
fn select_all_with_constness_or_error(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
constness: rustc_hir::Constness,
|
||||
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
|
||||
self.select_with_constness_where_possible(infcx, constness)?;
|
||||
|
||||
let errors: Vec<_> = self
|
||||
.predicates
|
||||
.to_errors(CodeAmbiguity)
|
||||
.into_iter()
|
||||
.map(to_fulfillment_error)
|
||||
.collect();
|
||||
if errors.is_empty() { Ok(()) } else { Err(errors) }
|
||||
}
|
||||
|
||||
fn select_where_possible(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
|
@ -236,6 +253,15 @@ 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,
|
||||
) -> Result<(), 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())
|
||||
}
|
||||
|
|
|
@ -130,6 +130,9 @@ pub struct SelectionContext<'cx, 'tcx> {
|
|||
/// and a negative impl
|
||||
allow_negative_impls: bool,
|
||||
|
||||
/// Do we only want const impls when we have a const trait predicate?
|
||||
const_impls_required: 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.
|
||||
|
@ -221,6 +224,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: false,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls: false,
|
||||
const_impls_required: false,
|
||||
query_mode: TraitQueryMode::Standard,
|
||||
}
|
||||
}
|
||||
|
@ -232,6 +236,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: true,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls: false,
|
||||
const_impls_required: false,
|
||||
query_mode: TraitQueryMode::Standard,
|
||||
}
|
||||
}
|
||||
|
@ -247,6 +252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: false,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls,
|
||||
const_impls_required: false,
|
||||
query_mode: TraitQueryMode::Standard,
|
||||
}
|
||||
}
|
||||
|
@ -262,10 +268,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
intercrate: false,
|
||||
intercrate_ambiguity_causes: None,
|
||||
allow_negative_impls: false,
|
||||
const_impls_required: 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,
|
||||
const_impls_required: 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
|
||||
|
@ -1024,26 +1046,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
// Respect const trait obligations
|
||||
if let hir::Constness::Const = obligation.predicate.skip_binder().constness {
|
||||
if Some(obligation.predicate.skip_binder().trait_ref.def_id)
|
||||
!= tcx.lang_items().sized_trait()
|
||||
// const Sized bounds are skipped
|
||||
{
|
||||
match candidate {
|
||||
// const impl
|
||||
ImplCandidate(def_id)
|
||||
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
||||
// const param
|
||||
ParamCandidate(ty::ConstnessAnd {
|
||||
constness: hir::Constness::Const, ..
|
||||
}) => {}
|
||||
// auto trait impl
|
||||
AutoImplCandidate(..) => {}
|
||||
// FIXME check if this is right, but this would allow Sized impls
|
||||
// BuiltinCandidate { .. } => {}
|
||||
_ => {
|
||||
// reject all other types of candidates
|
||||
return Err(Unimplemented);
|
||||
if self.const_impls_required {
|
||||
if let hir::Constness::Const = obligation.predicate.skip_binder().constness {
|
||||
if Some(obligation.predicate.skip_binder().trait_ref.def_id)
|
||||
!= tcx.lang_items().sized_trait()
|
||||
// const Sized bounds are skipped
|
||||
{
|
||||
match candidate {
|
||||
// const impl
|
||||
ImplCandidate(def_id)
|
||||
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
|
||||
// const param
|
||||
ParamCandidate(ty::ConstnessAnd {
|
||||
constness: hir::Constness::Const,
|
||||
..
|
||||
}) => {}
|
||||
// auto trait impl
|
||||
AutoImplCandidate(..) => {}
|
||||
// FIXME check if this is right, but this would allow Sized impls
|
||||
// BuiltinCandidate { .. } => {}
|
||||
_ => {
|
||||
// reject all other types of candidates
|
||||
return Err(Unimplemented);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue