Skip to content

Commit 85d6029

Browse files
committed
AbstractConst::root: Always run subst when Node is Leaf
1 parent 72a51c3 commit 85d6029

File tree

3 files changed

+25
-27
lines changed

3 files changed

+25
-27
lines changed

compiler/rustc_privacy/src/lib.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_middle::mir::abstract_const::Node as ACNode;
2323
use rustc_middle::span_bug;
2424
use rustc_middle::ty::fold::TypeVisitor;
2525
use rustc_middle::ty::query::Providers;
26-
use rustc_middle::ty::subst::{InternalSubsts, Subst};
26+
use rustc_middle::ty::subst::InternalSubsts;
2727
use rustc_middle::ty::{self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable};
2828
use rustc_session::lint;
2929
use rustc_span::hygiene::Transparency;
@@ -153,11 +153,8 @@ where
153153
tcx: TyCtxt<'tcx>,
154154
ct: AbstractConst<'tcx>,
155155
) -> ControlFlow<V::BreakTy> {
156-
const_evaluatable::walk_abstract_const(tcx, ct, |node| match node.root() {
157-
ACNode::Leaf(leaf) => {
158-
let leaf = leaf.subst(tcx, ct.substs);
159-
self.visit_const(leaf)
160-
}
156+
const_evaluatable::walk_abstract_const(tcx, ct, |node| match node.root(tcx, ct.substs) {
157+
ACNode::Leaf(leaf) => self.visit_const(leaf),
161158
ACNode::Cast(_, _, ty) => self.visit_ty(ty),
162159
ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
163160
ControlFlow::CONTINUE

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//! In this case we try to build an abstract representation of this constant using
99
//! `mir_abstract_const` which can then be checked for structural equality with other
1010
//! generic constants mentioned in the `caller_bounds` of the current environment.
11+
use crate::traits::ty::subst::GenericArg;
1112
use rustc_errors::ErrorReported;
1213
use rustc_hir::def::DefKind;
1314
use rustc_index::bit_set::BitSet;
@@ -80,9 +81,8 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
8081
Concrete,
8182
}
8283
let mut failure_kind = FailureKind::Concrete;
83-
walk_abstract_const::<!, _>(tcx, ct, |node| match node.root() {
84+
walk_abstract_const::<!, _>(tcx, ct, |node| match node.root(tcx, ct.substs) {
8485
Node::Leaf(leaf) => {
85-
let leaf = leaf.subst(tcx, ct.substs);
8686
if leaf.has_infer_types_or_consts() {
8787
failure_kind = FailureKind::MentionsInfer;
8888
} else if leaf.definitely_has_param_types_or_consts(tcx) {
@@ -92,7 +92,6 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
9292
ControlFlow::CONTINUE
9393
}
9494
Node::Cast(_, _, ty) => {
95-
let ty = ty.subst(tcx, ct.substs);
9695
if ty.has_infer_types_or_consts() {
9796
failure_kind = FailureKind::MentionsInfer;
9897
} else if ty.definitely_has_param_types_or_consts(tcx) {
@@ -218,8 +217,12 @@ impl<'tcx> AbstractConst<'tcx> {
218217
}
219218

220219
#[inline]
221-
pub fn root(self) -> Node<'tcx> {
222-
self.inner.last().copied().unwrap()
220+
pub fn root(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Node<'tcx> {
221+
let mut node = self.inner.last().copied().unwrap();
222+
if let Node::Leaf(leaf) = node {
223+
node = Node::Leaf(leaf.subst(tcx, substs));
224+
}
225+
node
223226
}
224227
}
225228

@@ -587,7 +590,7 @@ where
587590
f: &mut dyn FnMut(AbstractConst<'tcx>) -> ControlFlow<R>,
588591
) -> ControlFlow<R> {
589592
f(ct)?;
590-
let root = ct.root();
593+
let root = ct.root(tcx, ct.substs);
591594
match root {
592595
Node::Leaf(_) => ControlFlow::CONTINUE,
593596
Node::Binop(_, l, r) => {
@@ -615,27 +618,23 @@ pub(super) fn try_unify<'tcx>(
615618
// We substitute generics repeatedly to allow AbstractConsts to unify where a
616619
// ConstKind::Unevalated could be turned into an AbstractConst that would unify e.g.
617620
// Param(N) should unify with Param(T), substs: [Unevaluated("T2", [Unevaluated("T3", [Param(N)])])]
618-
while let Node::Leaf(a_ct) = a.root() {
619-
let a_ct = a_ct.subst(tcx, a.substs);
621+
while let Node::Leaf(a_ct) = a.root(tcx, a.substs) {
620622
match AbstractConst::from_const(tcx, a_ct) {
621623
Ok(Some(a_act)) => a = a_act,
622624
Ok(None) => break,
623625
Err(_) => return true,
624626
}
625627
}
626-
while let Node::Leaf(b_ct) = b.root() {
627-
let b_ct = b_ct.subst(tcx, b.substs);
628+
while let Node::Leaf(b_ct) = b.root(tcx, b.substs) {
628629
match AbstractConst::from_const(tcx, b_ct) {
629630
Ok(Some(b_act)) => b = b_act,
630631
Ok(None) => break,
631632
Err(_) => return true,
632633
}
633634
}
634635

635-
match (a.root(), b.root()) {
636+
match (a.root(tcx, a.substs), b.root(tcx, b.substs)) {
636637
(Node::Leaf(a_ct), Node::Leaf(b_ct)) => {
637-
let a_ct = a_ct.subst(tcx, a.substs);
638-
let b_ct = b_ct.subst(tcx, b.substs);
639638
if a_ct.ty != b_ct.ty {
640639
return false;
641640
}

compiler/rustc_trait_selection/src/traits/object_safety.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -838,14 +838,16 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
838838
// constants which are not considered const evaluatable.
839839
use rustc_middle::mir::abstract_const::Node;
840840
if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) {
841-
const_evaluatable::walk_abstract_const(self.tcx, ct, |node| match node.root() {
842-
Node::Leaf(leaf) => {
843-
let leaf = leaf.subst(self.tcx, ct.substs);
844-
self.visit_const(leaf)
845-
}
846-
Node::Cast(_, _, ty) => self.visit_ty(ty),
847-
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
848-
ControlFlow::CONTINUE
841+
const_evaluatable::walk_abstract_const(self.tcx, ct, |node| {
842+
match node.root(self.tcx, ct.substs) {
843+
Node::Leaf(leaf) => {
844+
// let leaf = leaf.subst(self.tcx, ct.substs);
845+
self.visit_const(leaf)
846+
}
847+
Node::Cast(_, _, ty) => self.visit_ty(ty),
848+
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
849+
ControlFlow::CONTINUE
850+
}
849851
}
850852
})
851853
} else {

0 commit comments

Comments
 (0)