Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add const generics to ty (and transitive dependencies) #58583

Merged
merged 34 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
62f23c2
Add Const generic param to ty
varkor Feb 20, 2019
11c31bb
Add ParamConst
varkor Feb 20, 2019
a36d386
Add ConstVid
varkor Feb 20, 2019
8cbbbaa
Add InferConst
varkor Feb 20, 2019
386e9fb
Add type_flags helper methods to consts
varkor Feb 20, 2019
2ce19ae
Use non_erasable_generics for codegen
varkor Feb 20, 2019
691d054
Take const generics into account when monomorphising
varkor Feb 20, 2019
1ebc858
Add const kind and UnpackedKind::Const
varkor Feb 20, 2019
7f2a4f7
Add ConstValue::Param and ConstValue::Infer
varkor Feb 20, 2019
f7f60ee
Add type constraints from const parameters
varkor Feb 20, 2019
73a6df6
Update diagnostics to include const parameters
varkor Feb 20, 2019
9a9aa5b
Implement Hash for new types
varkor Feb 20, 2019
63b7572
Stub methods in infer
varkor Feb 20, 2019
29c272d
Take const into account in context
varkor Feb 20, 2019
cbf5d22
Add const type flags
varkor Feb 20, 2019
0d1c9c0
Pretty printing for const generics
varkor Feb 20, 2019
f761c41
Make a lazy const from a const param
varkor Feb 20, 2019
f7cd97f
Add ast_const_to_const
varkor Feb 20, 2019
a8361eb
Refactor compare_method
varkor Feb 20, 2019
3001ae7
Implement wfcheck for const parameters
varkor Feb 20, 2019
eb2b8be
Implement collect for const parameters
varkor Feb 20, 2019
fc0fbe8
Stub rustdoc const generics implementations
varkor Feb 20, 2019
133e776
Add HAS_CT_INFER
varkor Feb 20, 2019
2dfde88
Implement structural_impls for const generics
varkor Feb 20, 2019
8e56729
Handle new ConstValue variants in mir
varkor Feb 20, 2019
c236c24
Handle const generics in typeck
varkor Feb 20, 2019
54b935b
Handle const generics elsewhere
varkor Feb 20, 2019
4c18ee4
Update const generics tests
varkor Feb 20, 2019
3e3a421
Update test fallout
varkor Feb 20, 2019
162405f
Fix negative integer literal test
varkor Feb 20, 2019
0da0457
Clean up some generic substs handling
varkor Feb 20, 2019
5c8b3c3
Fix rebase fallout
varkor Mar 5, 2019
ed9227a
Make adjustments for comments
varkor Mar 5, 2019
de4478a
Refactor const_to_op
varkor Mar 6, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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