diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-03-10 12:31:58 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-10 12:31:58 +0100 |
| commit | 4bd32ac31d6ecc212da191dc2cc047fb0a1e8e13 (patch) | |
| tree | 8c092f71c3cdb1d4ba382bf37e002ed6c2a70ea8 | |
| parent | 104f4300cfddbd956e32820ef202a732f06ec848 (diff) | |
| parent | a8f905cdd9dda7b87d78faca5270da4552cf488e (diff) | |
| download | rust-4bd32ac31d6ecc212da191dc2cc047fb0a1e8e13.tar.gz rust-4bd32ac31d6ecc212da191dc2cc047fb0a1e8e13.zip | |
Rollup merge of #108879 - compiler-errors:constrained-root-var, r=lcnr
Unconstrained terms should account for infer vars being equated Follow-up from the canonicalization PR, wanted to break this one out so I can approve the other PR. r? `@lcnr`
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/eval_ctxt.rs | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 95612674eb9..ca438a103cf 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -93,37 +93,42 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }; // Guard against `<T as Trait<?0>>::Assoc = ?0>`. - struct ContainsTerm<'tcx> { + struct ContainsTerm<'a, 'tcx> { term: ty::Term<'tcx>, + infcx: &'a InferCtxt<'tcx>, } - impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> { + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'_, 'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - if t.needs_infer() { - if ty::Term::from(t) == self.term { - ControlFlow::Break(()) - } else { - t.super_visit_with(self) - } + if let Some(vid) = t.ty_vid() + && let ty::TermKind::Ty(term) = self.term.unpack() + && let Some(term_vid) = term.ty_vid() + && self.infcx.root_var(vid) == self.infcx.root_var(term_vid) + { + ControlFlow::Break(()) + } else if t.has_non_region_infer() { + t.super_visit_with(self) } else { ControlFlow::Continue(()) } } fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { - if c.needs_infer() { - if ty::Term::from(c) == self.term { - ControlFlow::Break(()) - } else { - c.super_visit_with(self) - } + if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = c.kind() + && let ty::TermKind::Const(term) = self.term.unpack() + && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind() + && self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid) + { + ControlFlow::Break(()) + } else if c.has_non_region_infer() { + c.super_visit_with(self) } else { ControlFlow::Continue(()) } } } - let mut visitor = ContainsTerm { term: goal.predicate.term }; + let mut visitor = ContainsTerm { infcx: self.infcx, term: goal.predicate.term }; term_is_infer && goal.predicate.projection_ty.visit_with(&mut visitor).is_continue() |
