From d5a94c4a88ab1d9696ec17964bc989bd6fa4e260 Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Mon, 11 Aug 2014 16:54:16 -0700 Subject: [PATCH 1/3] Revert "don't translate items when monomorphizing foreign-ABI functions" This reverts commit 0c158b4fbfcec7d6f18859661047dff2109fdfe4. --- src/librustc/middle/trans/base.rs | 3 +-- src/librustc/middle/trans/foreign.rs | 11 ++++------- src/librustc/middle/trans/monomorphize.rs | 2 +- src/test/run-make/issue-7349/Makefile | 6 +++--- src/test/run-make/issue-7349/foo.rs | 9 --------- 5 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0860f84dbef47..abf2fc28f2243 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2066,8 +2066,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { llfn, ¶m_substs::empty(), item.id, - None, - TranslateItems); + None); } else { trans_fn(ccx, &**decl, diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 4ca2060ca866d..93e3572054848 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -577,8 +577,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, llwrapfn: ValueRef, param_substs: ¶m_substs, id: ast::NodeId, - hash: Option<&str>, - handle_items: HandleItemsFlag) { + hash: Option<&str>) { let _icx = push_ctxt("foreign::build_foreign_fn"); let fnty = ty::node_id_to_type(ccx.tcx(), id); @@ -587,8 +586,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, unsafe { // unsafe because we call LLVM operations // Build up the Rust function (`foo0` above). - let llrustfn = build_rust_fn(ccx, decl, body, param_substs, attrs, id, - hash, handle_items); + let llrustfn = build_rust_fn(ccx, decl, body, param_substs, attrs, id, hash); // Build up the foreign wrapper (`foo` above). return build_wrap_fn(ccx, llrustfn, llwrapfn, &tys, mty); @@ -600,8 +598,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, param_substs: ¶m_substs, attrs: &[ast::Attribute], id: ast::NodeId, - hash: Option<&str>, - handle_items: HandleItemsFlag) + hash: Option<&str>) -> ValueRef { let _icx = push_ctxt("foreign::foreign::build_rust_fn"); let tcx = ccx.tcx(); @@ -633,7 +630,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice()); base::set_llvm_fn_attrs(attrs, llfn); - base::trans_fn(ccx, decl, body, llfn, param_substs, id, [], handle_items); + base::trans_fn(ccx, decl, body, llfn, param_substs, id, [], TranslateItems); llfn } diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 070bd89d28963..97f0f1beeace6 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -164,7 +164,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, if abi != abi::Rust { foreign::trans_rust_fn_with_foreign_abi( ccx, &**decl, &**body, [], d, &psubsts, fn_id.node, - Some(hash.as_slice()), IgnoreItems); + Some(hash.as_slice())); } else { trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, [], IgnoreItems); diff --git a/src/test/run-make/issue-7349/Makefile b/src/test/run-make/issue-7349/Makefile index 7f715a475bead..18ba80a712d11 100644 --- a/src/test/run-make/issue-7349/Makefile +++ b/src/test/run-make/issue-7349/Makefile @@ -2,10 +2,10 @@ # Test to make sure that inner functions within a polymorphic outer function # don't get re-translated when the outer function is monomorphized. The test -# code monomorphizes the outer functions several times, but the magic constants -# used in the inner functions should each appear only once in the generated IR. +# code monomorphizes the outer function several times, but the magic constant +# `8675309` used in the inner function should appear only once in the generated +# IR. all: $(RUSTC) foo.rs --emit=ir [ "$$(grep -c 8675309 "$(TMPDIR)/foo.ll")" -eq "1" ] - [ "$$(grep -c 11235813 "$(TMPDIR)/foo.ll")" -eq "1" ] diff --git a/src/test/run-make/issue-7349/foo.rs b/src/test/run-make/issue-7349/foo.rs index 870d1749278d7..775b7314841cc 100644 --- a/src/test/run-make/issue-7349/foo.rs +++ b/src/test/run-make/issue-7349/foo.rs @@ -15,16 +15,7 @@ fn outer() { } } -extern "C" fn outer_foreign() { - #[allow(dead_code)] - fn inner() -> uint { - 11235813 - } -} - fn main() { outer::(); outer::(); - outer_foreign::(); - outer_foreign::(); } From 428d5ac5b94b2470ce379b0751861ec903825d7b Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Mon, 11 Aug 2014 16:55:13 -0700 Subject: [PATCH 2/3] Revert "avoid redundant translation of items during monomorphization" This reverts commit f97f65f7b70e455c1c3e72e620120c9f1a96d89a. Conflicts: src/librustc/middle/trans/base.rs src/librustc/middle/trans/foreign.rs src/librustc/middle/trans/monomorphize.rs --- src/librustc/middle/trans/base.rs | 23 ++++++++--------------- src/librustc/middle/trans/callee.rs | 3 +-- src/librustc/middle/trans/closure.rs | 8 +++----- src/librustc/middle/trans/common.rs | 9 --------- src/librustc/middle/trans/controlflow.rs | 7 +------ src/librustc/middle/trans/foreign.rs | 2 +- src/librustc/middle/trans/glue.rs | 2 +- src/librustc/middle/trans/inline.rs | 2 +- src/librustc/middle/trans/meth.rs | 3 +-- src/librustc/middle/trans/monomorphize.rs | 8 +++----- src/librustc/middle/trans/reflect.rs | 2 +- src/test/run-make/issue-7349/Makefile | 11 ----------- src/test/run-make/issue-7349/foo.rs | 21 --------------------- 13 files changed, 21 insertions(+), 80 deletions(-) delete mode 100644 src/test/run-make/issue-7349/Makefile delete mode 100644 src/test/run-make/issue-7349/foo.rs diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index abf2fc28f2243..0c224a440ff6f 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1343,8 +1343,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext, output_type: ty::t, param_substs: &'a param_substs, sp: Option, - block_arena: &'a TypedArena>, - handle_items: HandleItemsFlag) + block_arena: &'a TypedArena>) -> FunctionContext<'a> { param_substs.validate(); @@ -1379,8 +1378,7 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext, block_arena: block_arena, ccx: ccx, debug_context: debug_context, - scopes: RefCell::new(Vec::new()), - handle_items: handle_items, + scopes: RefCell::new(Vec::new()) }; if has_env { @@ -1708,8 +1706,7 @@ pub fn trans_closure(ccx: &CrateContext, abi: Abi, has_env: bool, is_unboxed_closure: IsUnboxedClosureFlag, - maybe_load_env: <'a> |&'a Block<'a>| -> &'a Block<'a>, - handle_items: HandleItemsFlag) { + maybe_load_env: <'a> |&'a Block<'a>| -> &'a Block<'a>) { ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1); let _icx = push_ctxt("trans_closure"); @@ -1726,8 +1723,7 @@ pub fn trans_closure(ccx: &CrateContext, output_type, param_substs, Some(body.span), - &arena, - handle_items); + &arena); let mut bcx = init_function(&fcx, false, output_type); // cleanup scope for the incoming arguments @@ -1836,8 +1832,7 @@ pub fn trans_fn(ccx: &CrateContext, llfndecl: ValueRef, param_substs: ¶m_substs, id: ast::NodeId, - attrs: &[ast::Attribute], - handle_items: HandleItemsFlag) { + attrs: &[ast::Attribute]) { let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_string(id).to_string()); debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx())); let _icx = push_ctxt("trans_fn"); @@ -1857,8 +1852,7 @@ pub fn trans_fn(ccx: &CrateContext, abi, false, NotUnboxedClosure, - |bcx| bcx, - handle_items); + |bcx| bcx); } pub fn trans_enum_variant(ccx: &CrateContext, @@ -1964,7 +1958,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext, let arena = TypedArena::new(); let fcx = new_fn_ctxt(ccx, llfndecl, ctor_id, false, result_ty, - param_substs, None, &arena, TranslateItems); + param_substs, None, &arena); let bcx = init_function(&fcx, false, result_ty); assert!(!fcx.needs_ret_allocas); @@ -2074,8 +2068,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { llfn, ¶m_substs::empty(), item.id, - item.attrs.as_slice(), - TranslateItems); + item.attrs.as_slice()); } } else { // Be sure to travel more than just one layer deep to catch nested diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 8e6ff0cdb3e11..379b53eebbb4f 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -339,8 +339,7 @@ pub fn trans_unboxing_shim(bcx: &Block, return_type, &empty_param_substs, None, - &block_arena, - TranslateItems); + &block_arena); let mut bcx = init_function(&fcx, false, return_type); // Create the substituted versions of the self type. diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index eeff0609a56dd..44c52a6739ab4 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -394,8 +394,7 @@ pub fn trans_expr_fn<'a>( ty::ty_fn_abi(fty), true, NotUnboxedClosure, - |bcx| load_environment(bcx, cdata_ty, &freevars, store), - bcx.fcx.handle_items); + |bcx| load_environment(bcx, cdata_ty, &freevars, store)); fill_fn_pair(bcx, dest_addr, llfn, llbox); bcx } @@ -487,8 +486,7 @@ pub fn trans_unboxed_closure<'a>( ty::ty_fn_abi(function_type), true, IsUnboxedClosure, - |bcx| load_unboxed_closure_environment(bcx, freevars_ptr), - bcx.fcx.handle_items); + |bcx| load_unboxed_closure_environment(bcx, freevars_ptr)); // Don't hoist this to the top of the function. It's perfectly legitimate // to have a zero-size unboxed closure (in which case dest will be @@ -575,7 +573,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext, let arena = TypedArena::new(); let empty_param_substs = param_substs::empty(); let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, true, f.sig.output, - &empty_param_substs, None, &arena, TranslateItems); + &empty_param_substs, None, &arena); let bcx = init_function(&fcx, true, f.sig.output); let args = create_datums_for_fn_args(&fcx, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 5e46550eccba5..3b89c73b31da8 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -224,12 +224,6 @@ impl SubstP for T { pub type RvalueDatum = datum::Datum; pub type LvalueDatum = datum::Datum; -#[deriving(Clone, Eq, PartialEq)] -pub enum HandleItemsFlag { - IgnoreItems, - TranslateItems, -} - // Function context. Every LLVM function we create will have one of // these. pub struct FunctionContext<'a> { @@ -303,9 +297,6 @@ pub struct FunctionContext<'a> { // Cleanup scopes. pub scopes: RefCell> >, - - // How to handle items encountered during translation of this function. - pub handle_items: HandleItemsFlag, } impl<'a> FunctionContext<'a> { diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 02a5f715ecb23..6ea85f83d25ac 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -69,12 +69,7 @@ pub fn trans_stmt<'a>(cx: &'a Block<'a>, debuginfo::create_local_var_metadata(bcx, &**local); } } - ast::DeclItem(ref i) => { - match fcx.handle_items { - TranslateItems => trans_item(cx.fcx.ccx, &**i), - IgnoreItems => {} - } - } + ast::DeclItem(ref i) => trans_item(cx.fcx.ccx, &**i) } } ast::StmtMac(..) => cx.tcx().sess.bug("unexpanded macro") diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 93e3572054848..88bb88da3f043 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -630,7 +630,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: &CrateContext, let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice()); base::set_llvm_fn_attrs(attrs, llfn); - base::trans_fn(ccx, decl, body, llfn, param_substs, id, [], TranslateItems); + base::trans_fn(ccx, decl, body, llfn, param_substs, id, []); llfn } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 1d016f6db2659..cc7cb16334131 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -468,7 +468,7 @@ fn make_generic_glue(ccx: &CrateContext, let arena = TypedArena::new(); let empty_param_substs = param_substs::empty(); let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, ty::mk_nil(), - &empty_param_substs, None, &arena, TranslateItems); + &empty_param_substs, None, &arena); let bcx = init_function(&fcx, false, ty::mk_nil()); diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 877dd647c3b20..bf39f3a6aa385 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -133,7 +133,7 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) if unparameterized { let llfn = get_item_val(ccx, mth.id); trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), llfn, - ¶m_substs::empty(), mth.id, [], TranslateItems); + ¶m_substs::empty(), mth.id, []); } local_def(mth.id) } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 7f7b70e075d1d..9e45b294a37b3 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -75,8 +75,7 @@ pub fn trans_impl(ccx: &CrateContext, llfn, ¶m_substs::empty(), method.id, - [], - TranslateItems); + []); } else { let mut v = TransItemVisitor{ ccx: ccx }; visit::walk_method_helper(&mut v, &**method, ()); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 97f0f1beeace6..6d705c7d914e3 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -166,8 +166,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, ccx, &**decl, &**body, [], d, &psubsts, fn_id.node, Some(hash.as_slice())); } else { - trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, [], - IgnoreItems); + trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, []); } d @@ -201,8 +200,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, ast_map::NodeMethod(mth) => { let d = mk_lldecl(abi::Rust); set_llvm_fn_attrs(mth.attrs.as_slice(), d); - trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, &psubsts, mth.id, [], - IgnoreItems); + trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, &psubsts, mth.id, []); d } ast_map::NodeTraitMethod(method) => { @@ -211,7 +209,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, let d = mk_lldecl(abi::Rust); set_llvm_fn_attrs(mth.attrs.as_slice(), d); trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, - &psubsts, mth.id, [], IgnoreItems); + &psubsts, mth.id, []); d } _ => { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index e49d483e8d93d..9caa9f681aadf 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -312,7 +312,7 @@ impl<'a, 'b> Reflector<'a, 'b> { let empty_param_substs = param_substs::empty(); let fcx = new_fn_ctxt(ccx, llfdecl, ast::DUMMY_NODE_ID, false, ty::mk_u64(), &empty_param_substs, - None, &arena, TranslateItems); + None, &arena); let bcx = init_function(&fcx, false, ty::mk_u64()); // we know the return type of llfdecl is an int here, so diff --git a/src/test/run-make/issue-7349/Makefile b/src/test/run-make/issue-7349/Makefile deleted file mode 100644 index 18ba80a712d11..0000000000000 --- a/src/test/run-make/issue-7349/Makefile +++ /dev/null @@ -1,11 +0,0 @@ --include ../tools.mk - -# Test to make sure that inner functions within a polymorphic outer function -# don't get re-translated when the outer function is monomorphized. The test -# code monomorphizes the outer function several times, but the magic constant -# `8675309` used in the inner function should appear only once in the generated -# IR. - -all: - $(RUSTC) foo.rs --emit=ir - [ "$$(grep -c 8675309 "$(TMPDIR)/foo.ll")" -eq "1" ] diff --git a/src/test/run-make/issue-7349/foo.rs b/src/test/run-make/issue-7349/foo.rs deleted file mode 100644 index 775b7314841cc..0000000000000 --- a/src/test/run-make/issue-7349/foo.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn outer() { - #[allow(dead_code)] - fn inner() -> uint { - 8675309 - } -} - -fn main() { - outer::(); - outer::(); -} From 0f847ba74da083124f3d5d38d36fc1135737c12c Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Tue, 12 Aug 2014 09:19:47 -0700 Subject: [PATCH 3/3] more consistent handling of inner items --- src/librustc/middle/trans/base.rs | 10 ++++---- src/librustc/middle/trans/controlflow.rs | 3 ++- src/librustc/middle/trans/meth.rs | 5 ++-- src/test/run-make/issue-7349/Makefile | 11 +++++++++ src/test/run-make/issue-7349/foo.rs | 30 ++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 src/test/run-make/issue-7349/Makefile create mode 100644 src/test/run-make/issue-7349/foo.rs diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0c224a440ff6f..35d32d9952506 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2070,12 +2070,12 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) { item.id, item.attrs.as_slice()); } - } else { - // Be sure to travel more than just one layer deep to catch nested - // items in blocks and such. - let mut v = TransItemVisitor{ ccx: ccx }; - v.visit_block(&**body, ()); } + + // Be sure to travel more than just one layer deep to catch nested + // items in blocks and such. + let mut v = TransItemVisitor{ ccx: ccx }; + v.visit_block(&**body, ()); } ast::ItemImpl(ref generics, _, _, ref ms) => { meth::trans_impl(ccx, item.ident, ms.as_slice(), generics, item.id); diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 6ea85f83d25ac..a481f92db3391 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -69,7 +69,8 @@ pub fn trans_stmt<'a>(cx: &'a Block<'a>, debuginfo::create_local_var_metadata(bcx, &**local); } } - ast::DeclItem(ref i) => trans_item(cx.fcx.ccx, &**i) + // Inner items are visited by `trans_item`/`trans_meth`. + ast::DeclItem(_) => {}, } } ast::StmtMac(..) => cx.tcx().sess.bug("unexpanded macro") diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 9e45b294a37b3..3578b25c83957 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -76,10 +76,9 @@ pub fn trans_impl(ccx: &CrateContext, ¶m_substs::empty(), method.id, []); - } else { - let mut v = TransItemVisitor{ ccx: ccx }; - visit::walk_method_helper(&mut v, &**method, ()); } + let mut v = TransItemVisitor{ ccx: ccx }; + visit::walk_method_helper(&mut v, &**method, ()); } } diff --git a/src/test/run-make/issue-7349/Makefile b/src/test/run-make/issue-7349/Makefile new file mode 100644 index 0000000000000..7f715a475bead --- /dev/null +++ b/src/test/run-make/issue-7349/Makefile @@ -0,0 +1,11 @@ +-include ../tools.mk + +# Test to make sure that inner functions within a polymorphic outer function +# don't get re-translated when the outer function is monomorphized. The test +# code monomorphizes the outer functions several times, but the magic constants +# used in the inner functions should each appear only once in the generated IR. + +all: + $(RUSTC) foo.rs --emit=ir + [ "$$(grep -c 8675309 "$(TMPDIR)/foo.ll")" -eq "1" ] + [ "$$(grep -c 11235813 "$(TMPDIR)/foo.ll")" -eq "1" ] diff --git a/src/test/run-make/issue-7349/foo.rs b/src/test/run-make/issue-7349/foo.rs new file mode 100644 index 0000000000000..870d1749278d7 --- /dev/null +++ b/src/test/run-make/issue-7349/foo.rs @@ -0,0 +1,30 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn outer() { + #[allow(dead_code)] + fn inner() -> uint { + 8675309 + } +} + +extern "C" fn outer_foreign() { + #[allow(dead_code)] + fn inner() -> uint { + 11235813 + } +} + +fn main() { + outer::(); + outer::(); + outer_foreign::(); + outer_foreign::(); +}