mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
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:
commit
a19cf18c7d
@ -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,
|
||||
|
@ -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,);
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -3,7 +3,7 @@ use rustc::hir;
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::mir::interpret::ConstValue;
|
||||
use rustc::session::config::OptLevel;
|
||||
use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, ParamConst};
|
||||
use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts};
|
||||
use rustc::ty::subst::{SubstsRef, InternalSubsts};
|
||||
use syntax::ast;
|
||||
use syntax::attr::InlineAttr;
|
||||
@ -240,11 +240,11 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Pushes the type name of the specified type to the provided string.
|
||||
// If 'debug' is true, printing normally unprintable types is allowed
|
||||
// (e.g. ty::GeneratorWitness). This parameter should only be set when
|
||||
// this method is being used for logging purposes (e.g. with debug! or info!)
|
||||
// When being used for codegen purposes, 'debug' should be set to 'false'
|
||||
// in order to catch unexpected types that should never end up in a type name
|
||||
// If `debug` is true, printing normally unprintable types is allowed
|
||||
// (e.g. `ty::GeneratorWitness`). This parameter should only be set when
|
||||
// this method is being used for logging purposes (e.g. with `debug!` or `info!`)
|
||||
// When being used for codegen purposes, `debug` should be set to `false`
|
||||
// in order to catch unexpected types that should never end up in a type name.
|
||||
pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
|
||||
match t.sty {
|
||||
ty::Bool => output.push_str("bool"),
|
||||
@ -387,22 +387,34 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
||||
if debug {
|
||||
output.push_str(&format!("`{:?}`", t));
|
||||
} else {
|
||||
bug!("DefPathBasedNames: Trying to create type name for \
|
||||
unexpected type: {:?}", t);
|
||||
bug!(
|
||||
"DefPathBasedNames: trying to create type name for unexpected type: {:?}",
|
||||
t,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(const_generics): handle debug printing.
|
||||
// Pushes the the name of the specified const to the provided string.
|
||||
// If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed,
|
||||
// as well as the unprintable types of constants (see `push_type_name` for more details).
|
||||
pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) {
|
||||
match c.val {
|
||||
ConstValue::Infer(..) | ConstValue::Placeholder(_) => output.push_str("_"),
|
||||
ConstValue::Param(ParamConst { name, .. }) => {
|
||||
write!(output, "{}", name).unwrap();
|
||||
ConstValue::Scalar(..) | ConstValue::Slice(..) | ConstValue::ByRef(..) => {
|
||||
// FIXME(const_generics): we could probably do a better job here.
|
||||
write!(output, "{:?}", c).unwrap()
|
||||
}
|
||||
_ => {
|
||||
if debug {
|
||||
write!(output, "{:?}", c).unwrap()
|
||||
} else {
|
||||
bug!(
|
||||
"DefPathBasedNames: trying to create const name for unexpected const: {:?}",
|
||||
c,
|
||||
);
|
||||
}
|
||||
}
|
||||
ConstValue::Unevaluated(..) => output.push_str("_: _"),
|
||||
_ => write!(output, "{:?}", c).unwrap(),
|
||||
}
|
||||
output.push_str(": ");
|
||||
self.push_type_name(c.ty, output, debug);
|
||||
|
@ -5785,8 +5785,6 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty
|
||||
);
|
||||
|
||||
// FIXME(const_generics): we probably want to check the bounds for const parameters too.
|
||||
|
||||
if own_counts.types == 0 {
|
||||
return;
|
||||
}
|
||||
|
@ -1706,9 +1706,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
||||
}
|
||||
Some(param.clean(cx))
|
||||
}
|
||||
ty::GenericParamDefKind::Const { .. } => {
|
||||
unimplemented!() // FIXME(const_generics)
|
||||
}
|
||||
ty::GenericParamDefKind::Const { .. } => None,
|
||||
}).collect::<Vec<GenericParamDef>>();
|
||||
|
||||
let mut where_predicates = preds.predicates.iter()
|
||||
|
@ -6045,10 +6045,6 @@ impl<'a> Parser<'a> {
|
||||
});
|
||||
assoc_ty_bindings.push(span);
|
||||
} else if self.check_const_arg() {
|
||||
// FIXME(const_generics): to distinguish between idents for types and consts,
|
||||
// we should introduce a GenericArg::Ident in the AST and distinguish when
|
||||
// lowering to the HIR. For now, idents for const args are not permitted.
|
||||
|
||||
// Parse const argument.
|
||||
let expr = if let token::OpenDelim(token::Brace) = self.token {
|
||||
self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())?
|
||||
|
Loading…
Reference in New Issue
Block a user