Skip to content

Commit a19cf18

Browse files
committed
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
2 parents c3b8ab5 + 9a2772a commit a19cf18

File tree

10 files changed

+71
-40
lines changed

10 files changed

+71
-40
lines changed

src/librustc/infer/at.rs

+15
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
2828
use super::*;
2929

30+
use crate::ty::Const;
3031
use crate::ty::relate::{Relate, TypeRelation};
3132

3233
pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
@@ -308,6 +309,20 @@ impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> {
308309
}
309310
}
310311

312+
impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> {
313+
fn to_trace(cause: &ObligationCause<'tcx>,
314+
a_is_expected: bool,
315+
a: Self,
316+
b: Self)
317+
-> TypeTrace<'tcx>
318+
{
319+
TypeTrace {
320+
cause: cause.clone(),
321+
values: Consts(ExpectedFound::new(a_is_expected, a, b))
322+
}
323+
}
324+
}
325+
311326
impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
312327
fn to_trace(cause: &ObligationCause<'tcx>,
313328
a_is_expected: bool,

src/librustc/infer/canonical/query_response.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
318318
obligations.extend(ok.into_obligations());
319319
}
320320

321-
(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
322-
unimplemented!() // FIXME(const_generics)
321+
(UnpackedKind::Const(v1), UnpackedKind::Const(v2)) => {
322+
let ok = self.at(cause, param_env).eq(v1, v2)?;
323+
obligations.extend(ok.into_obligations());
323324
}
324325

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

src/librustc/infer/error_reporting/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12601260
match *values {
12611261
infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found),
12621262
infer::Regions(ref exp_found) => self.expected_found_str(exp_found),
1263+
infer::Consts(ref exp_found) => self.expected_found_str(exp_found),
12631264
infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
12641265
infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found),
12651266
}

src/librustc/infer/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
232232
pub enum ValuePairs<'tcx> {
233233
Types(ExpectedFound<Ty<'tcx>>),
234234
Regions(ExpectedFound<ty::Region<'tcx>>),
235+
Consts(ExpectedFound<&'tcx ty::Const<'tcx>>),
235236
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
236237
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
237238
}
@@ -1730,6 +1731,7 @@ EnumTypeFoldableImpl! {
17301731
impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> {
17311732
(ValuePairs::Types)(a),
17321733
(ValuePairs::Regions)(a),
1734+
(ValuePairs::Consts)(a),
17331735
(ValuePairs::TraitRefs)(a),
17341736
(ValuePairs::PolyTraitRefs)(a),
17351737
}

src/librustc/ty/structural_impls.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use crate::hir::def::Namespace;
77
use crate::mir::ProjectionKind;
88
use crate::mir::interpret::ConstValue;
9-
use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid};
9+
use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
1010
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
1111
use crate::ty::print::{FmtPrinter, Printer};
1212
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -1352,8 +1352,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
13521352
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
13531353
match *self {
13541354
ConstValue::ByRef(ptr, alloc) => ConstValue::ByRef(ptr, alloc),
1355-
// FIXME(const_generics): implement TypeFoldable for InferConst
1356-
ConstValue::Infer(ic) => ConstValue::Infer(ic),
1355+
ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)),
13571356
ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
13581357
ConstValue::Placeholder(p) => ConstValue::Placeholder(p),
13591358
ConstValue::Scalar(a) => ConstValue::Scalar(a),
@@ -1366,8 +1365,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
13661365
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
13671366
match *self {
13681367
ConstValue::ByRef(..) => false,
1369-
// FIXME(const_generics): implement TypeFoldable for InferConst
1370-
ConstValue::Infer(_) => false,
1368+
ConstValue::Infer(ic) => ic.visit_with(visitor),
13711369
ConstValue::Param(p) => p.visit_with(visitor),
13721370
ConstValue::Placeholder(_) => false,
13731371
ConstValue::Scalar(_) => false,
@@ -1376,3 +1374,13 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
13761374
}
13771375
}
13781376
}
1377+
1378+
impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
1379+
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
1380+
*self
1381+
}
1382+
1383+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
1384+
false
1385+
}
1386+
}

src/librustc/ty/subst.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
618618
}
619619
};
620620

621-
// FIXME(const_generics): shift const through binders
622-
ct
621+
self.shift_vars_through_binders(ct)
623622
}
624623

625624
/// 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> {
664663
/// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
665664
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
666665
/// is that only in the second case have we passed through a fn binder.
667-
fn shift_vars_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
668-
debug!("shift_vars(ty={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
669-
ty, self.binders_passed, ty.has_escaping_bound_vars());
666+
fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
667+
debug!("shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
668+
val, self.binders_passed, val.has_escaping_bound_vars());
670669

671-
if self.binders_passed == 0 || !ty.has_escaping_bound_vars() {
672-
return ty;
670+
if self.binders_passed == 0 || !val.has_escaping_bound_vars() {
671+
return val;
673672
}
674673

675-
let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed);
674+
let result = ty::fold::shift_vars(self.tcx(), &val, self.binders_passed);
676675
debug!("shift_vars: shifted result = {:?}", result);
677676

678677
result

src/librustc_mir/monomorphize/item.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc::hir;
33
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
44
use rustc::mir::interpret::ConstValue;
55
use rustc::session::config::OptLevel;
6-
use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, ParamConst};
6+
use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts};
77
use rustc::ty::subst::{SubstsRef, InternalSubsts};
88
use syntax::ast;
99
use syntax::attr::InlineAttr;
@@ -240,11 +240,11 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
240240
}
241241

242242
// Pushes the type name of the specified type to the provided string.
243-
// If 'debug' is true, printing normally unprintable types is allowed
244-
// (e.g. ty::GeneratorWitness). This parameter should only be set when
245-
// this method is being used for logging purposes (e.g. with debug! or info!)
246-
// When being used for codegen purposes, 'debug' should be set to 'false'
247-
// in order to catch unexpected types that should never end up in a type name
243+
// If `debug` is true, printing normally unprintable types is allowed
244+
// (e.g. `ty::GeneratorWitness`). This parameter should only be set when
245+
// this method is being used for logging purposes (e.g. with `debug!` or `info!`)
246+
// When being used for codegen purposes, `debug` should be set to `false`
247+
// in order to catch unexpected types that should never end up in a type name.
248248
pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) {
249249
match t.sty {
250250
ty::Bool => output.push_str("bool"),
@@ -387,22 +387,34 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
387387
if debug {
388388
output.push_str(&format!("`{:?}`", t));
389389
} else {
390-
bug!("DefPathBasedNames: Trying to create type name for \
391-
unexpected type: {:?}", t);
390+
bug!(
391+
"DefPathBasedNames: trying to create type name for unexpected type: {:?}",
392+
t,
393+
);
392394
}
393395
}
394396
}
395397
}
396398

397-
// FIXME(const_generics): handle debug printing.
399+
// Pushes the the name of the specified const to the provided string.
400+
// If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed,
401+
// as well as the unprintable types of constants (see `push_type_name` for more details).
398402
pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) {
399403
match c.val {
400-
ConstValue::Infer(..) | ConstValue::Placeholder(_) => output.push_str("_"),
401-
ConstValue::Param(ParamConst { name, .. }) => {
402-
write!(output, "{}", name).unwrap();
404+
ConstValue::Scalar(..) | ConstValue::Slice(..) | ConstValue::ByRef(..) => {
405+
// FIXME(const_generics): we could probably do a better job here.
406+
write!(output, "{:?}", c).unwrap()
407+
}
408+
_ => {
409+
if debug {
410+
write!(output, "{:?}", c).unwrap()
411+
} else {
412+
bug!(
413+
"DefPathBasedNames: trying to create const name for unexpected const: {:?}",
414+
c,
415+
);
416+
}
403417
}
404-
ConstValue::Unevaluated(..) => output.push_str("_: _"),
405-
_ => write!(output, "{:?}", c).unwrap(),
406418
}
407419
output.push_str(": ");
408420
self.push_type_name(c.ty, output, debug);

src/librustc_typeck/check/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -5785,8 +5785,6 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
57855785
ty
57865786
);
57875787

5788-
// FIXME(const_generics): we probably want to check the bounds for const parameters too.
5789-
57905788
if own_counts.types == 0 {
57915789
return;
57925790
}

src/librustdoc/clean/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1706,9 +1706,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
17061706
}
17071707
Some(param.clean(cx))
17081708
}
1709-
ty::GenericParamDefKind::Const { .. } => {
1710-
unimplemented!() // FIXME(const_generics)
1711-
}
1709+
ty::GenericParamDefKind::Const { .. } => None,
17121710
}).collect::<Vec<GenericParamDef>>();
17131711

17141712
let mut where_predicates = preds.predicates.iter()

src/libsyntax/parse/parser.rs

-4
Original file line numberDiff line numberDiff line change
@@ -6045,10 +6045,6 @@ impl<'a> Parser<'a> {
60456045
});
60466046
assoc_ty_bindings.push(span);
60476047
} else if self.check_const_arg() {
6048-
// FIXME(const_generics): to distinguish between idents for types and consts,
6049-
// we should introduce a GenericArg::Ident in the AST and distinguish when
6050-
// lowering to the HIR. For now, idents for const args are not permitted.
6051-
60526048
// Parse const argument.
60536049
let expr = if let token::OpenDelim(token::Brace) = self.token {
60546050
self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())?

0 commit comments

Comments
 (0)