Make DefiningAnchor::Bind only store the opaque types that may be constrained, instead of the current infcx root item.

This makes `Bind` almost always be empty, so we can start forwarding it to queries, allowing us to remove `Bubble` entirely
This commit is contained in:
Oli Scherer 2024-02-29 12:21:20 +00:00
parent 65cd843ae0
commit 40d5609548
47 changed files with 300 additions and 229 deletions

View file

@ -210,12 +210,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
self.visit_opaque_ty(alias_ty);
}
// Skips type aliases, as they are meant to be transparent.
ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => {
self.tcx
.type_of(alias_ty.def_id)
.instantiate(self.tcx, alias_ty.args)
.visit_with(self);
}
// RPITIT are encoded as projections, not opaque types, make sure to handle these special
// projections independently of the projection handling below.
ty::Alias(ty::Projection, alias_ty)
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) =
self.tcx.opt_rpitit_info(alias_ty.def_id)
&& fn_def_id == self.item.into() =>
{
let ty = self.tcx.type_of(alias_ty.def_id).instantiate(self.tcx, alias_ty.args);
let ty::Alias(ty::Opaque, alias_ty) = ty.kind() else { bug!("{ty:?}") };
self.visit_opaque_ty(alias_ty);
}
ty::Alias(ty::Projection, alias_ty) => {
// This avoids having to do normalization of `Self::AssocTy` by only
// supporting the case of a method defining opaque types from assoc types

View file

@ -23,8 +23,14 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
match kind {
// Walk over the signature of the function
DefKind::AssocFn | DefKind::Fn => {
let ty_sig = tcx.fn_sig(item).instantiate_identity();
let hir_sig = tcx.hir_node_by_def_id(item).fn_decl().unwrap();
// If the type of the item uses `_`, we're gonna error out anyway, but
// typeck (which type_of invokes below), will call back into opaque_types_defined_by
// causing a cycle. So we just bail out in this case.
if hir_sig.output.get_infer_ret_ty().is_some() {
return V::Result::output();
}
let ty_sig = tcx.fn_sig(item).instantiate_identity();
// Walk over the inputs and outputs manually in order to get good spans for them.
try_visit!(visitor.visit(hir_sig.output.span(), ty_sig.output()));
for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
@ -39,6 +45,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
// Walk over the type of the item
DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
// If the type of the item uses `_`, we're gonna error out anyway, but
// typeck (which type_of invokes below), will call back into opaque_types_defined_by
// causing a cycle. So we just bail out in this case.
if ty.is_suggestable_infer_ty() {
return V::Result::output();
}
// Associated types in traits don't necessarily have a type that we can visit
try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
}