diff options
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(_) |