diff options
| author | lcnr <rust@lcnr.de> | 2024-01-11 13:02:50 +0100 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2024-03-14 17:19:40 +0100 |
| commit | 24a1729566f21f0df2cc258f61adddd6be7c40b3 (patch) | |
| tree | 5440e3a84c6303c51e3dde560b32d03a87613174 /compiler/rustc_trait_selection/src | |
| parent | c2fbe404d21572a04dabc6a0e23eb3ab367832ad (diff) | |
| download | rust-24a1729566f21f0df2cc258f61adddd6be7c40b3.tar.gz rust-24a1729566f21f0df2cc258f61adddd6be7c40b3.zip | |
eagerly instantiate binders to avoid relying on `sub`
Diffstat (limited to 'compiler/rustc_trait_selection/src')
5 files changed, 48 insertions, 22 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index d18acb8c864..b85a05c774f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -3409,6 +3409,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err) } + // FIXME(@lcnr): This function could be changed to trait `TraitRef` directly + // instead of using a `Binder`. fn report_signature_mismatch_error( &self, obligation: &PredicateObligation<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 89654ed61ae..49091e53be7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -165,7 +165,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate); let placeholder_trait_predicate = self.infcx.enter_forall_and_leak_universe(poly_trait_predicate); - debug!(?placeholder_trait_predicate); // The bounds returned by `item_bounds` may contain duplicates after // normalization, so try to deduplicate when possible to avoid @@ -184,8 +183,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { selcx.infcx.probe(|_| { match selcx.match_normalize_trait_ref( obligation, - bound.to_poly_trait_ref(), placeholder_trait_predicate.trait_ref, + bound.to_poly_trait_ref(), ) { Ok(None) => { candidates.vec.push(ProjectionCandidate(idx)); @@ -881,8 +880,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx.probe(|_| { self.match_normalize_trait_ref( obligation, - upcast_trait_ref, placeholder_trait_predicate.trait_ref, + upcast_trait_ref, ) .is_ok() }) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 70f6b240ab7..51fc223a5d1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -9,7 +9,7 @@ use rustc_ast::Mutability; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::lang_items::LangItem; -use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType; +use rustc_infer::infer::HigherRankedType; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; use rustc_middle::ty::{ @@ -161,8 +161,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let placeholder_trait_predicate = self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref; let placeholder_self_ty = placeholder_trait_predicate.self_ty(); - let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); - let candidate_predicate = self .for_each_item_bound( placeholder_self_ty, @@ -182,6 +180,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .expect("projection candidate is not a trait predicate") .map_bound(|t| t.trait_ref); + let candidate = self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + candidate, + ); let mut obligations = Vec::new(); let candidate = normalize_with_depth_to( self, @@ -195,7 +198,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligations.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate) + .eq(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| Unimplemented)?, ); @@ -499,7 +502,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let trait_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty()); - let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref); let ty::Dynamic(data, ..) = *self_ty.kind() else { span_bug!(obligation.cause.span, "object candidate with non-object"); }; @@ -520,19 +522,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let unnormalized_upcast_trait_ref = supertraits.nth(index).expect("supertraits iterator no longer has as many elements"); + let upcast_trait_ref = self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + unnormalized_upcast_trait_ref, + ); let upcast_trait_ref = normalize_with_depth_to( self, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - unnormalized_upcast_trait_ref, + upcast_trait_ref, &mut nested, ); nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref) + .eq(DefineOpaqueTypes::No, trait_predicate.trait_ref, upcast_trait_ref) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| Unimplemented)?, ); @@ -1021,7 +1028,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, self_ty_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { - let obligation_trait_ref = obligation.predicate.to_poly_trait_ref(); + let obligation_trait_ref = + self.infcx.enter_forall_and_leak_universe(obligation.predicate.to_poly_trait_ref()); + let self_ty_trait_ref = self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + self_ty_trait_ref, + ); // Normalize the obligation and expected trait refs together, because why not let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } = ensure_sufficient_stack(|| { @@ -1037,15 +1050,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs self.infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref) + .eq(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref) .map(|InferOk { mut obligations, .. }| { obligations.extend(nested); obligations }) .map_err(|terr| { SignatureMismatch(Box::new(SignatureMismatchData { - expected_trait_ref: obligation_trait_ref, - found_trait_ref: expected_trait_ref, + expected_trait_ref: ty::Binder::dummy(obligation_trait_ref), + found_trait_ref: ty::Binder::dummy(expected_trait_ref), terr, })) }) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a6bd1ba9c3f..be748de1b17 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -33,6 +33,7 @@ use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::BoundRegionConversionTime; +use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::TraitObligation; use rustc_middle::dep_graph::dep_kinds; @@ -1651,15 +1652,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn match_normalize_trait_ref( &mut self, obligation: &PolyTraitObligation<'tcx>, - trait_bound: ty::PolyTraitRef<'tcx>, placeholder_trait_ref: ty::TraitRef<'tcx>, - ) -> Result<Option<ty::PolyTraitRef<'tcx>>, ()> { + trait_bound: ty::PolyTraitRef<'tcx>, + ) -> Result<Option<ty::TraitRef<'tcx>>, ()> { debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars()); if placeholder_trait_ref.def_id != trait_bound.def_id() { // Avoid unnecessary normalization return Err(()); } + let trait_bound = self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + trait_bound, + ); let Normalized { value: trait_bound, obligations: _ } = ensure_sufficient_stack(|| { normalize_with_depth( self, @@ -1671,7 +1677,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); self.infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, ty::Binder::dummy(placeholder_trait_ref), trait_bound) + .eq(DefineOpaqueTypes::No, placeholder_trait_ref, trait_bound) .map(|InferOk { obligations: _, value: () }| { // This method is called within a probe, so we can't have // inference variables and placeholders escape. @@ -1683,7 +1689,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }) .map_err(|_| ()) } - fn where_clause_may_apply<'o>( &mut self, stack: &TraitObligationStack<'o, 'tcx>, @@ -1733,7 +1738,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let is_match = self .infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, obligation.predicate, infer_projection) + .eq(DefineOpaqueTypes::No, obligation.predicate, infer_projection) .is_ok_and(|InferOk { obligations, value: () }| { self.evaluate_predicates_recursively( TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()), @@ -2533,7 +2538,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .sup( + .eq( DefineOpaqueTypes::No, upcast_principal.map_bound(|trait_ref| { ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref) @@ -2571,7 +2576,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { nested.extend( self.infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, source_projection, target_projection) + .eq(DefineOpaqueTypes::No, source_projection, target_projection) .map_err(|_| SelectionError::Unimplemented)? .into_obligations(), ); @@ -2615,9 +2620,15 @@ impl<'tcx> SelectionContext<'_, 'tcx> { obligation: &PolyTraitObligation<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, ()> { + let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate); + let trait_ref = self.infcx.instantiate_binder_with_fresh_vars( + obligation.cause.span, + HigherRankedType, + poly_trait_ref, + ); self.infcx .at(&obligation.cause, obligation.param_env) - .sup(DefineOpaqueTypes::No, obligation.predicate.to_poly_trait_ref(), poly_trait_ref) + .eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| ()) } diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 3c0316fce17..46a68508753 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -320,6 +320,7 @@ fn vtable_entries<'tcx>( } /// Find slot base for trait methods within vtable entries of another trait +// FIXME(@lcnr): This isn't a query, so why does it take a tuple as its argument. pub(super) fn vtable_trait_first_method_offset<'tcx>( tcx: TyCtxt<'tcx>, key: ( |
