Canonicalize the ROOT VAR
This commit is contained in:
parent
160c2ebeca
commit
8d13454498
@ -1356,6 +1356,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
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
|
||||
/// `value` with their final value. Note that region variables
|
||||
/// 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)
|
||||
}
|
||||
|
||||
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() {
|
||||
ty::Infer(ty::TyVar(vid)) => match self.infcx.probe_ty_var(vid) {
|
||||
Ok(t) => return self.fold_ty(t),
|
||||
Err(ui) => CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||
},
|
||||
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),
|
||||
Err(ui) => CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::IntVar(_)) => {
|
||||
let nt = self.infcx.shallow_resolve(t);
|
||||
if nt != t {
|
||||
@ -338,13 +350,23 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
|
||||
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() {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => match self.infcx.probe_const_var(vid)
|
||||
{
|
||||
Ok(c) => return self.fold_const(c),
|
||||
Err(universe) => CanonicalVarKind::Const(universe, c.ty()),
|
||||
},
|
||||
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),
|
||||
Err(universe) => CanonicalVarKind::Const(universe, c.ty()),
|
||||
}
|
||||
}
|
||||
ty::ConstKind::Infer(ty::InferConst::Fresh(_)) => {
|
||||
bug!("fresh var during canonicalization: {c:?}")
|
||||
}
|
||||
|
@ -238,6 +238,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||
&& has_changed
|
||||
&& !self.in_projection_eq_hack
|
||||
&& !self.search_graph.in_cycle()
|
||||
&& false
|
||||
{
|
||||
let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
|
||||
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…
x
Reference in New Issue
Block a user