about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKevin Butler <haqkrs@gmail.com>2014-04-17 01:17:23 +0100
committerKevin Butler <haqkrs@gmail.com>2014-04-17 18:24:52 +0100
commitf829d208a30a4a8880ffb07ce4582e30c8f8d57f (patch)
tree3bd7eb287baab3dcf038af85e8eac66edac4ff9c
parent52a53e8ae78d77b3c3735fbaf00e53152402295e (diff)
downloadrust-f829d208a30a4a8880ffb07ce4582e30c8f8d57f.tar.gz
rust-f829d208a30a4a8880ffb07ce4582e30c8f8d57f.zip
Catch forward declarations in default type params at AST conversion.
-rw-r--r--src/librustc/middle/typeck/collect.rs19
-rw-r--r--src/test/compile-fail/generic-type-params-forward-mention.rs3
2 files changed, 19 insertions, 3 deletions
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/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>`
 }