Skip to content

Commit 4f865bf

Browse files
compiler-errorslcnr
authored andcommitted
Incompletely prefer opaque type bounds when self type bottoms out in infer
1 parent 8f76fdc commit 4f865bf

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
@@ -9,10 +9,10 @@ use derive_where::derive_where;
99
use rustc_type_ir::inherent::*;
1010
use rustc_type_ir::lang_items::TraitSolverLangItem;
1111
use rustc_type_ir::{
12-
self as ty, Interner, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _,
13-
TypeVisitor, TypingMode, Upcast as _, elaborate,
12+
self as ty, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
13+
TypeVisitable, TypeVisitableExt as _, TypeVisitor, TypingMode, Upcast as _, elaborate,
1414
};
15-
use tracing::{debug, instrument};
15+
use tracing::instrument;
1616

1717
use super::trait_goals::TraitGoalProvenVia;
1818
use super::{has_only_region_constraints, inspect};
@@ -368,8 +368,7 @@ where
368368
};
369369

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

375374
let goal: Goal<I, G> =
@@ -874,6 +873,60 @@ where
874873
}
875874
}
876875

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

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)