about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/trans/base.rs22
-rw-r--r--src/librustc/middle/trans/meth.rs14
-rw-r--r--src/test/auxiliary/nested_item.rs40
-rw-r--r--src/test/run-pass/nested_item_main.rs19
4 files changed, 85 insertions, 10 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index e8186477877..1dc30d2221d 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -87,6 +87,7 @@ use syntax::parse::token::{special_idents};
 use syntax::print::pprust::stmt_to_str;
 use syntax::{ast, ast_util, codemap, ast_map};
 use syntax::abi::{X86, X86_64, Arm, Mips};
+use syntax::visit::Visitor;
 
 pub use middle::trans::context::task_llcx;
 
@@ -2162,6 +2163,14 @@ pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
     }
 }
 
+pub struct TransItemVisitor;
+
+impl Visitor<@mut CrateContext> for TransItemVisitor {
+    fn visit_item(&mut self, i: @ast::item, ccx: @mut CrateContext) {
+        trans_item(ccx, i);
+    }
+}
+
 pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
     let _icx = push_ctxt("trans_item");
     let path = match ccx.tcx.items.get_copy(&item.id) {
@@ -2193,15 +2202,10 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) {
                      item.id,
                      item.attrs);
         } else {
-            for stmt in body.stmts.iter() {
-                match stmt.node {
-                  ast::stmt_decl(@codemap::spanned { node: ast::decl_item(i),
-                                                 _ }, _) => {
-                    trans_item(ccx, i);
-                  }
-                  _ => ()
-                }
-            }
+            // Be sure to travel more than just one layer deep to catch nested
+            // items in blocks and such.
+            let mut v = TransItemVisitor;
+            v.visit_block(body, ccx);
         }
       }
       ast::item_impl(ref generics, _, _, ref ms) => {
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 717dfbb6784..fb4dd8a74fb 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -37,6 +37,7 @@ use std::vec;
 use syntax::ast_map::{path, path_mod, path_name};
 use syntax::ast_util;
 use syntax::{ast, ast_map};
+use syntax::visit;
 
 /**
 The main "translation" pass for methods.  Generates code
@@ -56,7 +57,15 @@ pub fn trans_impl(ccx: @mut CrateContext,
     debug!("trans_impl(path=%s, name=%s, id=%?)",
            path.repr(tcx), name.repr(tcx), id);
 
-    if !generics.ty_params.is_empty() { return; }
+    // Both here and below with generic methods, be sure to recurse and look for
+    // items that we need to translate.
+    if !generics.ty_params.is_empty() {
+        let mut v = TransItemVisitor;
+        for method in methods.iter() {
+            visit::walk_method_helper(&mut v, *method, ccx);
+        }
+        return;
+    }
     let sub_path = vec::append_one(path, path_name(name));
     for method in methods.iter() {
         if method.generics.ty_params.len() == 0u {
@@ -69,6 +78,9 @@ pub fn trans_impl(ccx: @mut CrateContext,
                          *method,
                          None,
                          llfn);
+        } else {
+            let mut v = TransItemVisitor;
+            visit::walk_method_helper(&mut v, *method, ccx);
         }
     }
 }
diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs
new file mode 100644
index 00000000000..e9dde0d14a3
--- /dev/null
+++ b/src/test/auxiliary/nested_item.rs
@@ -0,0 +1,40 @@
+// Copyright 2013 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.
+
+// original problem
+fn foo<T>() -> int {
+    {
+        static foo: int = 2;
+        foo
+    }
+}
+
+// issue 8134
+struct Foo;
+impl<T> Foo {
+    pub fn foo(&self) {
+        static X: uint = 1;
+    }
+}
+
+// issue 8134
+pub struct Parser<T>;
+impl<T: std::iterator::Iterator<char>> Parser<T> {
+    fn in_doctype(&mut self) {
+        static DOCTYPEPattern: [char, ..6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
+    }
+}
+
+struct Bar;
+impl<T> Foo {
+    pub fn bar(&self) {
+        static X: uint = 1;
+    }
+}
diff --git a/src/test/run-pass/nested_item_main.rs b/src/test/run-pass/nested_item_main.rs
new file mode 100644
index 00000000000..5ce05fea568
--- /dev/null
+++ b/src/test/run-pass/nested_item_main.rs
@@ -0,0 +1,19 @@
+// Copyright 2013 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.
+
+// aux-build:nested_item.rs
+// xfail-fast
+
+extern mod nested_item;
+
+pub fn main() {
+    assert_eq!(2, nested_item::foo::<()>());
+    assert_eq!(2, nested_item::foo::<int>());
+}