Change:
Will not actually be exported in the resulting object. There are two obvious fixes, the first being to expand on my pub-not-exported lint to warn you that this will not work, the second being to fix the compiler to export the symbol with the appropriate value (Without altering the existing inlining behaviour, although it may give a more reasonable option for cases like trying to take the address of a item). Happy to work on either, although I would need a mentor for the second part.
I'm not sure what you mean by it not being exported. It might not be visible as a symbol (if you're linking with some C code or something), but you can certainly reference that item from another Rust crate.
Sorry for not being clear. That's exactly what I meant, the symbol is not visible in the resulting object. This is pretty confusing (I've been doing a lot of C(++) <-Rust lately and I'm trying to make the compiler warn people about all the things that have tripped me up)
I think the right option is to expand the lint. The whole difference between and is that the former isn't guaranteed to have a location in memory. To a C programmer it's like a variable.
Sounds totally reasonable. I'll expand the lint.
Ah, I see now. I didn't know there was a lint for on items that don't export a symbol. That explains a lot!

Discussion:
"functions marked #[no_mangle] should be exported" } <ins> declare_lint! { PRIVATE_NO_MANGLE_STATICS, Warn, "statics marked #[no_mangle] should be exported" } declare_lint! { NO_MANGLE_CONST_ITEMS, Deny, "const items will not have their symbols exported" } </ins> #[derive(Copy)] <del> pub struct PrivateNoMangleFns; </del> <ins> pub struct InvalidNoMangleItems; </ins> <del> impl LintPass for PrivateNoMangleFns { </del> <ins> impl LintPass for InvalidNoMangleItems { </ins> fn get_lints(&self) -> LintArray { <del> lint_array!(PRIVATE_NO_MANGLE_FNS) </del> <ins> lint_array!(PRIVATE_NO_MANGLE_FNS, PRIVATE_NO_MANGLE_STATICS, NO_MANGLE_CONST_ITEMS) </ins> } fn check_item(&mut self, cx: &Context, it: &ast::Item) {

cx.span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg.as_slice()); } }, <ins> ast::ItemStatic(..) => { if attr::contains_name(it.attrs.as_slice(), "no_mangle") && !cx.exported_items.contains(&it.id) { let msg = format!("static {} is marked #[no_mangle], but not exported", it.ident); cx.span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg.as_slice()); } }, ast::ItemConst(..) => { if attr::contains_name(it.attrs.as_slice(), "no_mangle") { // Const items do not refer to a particular location in memory, and therefore // don't have anything to attach a symbol to let msg = "const items should never be #[no_mangle], consider instead using  `pub static`"; cx.span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg); } } </ins> _ => {}, } }

UnstableFeatures, Stability, UnconditionalRecursion, <del> PrivateNoMangleFns, </del> <ins> InvalidNoMangleItems, </ins> ); add_builtin_with_new!(sess,

// option. This file may not be copied, modified, or distributed // except according to those terms. <del> // compile-flags:-F private_no_mangle_fns </del> <ins> // compile-flags:-F private_no_mangle_fns -F no_mangle_const_items -F private_no_mangle_statics </ins> // FIXME(#19495) no_mangle'ing main ICE's. #[no_mangle] fn foo() { //~ ERROR function foo is marked #[no_mangle], but not exported } <ins> #[allow(dead_code)] #[no_mangle] const FOO: u64 = 1; //~ ERROR const items should never be #[no_mangle] #[no_mangle] pub const PUB_FOO: u64 = 1; //~ ERROR const items should never be #[no_mangle] </ins> #[no_mangle] pub fn bar()  { } <ins> #[no_mangle] pub static BAR: u64 = 1; #[allow(dead_code)] #[no_mangle] static PRIVATE_BAR: u64 = 1; //~ ERROR static PRIVATE_BAR is marked #[no_mangle], but not exported </ins> fn main() { foo(); bar();