Add span to error for missing type params on enums.

This commit is contained in:
Kevin Butler 2014-04-15 13:06:38 +01:00
parent 3b9ade0f81
commit 14e1fd4629
3 changed files with 14 additions and 13 deletions

View File

@ -2416,13 +2416,13 @@ pub enum Representability {
/// Check whether a type is representable. This means it cannot contain unboxed /// Check whether a type is representable. This means it cannot contain unboxed
/// structural recursion. This check is needed for structs and enums. /// structural recursion. This check is needed for structs and enums.
pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability { pub fn is_type_representable(cx: &ctxt, sp: Span, ty: t) -> Representability {
// Iterate until something non-representable is found // Iterate until something non-representable is found
fn find_nonrepresentable<It: Iterator<t>>(cx: &ctxt, seen: &mut Vec<DefId>, fn find_nonrepresentable<It: Iterator<t>>(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
mut iter: It) -> Representability { mut iter: It) -> Representability {
for ty in iter { for ty in iter {
let r = type_structurally_recursive(cx, seen, ty); let r = type_structurally_recursive(cx, sp, seen, ty);
if r != Representable { if r != Representable {
return r return r
} }
@ -2432,7 +2432,7 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
// Does the type `ty` directly (without indirection through a pointer) // Does the type `ty` directly (without indirection through a pointer)
// contain any types on stack `seen`? // contain any types on stack `seen`?
fn type_structurally_recursive(cx: &ctxt, seen: &mut Vec<DefId>, fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
ty: t) -> Representability { ty: t) -> Representability {
debug!("type_structurally_recursive: {}", debug!("type_structurally_recursive: {}",
::util::ppaux::ty_to_str(cx, ty)); ::util::ppaux::ty_to_str(cx, ty));
@ -2455,19 +2455,19 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
match get(ty).sty { match get(ty).sty {
// Tuples // Tuples
ty_tup(ref ts) => { ty_tup(ref ts) => {
find_nonrepresentable(cx, seen, ts.iter().map(|t| *t)) find_nonrepresentable(cx, sp, seen, ts.iter().map(|t| *t))
} }
// Fixed-length vectors. // Fixed-length vectors.
// FIXME(#11924) Behavior undecided for zero-length vectors. // FIXME(#11924) Behavior undecided for zero-length vectors.
ty_vec(ty, VstoreFixed(_)) => { ty_vec(ty, VstoreFixed(_)) => {
type_structurally_recursive(cx, seen, ty) type_structurally_recursive(cx, sp, seen, ty)
} }
// Push struct and enum def-ids onto `seen` before recursing. // Push struct and enum def-ids onto `seen` before recursing.
ty_struct(did, ref substs) => { ty_struct(did, ref substs) => {
seen.push(did); seen.push(did);
let fields = struct_fields(cx, did, substs); let fields = struct_fields(cx, did, substs);
let r = find_nonrepresentable(cx, seen, let r = find_nonrepresentable(cx, sp, seen,
fields.iter().map(|f| f.mt.ty)); fields.iter().map(|f| f.mt.ty));
seen.pop(); seen.pop();
r r
@ -2478,8 +2478,10 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
let mut r = Representable; let mut r = Representable;
for variant in vs.iter() { for variant in vs.iter() {
let iter = variant.args.iter().map(|aty| subst(cx, substs, *aty)); let iter = variant.args.iter().map(|aty| {
r = find_nonrepresentable(cx, seen, iter); aty.subst_spanned(cx, substs, Some(sp))
});
r = find_nonrepresentable(cx, sp, seen, iter);
if r != Representable { break } if r != Representable { break }
} }
@ -2499,7 +2501,7 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
// contains a different, structurally recursive type, maintain a stack // contains a different, structurally recursive type, maintain a stack
// of seen types and check recursion for each of them (issues #3008, #3779). // of seen types and check recursion for each of them (issues #3008, #3779).
let mut seen: Vec<DefId> = Vec::new(); let mut seen: Vec<DefId> = Vec::new();
type_structurally_recursive(cx, &mut seen, ty) type_structurally_recursive(cx, sp, &mut seen, ty)
} }
pub fn type_is_trait(ty: t) -> bool { pub fn type_is_trait(ty: t) -> bool {

View File

@ -3356,7 +3356,7 @@ pub fn check_representable(tcx: &ty::ctxt,
// recursive type. It is only necessary to throw an error on those that // recursive type. It is only necessary to throw an error on those that
// contain themselves. For case 2, there must be an inner type that will be // contain themselves. For case 2, there must be an inner type that will be
// caught by case 1. // caught by case 1.
match ty::is_type_representable(tcx, rty) { match ty::is_type_representable(tcx, sp, rty) {
ty::SelfRecursive => { ty::SelfRecursive => {
tcx.sess.span_err( tcx.sess.span_err(
sp, format!("illegal recursive {} type; \ sp, format!("illegal recursive {} type; \

View File

@ -8,10 +8,9 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// error-pattern: missing type param `Z` in the substitution of `Z`
fn f<Z>() -> bool { fn f<Z>() -> bool {
enum E { V(Z) } enum E { V(Z) }
//~^ ERROR missing type param `Z` in the substitution of `Z`
true true
} }