1
Fork 0

Rollup merge of #137689 - compiler-errors:coroutine, r=lcnr

Use `Binder<Vec<Ty>>` instead of `Vec<Binder<Ty>>` in both solvers for sized/auto traits/etc.

It's more conceptually justified IMO, especially when binders get implications.

r? lcnr
This commit is contained in:
Matthias Krüger 2025-03-01 05:49:53 +01:00 committed by GitHub
commit 3cd89f2718
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 98 additions and 157 deletions

View file

@ -9,7 +9,7 @@ use std::ops::ControlFlow;
use std::{cmp, iter};
use hir::def::DefKind;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
@ -25,7 +25,6 @@ use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds};
pub use rustc_middle::traits::select::*;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
use rustc_middle::ty::{
self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
@ -2205,8 +2204,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
}
ty::CoroutineWitness(def_id, args) => {
let hidden_types = bind_coroutine_hidden_types_above(
self.infcx,
let hidden_types = rebind_coroutine_witness_types(
self.infcx.tcx,
def_id,
args,
obligation.predicate.bound_vars(),
@ -2354,7 +2353,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
}
ty::CoroutineWitness(def_id, args) => {
bind_coroutine_hidden_types_above(self.infcx, def_id, args, t.bound_vars())
rebind_coroutine_witness_types(self.infcx.tcx, def_id, args, t.bound_vars())
}
// For `PhantomData<T>`, we pass `T`.
@ -2849,6 +2848,23 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
}
}
fn rebind_coroutine_witness_types<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
let bound_coroutine_types = tcx.coroutine_hidden_types(def_id).skip_binder();
let shifted_coroutine_types =
tcx.shift_bound_var_indices(bound_vars.len(), bound_coroutine_types.skip_binder());
ty::Binder::bind_with_vars(
ty::EarlyBinder::bind(shifted_coroutine_types.to_vec()).instantiate(tcx, args),
tcx.mk_bound_variable_kinds_from_iter(
bound_vars.iter().chain(bound_coroutine_types.bound_vars()),
),
)
}
impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
TraitObligationStackList::with(self)
@ -3157,56 +3173,3 @@ pub(crate) enum ProjectionMatchesProjection {
Ambiguous,
No,
}
/// Replace all regions inside the coroutine interior with late bound regions.
/// Note that each region slot in the types gets a new fresh late bound region, which means that
/// none of the regions inside relate to any other, even if typeck had previously found constraints
/// that would cause them to be related.
#[instrument(level = "trace", skip(infcx), ret)]
fn bind_coroutine_hidden_types_above<'tcx>(
infcx: &InferCtxt<'tcx>,
def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
bound_vars: &ty::List<ty::BoundVariableKind>,
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
let tcx = infcx.tcx;
let mut seen_tys = FxHashSet::default();
let considering_regions = infcx.considering_regions;
let num_bound_variables = bound_vars.len() as u32;
let mut counter = num_bound_variables;
let hidden_types: Vec<_> = tcx
.coroutine_hidden_types(def_id)
// Deduplicate tys to avoid repeated work.
.filter(|bty| seen_tys.insert(*bty))
.map(|mut bty| {
// Only remap erased regions if we use them.
if considering_regions {
bty = bty.map_bound(|ty| {
fold_regions(tcx, ty, |r, current_depth| match r.kind() {
ty::ReErased => {
let br = ty::BoundRegion {
var: ty::BoundVar::from_u32(counter),
kind: ty::BoundRegionKind::Anon,
};
counter += 1;
ty::Region::new_bound(tcx, current_depth, br)
}
r => bug!("unexpected region: {r:?}"),
})
})
}
bty.instantiate(tcx, args)
})
.collect();
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
bound_vars.iter().chain(
(num_bound_variables..counter)
.map(|_| ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon)),
),
);
ty::Binder::bind_with_vars(hidden_types, bound_vars)
}