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

Disallow Unsized Enums #37111

Merged
merged 3 commits into from
Oct 26, 2016
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
3 changes: 1 addition & 2 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,8 +856,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
trait_name));
}
ObligationCauseCode::FieldSized => {
err.note("only the last field of a struct or enum variant \
may have a dynamically sized type");
err.note("only the last field of a struct may have a dynamically sized type");
}
ObligationCauseCode::ConstSized => {
err.note("constant expressions must have a statically known size");
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
self.check_variances_for_type_defn(item, ast_generics);
}
hir::ItemEnum(ref enum_def, ref ast_generics) => {
self.check_type_defn(item, false, |fcx| {
self.check_type_defn(item, true, |fcx| {
fcx.enum_variants(enum_def)
});

Expand Down
2 changes: 2 additions & 0 deletions src/test/compile-fail/issue-17025.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-test the unsized enum no longer compiles
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have ignored this test for now, but it has effectively become useless and could be deleted but I'm unsure what the policy is in this case.


enum A {
B(char),
C([Box<A>]),
Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/issue-5883.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,4 @@ fn new_struct(r: A+'static)
Struct { r: r }
}

trait Curve {}
enum E {X(Curve+'static)}
fn main() {}
7 changes: 0 additions & 7 deletions src/test/compile-fail/unsized-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,4 @@ fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
//
// Not OK: `T` is not sized.

enum Bar<U: ?Sized> { BarSome(U), BarNone }
fn bar1<T: ?Sized>() { not_sized::<Bar<T>>() }
fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
//~^ ERROR `T: std::marker::Sized` is not satisfied
//
// Not OK: `Bar<T>` is not sized, but it should be.

fn main() { }
68 changes: 68 additions & 0 deletions src/test/compile-fail/unsized-enum2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 206 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ops::Deref;

// Due to aggressive error message deduplication, we require 20 *different*
// unsized types (even Path and [u8] are considered the "same").

trait Foo {}
trait Bar {}
trait FooBar {}
trait BarFoo {}

trait PathHelper1 {}
trait PathHelper2 {}
trait PathHelper3 {}
trait PathHelper4 {}

struct Path1(PathHelper1);
struct Path2(PathHelper2);
struct Path3(PathHelper3);
struct Path4(PathHelper4);

enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized> {
// parameter
VA(W), //~ ERROR `W: std::marker::Sized` is not satisfied
VB{x: X}, //~ ERROR `X: std::marker::Sized` is not satisfied
VC(isize, Y), //~ ERROR `Y: std::marker::Sized` is not satisfied
VD{u: isize, x: Z}, //~ ERROR `Z: std::marker::Sized` is not satisfied

// slice / str
VE([u8]), //~ ERROR `[u8]: std::marker::Sized` is not satisfied
VF{x: str}, //~ ERROR `str: std::marker::Sized` is not satisfied
VG(isize, [f32]), //~ ERROR `[f32]: std::marker::Sized` is not satisfied
VH{u: isize, x: [u32]}, //~ ERROR `[u32]: std::marker::Sized` is not satisfied

// unsized struct
VI(Path1), //~ ERROR `PathHelper1 + 'static: std::marker::Sized` is not satisfied
VJ{x: Path2}, //~ ERROR `PathHelper2 + 'static: std::marker::Sized` is not satisfied
VK(isize, Path3), //~ ERROR `PathHelper3 + 'static: std::marker::Sized` is not satisfied
VL{u: isize, x: Path4}, //~ ERROR `PathHelper4 + 'static: std::marker::Sized` is not satisfied

// plain trait
VM(Foo), //~ ERROR `Foo + 'static: std::marker::Sized` is not satisfied
VN{x: Bar}, //~ ERROR `Bar + 'static: std::marker::Sized` is not satisfied
VO(isize, FooBar), //~ ERROR `FooBar + 'static: std::marker::Sized` is not satisfied
VP{u: isize, x: BarFoo}, //~ ERROR `BarFoo + 'static: std::marker::Sized` is not satisfied

// projected
VQ(<&'static [i8] as Deref>::Target), //~ ERROR `[i8]: std::marker::Sized` is not satisfied
VR{x: <&'static [char] as Deref>::Target},
//~^ ERROR `[char]: std::marker::Sized` is not satisfied
VS(isize, <&'static [f64] as Deref>::Target),
//~^ ERROR `[f64]: std::marker::Sized` is not satisfied
VT{u: isize, x: <&'static [i32] as Deref>::Target},
//~^ ERROR `[i32]: std::marker::Sized` is not satisfied
}


fn main() { }

17 changes: 3 additions & 14 deletions src/test/compile-fail/unsized3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,8 @@ fn f3<X: ?Sized + T>(x: &X) {
fn f4<X: T>(x: &X) {
}

// Test with unsized enum.
enum E<X: ?Sized> {
V(X),
}

fn f5<Y>(x: &Y) {}
fn f6<X: ?Sized>(x: &X) {}
fn f7<X: ?Sized>(x1: &E<X>, x2: &E<X>) {
f5(x1);
//~^ ERROR `X: std::marker::Sized` is not satisfied
f6(x2); // ok
}


// Test with unsized struct.
struct S<X: ?Sized> {
Expand All @@ -57,13 +46,13 @@ fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
}

// Test some tuples.
fn f9<X: ?Sized>(x1: Box<S<X>>, x2: Box<E<X>>) {
fn f9<X: ?Sized>(x1: Box<S<X>>) {
f5(&(*x1, 34));
//~^ ERROR `X: std::marker::Sized` is not satisfied
}

fn f10<X: ?Sized>(x1: Box<S<X>>, x2: Box<E<X>>) {
f5(&(32, *x2));
fn f10<X: ?Sized>(x1: Box<S<X>>) {
f5(&(32, *x1));
//~^ ERROR `X: std::marker::Sized` is not satisfied
}

Expand Down
8 changes: 1 addition & 7 deletions src/test/run-pass/unsized2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,14 @@ trait T7<X: ?Sized+T> {
fn m2(&self, x: &T5<X>);
}

// The last field in a struct or variant may be unsized
// The last field in a struct may be unsized
struct S2<X: ?Sized> {
f: X,
}
struct S3<X: ?Sized> {
f1: isize,
f2: X,
}
enum E<X: ?Sized> {
V1(X),
V2{x: X},
V3(isize, X),
V4{u: isize, x: X},
}

pub fn main() {
}