Skip to content

Commit 05ba713

Browse files
Incompletely prefer opaque type bounds when self type bottoms out in infer
1 parent 41dea37 commit 05ba713

File tree

2 files changed

+77
-4
lines changed
  • compiler/rustc_next_trait_solver/src/solve

2 files changed

+77
-4
lines changed

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

+58-4
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use derive_where::derive_where;
66
use rustc_type_ir::inherent::*;
77
use rustc_type_ir::lang_items::TraitSolverLangItem;
88
use rustc_type_ir::{
9-
self as ty, Interner, TypeFoldable, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
9+
self as ty, Interner, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt as _,
10+
TypingMode, Upcast as _, elaborate,
1011
};
11-
use tracing::{debug, instrument};
12+
use tracing::instrument;
1213

1314
use super::has_only_region_constraints;
1415
use super::trait_goals::TraitGoalProvenVia;
@@ -316,8 +317,7 @@ where
316317
};
317318

318319
if normalized_self_ty.is_ty_var() {
319-
debug!("self type has been normalized to infer");
320-
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
320+
return self.try_assemble_bounds_via_registered_opaque(goal, normalized_self_ty);
321321
}
322322

323323
let goal: Goal<I, G> =
@@ -828,6 +828,60 @@ where
828828
}
829829
}
830830

831+
fn try_assemble_bounds_via_registered_opaque<G: GoalKind<D>>(
832+
&mut self,
833+
goal: Goal<I, G>,
834+
self_ty: I::Ty,
835+
) -> Vec<Candidate<I>> {
836+
//println!("for goal {goal:#?} and {self_ty:?}, we found an alias: {:#?}", self.find_sup_as_registered_opaque(self_ty));
837+
838+
let Some(alias_ty) = self.find_sup_as_registered_opaque(self_ty) else {
839+
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
840+
};
841+
842+
let mut candidates = vec![];
843+
for item_bound in
844+
self.cx().item_self_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args)
845+
{
846+
// TODO: comment
847+
let assumption =
848+
item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty });
849+
candidates.extend(G::probe_and_match_goal_against_assumption(
850+
self,
851+
CandidateSource::AliasBound,
852+
goal,
853+
assumption,
854+
|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS),
855+
));
856+
}
857+
858+
struct ReplaceOpaque<I: Interner> {
859+
cx: I,
860+
alias_ty: ty::AliasTy<I>,
861+
self_ty: I::Ty,
862+
}
863+
impl<I: Interner> TypeFolder<I> for ReplaceOpaque<I> {
864+
fn cx(&self) -> I {
865+
self.cx
866+
}
867+
fn fold_ty(&mut self, ty: I::Ty) -> I::Ty {
868+
if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() {
869+
if alias_ty == self.alias_ty {
870+
return self.self_ty;
871+
}
872+
}
873+
ty.super_fold_with(self)
874+
}
875+
}
876+
877+
// TODO:
878+
if candidates.is_empty() {
879+
candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity));
880+
}
881+
882+
candidates
883+
}
884+
831885
/// Assemble and merge candidates for goals which are related to an underlying trait
832886
/// goal. Right now, this is normalizes-to and host effect goals.
833887
///

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

+19
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,25 @@ where
11141114
) -> Result<Certainty, NoSolution> {
11151115
self.delegate.is_transmutable(dst, src, assume)
11161116
}
1117+
1118+
pub(crate) fn find_sup_as_registered_opaque(&self, self_ty: I::Ty) -> Option<ty::AliasTy<I>> {
1119+
self.delegate
1120+
.clone_opaque_types_for_query_response()
1121+
.into_iter()
1122+
.find(|(_, hidden_ty)| {
1123+
if let ty::Infer(ty::TyVar(self_vid)) = self_ty.kind() {
1124+
if let ty::Infer(ty::TyVar(hidden_vid)) = hidden_ty.kind() {
1125+
if self.delegate.sub_root_ty_var(self_vid)
1126+
== self.delegate.sub_root_ty_var(hidden_vid)
1127+
{
1128+
return true;
1129+
}
1130+
}
1131+
}
1132+
false
1133+
})
1134+
.map(|(key, _)| ty::AliasTy::new_from_args(self.cx(), key.def_id.into(), key.args))
1135+
}
11171136
}
11181137

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

0 commit comments

Comments
 (0)