Rollup merge of #65181 - nikomatsakis:lazy-norm-anon-const-push-1, r=varkor

fix bug in folding for constants

These was a bug in the folding for constants that caused it to overlook bound regions. This branch includes some other little things that I did while trying to track the bug down.

r? @oli-obk
This commit is contained in:
Mazdak Farrokhzad
2019-10-08 05:02:43 +02:00
committed by GitHub
5 changed files with 26 additions and 11 deletions

View File

@@ -250,7 +250,9 @@ impl FlagComputation {
ConstValue::Placeholder(_) => { ConstValue::Placeholder(_) => {
self.add_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_CT_PLACEHOLDER); self.add_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_CT_PLACEHOLDER);
} }
_ => {}, ConstValue::Scalar(_) => { }
ConstValue::Slice { data: _, start: _, end: _ } => { }
ConstValue::ByRef { alloc: _, offset: _ } => { }
} }
} }

View File

@@ -911,13 +911,15 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
} }
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool { fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> bool {
if let ty::Const { // we don't have a `visit_infer_const` callback, so we have to
val: ConstValue::Infer(ty::InferConst::Canonical(debruijn, _)), // hook in here to catch this case (annoying...), but
.. // otherwise we do want to remember to visit the rest of the
} = *ct { // const, as it has types/regions embedded in a lot of other
debruijn >= self.outer_index // places.
} else { match ct.val {
false ConstValue::Infer(ty::InferConst::Canonical(debruijn, _))
if debruijn >= self.outer_index => true,
_ => ct.super_visit_with(self),
} }
} }
} }

View File

@@ -689,7 +689,7 @@ pub trait PrettyPrinter<'tcx>:
if self.tcx().sess.verbose() { if self.tcx().sess.verbose() {
p!(write( p!(write(
" closure_kind_ty={:?} closure_sig_ty={:?}", " closure_kind_ty={:?} closure_sig_ty={:?}",
substs.as_closure().kind(did, self.tcx()), substs.as_closure().kind_ty(did, self.tcx()),
substs.as_closure().sig_ty(did, self.tcx()) substs.as_closure().sig_ty(did, self.tcx())
)); ));
} }
@@ -698,7 +698,9 @@ pub trait PrettyPrinter<'tcx>:
}, },
ty::Array(ty, sz) => { ty::Array(ty, sz) => {
p!(write("["), print(ty), write("; ")); p!(write("["), print(ty), write("; "));
if let ConstValue::Unevaluated(..) = sz.val { if self.tcx().sess.verbose() {
p!(write("{:?}", sz));
} else if let ConstValue::Unevaluated(..) = sz.val {
// do not try to evalute unevaluated constants. If we are const evaluating an // do not try to evalute unevaluated constants. If we are const evaluating an
// array length anon const, rustc will (with debug assertions) print the // array length anon const, rustc will (with debug assertions) print the
// constant's path. Which will end up here again. // constant's path. Which will end up here again.
@@ -855,6 +857,11 @@ pub trait PrettyPrinter<'tcx>:
) -> Result<Self::Const, Self::Error> { ) -> Result<Self::Const, Self::Error> {
define_scoped_cx!(self); define_scoped_cx!(self);
if self.tcx().sess.verbose() {
p!(write("Const({:?}: {:?})", ct.val, ct.ty));
return Ok(self);
}
let u8 = self.tcx().types.u8; let u8 = self.tcx().types.u8;
if let ty::FnDef(did, substs) = ct.ty.kind { if let ty::FnDef(did, substs) = ct.ty.kind {
p!(print_value_path(did, substs)); p!(print_value_path(did, substs));

View File

@@ -2203,7 +2203,9 @@ impl<'tcx> TyS<'tcx> {
_ => bug!("cannot convert type `{:?}` to a closure kind", self), _ => bug!("cannot convert type `{:?}` to a closure kind", self),
}, },
Infer(_) => None, // "Bound" types appear in canonical queries when the
// closure type is not yet known
Bound(..) | Infer(_) => None,
Error => Some(ty::ClosureKind::Fn), Error => Some(ty::ClosureKind::Fn),

View File

@@ -17,10 +17,12 @@ fn evaluate_obligation<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
canonical_goal: CanonicalPredicateGoal<'tcx>, canonical_goal: CanonicalPredicateGoal<'tcx>,
) -> Result<EvaluationResult, OverflowError> { ) -> Result<EvaluationResult, OverflowError> {
debug!("evaluate_obligation(canonical_goal={:#?})", canonical_goal);
tcx.infer_ctxt().enter_with_canonical( tcx.infer_ctxt().enter_with_canonical(
DUMMY_SP, DUMMY_SP,
&canonical_goal, &canonical_goal,
|ref infcx, goal, _canonical_inference_vars| { |ref infcx, goal, _canonical_inference_vars| {
debug!("evaluate_obligation: goal={:#?}", goal);
let ParamEnvAnd { let ParamEnvAnd {
param_env, param_env,
value: predicate, value: predicate,