diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9c0c2d484a0a..bc01d2b126d3 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2416,13 +2416,13 @@ pub enum Representability { /// Check whether a type is representable. This means it cannot contain unboxed /// 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 - fn find_nonrepresentable>(cx: &ctxt, seen: &mut Vec, + fn find_nonrepresentable>(cx: &ctxt, sp: Span, seen: &mut Vec, mut iter: It) -> Representability { for ty in iter { - let r = type_structurally_recursive(cx, seen, ty); + let r = type_structurally_recursive(cx, sp, seen, ty); if r != Representable { 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) // contain any types on stack `seen`? - fn type_structurally_recursive(cx: &ctxt, seen: &mut Vec, + fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec, ty: t) -> Representability { debug!("type_structurally_recursive: {}", ::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 { // Tuples 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. // FIXME(#11924) Behavior undecided for zero-length vectors. 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. ty_struct(did, ref substs) => { seen.push(did); 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)); seen.pop(); r @@ -2478,8 +2478,10 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability { let mut r = Representable; for variant in vs.iter() { - let iter = variant.args.iter().map(|aty| subst(cx, substs, *aty)); - r = find_nonrepresentable(cx, seen, iter); + let iter = variant.args.iter().map(|aty| { + aty.subst_spanned(cx, substs, Some(sp)) + }); + r = find_nonrepresentable(cx, sp, seen, iter); 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 // of seen types and check recursion for each of them (issues #3008, #3779). let mut seen: Vec = 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 { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index cff8c149bb6e..6770640cfacc 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3356,7 +3356,7 @@ pub fn check_representable(tcx: &ty::ctxt, // 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 // caught by case 1. - match ty::is_type_representable(tcx, rty) { + match ty::is_type_representable(tcx, sp, rty) { ty::SelfRecursive => { tcx.sess.span_err( sp, format!("illegal recursive {} type; \ diff --git a/src/test/compile-fail/issue-5997-enum.rs b/src/test/compile-fail/issue-5997-enum.rs index d74bb39531c8..951f991f1069 100644 --- a/src/test/compile-fail/issue-5997-enum.rs +++ b/src/test/compile-fail/issue-5997-enum.rs @@ -8,10 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: missing type param `Z` in the substitution of `Z` - fn f() -> bool { enum E { V(Z) } + //~^ ERROR missing type param `Z` in the substitution of `Z` true }