summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs175
1 files changed, 82 insertions, 93 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 40596078f..0bf54c096 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -26,7 +26,7 @@ pub mod wf;
use crate::errors::DumpVTableEntries;
use crate::infer::outlives::env::OutlivesEnvironment;
use crate::infer::{InferCtxt, TyCtxtInferExt};
-use crate::traits::error_reporting::InferCtxtExt as _;
+use crate::traits::error_reporting::TypeErrCtxtExt as _;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
@@ -34,12 +34,11 @@ use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_infer::traits::TraitEngineExt as _;
use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{
- self, DefIdTree, GenericParamDefKind, Subst, ToPredicate, Ty, TyCtxt, TypeSuperVisitable,
- VtblEntry,
+ self, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, VtblEntry,
};
+use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_span::{sym, Span};
use smallvec::SmallVec;
@@ -130,7 +129,7 @@ pub fn predicates_for_generics<'tcx>(
move |(idx, (predicate, span))| Obligation {
cause: cause(idx, span),
recursion_depth: 0,
- param_env: param_env,
+ param_env,
predicate,
},
)
@@ -141,8 +140,8 @@ pub fn predicates_for_generics<'tcx>(
/// `bound` or is not known to meet bound (note that this is
/// conservative towards *no impl*, which is the opposite of the
/// `evaluate` methods).
-pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
- infcx: &InferCtxt<'a, 'tcx>,
+pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
+ infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
def_id: DefId,
@@ -171,7 +170,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
result
);
- if result && ty.has_infer_types_or_consts() {
+ if result && ty.has_non_region_infer() {
// Because of inference "guessing", selection can sometimes claim
// to succeed while the success requires a guess. To ensure
// this function's result remains infallible, we must confirm
@@ -235,54 +234,51 @@ fn do_normalize_predicates<'tcx>(
// by wfcheck anyway, so I'm not sure we have to check
// them here too, and we will remove this function when
// we move over to lazy normalization *anyway*.
- tcx.infer_ctxt().ignoring_regions().enter(|infcx| {
- let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
- Ok(predicates) => predicates,
- Err(errors) => {
- let reported = infcx.report_fulfillment_errors(&errors, None, false);
- return Err(reported);
- }
- };
+ let infcx = tcx.infer_ctxt().ignoring_regions().build();
+ let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
+ Ok(predicates) => predicates,
+ Err(errors) => {
+ let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
+ return Err(reported);
+ }
+ };
- debug!("do_normalize_predictes: normalized predicates = {:?}", predicates);
+ debug!("do_normalize_predictes: normalized predicates = {:?}", predicates);
- // We can use the `elaborated_env` here; the region code only
- // cares about declarations like `'a: 'b`.
- let outlives_env = OutlivesEnvironment::new(elaborated_env);
+ // We can use the `elaborated_env` here; the region code only
+ // cares about declarations like `'a: 'b`.
+ let outlives_env = OutlivesEnvironment::new(elaborated_env);
+
+ // FIXME: It's very weird that we ignore region obligations but apparently
+ // still need to use `resolve_regions` as we need the resolved regions in
+ // the normalized predicates.
+ let errors = infcx.resolve_regions(&outlives_env);
+ if !errors.is_empty() {
+ tcx.sess.delay_span_bug(
+ span,
+ format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"),
+ );
+ }
- // FIXME: It's very weird that we ignore region obligations but apparently
- // still need to use `resolve_regions` as we need the resolved regions in
- // the normalized predicates.
- let errors = infcx.resolve_regions(&outlives_env);
- if !errors.is_empty() {
- tcx.sess.delay_span_bug(
+ match infcx.fully_resolve(predicates) {
+ Ok(predicates) => Ok(predicates),
+ Err(fixup_err) => {
+ // If we encounter a fixup error, it means that some type
+ // variable wound up unconstrained. I actually don't know
+ // if this can happen, and I certainly don't expect it to
+ // happen often, but if it did happen it probably
+ // represents a legitimate failure due to some kind of
+ // unconstrained variable.
+ //
+ // @lcnr: Let's still ICE here for now. I want a test case
+ // for that.
+ span_bug!(
span,
- format!(
- "failed region resolution while normalizing {elaborated_env:?}: {errors:?}"
- ),
+ "inference variables in normalized parameter environment: {}",
+ fixup_err
);
}
-
- match infcx.fully_resolve(predicates) {
- Ok(predicates) => Ok(predicates),
- Err(fixup_err) => {
- // If we encounter a fixup error, it means that some type
- // variable wound up unconstrained. I actually don't know
- // if this can happen, and I certainly don't expect it to
- // happen often, but if it did happen it probably
- // represents a legitimate failure due to some kind of
- // unconstrained variable.
- //
- // @lcnr: Let's still ICE here for now. I want a test case
- // for that.
- span_bug!(
- span,
- "inference variables in normalized parameter environment: {}",
- fixup_err
- );
- }
- }
- })
+ }
}
// FIXME: this is gonna need to be removed ...
@@ -394,8 +390,8 @@ pub fn normalize_param_env_or_error<'tcx>(
}
/// Normalize a type and process all resulting obligations, returning any errors
-pub fn fully_normalize<'a, 'tcx, T>(
- infcx: &InferCtxt<'a, 'tcx>,
+pub fn fully_normalize<'tcx, T>(
+ infcx: &InferCtxt<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: T,
@@ -430,8 +426,8 @@ where
/// Process an obligation (and any nested obligations that come from it) to
/// completion, returning any errors
-pub fn fully_solve_obligation<'a, 'tcx>(
- infcx: &InferCtxt<'a, 'tcx>,
+pub fn fully_solve_obligation<'tcx>(
+ infcx: &InferCtxt<'tcx>,
obligation: PredicateObligation<'tcx>,
) -> Vec<FulfillmentError<'tcx>> {
let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
@@ -441,8 +437,8 @@ pub fn fully_solve_obligation<'a, 'tcx>(
/// Process a set of obligations (and any nested obligations that come from them)
/// to completion
-pub fn fully_solve_obligations<'a, 'tcx>(
- infcx: &InferCtxt<'a, 'tcx>,
+pub fn fully_solve_obligations<'tcx>(
+ infcx: &InferCtxt<'tcx>,
obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
) -> Vec<FulfillmentError<'tcx>> {
let mut engine = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
@@ -453,8 +449,8 @@ pub fn fully_solve_obligations<'a, 'tcx>(
/// Process a bound (and any nested obligations that come from it) to completion.
/// This is a convenience function for traits that have no generic arguments, such
/// as auto traits, and builtin traits like Copy or Sized.
-pub fn fully_solve_bound<'a, 'tcx>(
- infcx: &InferCtxt<'a, 'tcx>,
+pub fn fully_solve_bound<'tcx>(
+ infcx: &InferCtxt<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
@@ -474,21 +470,20 @@ pub fn impossible_predicates<'tcx>(
) -> bool {
debug!("impossible_predicates(predicates={:?})", predicates);
- let result = tcx.infer_ctxt().enter(|infcx| {
- let param_env = ty::ParamEnv::reveal_all();
- let ocx = ObligationCtxt::new(&infcx);
- let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates);
- for predicate in predicates {
- let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
- ocx.register_obligation(obligation);
- }
- let errors = ocx.select_all_or_error();
+ let infcx = tcx.infer_ctxt().build();
+ let param_env = ty::ParamEnv::reveal_all();
+ let ocx = ObligationCtxt::new(&infcx);
+ let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates);
+ for predicate in predicates {
+ let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
+ ocx.register_obligation(obligation);
+ }
+ let errors = ocx.select_all_or_error();
- // Clean up after ourselves
- let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
+ // Clean up after ourselves
+ let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
- !errors.is_empty()
- });
+ let result = !errors.is_empty();
debug!("impossible_predicates = {:?}", result);
result
}
@@ -579,18 +574,16 @@ fn is_impossible_method<'tcx>(
}
});
- tcx.infer_ctxt().ignoring_regions().enter(|ref infcx| {
- for obligation in predicates_for_trait {
- // Ignore overflow error, to be conservative.
- if let Ok(result) = infcx.evaluate_obligation(&obligation)
- && !result.may_apply()
- {
- return true;
- }
+ let infcx = tcx.infer_ctxt().ignoring_regions().build();
+ for obligation in predicates_for_trait {
+ // Ignore overflow error, to be conservative.
+ if let Ok(result) = infcx.evaluate_obligation(&obligation)
+ && !result.may_apply()
+ {
+ return true;
}
-
- false
- })
+ }
+ false
}
#[derive(Clone, Debug)]
@@ -771,12 +764,9 @@ fn dump_vtable_entries<'tcx>(
});
}
-fn own_existential_vtable_entries<'tcx>(
- tcx: TyCtxt<'tcx>,
- trait_ref: ty::PolyExistentialTraitRef<'tcx>,
-) -> &'tcx [DefId] {
+fn own_existential_vtable_entries<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> &'tcx [DefId] {
let trait_methods = tcx
- .associated_items(trait_ref.def_id())
+ .associated_items(trait_def_id)
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Fn);
// Now list each method's DefId (for within its trait).
@@ -785,7 +775,7 @@ fn own_existential_vtable_entries<'tcx>(
let def_id = trait_method.def_id;
// Some methods cannot be called on an object; skip those.
- if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) {
+ if !is_vtable_safe_method(tcx, trait_def_id, &trait_method) {
debug!("own_existential_vtable_entry: not vtable safe");
return None;
}
@@ -817,7 +807,7 @@ fn vtable_entries<'tcx>(
// Lookup the shape of vtable for the trait.
let own_existential_entries =
- tcx.own_existential_vtable_entries(existential_trait_ref);
+ tcx.own_existential_vtable_entries(existential_trait_ref.def_id());
let own_entries = own_existential_entries.iter().copied().map(|def_id| {
debug!("vtable_entries: trait_method={:?}", def_id);
@@ -953,10 +943,9 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>(
}),
);
- let implsrc = tcx.infer_ctxt().enter(|infcx| {
- let mut selcx = SelectionContext::new(&infcx);
- selcx.select(&obligation).unwrap()
- });
+ let infcx = tcx.infer_ctxt().build();
+ let mut selcx = SelectionContext::new(&infcx);
+ let implsrc = selcx.select(&obligation).unwrap();
let Some(ImplSource::TraitUpcasting(implsrc_traitcasting)) = implsrc else {
bug!();