From 6f3c202d3e5d9497fa0130f31bc1c3a3f0986edb Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Sun, 19 Jan 2014 18:29:47 +1100 Subject: [PATCH] rustc: check instantiability of fixed length vectors properly. Previously, they were treated like ~[] and &[] (which can have length 0), but fixed length vectors are fixed length, i.e. we know at compile time if it's possible to have length zero (which is only for [T, .. 0]). Fixes #11659. --- src/librustc/middle/ty.rs | 6 +++++ .../uninstantiable-fixed-length-vec.rs | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/test/compile-fail/uninstantiable-fixed-length-vec.rs diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 538a3c89bef72..5e0a40b90dd37 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2287,6 +2287,12 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { ::util::ppaux::ty_to_str(cx, ty)); let r = match get(ty).sty { + // fixed length vectors need special treatment compared to + // normal vectors, since they don't necessarily have the + // possibilty to have length zero. + ty_vec(_, vstore_fixed(0)) => false, // don't need no contents + ty_vec(mt, vstore_fixed(_)) => type_requires(cx, seen, r_ty, mt.ty), + ty_nil | ty_bot | ty_bool | diff --git a/src/test/compile-fail/uninstantiable-fixed-length-vec.rs b/src/test/compile-fail/uninstantiable-fixed-length-vec.rs new file mode 100644 index 0000000000000..bb2c3247e030f --- /dev/null +++ b/src/test/compile-fail/uninstantiable-fixed-length-vec.rs @@ -0,0 +1,26 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// issue #11659, the compiler needs to know that a fixed length vector +// always requires instantiable contents to instantiable itself +// (unlike a ~[] vector which can have length zero). + +// ~ to avoid infinite size. +struct Uninstantiable { //~ ERROR cannot be instantiated without an instance of itself + p: ~[Uninstantiable, .. 1] +} + +struct Instantiable { p: ~[Instantiable, .. 0] } + + +fn main() { + let _ = None::; + let _ = Instantiable { p: ~([]) }; +}