summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/query
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/query')
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs32
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs6
3 files changed, 28 insertions, 18 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index c84f128dd..09b58894d 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -2,9 +2,7 @@ use rustc_middle::ty;
use crate::infer::canonical::OriginalQueryValues;
use crate::infer::InferCtxt;
-use crate::traits::{
- EvaluationResult, OverflowError, PredicateObligation, SelectionContext, TraitQueryMode,
-};
+use crate::traits::{EvaluationResult, OverflowError, PredicateObligation, SelectionContext};
pub trait InferCtxtExt<'tcx> {
fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool;
@@ -68,7 +66,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
let mut _orig_values = OriginalQueryValues::default();
let param_env = match obligation.predicate.kind().skip_binder() {
- ty::PredicateKind::Trait(pred) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
// we ignore the value set to it.
let mut _constness = pred.constness;
obligation
@@ -97,7 +95,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
match self.evaluate_obligation(obligation) {
Ok(result) => result,
Err(OverflowError::Canonical) => {
- let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard);
+ let mut selcx = SelectionContext::new(&self);
selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| match r {
OverflowError::Canonical => {
span_bug!(
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 58e4597b7..7ad532d8a 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -7,7 +7,7 @@ use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
use crate::traits::error_reporting::TypeErrCtxtExt;
use crate::traits::project::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
-use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
+use crate::traits::{ObligationCause, PredicateObligation, Reveal};
use rustc_data_structures::sso::SsoHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_infer::traits::Normalized;
@@ -22,13 +22,20 @@ use super::NoSolution;
pub use rustc_middle::traits::query::NormalizationResult;
-pub trait AtExt<'tcx> {
- fn normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
+pub trait QueryNormalizeExt<'tcx> {
+ /// Normalize a value using the `QueryNormalizer`.
+ ///
+ /// This normalization should *only* be used when the projection does not
+ /// have possible ambiguity or may not be well-formed.
+ ///
+ /// After codegen, when lifetimes do not matter, it is preferable to instead
+ /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
+ fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
where
T: TypeFoldable<'tcx>;
}
-impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
+impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> {
/// Normalize `value` in the context of the inference context,
/// yielding a resulting type, or an error if `value` cannot be
/// normalized. If you don't care about regions, you should prefer
@@ -42,7 +49,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
/// normalizing, but for now should be used only when we actually
/// know that normalization will succeed, since error reporting
/// and other details are still "under development".
- fn normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
+ fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
where
T: TypeFoldable<'tcx>,
{
@@ -207,13 +214,12 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
let substs = substs.try_fold_with(self)?;
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.anon_depth) {
- let obligation = Obligation::with_depth(
- self.cause.clone(),
- recursion_limit.0,
- self.param_env,
- ty,
+ self.infcx.err_ctxt().report_overflow_error(
+ &ty,
+ self.cause.span,
+ true,
+ |_| {},
);
- self.infcx.err_ctxt().report_overflow_error(&obligation, true);
}
let generic_ty = self.tcx().bound_type_of(def_id);
@@ -353,6 +359,10 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
&mut self,
constant: ty::Const<'tcx>,
) -> Result<ty::Const<'tcx>, Self::Error> {
+ if !needs_normalization(&constant, self.param_env.reveal()) {
+ return Ok(constant);
+ }
+
let constant = constant.try_super_fold_with(self)?;
debug!(?constant, ?self.param_env);
Ok(crate::traits::project::with_replaced_escaping_bound_vars(
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
index 081308ac7..68434c2b6 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
@@ -15,7 +15,9 @@ 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 ty::PredicateKind::Trait(trait_ref) = key.value.predicate.kind().skip_binder() {
+ if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_ref)) =
+ key.value.predicate.kind().skip_binder()
+ {
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
if trait_ref.def_id() == sized_def_id {
if trait_ref.self_ty().is_trivially_sized(tcx) {
@@ -33,7 +35,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
mut canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
) -> Fallible<CanonicalizedQueryResponse<'tcx, ()>> {
match canonicalized.value.value.predicate.kind().skip_binder() {
- ty::PredicateKind::Trait(pred) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
canonicalized.value.param_env.remap_constness_with(pred.constness);
}
_ => canonicalized.value.param_env = canonicalized.value.param_env.without_const(),