about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-17 21:21:24 -0700
committerbors <bors@rust-lang.org>2014-04-17 21:21:24 -0700
commit29a39700a1a46de2046bd6913da9c38d064a5a8f (patch)
tree05b01679163dea916d0ae256d925f556e0467914 /src
parent3f8e68686f826ed333321a6650481162c95911f6 (diff)
parentf829d208a30a4a8880ffb07ce4582e30c8f8d57f (diff)
downloadrust-29a39700a1a46de2046bd6913da9c38d064a5a8f.tar.gz
rust-29a39700a1a46de2046bd6913da9c38d064a5a8f.zip
auto merge of #13525 : Ryman/rust/issue_5997, r=alexcrichton
Closes #5997.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/resolve.rs10
-rw-r--r--src/librustc/middle/subst.rs5
-rw-r--r--src/librustc/middle/ty.rs22
-rw-r--r--src/librustc/middle/typeck/check/mod.rs2
-rw-r--r--src/librustc/middle/typeck/collect.rs19
-rw-r--r--src/test/compile-fail/bad-type-env-capture.rs2
-rw-r--r--src/test/compile-fail/generic-type-params-forward-mention.rs3
-rw-r--r--src/test/compile-fail/issue-3021-c.rs4
-rw-r--r--src/test/compile-fail/issue-3214.rs2
-rw-r--r--src/test/compile-fail/issue-5997-enum.rs21
-rw-r--r--src/test/compile-fail/issue-5997-struct.rs21
-rw-r--r--src/test/compile-fail/nested-ty-params.rs2
-rw-r--r--src/test/compile-fail/type-arg-out-of-scope.rs2
-rw-r--r--src/test/run-pass/issue-5997.rs22
14 files changed, 111 insertions, 26 deletions
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 9c00b8adfa3..5831ab850d3 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -3507,8 +3507,9 @@ impl<'a> Resolver<'a> {
                         // its scope.
 
                         self.resolve_error(span,
-                                              "attempt to use a type \
-                                              argument out of scope");
+                                              "can't use type parameters from \
+                                              outer function; try using a local \
+                                              type parameter instead");
                     }
 
                     return None;
@@ -3530,8 +3531,9 @@ impl<'a> Resolver<'a> {
                         // its scope.
 
                         self.resolve_error(span,
-                                              "attempt to use a type \
-                                              argument out of scope");
+                                              "can't use type parameters from \
+                                              outer function; try using a local \
+                                              type parameter instead");
                     }
 
                     return None;
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 7500c23e006..c9539b1d9a3 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -95,8 +95,9 @@ impl<'a> TypeFolder for SubstFolder<'a> {
                                               root.repr(self.tcx)),
                         None => ~""
                     };
-                    let m = format!("missing type param `{}`{}",
-                                    t.repr(self.tcx), root_msg);
+                    let m = format!("can't use type parameters from outer \
+                                    function{}; try using a local type \
+                                    parameter instead", root_msg);
                     match self.span {
                         Some(span) => self.tcx.sess.span_err(span, m),
                         None => self.tcx.sess.err(m)
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 9c0c2d484a0..bc01d2b126d 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<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 {
         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<DefId>,
+    fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
                                    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<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 {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index cff8c149bb6..6770640cfac 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/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 7e53445147f..6df8da3edaa 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -945,7 +945,24 @@ pub fn ty_generics(ccx: &CrateCtxt,
                 let param_ty = ty::param_ty {idx: base_index + offset,
                                              def_id: local_def(param.id)};
                 let bounds = @compute_bounds(ccx, param_ty, &param.bounds);
-                let default = param.default.map(|x| ast_ty_to_ty(ccx, &ExplicitRscope, x));
+                let default = param.default.map(|path| {
+                    let ty = ast_ty_to_ty(ccx, &ExplicitRscope, path);
+                    let cur_idx = param_ty.idx;
+
+                    ty::walk_ty(ty, |t| {
+                        match ty::get(t).sty {
+                            ty::ty_param(p) => if p.idx > cur_idx {
+                                ccx.tcx.sess.span_err(path.span,
+                                                        "type parameters with a default cannot use \
+                                                        forward declared identifiers")
+                            },
+                            _ => {}
+                        }
+                    });
+
+                    ty
+                });
+
                 let def = ty::TypeParameterDef {
                     ident: param.ident,
                     def_id: local_def(param.id),
diff --git a/src/test/compile-fail/bad-type-env-capture.rs b/src/test/compile-fail/bad-type-env-capture.rs
index f03665febd2..4e5dc652fb5 100644
--- a/src/test/compile-fail/bad-type-env-capture.rs
+++ b/src/test/compile-fail/bad-type-env-capture.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn foo<T>() {
-    fn bar(b: T) { } //~ ERROR attempt to use a type argument out of scope
+    fn bar(b: T) { } //~ ERROR can't use type parameters from outer
     //~^ ERROR use of undeclared type name
 }
 fn main() { }
diff --git a/src/test/compile-fail/generic-type-params-forward-mention.rs b/src/test/compile-fail/generic-type-params-forward-mention.rs
index 424a92d74ee..ace53fb51a4 100644
--- a/src/test/compile-fail/generic-type-params-forward-mention.rs
+++ b/src/test/compile-fail/generic-type-params-forward-mention.rs
@@ -12,8 +12,7 @@
 
 // Ensure that we get an error and not an ICE for this problematic case.
 struct Foo<T = Option<U>, U = bool>;
-
+//~^ ERROR type parameters with a default cannot use forward declared identifiers
 fn main() {
     let x: Foo;
-    //~^ ERROR missing type param `U` in the substitution of `std::option::Option<U>`
 }
diff --git a/src/test/compile-fail/issue-3021-c.rs b/src/test/compile-fail/issue-3021-c.rs
index 1fb71f01d06..5b3e343deea 100644
--- a/src/test/compile-fail/issue-3021-c.rs
+++ b/src/test/compile-fail/issue-3021-c.rs
@@ -11,8 +11,8 @@
 fn siphash<T>() {
 
     trait t {
-        fn g(&self, x: T) -> T;  //~ ERROR attempt to use a type argument out of scope
-        //~^ ERROR attempt to use a type argument out of scope
+        fn g(&self, x: T) -> T;  //~ ERROR can't use type parameters from outer function; try using
+        //~^ ERROR can't use type parameters from outer function; try using
         //~^^ ERROR use of undeclared type name `T`
         //~^^^ ERROR use of undeclared type name `T`
     }
diff --git a/src/test/compile-fail/issue-3214.rs b/src/test/compile-fail/issue-3214.rs
index 5be0a1e708b..be49ca1fe06 100644
--- a/src/test/compile-fail/issue-3214.rs
+++ b/src/test/compile-fail/issue-3214.rs
@@ -10,7 +10,7 @@
 
 fn foo<T>() {
     struct foo {
-        x: T, //~ ERROR attempt to use a type argument out of scope
+        x: T, //~ ERROR can't use type parameters from outer function;
         //~^ ERROR use of undeclared type name
     }
 
diff --git a/src/test/compile-fail/issue-5997-enum.rs b/src/test/compile-fail/issue-5997-enum.rs
new file mode 100644
index 00000000000..7be01b4abb4
--- /dev/null
+++ b/src/test/compile-fail/issue-5997-enum.rs
@@ -0,0 +1,21 @@
+// 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 <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.
+
+fn f<Z>() -> bool {
+    enum E { V(Z) }
+    //~^ ERROR can't use type parameters from outer function in the
+
+    true
+}
+
+fn main() {
+    let b = f::<int>();
+    assert!(b);
+}
diff --git a/src/test/compile-fail/issue-5997-struct.rs b/src/test/compile-fail/issue-5997-struct.rs
new file mode 100644
index 00000000000..b2a63ed1c7b
--- /dev/null
+++ b/src/test/compile-fail/issue-5997-struct.rs
@@ -0,0 +1,21 @@
+// 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 <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.
+
+fn f<T>() -> bool {
+    struct S(T); //~ ERROR use of undeclared type name `T`
+    //~^ ERROR can't use type parameters from outer function; try using
+
+    true
+}
+
+fn main() {
+    let b = f::<int>();
+    assert!(b);
+}
diff --git a/src/test/compile-fail/nested-ty-params.rs b/src/test/compile-fail/nested-ty-params.rs
index 7b7ce6bee2f..0ee2a3add87 100644
--- a/src/test/compile-fail/nested-ty-params.rs
+++ b/src/test/compile-fail/nested-ty-params.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:attempt to use a type argument out of scope
+// error-pattern:can't use type parameters from outer function; try using
 fn hd<U>(v: Vec<U> ) -> U {
     fn hd1(w: [U]) -> U { return w[0]; }
 
diff --git a/src/test/compile-fail/type-arg-out-of-scope.rs b/src/test/compile-fail/type-arg-out-of-scope.rs
index 240b1aa06d4..ac2f9d0379f 100644
--- a/src/test/compile-fail/type-arg-out-of-scope.rs
+++ b/src/test/compile-fail/type-arg-out-of-scope.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:attempt to use a type argument out of scope
+// error-pattern:can't use type parameters from outer function; try using
 fn foo<T>(x: T) {
     fn bar(f: |T| -> T) { }
 }
diff --git a/src/test/run-pass/issue-5997.rs b/src/test/run-pass/issue-5997.rs
new file mode 100644
index 00000000000..9e2a001cb21
--- /dev/null
+++ b/src/test/run-pass/issue-5997.rs
@@ -0,0 +1,22 @@
+// 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 <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.
+
+fn f<T>() -> bool {
+    enum E<T> { V(T) }
+
+    struct S<T>(T);
+
+    true
+}
+
+fn main() {
+    let b = f::<int>();
+    assert!(b);
+}
\ No newline at end of file