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

Make const parameters enforce no variance constraints #60058

Merged
merged 4 commits into from
Apr 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 13 additions & 5 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,12 +934,10 @@ impl<'a, 'gcx, 'tcx> Generics {
}

pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
for param in &self.params {
match param.kind {
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
GenericParamDefKind::Lifetime => {}
}
if self.own_requires_monomorphization() {
return true;
}

if let Some(parent_def_id) = self.parent {
let parent = tcx.generics_of(parent_def_id);
parent.requires_monomorphization(tcx)
Expand All @@ -948,6 +946,16 @@ impl<'a, 'gcx, 'tcx> Generics {
}
}

pub fn own_requires_monomorphization(&self) -> bool {
for param in &self.params {
match param.kind {
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => return true,
GenericParamDefKind::Lifetime => {}
}
}
false
}

pub fn region_param(&'tcx self,
param: &EarlyBoundRegion,
tcx: TyCtxt<'a, 'gcx, 'tcx>)
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_mir/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let type_length_limit = *tcx.sess.type_length_limit.get();
// We include the const length in the type length, as it's better
// to be overly conservative.
// FIXME(const_generics): we should instead uniformly walk through `substs`,
// ignoring lifetimes.
if type_length + const_length > type_length_limit {
// The instance name is already known to be too long for rustc.
// Show only the first and last 32 characters to avoid blasting
Expand Down Expand Up @@ -1135,8 +1137,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
continue;
}

let counts = tcx.generics_of(method.def_id).own_counts();
if counts.types + counts.consts != 0 {
if tcx.generics_of(method.def_id).own_requires_monomorphization() {
continue;
}

Expand Down
3 changes: 1 addition & 2 deletions src/librustc_mir/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,7 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D

// FIXME: when we make this a hard error, this should have its
// own error code.
let counts = tcx.generics_of(def_id).own_counts();
let message = if counts.types + counts.consts != 0 {
let message = if tcx.generics_of(def_id).own_requires_monomorphization() {
"#[derive] can't be used on a #[repr(packed)] struct with \
type or const parameters (error E0133)".to_string()
} else {
Expand Down
30 changes: 5 additions & 25 deletions src/librustc_typeck/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
//! We walk the set of items and, for each member, generate new constraints.

use hir::def_id::DefId;
use rustc::mir::interpret::ConstValue;
use rustc::ty::subst::{SubstsRef, UnpackedKind};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::hir;
Expand Down Expand Up @@ -239,8 +238,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
UnpackedKind::Type(ty) => {
self.add_constraints_from_ty(current, ty, variance_i)
}
UnpackedKind::Const(ct) => {
self.add_constraints_from_const(current, ct, variance_i)
UnpackedKind::Const(_) => {
// Consts impose no constraints.
}
}
}
Expand Down Expand Up @@ -275,9 +274,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
}

ty::Array(typ, len) => {
ty::Array(typ, _) => {
self.add_constraints_from_ty(current, typ, variance);
self.add_constraints_from_const(current, len, variance);
}

ty::Slice(typ) => {
Expand Down Expand Up @@ -395,8 +393,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
UnpackedKind::Type(ty) => {
self.add_constraints_from_ty(current, ty, variance_i)
}
UnpackedKind::Const(ct) => {
self.add_constraints_from_const(current, ct, variance_i)
UnpackedKind::Const(_) => {
// Consts impose no constraints.
}
}
}
Expand Down Expand Up @@ -449,24 +447,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
}

fn add_constraints_from_const(
&mut self,
current: &CurrentItem,
ct: &ty::Const<'tcx>,
variance: VarianceTermPtr<'a>
) {
debug!(
"add_constraints_from_const(ct={:?}, variance={:?})",
ct,
variance
);

self.add_constraints_from_ty(current, ct.ty, variance);
if let ConstValue::Param(ref data) = ct.val {
self.add_constraint(current, data.index, variance);
}
}

/// Adds constraints appropriate for a mutability-type pair
/// appearing in a context with ambient variance `variance`
fn add_constraints_from_mt(&mut self,
Expand Down
13 changes: 10 additions & 3 deletions src/librustc_typeck/variance/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,19 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
self.terms_cx.inferred_starts.iter().map(|(&id, &InferredIndex(start))| {
let def_id = tcx.hir().local_def_id_from_hir_id(id);
let generics = tcx.generics_of(def_id);
let count = generics.count();

let mut variances = solutions[start..start+generics.count()].to_vec();

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

// Functions can have unused type parameters: make those invariant.
// Const parameters are always invariant.
for (idx, param) in generics.params.iter().enumerate() {
if let ty::GenericParamDefKind::Const = param.kind {
variances[idx] = ty::Invariant;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be variances[generics.parent_count + idx] = ty::Invariant? Since count also include parent generics while params do not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you'd also want to change the variance of parent generics here. Maybe this code should be elsewhere?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're absolutely right. Thanks for spotting that!

}
}

// Functions are permitted to have unused generic parameters: make those invariant.
if let ty::FnDef(..) = tcx.type_of(def_id).sty {
for variance in &mut variances {
if *variance == ty::Bivariant {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/variance/terms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
// for a particular item are assigned continuous indices.

let arena = self.arena;
self.inferred_terms.extend((start..start+count).map(|i| {
self.inferred_terms.extend((start..(start + count)).map(|i| {
&*arena.alloc(InferredTerm(InferredIndex(i)))
}));
}
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/const-generics/unused-const-param.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-pass

#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

struct A<const N: usize>; // ok

fn main() {}
6 changes: 6 additions & 0 deletions src/test/ui/const-generics/unused-const-param.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/unused-const-param.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^