summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs (renamed from compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs)98
1 files changed, 50 insertions, 48 deletions
diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index 2741d9f77..e806e9487 100644
--- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -77,7 +77,7 @@ use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
use rustc_span::Span;
-use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
+use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
@@ -130,8 +130,10 @@ fn check_always_applicable(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node
///
/// Example
///
+/// ```ignore (illustrative)
/// impl<A, B> Foo<A> for B { /* impl2 */ }
/// impl<C> Foo<Vec<C>> for C { /* impl1 */ }
+/// ```
///
/// Would return `S1 = [C]` and `S2 = [Vec<C>, C]`.
fn get_impl_substs<'tcx>(
@@ -139,34 +141,33 @@ fn get_impl_substs<'tcx>(
impl1_def_id: LocalDefId,
impl2_node: Node,
) -> Option<(SubstsRef<'tcx>, SubstsRef<'tcx>)> {
- tcx.infer_ctxt().enter(|ref infcx| {
- let ocx = ObligationCtxt::new(infcx);
- let param_env = tcx.param_env(impl1_def_id);
- let impl1_hir_id = tcx.hir().local_def_id_to_hir_id(impl1_def_id);
+ let infcx = &tcx.infer_ctxt().build();
+ let ocx = ObligationCtxt::new(infcx);
+ let param_env = tcx.param_env(impl1_def_id);
+ let impl1_hir_id = tcx.hir().local_def_id_to_hir_id(impl1_def_id);
- let assumed_wf_types =
- ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id);
+ let assumed_wf_types =
+ ocx.assumed_wf_types(param_env, tcx.def_span(impl1_def_id), impl1_def_id);
- let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
- let impl2_substs =
- translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
+ let impl1_substs = InternalSubsts::identity_for_item(tcx, impl1_def_id.to_def_id());
+ let impl2_substs =
+ translate_substs(infcx, param_env, impl1_def_id.to_def_id(), impl1_substs, impl2_node);
- let errors = ocx.select_all_or_error();
- if !errors.is_empty() {
- ocx.infcx.report_fulfillment_errors(&errors, None, false);
- return None;
- }
+ let errors = ocx.select_all_or_error();
+ if !errors.is_empty() {
+ ocx.infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
+ return None;
+ }
- let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_hir_id, assumed_wf_types);
- let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
- infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
- let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
- let span = tcx.def_span(impl1_def_id);
- tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
- return None;
- };
- Some((impl1_substs, impl2_substs))
- })
+ let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_hir_id, assumed_wf_types);
+ let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds);
+ infcx.check_region_obligations_and_report_errors(impl1_def_id, &outlives_env);
+ let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else {
+ let span = tcx.def_span(impl1_def_id);
+ tcx.sess.emit_err(SubstsOnOverriddenImpl { span });
+ return None;
+ };
+ Some((impl1_substs, impl2_substs))
}
/// Returns a list of all of the unconstrained subst of the given impl.
@@ -226,13 +227,17 @@ fn unconstrained_parent_impl_substs<'tcx>(
///
/// For example forbid the following:
///
+/// ```ignore (illustrative)
/// impl<A> Tr for A { }
/// impl<B> Tr for (B, B) { }
+/// ```
///
/// Note that only consider the unconstrained parameters of the base impl:
///
+/// ```ignore (illustrative)
/// impl<S, I: IntoIterator<Item = S>> Tr<S> for I { }
/// impl<T> Tr<T> for Vec<T> { }
+/// ```
///
/// The substs for the parent impl here are `[T, Vec<T>]`, which repeats `T`,
/// but `S` is constrained in the parent impl, so `parent_substs` is only
@@ -257,8 +262,10 @@ fn check_duplicate_params<'tcx>(
///
/// For example forbid the following:
///
+/// ```ignore (illustrative)
/// impl<A> Tr for A { }
/// impl Tr for &'static i32 { }
+/// ```
fn check_static_lifetimes<'tcx>(
tcx: TyCtxt<'tcx>,
parent_substs: &Vec<GenericArg<'tcx>>,
@@ -344,23 +351,21 @@ fn check_predicates<'tcx>(
// Include the well-formed predicates of the type parameters of the impl.
for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().substs {
- tcx.infer_ctxt().enter(|ref infcx| {
- let obligations = wf::obligations(
- infcx,
- tcx.param_env(impl1_def_id),
- tcx.hir().local_def_id_to_hir_id(impl1_def_id),
- 0,
- arg,
- span,
- )
- .unwrap();
+ let infcx = &tcx.infer_ctxt().build();
+ let obligations = wf::obligations(
+ infcx,
+ tcx.param_env(impl1_def_id),
+ tcx.hir().local_def_id_to_hir_id(impl1_def_id),
+ 0,
+ arg,
+ span,
+ )
+ .unwrap();
- assert!(!obligations.needs_infer());
- impl2_predicates.extend(
- traits::elaborate_obligations(tcx, obligations)
- .map(|obligation| obligation.predicate),
- )
- })
+ assert!(!obligations.needs_infer());
+ impl2_predicates.extend(
+ traits::elaborate_obligations(tcx, obligations).map(|obligation| obligation.predicate),
+ )
}
impl2_predicates.extend(
traits::elaborate_predicates_with_span(tcx, always_applicable_traits)
@@ -423,13 +428,10 @@ fn trait_predicate_kind<'tcx>(
predicate: ty::Predicate<'tcx>,
) -> Option<TraitSpecializationKind> {
match predicate.kind().skip_binder() {
- ty::PredicateKind::Trait(ty::TraitPredicate {
- trait_ref,
- constness: ty::BoundConstness::NotConst,
- polarity: _,
- }) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
- ty::PredicateKind::Trait(_)
- | ty::PredicateKind::RegionOutlives(_)
+ ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity: _ }) => {
+ Some(tcx.trait_def(trait_ref.def_id).specialization_kind)
+ }
+ ty::PredicateKind::RegionOutlives(_)
| ty::PredicateKind::TypeOutlives(_)
| ty::PredicateKind::Projection(_)
| ty::PredicateKind::WellFormed(_)