initial revert
This commit is contained in:
parent
b0ec3e09a9
commit
71bbb603f4
127 changed files with 540 additions and 1050 deletions
|
@ -444,7 +444,7 @@ fn orphan_check_trait_ref<'tcx>(
|
|||
) -> Result<(), OrphanCheckErr<'tcx>> {
|
||||
debug!("orphan_check_trait_ref(trait_ref={:?}, in_crate={:?})", trait_ref, in_crate);
|
||||
|
||||
if trait_ref.needs_infer() && trait_ref.definitely_needs_subst(tcx) {
|
||||
if trait_ref.needs_infer() && trait_ref.needs_subst() {
|
||||
bug!(
|
||||
"can't orphan check a trait ref with both params and inference variables {:?}",
|
||||
trait_ref
|
||||
|
|
|
@ -19,7 +19,7 @@ use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable
|
|||
use rustc_middle::ty::subst::{Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::cmp;
|
||||
|
@ -29,20 +29,26 @@ use std::ops::ControlFlow;
|
|||
/// Check if a given constant can be evaluated.
|
||||
pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||
infcx: &InferCtxt<'cx, 'tcx>,
|
||||
uv: ty::Unevaluated<'tcx, ()>,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<(), NotConstEvaluatable> {
|
||||
debug!("is_const_evaluatable({:?})", uv);
|
||||
debug!("is_const_evaluatable({:?}, {:?})", def, substs);
|
||||
if infcx.tcx.features().generic_const_exprs {
|
||||
let tcx = infcx.tcx;
|
||||
match AbstractConst::new(tcx, uv)? {
|
||||
match AbstractConst::new(tcx, def, substs)? {
|
||||
// We are looking at a generic abstract constant.
|
||||
Some(ct) => {
|
||||
for pred in param_env.caller_bounds() {
|
||||
match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
||||
if let Some(b_ct) = AbstractConst::new(tcx, uv)? {
|
||||
ty::PredicateKind::ConstEvaluatable(b_def, b_substs) => {
|
||||
if b_def == def && b_substs == substs {
|
||||
debug!("is_const_evaluatable: caller_bound ~~> ok");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(b_ct) = AbstractConst::new(tcx, b_def, b_substs)? {
|
||||
// Try to unify with each subtree in the AbstractConst to allow for
|
||||
// `N + 1` being const evaluatable even if theres only a `ConstEvaluatable`
|
||||
// predicate for `(N + 1) * 2`
|
||||
|
@ -84,7 +90,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
|||
Node::Leaf(leaf) => {
|
||||
if leaf.has_infer_types_or_consts() {
|
||||
failure_kind = FailureKind::MentionsInfer;
|
||||
} else if leaf.definitely_has_param_types_or_consts(tcx) {
|
||||
} else if leaf.has_param_types_or_consts() {
|
||||
failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
|
||||
}
|
||||
|
||||
|
@ -93,7 +99,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
|||
Node::Cast(_, _, ty) => {
|
||||
if ty.has_infer_types_or_consts() {
|
||||
failure_kind = FailureKind::MentionsInfer;
|
||||
} else if ty.definitely_has_param_types_or_consts(tcx) {
|
||||
} else if ty.has_param_types_or_consts() {
|
||||
failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
|
||||
}
|
||||
|
||||
|
@ -126,7 +132,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
|||
}
|
||||
|
||||
let future_compat_lint = || {
|
||||
if let Some(local_def_id) = uv.def.did.as_local() {
|
||||
if let Some(local_def_id) = def.did.as_local() {
|
||||
infcx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
||||
infcx.tcx.hir().local_def_id_to_hir_id(local_def_id),
|
||||
|
@ -147,12 +153,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
|||
// and hopefully soon change this to an error.
|
||||
//
|
||||
// See #74595 for more details about this.
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
||||
let concrete = infcx.const_eval_resolve(
|
||||
param_env,
|
||||
ty::Unevaluated { def, substs, promoted: None },
|
||||
Some(span),
|
||||
);
|
||||
|
||||
if concrete.is_ok() && uv.substs(infcx.tcx).definitely_has_param_types_or_consts(infcx.tcx) {
|
||||
match infcx.tcx.def_kind(uv.def.did) {
|
||||
if concrete.is_ok() && substs.has_param_types_or_consts() {
|
||||
match infcx.tcx.def_kind(def.did) {
|
||||
DefKind::AnonConst | DefKind::InlineConst => {
|
||||
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
|
||||
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(def);
|
||||
|
||||
if mir_body.is_polymorphic {
|
||||
future_compat_lint();
|
||||
|
@ -164,7 +174,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
|||
|
||||
debug!(?concrete, "is_const_evaluatable");
|
||||
match concrete {
|
||||
Err(ErrorHandled::TooGeneric) => Err(match uv.has_infer_types_or_consts() {
|
||||
Err(ErrorHandled::TooGeneric) => Err(match substs.has_infer_types_or_consts() {
|
||||
true => NotConstEvaluatable::MentionsInfer,
|
||||
false => NotConstEvaluatable::MentionsParam,
|
||||
}),
|
||||
|
@ -192,11 +202,12 @@ pub struct AbstractConst<'tcx> {
|
|||
impl<'tcx> AbstractConst<'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
uv: ty::Unevaluated<'tcx, ()>,
|
||||
def: ty::WithOptConstParam<DefId>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
|
||||
let inner = tcx.thir_abstract_const_opt_const_arg(uv.def)?;
|
||||
debug!("AbstractConst::new({:?}) = {:?}", uv, inner);
|
||||
Ok(inner.map(|inner| AbstractConst { inner, substs: uv.substs(tcx) }))
|
||||
let inner = tcx.thir_abstract_const_opt_const_arg(def)?;
|
||||
debug!("AbstractConst::new({:?}, {:?}) = {:?}", def, substs, inner);
|
||||
Ok(inner.map(|inner| AbstractConst { inner, substs }))
|
||||
}
|
||||
|
||||
pub fn from_const(
|
||||
|
@ -204,7 +215,9 @@ impl<'tcx> AbstractConst<'tcx> {
|
|||
ct: &ty::Const<'tcx>,
|
||||
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
|
||||
match ct.val {
|
||||
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()),
|
||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: _ }) => {
|
||||
AbstractConst::new(tcx, def, substs)
|
||||
}
|
||||
ty::ConstKind::Error(_) => Err(ErrorReported),
|
||||
_ => Ok(None),
|
||||
}
|
||||
|
@ -271,7 +284,6 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
struct IsThirPolymorphic<'a, 'tcx> {
|
||||
is_poly: bool,
|
||||
thir: &'a thir::Thir<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
use thir::visit;
|
||||
|
@ -281,25 +293,25 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &thir::Expr<'tcx>) {
|
||||
self.is_poly |= expr.ty.definitely_has_param_types_or_consts(self.tcx);
|
||||
self.is_poly |= expr.ty.has_param_types_or_consts();
|
||||
if !self.is_poly {
|
||||
visit::walk_expr(self, expr)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) {
|
||||
self.is_poly |= pat.ty.definitely_has_param_types_or_consts(self.tcx);
|
||||
self.is_poly |= pat.ty.has_param_types_or_consts();
|
||||
if !self.is_poly {
|
||||
visit::walk_pat(self, pat);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) {
|
||||
self.is_poly |= ct.definitely_has_param_types_or_consts(self.tcx);
|
||||
self.is_poly |= ct.has_param_types_or_consts();
|
||||
}
|
||||
}
|
||||
|
||||
let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body, tcx };
|
||||
let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body };
|
||||
visit::walk_expr(&mut is_poly_vis, &body[body_id]);
|
||||
debug!("AbstractConstBuilder: is_poly={}", is_poly_vis.is_poly);
|
||||
if !is_poly_vis.is_poly {
|
||||
|
@ -527,11 +539,14 @@ pub(super) fn thir_abstract_const<'tcx>(
|
|||
|
||||
pub(super) fn try_unify_abstract_consts<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>),
|
||||
((a, a_substs), (b, b_substs)): (
|
||||
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
|
||||
(ty::WithOptConstParam<DefId>, SubstsRef<'tcx>),
|
||||
),
|
||||
) -> bool {
|
||||
(|| {
|
||||
if let Some(a) = AbstractConst::new(tcx, a)? {
|
||||
if let Some(b) = AbstractConst::new(tcx, b)? {
|
||||
if let Some(a) = AbstractConst::new(tcx, a, a_substs)? {
|
||||
if let Some(b) = AbstractConst::new(tcx, b, b_substs)? {
|
||||
return Ok(try_unify(tcx, a, b));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -819,10 +819,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
match obligation.predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
||||
ty::PredicateKind::ConstEvaluatable(def, _) => {
|
||||
let mut err =
|
||||
self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
|
||||
let const_span = self.tcx.def_span(uv.def.did);
|
||||
let const_span = self.tcx.def_span(def.did);
|
||||
match self.tcx.sess.source_map().span_to_snippet(const_span) {
|
||||
Ok(snippet) => err.help(&format!(
|
||||
"try adding a `where` bound using this expression: `where [(); {}]:`",
|
||||
|
|
|
@ -527,10 +527,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
||||
ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
|
||||
match const_evaluatable::is_const_evaluatable(
|
||||
self.selcx.infcx(),
|
||||
uv,
|
||||
def_id,
|
||||
substs,
|
||||
obligation.param_env,
|
||||
obligation.cause.span,
|
||||
) {
|
||||
|
@ -538,9 +539,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
Err(NotConstEvaluatable::MentionsInfer) => {
|
||||
pending_obligation.stalled_on.clear();
|
||||
pending_obligation.stalled_on.extend(
|
||||
uv.substs(infcx.tcx)
|
||||
.iter()
|
||||
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
|
||||
substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg),
|
||||
);
|
||||
ProcessResult::Unchanged
|
||||
}
|
||||
|
@ -564,7 +563,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
||||
(c1.val, c2.val)
|
||||
{
|
||||
if infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) {
|
||||
if infcx.try_unify_abstract_consts(a, b) {
|
||||
return ProcessResult::Changed(vec![]);
|
||||
}
|
||||
}
|
||||
|
@ -583,7 +582,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
Err(ErrorHandled::TooGeneric) => {
|
||||
stalled_on.extend(
|
||||
unevaluated
|
||||
.substs(tcx)
|
||||
.substs
|
||||
.iter()
|
||||
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
|
||||
);
|
||||
|
@ -654,7 +653,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
|
||||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let infcx = self.selcx.infcx();
|
||||
if obligation.predicate.is_known_global() {
|
||||
if obligation.predicate.is_global() {
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
if infcx.predicate_must_hold_considering_regions(obligation) {
|
||||
|
@ -708,7 +707,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let tcx = self.selcx.tcx();
|
||||
|
||||
if obligation.predicate.is_global(tcx) {
|
||||
if obligation.predicate.is_global() {
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) {
|
||||
|
@ -756,15 +755,14 @@ fn substs_infer_vars<'a, 'tcx>(
|
|||
selcx: &mut SelectionContext<'a, 'tcx>,
|
||||
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
|
||||
) -> impl Iterator<Item = TyOrConstInferVar<'tcx>> {
|
||||
let tcx = selcx.tcx();
|
||||
selcx
|
||||
.infcx()
|
||||
.resolve_vars_if_possible(substs)
|
||||
.skip_binder() // ok because this check doesn't care about regions
|
||||
.iter()
|
||||
.filter(|arg| arg.has_infer_types_or_consts())
|
||||
.flat_map(move |arg| {
|
||||
let mut walker = arg.walk(tcx);
|
||||
.flat_map(|arg| {
|
||||
let mut walker = arg.walk();
|
||||
while let Some(c) = walker.next() {
|
||||
if !c.has_infer_types_or_consts() {
|
||||
walker.visited.remove(&c);
|
||||
|
|
|
@ -465,7 +465,7 @@ fn subst_and_check_impossible_predicates<'tcx>(
|
|||
debug!("subst_and_check_impossible_predicates(key={:?})", key);
|
||||
|
||||
let mut predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
|
||||
predicates.retain(|predicate| !predicate.definitely_needs_subst(tcx));
|
||||
predicates.retain(|predicate| !predicate.needs_subst());
|
||||
let result = impossible_predicates(tcx, predicates);
|
||||
|
||||
debug!("subst_and_check_impossible_predicates(key={:?}) = {:?}", key, result);
|
||||
|
|
|
@ -274,7 +274,7 @@ fn predicate_references_self<'tcx>(
|
|||
(predicate, sp): (ty::Predicate<'tcx>, Span),
|
||||
) -> Option<Span> {
|
||||
let self_ty = tcx.types.self_param;
|
||||
let has_self_ty = |arg: &GenericArg<'tcx>| arg.walk(tcx).any(|arg| arg == self_ty.into());
|
||||
let has_self_ty = |arg: &GenericArg<'_>| arg.walk().any(|arg| arg == self_ty.into());
|
||||
match predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(ref data) => {
|
||||
// In the case of a trait predicate, we can skip the "self" type.
|
||||
|
@ -768,9 +768,6 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
|||
|
||||
impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> {
|
||||
type BreakTy = ();
|
||||
fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
|
||||
Some(self.tcx)
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match t.kind() {
|
||||
|
@ -816,10 +813,9 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_unevaluated_const(
|
||||
&mut self,
|
||||
uv: ty::Unevaluated<'tcx>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
self.visit_ty(ct.ty)?;
|
||||
|
||||
// Constants can only influence object safety if they reference `Self`.
|
||||
// This is only possible for unevaluated constants, so we walk these here.
|
||||
//
|
||||
|
@ -833,7 +829,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
|||
// This shouldn't really matter though as we can't really use any
|
||||
// constants which are not considered const evaluatable.
|
||||
use rustc_middle::thir::abstract_const::Node;
|
||||
if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv.shrink()) {
|
||||
if let Ok(Some(ct)) = AbstractConst::from_const(self.tcx, ct) {
|
||||
const_evaluatable::walk_abstract_const(self.tcx, ct, |node| {
|
||||
match node.root(self.tcx) {
|
||||
Node::Leaf(leaf) => self.visit_const(leaf),
|
||||
|
@ -847,6 +843,30 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
|||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::PredicateKind::ConstEvaluatable(def, substs) = pred.kind().skip_binder() {
|
||||
// FIXME(generic_const_exprs): We should probably deduplicate the logic for
|
||||
// `AbstractConst`s here, it might make sense to change `ConstEvaluatable` to
|
||||
// take a `ty::Const` instead.
|
||||
use rustc_middle::thir::abstract_const::Node;
|
||||
if let Ok(Some(ct)) = AbstractConst::new(self.tcx, def, substs) {
|
||||
const_evaluatable::walk_abstract_const(self.tcx, ct, |node| {
|
||||
match node.root(self.tcx) {
|
||||
Node::Leaf(leaf) => self.visit_const(leaf),
|
||||
Node::Cast(_, _, ty) => self.visit_ty(ty),
|
||||
Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
} else {
|
||||
pred.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value
|
||||
|
|
|
@ -77,11 +77,8 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
|||
// The rest of the code is already set up to be lazy about replacing bound vars,
|
||||
// and only when we actually have to normalize.
|
||||
if value.has_escaping_bound_vars() {
|
||||
let mut max_visitor = MaxEscapingBoundVarVisitor {
|
||||
tcx: self.infcx.tcx,
|
||||
outer_index: ty::INNERMOST,
|
||||
escaping: 0,
|
||||
};
|
||||
let mut max_visitor =
|
||||
MaxEscapingBoundVarVisitor { outer_index: ty::INNERMOST, escaping: 0 };
|
||||
value.visit_with(&mut max_visitor);
|
||||
if max_visitor.escaping > 0 {
|
||||
normalizer.universes.extend((0..max_visitor.escaping).map(|_| None));
|
||||
|
@ -104,18 +101,13 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
/// Visitor to find the maximum escaping bound var
|
||||
struct MaxEscapingBoundVarVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
struct MaxEscapingBoundVarVisitor {
|
||||
// The index which would count as escaping
|
||||
outer_index: ty::DebruijnIndex,
|
||||
escaping: usize,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor<'tcx> {
|
||||
fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
|
||||
Some(self.tcx)
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &ty::Binder<'tcx, T>,
|
||||
|
|
|
@ -997,7 +997,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let tail_field_ty = tcx.type_of(tail_field.did);
|
||||
|
||||
let mut unsizing_params = GrowableBitSet::new_empty();
|
||||
for arg in tail_field_ty.walk(tcx) {
|
||||
for arg in tail_field_ty.walk() {
|
||||
if let Some(i) = maybe_unsizing_param_idx(arg) {
|
||||
unsizing_params.insert(i);
|
||||
}
|
||||
|
@ -1006,7 +1006,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// Ensure none of the other fields mention the parameters used
|
||||
// in unsizing.
|
||||
for field in prefix_fields {
|
||||
for arg in tcx.type_of(field.did).walk(tcx) {
|
||||
for arg in tcx.type_of(field.did).walk() {
|
||||
if let Some(i) = maybe_unsizing_param_idx(arg) {
|
||||
unsizing_params.remove(i);
|
||||
}
|
||||
|
|
|
@ -526,7 +526,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// contain the "'static" lifetime (any other lifetime
|
||||
// would either be late-bound or local), so it is guaranteed
|
||||
// to outlive any other lifetime
|
||||
if pred.0.is_global(self.infcx.tcx) && !pred.0.has_late_bound_regions() {
|
||||
if pred.0.is_global() && !pred.0.has_late_bound_regions() {
|
||||
Ok(EvaluatedToOk)
|
||||
} else {
|
||||
Ok(EvaluatedToOkModuloRegions)
|
||||
|
@ -619,10 +619,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
||||
ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
|
||||
match const_evaluatable::is_const_evaluatable(
|
||||
self.infcx,
|
||||
uv,
|
||||
def_id,
|
||||
substs,
|
||||
obligation.param_env,
|
||||
obligation.cause.span,
|
||||
) {
|
||||
|
@ -644,7 +645,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
||||
(c1.val, c2.val)
|
||||
{
|
||||
if self.infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) {
|
||||
if self.infcx.try_unify_abstract_consts(a, b) {
|
||||
return Ok(EvaluatedToOk);
|
||||
}
|
||||
}
|
||||
|
@ -711,12 +712,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
mut obligation: TraitObligation<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
if !self.intercrate
|
||||
&& obligation.is_global(self.tcx())
|
||||
&& obligation
|
||||
.param_env
|
||||
.caller_bounds()
|
||||
.iter()
|
||||
.all(|bound| bound.definitely_needs_subst(self.tcx()))
|
||||
&& obligation.is_global()
|
||||
&& obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst())
|
||||
{
|
||||
// If a param env has no global bounds, global obligations do not
|
||||
// depend on its particular value in order to work, so we can clear
|
||||
|
@ -1535,7 +1532,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// the param_env so that it can be given the lowest priority. See
|
||||
// #50825 for the motivation for this.
|
||||
let is_global = |cand: &ty::PolyTraitPredicate<'tcx>| {
|
||||
cand.is_global(self.infcx.tcx) && !cand.has_late_bound_regions()
|
||||
cand.is_global() && !cand.has_late_bound_regions()
|
||||
};
|
||||
|
||||
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
|
||||
|
|
|
@ -131,9 +131,6 @@ impl<'a, 'tcx> Search<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
|
||||
type BreakTy = NonStructuralMatchTy<'tcx>;
|
||||
fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
|
||||
Some(self.tcx())
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
debug!("Search visiting ty: {:?}", ty);
|
||||
|
|
|
@ -131,9 +131,8 @@ pub fn predicate_obligations<'a, 'tcx>(
|
|||
wf.compute(a.into());
|
||||
wf.compute(b.into());
|
||||
}
|
||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
||||
let substs = uv.substs(wf.tcx());
|
||||
let obligations = wf.nominal_obligations(uv.def.did, substs);
|
||||
ty::PredicateKind::ConstEvaluatable(def, substs) => {
|
||||
let obligations = wf.nominal_obligations(def.did, substs);
|
||||
wf.out.extend(obligations);
|
||||
|
||||
for arg in substs.iter() {
|
||||
|
@ -429,7 +428,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
|
||||
/// Pushes all the predicates needed to validate that `ty` is WF into `out`.
|
||||
fn compute(&mut self, arg: GenericArg<'tcx>) {
|
||||
let mut walker = arg.walk(self.tcx());
|
||||
let mut walker = arg.walk();
|
||||
let param_env = self.param_env;
|
||||
let depth = self.recursion_depth;
|
||||
while let Some(arg) = walker.next() {
|
||||
|
@ -442,17 +441,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
|
||||
GenericArgKind::Const(constant) => {
|
||||
match constant.val {
|
||||
ty::ConstKind::Unevaluated(uv) => {
|
||||
assert!(uv.promoted.is_none());
|
||||
let substs = uv.substs(self.tcx());
|
||||
ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) => {
|
||||
assert!(promoted.is_none());
|
||||
|
||||
let obligations = self.nominal_obligations(uv.def.did, substs);
|
||||
let obligations = self.nominal_obligations(def.did, substs);
|
||||
self.out.extend(obligations);
|
||||
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
|
||||
ty::Unevaluated::new(uv.def, substs),
|
||||
))
|
||||
.to_predicate(self.tcx());
|
||||
let predicate =
|
||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(def, substs))
|
||||
.to_predicate(self.tcx());
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
cause,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue