Auto merge of #53645 - varkor:const-generics-redux, r=eddyb

The Genesis of Generic Germination

*Long had its coming been foretold: a collaborative effort with @yodaldevoid, set in motion by @jplatte, to beget a new Kind: one of a very different Sort to those that come before it. Amidst promises of ineffable powers previously thought unobtainable, few dared believe that the prophecies were true. But as they gazed upon that which claimed to be the Beginning, a few gentle sparks of hope fluttered deep within. It was not Time yet. But it was a Sign. And maybe, for some, that was enough.*

There's a long way to go, but we're at the point where we would benefit from GitHub's reviewing capabilities.

r? @eddyb
This commit is contained in:
bors 2019-05-06 16:43:25 +00:00
commit a19cf18c7d
10 changed files with 71 additions and 40 deletions

View file

@ -27,6 +27,7 @@
use super::*;
use crate::ty::Const;
use crate::ty::relate::{Relate, TypeRelation};
pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
@ -308,6 +309,20 @@ impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
}
}
impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
fn to_trace(cause: &ObligationCause<'tcx>,
a_is_expected: bool,
a: Self,
b: Self)
-> TypeTrace<'tcx>
{
TypeTrace {
cause: cause.clone(),
values: Consts(ExpectedFound::new(a_is_expected, a, b))
}
}
}
impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
fn to_trace(cause: &ObligationCause<'tcx>,
a_is_expected: bool,

View file

@ -318,8 +318,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
obligations.extend(ok.into_obligations());
}
(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
unimplemented!() // FIXME(const_generics)
(UnpackedKind::Const(v1), UnpackedKind::Const(v2)) => {
let ok = self.at(cause, param_env).eq(v1, v2)?;
obligations.extend(ok.into_obligations());
}
_ => {
@ -626,8 +627,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
obligations
.extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
}
(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
unimplemented!() // FIXME(const_generics)
(UnpackedKind::Const(v1), UnpackedKind::Const(v2)) => {
let ok = self.at(cause, param_env).eq(v1, v2)?;
obligations.extend(ok.into_obligations());
}
_ => {
bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);

View file

@ -1260,6 +1260,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
match *values {
infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found),
infer::Regions(ref exp_found) => self.expected_found_str(exp_found),
infer::Consts(ref exp_found) => self.expected_found_str(exp_found),
infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found),
}

View file

@ -232,6 +232,7 @@ pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
pub enum ValuePairs<'tcx> {
Types(ExpectedFound<Ty<'tcx>>),
Regions(ExpectedFound<ty::Region<'tcx>>),
Consts(ExpectedFound<&'tcx ty::Const<'tcx>>),
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
}
@ -1730,6 +1731,7 @@ EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
(ValuePairs::Types)(a),
(ValuePairs::Regions)(a),
(ValuePairs::Consts)(a),
(ValuePairs::TraitRefs)(a),
(ValuePairs::PolyTraitRefs)(a),
}

View file

@ -6,7 +6,7 @@
use crate::hir::def::Namespace;
use crate::mir::ProjectionKind;
use crate::mir::interpret::ConstValue;
use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid};
use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::print::{FmtPrinter, Printer};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@ -1352,8 +1352,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
ConstValue::ByRef(ptr, alloc) => ConstValue::ByRef(ptr, alloc),
// FIXME(const_generics): implement TypeFoldable for InferConst
ConstValue::Infer(ic) => ConstValue::Infer(ic),
ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)),
ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
ConstValue::Placeholder(p) => ConstValue::Placeholder(p),
ConstValue::Scalar(a) => ConstValue::Scalar(a),
@ -1366,8 +1365,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
ConstValue::ByRef(..) => false,
// FIXME(const_generics): implement TypeFoldable for InferConst
ConstValue::Infer(_) => false,
ConstValue::Infer(ic) => ic.visit_with(visitor),
ConstValue::Param(p) => p.visit_with(visitor),
ConstValue::Placeholder(_) => false,
ConstValue::Scalar(_) => false,
@ -1376,3 +1374,13 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
}
}
}
impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
*self
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
false
}
}

View file

@ -618,8 +618,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
}
};
// FIXME(const_generics): shift const through binders
ct
self.shift_vars_through_binders(ct)
}
/// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
@ -664,15 +663,15 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
/// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
/// is that only in the second case have we passed through a fn binder.
fn shift_vars_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
debug!("shift_vars(ty={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
ty, self.binders_passed, ty.has_escaping_bound_vars());
fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
debug!("shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
val, self.binders_passed, val.has_escaping_bound_vars());
if self.binders_passed == 0 || !ty.has_escaping_bound_vars() {
return ty;
if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
return val;
}
let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed);
let result = ty::fold::shift_vars(self.tcx(), &val, self.binders_passed);
debug!("shift_vars: shifted result = {:?}", result);
result