support calls on opaque types :<

This commit is contained in:
lcnr 2025-09-11 13:08:36 +02:00
parent d1ed52b1f5
commit f4e19c6878
28 changed files with 734 additions and 124 deletions

View file

@ -302,6 +302,9 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
.map(|(k, h)| (k, h.ty))
.collect()
}
fn opaques_with_sub_unified_hidden_type(&self, ty: ty::TyVid) -> Vec<ty::AliasTy<'tcx>> {
self.opaques_with_sub_unified_hidden_type(ty)
}
fn register_hidden_type_in_storage(
&self,

View file

@ -1004,6 +1004,60 @@ impl<'tcx> InferCtxt<'tcx> {
self.inner.borrow_mut().opaque_type_storage.iter_opaque_types().collect()
}
pub fn has_opaques_with_sub_unified_hidden_type(&self, ty_vid: TyVid) -> bool {
if !self.next_trait_solver() {
return false;
}
let ty_sub_vid = self.sub_unification_table_root_var(ty_vid);
let inner = &mut *self.inner.borrow_mut();
let mut type_variables = inner.type_variable_storage.with_log(&mut inner.undo_log);
inner.opaque_type_storage.iter_opaque_types().any(|(_, hidden_ty)| {
if let ty::Infer(ty::TyVar(hidden_vid)) = *hidden_ty.ty.kind() {
let opaque_sub_vid = type_variables.sub_unification_table_root_var(hidden_vid);
if opaque_sub_vid == ty_sub_vid {
return true;
}
}
false
})
}
/// Searches for an opaque type key whose hidden type is related to `ty_vid`.
///
/// This only checks for a subtype relation, it does not require equality.
pub fn opaques_with_sub_unified_hidden_type(&self, ty_vid: TyVid) -> Vec<ty::AliasTy<'tcx>> {
// Avoid accidentally allowing more code to compile with the old solver.
if !self.next_trait_solver() {
return vec![];
}
let ty_sub_vid = self.sub_unification_table_root_var(ty_vid);
let inner = &mut *self.inner.borrow_mut();
// This is iffy, can't call `type_variables()` as we're already
// borrowing the `opaque_type_storage` here.
let mut type_variables = inner.type_variable_storage.with_log(&mut inner.undo_log);
inner
.opaque_type_storage
.iter_opaque_types()
.filter_map(|(key, hidden_ty)| {
if let ty::Infer(ty::TyVar(hidden_vid)) = *hidden_ty.ty.kind() {
let opaque_sub_vid = type_variables.sub_unification_table_root_var(hidden_vid);
if opaque_sub_vid == ty_sub_vid {
return Some(ty::AliasTy::new_from_args(
self.tcx,
key.def_id.into(),
key.args,
));
}
}
None
})
.collect()
}
#[inline(always)]
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
debug_assert!(!self.next_trait_solver());