Canonicalize the ROOT VAR
This commit is contained in:
parent
160c2ebeca
commit
8d13454498
5 changed files with 83 additions and 11 deletions
|
@ -1356,6 +1356,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
self.inner.borrow_mut().type_variables().root_var(var)
|
self.inner.borrow_mut().type_variables().root_var(var)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn root_const_var(&self, var: ty::ConstVid<'tcx>) -> ty::ConstVid<'tcx> {
|
||||||
|
self.inner.borrow_mut().const_unification_table().find(var)
|
||||||
|
}
|
||||||
|
|
||||||
/// Where possible, replaces type/const variables in
|
/// Where possible, replaces type/const variables in
|
||||||
/// `value` with their final value. Note that region variables
|
/// `value` with their final value. Note that region variables
|
||||||
/// are unaffected. If a type/const variable has not been unified, it
|
/// are unaffected. If a type/const variable has not been unified, it
|
||||||
|
|
|
@ -261,12 +261,24 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
|
||||||
self.interner().mk_re_late_bound(self.binder_index, br)
|
self.interner().mk_re_late_bound(self.binder_index, br)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, mut t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
let kind = match *t.kind() {
|
let kind = match *t.kind() {
|
||||||
ty::Infer(ty::TyVar(vid)) => match self.infcx.probe_ty_var(vid) {
|
ty::Infer(ty::TyVar(mut vid)) => {
|
||||||
|
// We need to canonicalize the *root* of our ty var.
|
||||||
|
// This is so that our canonical response correctly reflects
|
||||||
|
// any equated inference vars correctly!
|
||||||
|
|
||||||
|
let root_vid = self.infcx.root_var(vid);
|
||||||
|
if root_vid != vid {
|
||||||
|
t = self.infcx.tcx.mk_ty_var(root_vid);
|
||||||
|
vid = root_vid;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.infcx.probe_ty_var(vid) {
|
||||||
Ok(t) => return self.fold_ty(t),
|
Ok(t) => return self.fold_ty(t),
|
||||||
Err(ui) => CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
Err(ui) => CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||||
},
|
}
|
||||||
|
}
|
||||||
ty::Infer(ty::IntVar(_)) => {
|
ty::Infer(ty::IntVar(_)) => {
|
||||||
let nt = self.infcx.shallow_resolve(t);
|
let nt = self.infcx.shallow_resolve(t);
|
||||||
if nt != t {
|
if nt != t {
|
||||||
|
@ -338,13 +350,23 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
|
||||||
self.interner().mk_bound(self.binder_index, bt)
|
self.interner().mk_bound(self.binder_index, bt)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
fn fold_const(&mut self, mut c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
let kind = match c.kind() {
|
let kind = match c.kind() {
|
||||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => match self.infcx.probe_const_var(vid)
|
ty::ConstKind::Infer(ty::InferConst::Var(mut vid)) => {
|
||||||
{
|
// We need to canonicalize the *root* of our const var.
|
||||||
|
// This is so that our canonical response correctly reflects
|
||||||
|
// any equated inference vars correctly!
|
||||||
|
let root_vid = self.infcx.root_const_var(vid);
|
||||||
|
if root_vid != vid {
|
||||||
|
c = self.infcx.tcx.mk_const(ty::InferConst::Var(root_vid), c.ty());
|
||||||
|
vid = root_vid;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.infcx.probe_const_var(vid) {
|
||||||
Ok(c) => return self.fold_const(c),
|
Ok(c) => return self.fold_const(c),
|
||||||
Err(universe) => CanonicalVarKind::Const(universe, c.ty()),
|
Err(universe) => CanonicalVarKind::Const(universe, c.ty()),
|
||||||
},
|
}
|
||||||
|
}
|
||||||
ty::ConstKind::Infer(ty::InferConst::Fresh(_)) => {
|
ty::ConstKind::Infer(ty::InferConst::Fresh(_)) => {
|
||||||
bug!("fresh var during canonicalization: {c:?}")
|
bug!("fresh var during canonicalization: {c:?}")
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,6 +238,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||||
&& has_changed
|
&& has_changed
|
||||||
&& !self.in_projection_eq_hack
|
&& !self.in_projection_eq_hack
|
||||||
&& !self.search_graph.in_cycle()
|
&& !self.search_graph.in_cycle()
|
||||||
|
&& false
|
||||||
{
|
{
|
||||||
let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
|
let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
|
||||||
let canonical_response =
|
let canonical_response =
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
// check-pass
|
||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
|
||||||
|
trait Mirror {
|
||||||
|
type Item;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Wrapper<T>(T);
|
||||||
|
impl<T> Mirror for Wrapper<T> {
|
||||||
|
type Item = T;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mirror<T>()
|
||||||
|
where
|
||||||
|
Wrapper<T>: Mirror<Item = i32>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mirror::<_ /* ?0 */>();
|
||||||
|
|
||||||
|
// Solving `<Wrapper<?0> as Mirror>::Item = i32`
|
||||||
|
|
||||||
|
// First, we replace the term with a fresh infer var:
|
||||||
|
// `<Wrapper<?0> as Mirror>::Item = ?1`
|
||||||
|
|
||||||
|
// We select the impl candidate on line #6, which leads us to learn that
|
||||||
|
// `?0 == ?1`.
|
||||||
|
|
||||||
|
// That should be reflected in our canonical response, which should have
|
||||||
|
// `^0 = ^0, ^1 = ^0`
|
||||||
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
// !! We used to return a totally unconstrained response here :< !!
|
||||||
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
// Then, during the "equate term" part of the projection solving, we
|
||||||
|
// instantiate the response from the unconstrained projection predicate,
|
||||||
|
// and equate `?0 == i32`.
|
||||||
|
}
|
6
tests/ui/traits/new-solver/deduce-ty-from-object.rs
Normal file
6
tests/ui/traits/new-solver/deduce-ty-from-object.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// check-pass
|
||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: Box<dyn Iterator<Item = ()>> = Box::new(std::iter::empty());
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue