Skip to content

Commit e577e49

Browse files
committed
Auto merge of #60058 - varkor:const-generics-ty-refactor, r=cramertj
Make const parameters enforce no variance constraints Fixes #60047. Also includes some minor const refactoring for convenience.
2 parents be1dbaf + 318a10e commit e577e49

File tree

8 files changed

+47
-38
lines changed

8 files changed

+47
-38
lines changed

src/librustc/ty/mod.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -934,12 +934,10 @@ impl<'a, 'gcx, 'tcx> Generics {
934934
}
935935

936936
pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
937-
for param in &self.params {
938-
match param.kind {
939-
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
940-
GenericParamDefKind::Lifetime => {}
941-
}
937+
if self.own_requires_monomorphization() {
938+
return true;
942939
}
940+
943941
if let Some(parent_def_id) = self.parent {
944942
let parent = tcx.generics_of(parent_def_id);
945943
parent.requires_monomorphization(tcx)
@@ -948,6 +946,16 @@ impl<'a, 'gcx, 'tcx> Generics {
948946
}
949947
}
950948

949+
pub fn own_requires_monomorphization(&self) -> bool {
950+
for param in &self.params {
951+
match param.kind {
952+
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
953+
GenericParamDefKind::Lifetime => {}
954+
}
955+
}
956+
false
957+
}
958+
951959
pub fn region_param(&'tcx self,
952960
param: &EarlyBoundRegion,
953961
tcx: TyCtxt<'a, 'gcx, 'tcx>)

src/librustc_mir/monomorphize/collector.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,8 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
480480
let type_length_limit = *tcx.sess.type_length_limit.get();
481481
// We include the const length in the type length, as it's better
482482
// to be overly conservative.
483+
// FIXME(const_generics): we should instead uniformly walk through `substs`,
484+
// ignoring lifetimes.
483485
if type_length + const_length > type_length_limit {
484486
// The instance name is already known to be too long for rustc.
485487
// Show only the first and last 32 characters to avoid blasting
@@ -1135,8 +1137,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11351137
continue;
11361138
}
11371139

1138-
let counts = tcx.generics_of(method.def_id).own_counts();
1139-
if counts.types + counts.consts != 0 {
1140+
if tcx.generics_of(method.def_id).own_requires_monomorphization() {
11401141
continue;
11411142
}
11421143

src/librustc_mir/transform/check_unsafety.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -560,8 +560,7 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D
560560

561561
// FIXME: when we make this a hard error, this should have its
562562
// own error code.
563-
let counts = tcx.generics_of(def_id).own_counts();
564-
let message = if counts.types + counts.consts != 0 {
563+
let message = if tcx.generics_of(def_id).own_requires_monomorphization() {
565564
"#[derive] can't be used on a #[repr(packed)] struct with \
566565
type or const parameters (error E0133)".to_string()
567566
} else {

src/librustc_typeck/variance/constraints.rs

+5-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
//! We walk the set of items and, for each member, generate new constraints.
55
66
use hir::def_id::DefId;
7-
use rustc::mir::interpret::ConstValue;
87
use rustc::ty::subst::{SubstsRef, UnpackedKind};
98
use rustc::ty::{self, Ty, TyCtxt};
109
use rustc::hir;
@@ -239,8 +238,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
239238
UnpackedKind::Type(ty) => {
240239
self.add_constraints_from_ty(current, ty, variance_i)
241240
}
242-
UnpackedKind::Const(ct) => {
243-
self.add_constraints_from_const(current, ct, variance_i)
241+
UnpackedKind::Const(_) => {
242+
// Consts impose no constraints.
244243
}
245244
}
246245
}
@@ -275,9 +274,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
275274
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
276275
}
277276

278-
ty::Array(typ, len) => {
277+
ty::Array(typ, _) => {
279278
self.add_constraints_from_ty(current, typ, variance);
280-
self.add_constraints_from_const(current, len, variance);
281279
}
282280

283281
ty::Slice(typ) => {
@@ -395,8 +393,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
395393
UnpackedKind::Type(ty) => {
396394
self.add_constraints_from_ty(current, ty, variance_i)
397395
}
398-
UnpackedKind::Const(ct) => {
399-
self.add_constraints_from_const(current, ct, variance_i)
396+
UnpackedKind::Const(_) => {
397+
// Consts impose no constraints.
400398
}
401399
}
402400
}
@@ -449,24 +447,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
449447
}
450448
}
451449

452-
fn add_constraints_from_const(
453-
&mut self,
454-
current: &CurrentItem,
455-
ct: &ty::Const<'tcx>,
456-
variance: VarianceTermPtr<'a>
457-
) {
458-
debug!(
459-
"add_constraints_from_const(ct={:?}, variance={:?})",
460-
ct,
461-
variance
462-
);
463-
464-
self.add_constraints_from_ty(current, ct.ty, variance);
465-
if let ConstValue::Param(ref data) = ct.val {
466-
self.add_constraint(current, data.index, variance);
467-
}
468-
}
469-
470450
/// Adds constraints appropriate for a mutability-type pair
471451
/// appearing in a context with ambient variance `variance`
472452
fn add_constraints_from_mt(&mut self,

src/librustc_typeck/variance/solve.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,19 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
8585
self.terms_cx.inferred_starts.iter().map(|(&id, &InferredIndex(start))| {
8686
let def_id = tcx.hir().local_def_id_from_hir_id(id);
8787
let generics = tcx.generics_of(def_id);
88+
let count = generics.count();
8889

89-
let mut variances = solutions[start..start+generics.count()].to_vec();
90-
90+
let mut variances = solutions[start..(start + count)].to_vec();
9191
debug!("id={} variances={:?}", id, variances);
9292

93-
// Functions can have unused type parameters: make those invariant.
93+
// Const parameters are always invariant.
94+
for (idx, param) in generics.params.iter().enumerate() {
95+
if let ty::GenericParamDefKind::Const = param.kind {
96+
variances[idx] = ty::Invariant;
97+
}
98+
}
99+
100+
// Functions are permitted to have unused generic parameters: make those invariant.
94101
if let ty::FnDef(..) = tcx.type_of(def_id).sty {
95102
for variance in &mut variances {
96103
if *variance == ty::Bivariant {

src/librustc_typeck/variance/terms.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
119119
// for a particular item are assigned continuous indices.
120120

121121
let arena = self.arena;
122-
self.inferred_terms.extend((start..start+count).map(|i| {
122+
self.inferred_terms.extend((start..(start + count)).map(|i| {
123123
&*arena.alloc(InferredTerm(InferredIndex(i)))
124124
}));
125125
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-pass
2+
3+
#![feature(const_generics)]
4+
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
5+
6+
struct A<const N: usize>; // ok
7+
8+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2+
--> $DIR/unused-const-param.rs:3:12
3+
|
4+
LL | #![feature(const_generics)]
5+
| ^^^^^^^^^^^^^^
6+

0 commit comments

Comments
 (0)