diff options
Diffstat (limited to 'compiler/rustc_traits/src')
| -rw-r--r-- | compiler/rustc_traits/src/codegen.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/coroutine_witnesses.rs | 59 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/dropck_outlives.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/evaluate_obligation.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/implied_outlives_bounds.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/normalize_erasing_regions.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_traits/src/type_op.rs | 4 |
7 files changed, 65 insertions, 12 deletions
diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 7dd3c59edd0..4b05e2cc381 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -73,7 +73,7 @@ pub(crate) fn codegen_select_candidate<'tcx>( } let impl_source = infcx.resolve_vars_if_possible(impl_source); - let impl_source = tcx.erase_regions(impl_source); + let impl_source = tcx.erase_and_anonymize_regions(impl_source); if impl_source.has_non_region_infer() { // Unused generic types or consts on an impl get replaced with inference vars, // but never resolved, causing the return value of a query to contain inference diff --git a/compiler/rustc_traits/src/coroutine_witnesses.rs b/compiler/rustc_traits/src/coroutine_witnesses.rs index 447e13126cc..20f9b013724 100644 --- a/compiler/rustc_traits/src/coroutine_witnesses.rs +++ b/compiler/rustc_traits/src/coroutine_witnesses.rs @@ -1,5 +1,10 @@ -use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, TyCtxt, fold_regions}; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::infer::canonical::query_response::make_query_region_constraints; +use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_infer::traits::{Obligation, ObligationCause}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions}; +use rustc_span::def_id::DefId; +use rustc_trait_selection::traits::{ObligationCtxt, with_replaced_escaping_bound_vars}; /// Return the set of types that should be taken into account when checking /// trait bounds on a coroutine's internal state. This properly replaces @@ -30,8 +35,56 @@ pub(crate) fn coroutine_hidden_types<'tcx>( }), ); + let assumptions = compute_assumptions(tcx, def_id, bound_tys); + ty::EarlyBinder::bind(ty::Binder::bind_with_vars( - ty::CoroutineWitnessTypes { types: bound_tys }, + ty::CoroutineWitnessTypes { types: bound_tys, assumptions }, tcx.mk_bound_variable_kinds(&vars), )) } + +fn compute_assumptions<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, + bound_tys: &'tcx ty::List<Ty<'tcx>>, +) -> &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>> { + let infcx = tcx.infer_ctxt().build(ty::TypingMode::Analysis { + defining_opaque_types_and_generators: ty::List::empty(), + }); + with_replaced_escaping_bound_vars(&infcx, &mut vec![None], bound_tys, |bound_tys| { + let param_env = tcx.param_env(def_id); + let ocx = ObligationCtxt::new(&infcx); + + ocx.register_obligations(bound_tys.iter().map(|ty| { + Obligation::new( + tcx, + ObligationCause::dummy(), + param_env, + ty::ClauseKind::WellFormed(ty.into()), + ) + })); + let _errors = ocx.select_all_or_error(); + + let region_obligations = infcx.take_registered_region_obligations(); + let region_assumptions = infcx.take_registered_region_assumptions(); + let region_constraints = infcx.take_and_reset_region_constraints(); + + let outlives = make_query_region_constraints( + region_obligations, + ®ion_constraints, + region_assumptions, + ) + .outlives + .fold_with(&mut OpportunisticRegionResolver::new(&infcx)); + + tcx.mk_outlives_from_iter( + outlives + .into_iter() + .map(|(o, _)| o) + // FIXME(higher_ranked_auto): We probably should deeply resolve these before + // filtering out infers which only correspond to unconstrained infer regions + // which we can sometimes get. + .filter(|o| !o.has_infer()), + ) + }) +} diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 5eddad39e2b..d33ade7a9e1 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -1,5 +1,4 @@ use rustc_data_structures::fx::FxHashSet; -use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_middle::bug; @@ -7,6 +6,7 @@ use rustc_middle::query::Providers; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; use rustc_middle::ty::{self, GenericArgs, TyCtxt}; use rustc_span::DUMMY_SP; +use rustc_span::def_id::DefId; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::dropck_outlives::{ compute_dropck_outlives_inner, dtorck_constraint_for_ty_inner, diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index 7771db855d7..8f72bdf0972 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -19,12 +19,12 @@ fn evaluate_obligation<'tcx>( ) -> Result<EvaluationResult, OverflowError> { assert!(!tcx.next_trait_solver_globally()); debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal); - let (ref infcx, goal, _canonical_inference_vars) = + let (ref infcx, goal, _var_values) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical_goal); debug!("evaluate_obligation: goal={:#?}", goal); let ParamEnvAnd { param_env, value: predicate } = goal; - if sizedness_fast_path(tcx, predicate) { + if sizedness_fast_path(tcx, predicate, param_env) { return Ok(EvaluationResult::EvaluatedToOk); } diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 6fb483e6dac..397c24ff70c 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -7,7 +7,7 @@ use rustc_infer::infer::canonical::{self, Canonical}; use rustc_infer::traits::query::OutlivesBound; use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_middle::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_span::DUMMY_SP; use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::compute_implied_outlives_bounds_inner; @@ -25,7 +25,7 @@ fn implied_outlives_bounds<'tcx>( NoSolution, > { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { - let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts(); + let ParamEnvAnd { param_env, value: ImpliedOutlivesBounds { ty } } = key; compute_implied_outlives_bounds_inner( ocx, param_env, diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index c1b848a2e79..c98b56abe9c 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -41,7 +41,7 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + Par // fresh `InferCtxt`. If this assert does trigger, it will give // us a test case. debug_assert_eq!(normalized_value, resolved_value); - let erased = infcx.tcx.erase_regions(resolved_value); + let erased = infcx.tcx.erase_and_anonymize_regions(resolved_value); debug_assert!(!erased.has_infer(), "{erased:?}"); Ok(erased) } diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index e58ad639d20..f77e1994cf4 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -43,7 +43,7 @@ fn type_op_normalize<'tcx, T>( where T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>, { - let (param_env, Normalize { value }) = key.into_parts(); + let ParamEnvAnd { param_env, value: Normalize { value } } = key; let Normalized { value, obligations } = ocx.infcx.at(&ObligationCause::dummy(), param_env).query_normalize(value)?; ocx.register_obligations(obligations); @@ -96,6 +96,6 @@ pub fn type_op_prove_predicate_with_cause<'tcx>( key: ParamEnvAnd<'tcx, ProvePredicate<'tcx>>, cause: ObligationCause<'tcx>, ) { - let (param_env, ProvePredicate { predicate }) = key.into_parts(); + let ParamEnvAnd { param_env, value: ProvePredicate { predicate } } = key; ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate)); } |
