Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit bd9f84b

Browse files
compiler-errorslcnr
authored andcommitted
Incompletely prefer opaque type bounds when self type bottoms out in infer
1 parent 73c9073 commit bd9f84b

File tree

2 files changed

+78
-5
lines changed
  • compiler/rustc_next_trait_solver/src/solve

2 files changed

+78
-5
lines changed

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ use derive_where::derive_where;
88
use rustc_type_ir::inherent::*;
99
use rustc_type_ir::lang_items::TraitSolverLangItem;
1010
use rustc_type_ir::{
11-
self as ty, Interner, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _,
12-
TypeVisitor, TypingMode, Upcast as _, elaborate,
11+
self as ty, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
12+
TypeVisitable, TypeVisitableExt as _, TypeVisitor, TypingMode, Upcast as _, elaborate,
1313
};
14-
use tracing::{debug, instrument};
14+
use tracing::instrument;
1515

1616
use super::trait_goals::TraitGoalProvenVia;
1717
use super::{has_only_region_constraints, inspect};
@@ -367,8 +367,7 @@ where
367367
};
368368

369369
if normalized_self_ty.is_ty_var() {
370-
debug!("self type has been normalized to infer");
371-
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
370+
return self.try_assemble_bounds_via_registered_opaque(goal, normalized_self_ty);
372371
}
373372

374373
let goal: Goal<I, G> =
@@ -873,6 +872,60 @@ where
873872
}
874873
}
875874

875+
fn try_assemble_bounds_via_registered_opaque<G: GoalKind<D>>(
876+
&mut self,
877+
goal: Goal<I, G>,
878+
self_ty: I::Ty,
879+
) -> Vec<Candidate<I>> {
880+
//println!("for goal {goal:#?} and {self_ty:?}, we found an alias: {:#?}", self.find_sup_as_registered_opaque(self_ty));
881+
882+
let Some(alias_ty) = self.find_sup_as_registered_opaque(self_ty) else {
883+
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
884+
};
885+
886+
let mut candidates = vec![];
887+
for item_bound in
888+
self.cx().item_self_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args)
889+
{
890+
// TODO: comment
891+
let assumption =
892+
item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty });
893+
candidates.extend(G::probe_and_match_goal_against_assumption(
894+
self,
895+
CandidateSource::AliasBound,
896+
goal,
897+
assumption,
898+
|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS),
899+
));
900+
}
901+
902+
struct ReplaceOpaque<I: Interner> {
903+
cx: I,
904+
alias_ty: ty::AliasTy<I>,
905+
self_ty: I::Ty,
906+
}
907+
impl<I: Interner> TypeFolder<I> for ReplaceOpaque<I> {
908+
fn cx(&self) -> I {
909+
self.cx
910+
}
911+
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
912+
if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() {
913+
if alias_ty == self.alias_ty {
914+
return self.self_ty;
915+
}
916+
}
917+
ty.super_fold_with(self)
918+
}
919+
}
920+
921+
// TODO:
922+
if candidates.is_empty() {
923+
candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity));
924+
}
925+
926+
candidates
927+
}
928+
876929
/// Assemble and merge candidates for goals which are related to an underlying trait
877930
/// goal. Right now, this is normalizes-to and host effect goals.
878931
///

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,26 @@ where
10841084
) -> Result<Certainty, NoSolution> {
10851085
self.delegate.is_transmutable(dst, src, assume)
10861086
}
1087+
1088+
pub(crate) fn find_sup_as_registered_opaque(&self, self_ty: I::Ty) -> Option<ty::AliasTy<I>> {
1089+
self.delegate
1090+
.clone_opaque_types_lookup_table()
1091+
.into_iter()
1092+
.chain(self.delegate.clone_duplicate_opaque_types())
1093+
.find(|(_, hidden_ty)| {
1094+
if let ty::Infer(ty::TyVar(self_vid)) = self_ty.kind() {
1095+
if let ty::Infer(ty::TyVar(hidden_vid)) = hidden_ty.kind() {
1096+
if self.delegate.sub_root_ty_var(self_vid)
1097+
== self.delegate.sub_root_ty_var(hidden_vid)
1098+
{
1099+
return true;
1100+
}
1101+
}
1102+
}
1103+
false
1104+
})
1105+
.map(|(key, _)| ty::AliasTy::new_from_args(self.cx(), key.def_id.into(), key.args))
1106+
}
10871107
}
10881108

10891109
/// Eagerly replace aliases with inference variables, emitting `AliasRelate`

0 commit comments

Comments
 (0)