Skip to content

Commit

Permalink
Auto merge of #58583 - varkor:const-generics-ty, r=oli-obk
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Mar 7, 2019
2 parents f22dca0 + de4478a commit 88f755f
Show file tree
Hide file tree
Showing 74 changed files with 1,201 additions and 412 deletions.
27 changes: 27 additions & 0 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ for ty::subst::UnpackedKind<'gcx> {
match self {
ty::subst::UnpackedKind::Lifetime(lt) => lt.hash_stable(hcx, hasher),
ty::subst::UnpackedKind::Type(ty) => ty.hash_stable(hcx, hasher),
ty::subst::UnpackedKind::Const(ct) => ct.hash_stable(hcx, hasher),
}
}
}
Expand Down Expand Up @@ -134,6 +135,15 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
}
}

impl<'gcx, 'tcx> HashStable<StableHashingContext<'gcx>> for ty::ConstVid<'tcx> {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
self.index.hash_stable(hcx, hasher);
}
}

impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundVar {
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
Expand Down Expand Up @@ -297,6 +307,14 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::VariantFlags {
}
}

impl_stable_hash_for!(
impl<'tcx> for enum ty::InferConst<'tcx> [ ty::InferConst ] {
Var(vid),
Fresh(i),
Canonical(debruijn, var),
}
);

impl_stable_hash_for!(enum ty::VariantDiscr {
Explicit(def_id),
Relative(distance)
Expand All @@ -310,11 +328,14 @@ impl_stable_hash_for!(struct ty::FieldDef {

impl_stable_hash_for!(
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
Param(param),
Infer(infer),
Scalar(val),
Slice(a, b),
ByRef(ptr, alloc),
}
);

impl_stable_hash_for!(struct crate::mir::interpret::RawConst<'tcx> {
alloc_id,
ty,
Expand Down Expand Up @@ -518,6 +539,7 @@ impl_stable_hash_for!(struct ty::GenericParamDef {
impl_stable_hash_for!(enum ty::GenericParamDefKind {
Lifetime,
Type { has_default, object_lifetime_default, synthetic },
Const,
});

impl_stable_hash_for!(
Expand Down Expand Up @@ -736,6 +758,11 @@ for ty::FloatVid
}
}

impl_stable_hash_for!(struct ty::ParamConst {
index,
name
});

impl_stable_hash_for!(struct ty::ParamTy {
idx,
name
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/infer/canonical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ impl<'tcx> CanonicalVarValues<'tcx> {
UnpackedKind::Lifetime(..) => tcx.mk_region(
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(i))
).into(),
UnpackedKind::Const(..) => {
unimplemented!() // FIXME(const_generics)
}
})
.collect()
}
Expand Down
15 changes: 15 additions & 0 deletions src/librustc/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
obligations.extend(ok.into_obligations());
}

(UnpackedKind::Const(..), UnpackedKind::Const(..)) => {
unimplemented!() // FIXME(const_generics)
}

_ => {
bug!(
"kind mismatch, cannot unify {:?} and {:?}",
Expand Down Expand Up @@ -473,6 +477,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
opt_values[br.assert_bound_var()] = Some(*original_value);
}
}
UnpackedKind::Const(..) => {
unimplemented!() // FIXME(const_generics)
}
}
}

Expand Down Expand Up @@ -568,6 +575,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
ty::OutlivesPredicate(t1, r2)
)
),
UnpackedKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
// ecounter this branch.
span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
}
}
)
})
Expand Down Expand Up @@ -602,6 +614,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)
}
_ => {
bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '

let origin = *variables.var_origin(vid);
let new_var_id = variables.new_var(self.for_universe, false, origin);
let u = self.tcx().mk_var(new_var_id);
let u = self.tcx().mk_ty_var(new_var_id);
debug!("generalize: replacing original vid={:?} with new={:?}",
vid, u);
return Ok(u);
Expand Down
16 changes: 5 additions & 11 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,17 +691,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
) -> SubstsRef<'tcx> {
let generics = self.tcx.generics_of(def_id);
let mut num_supplied_defaults = 0;
let mut type_params = generics
.params
.iter()
.rev()
.filter_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { has_default, .. } => {
Some((param.def_id, has_default))
}
})
.peekable();
let mut type_params = generics.params.iter().rev().filter_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => None,
ty::GenericParamDefKind::Type { has_default, .. } => Some((param.def_id, has_default)),
ty::GenericParamDefKind::Const => None, // FIXME(const_generics:defaults)
}).peekable();
let has_default = {
let has_default = type_params.peek().map(|(_, has_default)| has_default);
*has_default.unwrap_or(&false)
Expand Down
13 changes: 8 additions & 5 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
type_variables
.unsolved_variables()
.into_iter()
.map(|t| self.tcx.mk_var(t))
.map(|t| self.tcx.mk_ty_var(t))
.chain(
(0..int_unification_table.len())
.map(|i| ty::IntVid { index: i as u32 })
Expand Down Expand Up @@ -981,7 +981,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}

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

pub fn next_ty_var_in_universe(
Expand All @@ -992,11 +992,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let vid = self.type_variables
.borrow_mut()
.new_var(universe, false, origin);
self.tcx.mk_var(vid)
self.tcx.mk_ty_var(vid)
}

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

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

self.tcx.mk_var(ty_var_id).into()
self.tcx.mk_ty_var(ty_var_id).into()
}
GenericParamDefKind::Const { .. } => {
unimplemented!() // FIXME(const_generics)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ where
ty::Projection(projection_ty)
if D::normalization() == NormalizationStrategy::Lazy =>
{
return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_var(vid)));
return Ok(self.relate_projection_ty(projection_ty, self.infcx.tcx.mk_ty_var(vid)));
}

_ => (),
Expand Down Expand Up @@ -764,7 +764,7 @@ where
// the universe `_universe`.
let new_var_id = variables.new_var(self.universe, false, origin);

let u = self.tcx().mk_var(new_var_id);
let u = self.tcx().mk_ty_var(new_var_id);
debug!(
"generalize: replacing original vid={:?} with new={:?}",
vid,
Expand Down
11 changes: 8 additions & 3 deletions src/librustc/infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
substs,
item_def_id: _,
}) => {
for r in substs.regions() {
bound_region(r);
for k in substs {
match k.unpack() {
UnpackedKind::Lifetime(lt) => bound_region(lt),
UnpackedKind::Type(ty) => types.push(ty),
UnpackedKind::Const(_) => {
// Const parameters don't impose constraints.
}
}
}
types.extend(substs.types());
}

Component::EscapingProjection(more_components) => {
Expand Down
20 changes: 13 additions & 7 deletions src/librustc/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ use crate::hir;
use crate::traits::ObligationCause;
use crate::ty::outlives::Component;
use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
use crate::ty::subst::UnpackedKind;

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

for component_ty in projection_ty.substs.types() {
self.type_must_outlive(origin.clone(), component_ty, region);
}

for r in projection_ty.substs.regions() {
self.delegate
.push_sub_region_constraint(origin.clone(), region, r);
for k in projection_ty.substs {
match k.unpack() {
UnpackedKind::Lifetime(lt) => {
self.delegate.push_sub_region_constraint(origin.clone(), region, lt);
}
UnpackedKind::Type(ty) => {
self.type_must_outlive(origin.clone(), ty, region);
}
UnpackedKind::Const(_) => {
// Const parameters don't impose constraints.
}
}
}

return;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1974,7 +1974,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
object_lifetime_default,
..
} => Some(object_lifetime_default),
GenericParamDefKind::Lifetime => None,
GenericParamDefKind::Lifetime | GenericParamDefKind::Const => None,
})
.collect()
})
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/mir/interpret/value.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt;

use crate::ty::{Ty, layout::{HasDataLayout, Size}};
use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}};

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

Expand All @@ -17,6 +17,12 @@ pub struct RawConst<'tcx> {
/// match the `LocalState` optimizations for easy conversions between `Value` and `ConstValue`.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
pub enum ConstValue<'tcx> {
/// A const generic parameter.
Param(ParamConst),

/// Infer the value of the const.
Infer(InferConst<'tcx>),

/// Used only for types with `layout::abi::Scalar` ABI and ZSTs.
///
/// Not using the enum `Value` to encode that this must not be `Undef`.
Expand All @@ -43,6 +49,8 @@ impl<'tcx> ConstValue<'tcx> {
#[inline]
pub fn try_to_scalar(&self) -> Option<Scalar> {
match *self {
ConstValue::Param(_) |
ConstValue::Infer(_) |
ConstValue::ByRef(..) |
ConstValue::Slice(..) => None,
ConstValue::Scalar(val) => Some(val),
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

for param in generics.params.iter() {
let value = match param.kind {
GenericParamDefKind::Type {..} => {
GenericParamDefKind::Type { .. } |
GenericParamDefKind::Const => {
trait_ref.substs[param.index as usize].to_string()
},
GenericParamDefKind::Lifetime => continue,
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,8 @@ fn vtable_methods<'a, 'tcx>(
InternalSubsts::for_item(tcx, def_id, |param, _|
match param.kind {
GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
GenericParamDefKind::Type {..} => {
GenericParamDefKind::Type { .. } |
GenericParamDefKind::Const => {
trait_ref.substs[param.index as usize]
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
}

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

Expand Down
3 changes: 2 additions & 1 deletion src/librustc/traits/on_unimplemented.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
let generics = tcx.generics_of(trait_ref.def_id);
let generic_map = generics.params.iter().filter_map(|param| {
let value = match param.kind {
GenericParamDefKind::Type {..} => {
GenericParamDefKind::Type { .. } |
GenericParamDefKind::Const => {
trait_ref.substs[param.index as usize].to_string()
},
GenericParamDefKind::Lifetime => return None
Expand Down
Loading

0 comments on commit 88f755f

Please sign in to comment.