diff options
| -rw-r--r-- | src/librustc/middle/trans/base.rs | 22 | ||||
| -rw-r--r-- | src/librustc/middle/trans/meth.rs | 14 | ||||
| -rw-r--r-- | src/test/auxiliary/nested_item.rs | 40 | ||||
| -rw-r--r-- | src/test/run-pass/nested_item_main.rs | 19 |
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>()); +} |
