Skip to content

Commit 88f755f

Browse files
committed
Auto merge of #58583 - varkor:const-generics-ty, r=oli-obk
Add const generics to ty (and transitive dependencies) Split out from #53645. This work is a collaborative effort with @yodaldevoid. There are a number of stubs. Some I plan to leave for the next PRs (e.g. `infer` and `rustdoc`). Others I can either fix up in this PR, or as follow ups (which would avoid the time-consuming rebasing). It was a little hard to split this up, as so much depends on ty and friends. Apologies for the large diff. r? @eddyb
2 parents f22dca0 + de4478a commit 88f755f

File tree

74 files changed

+1201
-412
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1201
-412
lines changed

src/librustc/ich/impls_ty.rs

+27
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ for ty::subst::UnpackedKind<'gcx> {
7474
match self {
7575
ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
7676
ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
77+
ty::subst::UnpackedKind::Const(ct) => ct.hash_stable(hcx, hasher),
7778
}
7879
}
7980
}
@@ -134,6 +135,15 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
134135
}
135136
}
136137

138+
impl<'gcx, 'tcx> HashStable<StableHashingContext<'gcx>> for ty::ConstVid<'tcx> {
139+
#[inline]
140+
fn hash_stable<W: StableHasherResult>(&self,
141+
hcx: &mut StableHashingContext<'gcx>,
142+
hasher: &mut StableHasher<W>) {
143+
self.index.hash_stable(hcx, hasher);
144+
}
145+
}
146+
137147
impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundVar {
138148
#[inline]
139149
fn hash_stable<W: StableHasherResult>(&self,
@@ -297,6 +307,14 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::VariantFlags {
297307
}
298308
}
299309

310+
impl_stable_hash_for!(
311+
impl<'tcx> for enum ty::InferConst<'tcx> [ ty::InferConst ] {
312+
Var(vid),
313+
Fresh(i),
314+
Canonical(debruijn, var),
315+
}
316+
);
317+
300318
impl_stable_hash_for!(enum ty::VariantDiscr {
301319
Explicit(def_id),
302320
Relative(distance)
@@ -310,11 +328,14 @@ impl_stable_hash_for!(struct ty::FieldDef {
310328

311329
impl_stable_hash_for!(
312330
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
331+
Param(param),
332+
Infer(infer),
313333
Scalar(val),
314334
Slice(a, b),
315335
ByRef(ptr, alloc),
316336
}
317337
);
338+
318339
impl_stable_hash_for!(struct crate::mir::interpret::RawConst<'tcx> {
319340
alloc_id,
320341
ty,
@@ -518,6 +539,7 @@ impl_stable_hash_for!(struct ty::GenericParamDef {
518539
impl_stable_hash_for!(enum ty::GenericParamDefKind {
519540
Lifetime,
520541
Type { has_default, object_lifetime_default, synthetic },
542+
Const,
521543
});
522544

523545
impl_stable_hash_for!(
@@ -736,6 +758,11 @@ for ty::FloatVid
736758
}
737759
}
738760

761+
impl_stable_hash_for!(struct ty::ParamConst {
762+
index,
763+
name
764+
});
765+
739766
impl_stable_hash_for!(struct ty::ParamTy {
740767
idx,
741768
name

src/librustc/infer/canonical/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,9 @@ impl<'tcx> CanonicalVarValues<'tcx> {
443443
UnpackedKind::Lifetime(..) => tcx.mk_region(
444444
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))
445445
).into(),
446+
UnpackedKind::Const(..) => {
447+
unimplemented!() // FIXME(const_generics)
448+
}
446449
})
447450
.collect()
448451
}

src/librustc/infer/canonical/query_response.rs

+15
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
315315
obligations.extend(ok.into_obligations());
316316
}
317317

318+
(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
319+
unimplemented!() // FIXME(const_generics)
320+
}
321+
318322
_ => {
319323
bug!(
320324
"kind mismatch, cannot unify {:?} and {:?}",
@@ -473,6 +477,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
473477
opt_values[br.assert_bound_var()] = Some(*original_value);
474478
}
475479
}
480+
UnpackedKind::Const(..) => {
481+
unimplemented!() // FIXME(const_generics)
482+
}
476483
}
477484
}
478485

@@ -568,6 +575,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
568575
ty::OutlivesPredicate(t1, r2)
569576
)
570577
),
578+
UnpackedKind::Const(..) => {
579+
// Consts cannot outlive one another, so we don't expect to
580+
// ecounter this branch.
581+
span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
582+
}
571583
}
572584
)
573585
})
@@ -602,6 +614,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
602614
obligations
603615
.extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
604616
}
617+
(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
618+
unimplemented!() // FIXME(const_generics)
619+
}
605620
_ => {
606621
bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
607622
}

src/librustc/infer/combine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
449449

450450
let origin = *variables.var_origin(vid);
451451
let new_var_id = variables.new_var(self.for_universe, false, origin);
452-
let u = self.tcx().mk_var(new_var_id);
452+
let u = self.tcx().mk_ty_var(new_var_id);
453453
debug!("generalize: replacing original vid={:?} with new={:?}",
454454
vid, u);
455455
return Ok(u);

src/librustc/infer/error_reporting/mod.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -691,17 +691,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
691691
) -> SubstsRef<'tcx> {
692692
let generics = self.tcx.generics_of(def_id);
693693
let mut num_supplied_defaults = 0;
694-
let mut type_params = generics
695-
.params
696-
.iter()
697-
.rev()
698-
.filter_map(|param| match param.kind {
699-
ty::GenericParamDefKind::Lifetime => None,
700-
ty::GenericParamDefKind::Type { has_default, .. } => {
701-
Some((param.def_id, has_default))
702-
}
703-
})
704-
.peekable();
694+
let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind {
695+
ty::GenericParamDefKind::Lifetime => None,
696+
ty::GenericParamDefKind::Type { has_default, .. } => Some((param.def_id, has_default)),
697+
ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
698+
}).peekable();
705699
let has_default = {
706700
let has_default = type_params.peek().map(|(_, has_default)| has_default);
707701
*has_default.unwrap_or(&false)

src/librustc/infer/mod.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
656656
type_variables
657657
.unsolved_variables()
658658
.into_iter()
659-
.map(|t| self.tcx.mk_var(t))
659+
.map(|t| self.tcx.mk_ty_var(t))
660660
.chain(
661661
(0..int_unification_table.len())
662662
.map(|i| ty::IntVid { index: i as u32 })
@@ -981,7 +981,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
981981
}
982982

983983
pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
984-
self.tcx.mk_var(self.next_ty_var_id(false, origin))
984+
self.tcx.mk_ty_var(self.next_ty_var_id(false, origin))
985985
}
986986

987987
pub fn next_ty_var_in_universe(
@@ -992,11 +992,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
992992
let vid = self.type_variables
993993
.borrow_mut()
994994
.new_var(universe, false, origin);
995-
self.tcx.mk_var(vid)
995+
self.tcx.mk_ty_var(vid)
996996
}
997997

998998
pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
999-
self.tcx.mk_var(self.next_ty_var_id(true, origin))
999+
self.tcx.mk_ty_var(self.next_ty_var_id(true, origin))
10001000
}
10011001

10021002
pub fn next_int_var_id(&self) -> IntVid {
@@ -1081,7 +1081,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10811081
TypeVariableOrigin::TypeParameterDefinition(span, param.name),
10821082
);
10831083

1084-
self.tcx.mk_var(ty_var_id).into()
1084+
self.tcx.mk_ty_var(ty_var_id).into()
1085+
}
1086+
GenericParamDefKind::Const { .. } => {
1087+
unimplemented!() // FIXME(const_generics)
10851088
}
10861089
}
10871090
}

src/librustc/infer/nll_relate/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ where
310310
ty::Projection(projection_ty)
311311
if D::normalization() == NormalizationStrategy::Lazy =>
312312
{
313-
return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_var(vid)));
313+
return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid)));
314314
}
315315

316316
_ => (),
@@ -764,7 +764,7 @@ where
764764
// the universe `_universe`.
765765
let new_var_id = variables.new_var(self.universe, false, origin);
766766

767-
let u = self.tcx().mk_var(new_var_id);
767+
let u = self.tcx().mk_ty_var(new_var_id);
768768
debug!(
769769
"generalize: replacing original vid={:?} with new={:?}",
770770
vid,

src/librustc/infer/opaque_types/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
381381
substs,
382382
item_def_id: _,
383383
}) => {
384-
for r in substs.regions() {
385-
bound_region(r);
384+
for k in substs {
385+
match k.unpack() {
386+
UnpackedKind::Lifetime(lt) => bound_region(lt),
387+
UnpackedKind::Type(ty) => types.push(ty),
388+
UnpackedKind::Const(_) => {
389+
// Const parameters don't impose constraints.
390+
}
391+
}
386392
}
387-
types.extend(substs.types());
388393
}
389394

390395
Component::EscapingProjection(more_components) => {

src/librustc/infer/outlives/obligations.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ use crate::hir;
6767
use crate::traits::ObligationCause;
6868
use crate::ty::outlives::Component;
6969
use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
70+
use crate::ty::subst::UnpackedKind;
7071

7172
impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
7273
/// Registers that the given region obligation must be resolved
@@ -430,13 +431,18 @@ where
430431
if approx_env_bounds.is_empty() && trait_bounds.is_empty() && needs_infer {
431432
debug!("projection_must_outlive: no declared bounds");
432433

433-
for component_ty in projection_ty.substs.types() {
434-
self.type_must_outlive(origin.clone(), component_ty, region);
435-
}
436-
437-
for r in projection_ty.substs.regions() {
438-
self.delegate
439-
.push_sub_region_constraint(origin.clone(), region, r);
434+
for k in projection_ty.substs {
435+
match k.unpack() {
436+
UnpackedKind::Lifetime(lt) => {
437+
self.delegate.push_sub_region_constraint(origin.clone(), region, lt);
438+
}
439+
UnpackedKind::Type(ty) => {
440+
self.type_must_outlive(origin.clone(), ty, region);
441+
}
442+
UnpackedKind::Const(_) => {
443+
// Const parameters don't impose constraints.
444+
}
445+
}
440446
}
441447

442448
return;

src/librustc/middle/resolve_lifetime.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1974,7 +1974,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
19741974
object_lifetime_default,
19751975
..
19761976
} => Some(object_lifetime_default),
1977-
GenericParamDefKind::Lifetime => None,
1977+
GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
19781978
})
19791979
.collect()
19801980
})

src/librustc/mir/interpret/value.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::fmt;
22

3-
use crate::ty::{Ty, layout::{HasDataLayout, Size}};
3+
use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}};
44

55
use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate};
66

@@ -17,6 +17,12 @@ pub struct RawConst<'tcx> {
1717
/// match the `LocalState` optimizations for easy conversions between `Value` and `ConstValue`.
1818
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
1919
pub enum ConstValue<'tcx> {
20+
/// A const generic parameter.
21+
Param(ParamConst),
22+
23+
/// Infer the value of the const.
24+
Infer(InferConst<'tcx>),
25+
2026
/// Used only for types with `layout::abi::Scalar` ABI and ZSTs.
2127
///
2228
/// Not using the enum `Value` to encode that this must not be `Undef`.
@@ -43,6 +49,8 @@ impl<'tcx> ConstValue<'tcx> {
4349
#[inline]
4450
pub fn try_to_scalar(&self) -> Option<Scalar> {
4551
match *self {
52+
ConstValue::Param(_) |
53+
ConstValue::Infer(_) |
4654
ConstValue::ByRef(..) |
4755
ConstValue::Slice(..) => None,
4856
ConstValue::Scalar(val) => Some(val),

src/librustc/traits/error_reporting.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
389389

390390
for param in generics.params.iter() {
391391
let value = match param.kind {
392-
GenericParamDefKind::Type {..} => {
392+
GenericParamDefKind::Type { .. } |
393+
GenericParamDefKind::Const => {
393394
trait_ref.substs[param.index as usize].to_string()
394395
},
395396
GenericParamDefKind::Lifetime => continue,

src/librustc/traits/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,8 @@ fn vtable_methods<'a, 'tcx>(
10101010
InternalSubsts::for_item(tcx, def_id, |param, _|
10111011
match param.kind {
10121012
GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
1013-
GenericParamDefKind::Type {..} => {
1013+
GenericParamDefKind::Type { .. } |
1014+
GenericParamDefKind::Const => {
10141015
trait_ref.substs[param.index as usize]
10151016
}
10161017
}

src/librustc/traits/object_safety.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
310310
}
311311

312312
// We can't monomorphize things like `fn foo<A>(...)`.
313-
if self.generics_of(method.def_id).own_counts().types != 0 {
313+
let own_counts = self.generics_of(method.def_id).own_counts();
314+
if own_counts.types + own_counts.consts != 0 {
314315
return Some(MethodViolationCode::Generic);
315316
}
316317

src/librustc/traits/on_unimplemented.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
280280
let generics = tcx.generics_of(trait_ref.def_id);
281281
let generic_map = generics.params.iter().filter_map(|param| {
282282
let value = match param.kind {
283-
GenericParamDefKind::Type {..} => {
283+
GenericParamDefKind::Type { .. } |
284+
GenericParamDefKind::Const => {
284285
trait_ref.substs[param.index as usize].to_string()
285286
},
286287
GenericParamDefKind::Lifetime => return None

0 commit comments

Comments
 (0)