Skip to content

Commit 3b3514a

Browse files
committed
consider placeholders in fn term_is_fully_unconstrained
1 parent 1c264ca commit 3b3514a

File tree

1 file changed

+49
-37
lines changed
  • compiler/rustc_trait_selection/src/solve/eval_ctxt

1 file changed

+49
-37
lines changed

Diff for: compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

+49-37
Original file line numberDiff line numberDiff line change
@@ -608,8 +608,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
608608

609609
/// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
610610
///
611-
/// This is the case if the `term` is an inference variable in the innermost universe
612-
/// and does not occur in any other part of the predicate.
611+
/// This is the case if the `term` does not occur in any other part of the predicate
612+
/// and is able to name all other placeholder and inference variables.
613613
#[instrument(level = "debug", skip(self), ret)]
614614
pub(super) fn term_is_fully_unconstrained(
615615
&self,
@@ -632,55 +632,67 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
632632
}
633633
};
634634

635-
// Guard against `<T as Trait<?0>>::Assoc = ?0>`.
636635
struct ContainsTermOrNotNameable<'a, 'tcx> {
637636
term: ty::Term<'tcx>,
638637
universe_of_term: ty::UniverseIndex,
639638
infcx: &'a InferCtxt<'tcx>,
640639
}
640+
641+
impl<'a, 'tcx> ContainsTermOrNotNameable<'a, 'tcx> {
642+
fn check_nameable(&self, universe: ty::UniverseIndex) -> ControlFlow<()> {
643+
if self.universe_of_term.can_name(universe) {
644+
ControlFlow::Continue(())
645+
} else {
646+
ControlFlow::Break(())
647+
}
648+
}
649+
}
650+
641651
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTermOrNotNameable<'_, 'tcx> {
642652
type BreakTy = ();
643653
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
644-
if let Some(vid) = t.ty_vid() {
645-
if let ty::TermKind::Ty(term) = self.term.unpack()
646-
&& let Some(term_vid) = term.ty_vid()
647-
&& self.infcx.root_var(vid) == self.infcx.root_var(term_vid)
648-
{
649-
ControlFlow::Break(())
650-
} else if self
651-
.universe_of_term
652-
.cannot_name(self.infcx.universe_of_ty(vid).unwrap())
653-
{
654-
ControlFlow::Break(())
655-
} else {
656-
ControlFlow::Continue(())
654+
match *t.kind() {
655+
ty::Infer(ty::TyVar(vid)) => {
656+
if let ty::TermKind::Ty(term) = self.term.unpack()
657+
&& let Some(term_vid) = term.ty_vid()
658+
&& self.infcx.root_var(vid) == self.infcx.root_var(term_vid)
659+
{
660+
ControlFlow::Break(())
661+
} else {
662+
self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
663+
}
664+
}
665+
ty::Placeholder(p) => self.check_nameable(p.universe),
666+
_ => {
667+
if t.has_non_region_infer() || t.has_placeholders() {
668+
t.super_visit_with(self)
669+
} else {
670+
ControlFlow::Continue(())
671+
}
657672
}
658-
} else if t.has_non_region_infer() {
659-
t.super_visit_with(self)
660-
} else {
661-
ControlFlow::Continue(())
662673
}
663674
}
664675

665676
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
666-
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = c.kind() {
667-
if let ty::TermKind::Const(term) = self.term.unpack()
668-
&& let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
669-
&& self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
670-
{
671-
ControlFlow::Break(())
672-
} else if self
673-
.universe_of_term
674-
.cannot_name(self.infcx.universe_of_ct(vid).unwrap())
675-
{
676-
ControlFlow::Break(())
677-
} else {
678-
ControlFlow::Continue(())
677+
match c.kind() {
678+
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
679+
if let ty::TermKind::Const(term) = self.term.unpack()
680+
&& let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
681+
&& self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
682+
{
683+
ControlFlow::Break(())
684+
} else {
685+
self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
686+
}
687+
}
688+
ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe),
689+
_ => {
690+
if c.has_non_region_infer() || c.has_placeholders() {
691+
c.super_visit_with(self)
692+
} else {
693+
ControlFlow::Continue(())
694+
}
679695
}
680-
} else if c.has_non_region_infer() {
681-
c.super_visit_with(self)
682-
} else {
683-
ControlFlow::Continue(())
684696
}
685697
}
686698
}

0 commit comments

Comments
 (0)