about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-06-29 21:07:09 +0300
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-06-29 21:27:33 +0300
commita1110bc3a33e1fd4e08e7532bb9cd28a0216016e (patch)
tree6c24950d448c0db2fba9417c12ddf9ab53bf8d0e /src
parent40db46c6ba0d59e5ad9aa056a73055d2d3b83d04 (diff)
downloadrust-a1110bc3a33e1fd4e08e7532bb9cd28a0216016e.tar.gz
rust-a1110bc3a33e1fd4e08e7532bb9cd28a0216016e.zip
Fix off-by-one error in default-type-parameter checking
Fixes #18183
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/collect.rs45
-rw-r--r--src/test/compile-fail/issue-18183.rs13
2 files changed, 39 insertions, 19 deletions
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index ef9dcd56a57..d4f04987a81 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1860,6 +1860,29 @@ fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
     result
 }
 
+fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
+                                            path: &P<ast::Ty>,
+                                            space: ParamSpace,
+                                            index: u32)
+                                            -> Ty<'tcx>
+{
+    let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);
+
+    for leaf_ty in ty.walk() {
+        if let ty::TyParam(p) = leaf_ty.sty {
+            if p.space == space && p.idx >= index {
+                span_err!(ccx.tcx.sess, path.span, E0128,
+                          "type parameters with a default cannot use \
+                           forward declared identifiers");
+
+                return ccx.tcx.types.err
+            }
+        }
+    }
+
+    ty
+}
+
 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                              ast_generics: &ast::Generics,
                                              space: ParamSpace,
@@ -1874,25 +1897,9 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         None => { }
     }
 
-    let default = match param.default {
-        None => None,
-        Some(ref path) => {
-            let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &**path);
-            let cur_idx = index;
-
-            for leaf_ty in ty.walk() {
-                if let ty::TyParam(p) = leaf_ty.sty {
-                    if p.idx > cur_idx {
-                        span_err!(tcx.sess, path.span, E0128,
-                                  "type parameters with a default cannot use \
-                                   forward declared identifiers");
-                    }
-                }
-            }
-
-            Some(ty)
-        }
-    };
+    let default = param.default.as_ref().map(
+        |def| convert_default_type_parameter(ccx, def, space, index)
+    );
 
     let object_lifetime_default =
         compute_object_lifetime_default(ccx, param.id,
diff --git a/src/test/compile-fail/issue-18183.rs b/src/test/compile-fail/issue-18183.rs
new file mode 100644
index 00000000000..e6f3a2bdd33
--- /dev/null
+++ b/src/test/compile-fail/issue-18183.rs
@@ -0,0 +1,13 @@
+// Copyright 2015 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.
+
+pub struct Foo<Bar=Bar>; //~ ERROR E0128
+pub struct Baz(Foo);
+fn main() {}