diff options
| author | Kevin Butler <haqkrs@gmail.com> | 2014-04-17 01:17:23 +0100 |
|---|---|---|
| committer | Kevin Butler <haqkrs@gmail.com> | 2014-04-17 18:24:52 +0100 |
| commit | f829d208a30a4a8880ffb07ce4582e30c8f8d57f (patch) | |
| tree | 3bd7eb287baab3dcf038af85e8eac66edac4ff9c | |
| parent | 52a53e8ae78d77b3c3735fbaf00e53152402295e (diff) | |
| download | rust-f829d208a30a4a8880ffb07ce4582e30c8f8d57f.tar.gz rust-f829d208a30a4a8880ffb07ce4582e30c8f8d57f.zip | |
Catch forward declarations in default type params at AST conversion.
| -rw-r--r-- | src/librustc/middle/typeck/collect.rs | 19 | ||||
| -rw-r--r-- | src/test/compile-fail/generic-type-params-forward-mention.rs | 3 |
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, ¶m.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>` } |
