diff --git a/src/libcore/str.rs b/src/libcore/str.rs index a89a7970ae9..1cd58aee061 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -30,6 +30,7 @@ use iter::range; use kinds::Sized; use mem; use num::Int; +use ops::FnMut; use option::Option; use option::Option::{None, Some}; use ops::{Fn, FnMut}; diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 8b2f644dfe3..009079bd214 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -65,17 +65,21 @@ const HOEDOWN_EXTENSIONS: libc::c_uint = type hoedown_document = libc::c_void; // this is opaque to us +type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, + *const hoedown_buffer, *mut libc::c_void); + +type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer, + libc::c_int, *mut libc::c_void); + #[repr(C)] struct hoedown_renderer { opaque: *mut hoedown_html_renderer_state, - blockcode: Option, + blockcode: Option, blockquote: Option, blockhtml: Option, - header: Option, + header: Option, other: [libc::size_t, ..28], } @@ -281,8 +285,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { toc_builder: if print_toc {Some(TocBuilder::new())} else {None} }; (*(*renderer).opaque).opaque = &mut opaque as *mut _ as *mut libc::c_void; - (*renderer).blockcode = Some(block); - (*renderer).header = Some(header); + (*renderer).blockcode = Some(block as blockcodefn); + (*renderer).header = Some(header as headerfn); let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16); hoedown_document_render(document, ob, s.as_ptr(), @@ -354,8 +358,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { unsafe { let ob = hoedown_buffer_new(DEF_OUNIT); let renderer = hoedown_html_renderer_new(0, 0); - (*renderer).blockcode = Some(block); - (*renderer).header = Some(header); + (*renderer).blockcode = Some(block as blockcodefn); + (*renderer).header = Some(header as headerfn); (*(*renderer).opaque).opaque = tests as *mut _ as *mut libc::c_void; let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16); diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index c2c17103554..9e4a66e0e5e 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -829,8 +829,12 @@ impl Path { let s = if self.has_nonsemantic_trailing_slash() { self.repr.slice_to(self.repr.len()-1) } else { self.repr.as_slice() }; - let idx = s.rfind(if !prefix_is_verbatim(self.prefix) { is_sep } - else { is_sep_verbatim }); + let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) { + is_sep + } else { + is_sep_verbatim + }; + let idx = s.rfind(sep_test); let prefixlen = self.prefix_len(); self.sepidx = idx.and_then(|x| if x < prefixlen { None } else { Some(x) }); } @@ -1048,7 +1052,11 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option { // None result means the string didn't need normalizing fn normalize_helper<'a>(s: &'a str, prefix: Option) -> (bool, Option>) { - let f = if !prefix_is_verbatim(prefix) { is_sep } else { is_sep_verbatim }; + let f: fn(char) -> bool = if !prefix_is_verbatim(prefix) { + is_sep + } else { + is_sep_verbatim + }; let is_abs = s.len() > prefix_len(prefix) && f(s.char_at(prefix_len(prefix))); let s_ = s.slice_from(prefix_len(prefix)); let s_ = if is_abs { s_.slice_from(1) } else { s_ }; diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index 4c33d1c418d..04718dcc6ae 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -189,11 +189,12 @@ macro_rules! __thread_local_inner { } }; - #[cfg(not(any(target_os = "macos", target_os = "linux")))] + #[cfg(all(stage0, not(any(target_os = "macos", target_os = "linux"))))] const INIT: ::std::thread_local::KeyInner<$t> = { unsafe extern fn __destroy(ptr: *mut u8) { ::std::thread_local::destroy_value::<$t>(ptr); } + ::std::thread_local::KeyInner { inner: ::std::cell::UnsafeCell { value: $init }, os: ::std::thread_local::OsStaticKey { @@ -203,6 +204,21 @@ macro_rules! __thread_local_inner { } }; + #[cfg(all(not(stage0), not(any(target_os = "macos", target_os = "linux"))))] + const INIT: ::std::thread_local::KeyInner<$t> = { + unsafe extern fn __destroy(ptr: *mut u8) { + ::std::thread_local::destroy_value::<$t>(ptr); + } + + ::std::thread_local::KeyInner { + inner: ::std::cell::UnsafeCell { value: $init }, + os: ::std::thread_local::OsStaticKey { + inner: ::std::thread_local::OS_INIT_INNER, + dtor: ::std::option::Option::Some(__destroy as unsafe extern fn(*mut u8)), + }, + } + }; + INIT }); } @@ -323,6 +339,12 @@ mod imp { // *should* be the case that this loop always terminates because we // provide the guarantee that a TLS key cannot be set after it is // flagged for destruction. + #[cfg(not(stage0))] + static DTORS: os::StaticKey = os::StaticKey { + inner: os::INIT_INNER, + dtor: Some(run_dtors as unsafe extern "C" fn(*mut u8)), + }; + #[cfg(stage0)] static DTORS: os::StaticKey = os::StaticKey { inner: os::INIT_INNER, dtor: Some(run_dtors), diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index aefbb2a1fea..f76c350902d 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -50,14 +50,16 @@ pub trait ItemDecorator { push: |P|); } -impl ItemDecorator for fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P|) { +impl ItemDecorator for F + where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P|) +{ fn expand(&self, ecx: &mut ExtCtxt, sp: Span, meta_item: &ast::MetaItem, item: &ast::Item, push: |P|) { - self.clone()(ecx, sp, meta_item, item, push) + (*self)(ecx, sp, meta_item, item, push) } } @@ -70,14 +72,16 @@ pub trait ItemModifier { -> P; } -impl ItemModifier for fn(&mut ExtCtxt, Span, &ast::MetaItem, P) -> P { +impl ItemModifier for F + where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P) -> P +{ fn expand(&self, ecx: &mut ExtCtxt, span: Span, meta_item: &ast::MetaItem, item: P) -> P { - self.clone()(ecx, span, meta_item, item) + (*self)(ecx, span, meta_item, item) } } @@ -93,13 +97,15 @@ pub trait TTMacroExpander { pub type MacroExpanderFn = for<'cx> fn(&'cx mut ExtCtxt, Span, &[ast::TokenTree]) -> Box; -impl TTMacroExpander for MacroExpanderFn { +impl TTMacroExpander for F + where F : for<'cx> Fn(&'cx mut ExtCtxt, Span, &[ast::TokenTree]) -> Box +{ fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, token_tree: &[ast::TokenTree]) -> Box { - self.clone()(ecx, span, token_tree) + (*self)(ecx, span, token_tree) } } @@ -115,14 +121,18 @@ pub trait IdentMacroExpander { pub type IdentMacroExpanderFn = for<'cx> fn(&'cx mut ExtCtxt, Span, ast::Ident, Vec) -> Box; -impl IdentMacroExpander for IdentMacroExpanderFn { +impl IdentMacroExpander for F + where F : for<'cx> Fn(&'cx mut ExtCtxt, Span, ast::Ident, + Vec) -> Box +{ fn expand<'cx>(&self, cx: &'cx mut ExtCtxt, sp: Span, ident: ast::Ident, token_tree: Vec ) - -> Box { - self.clone()(cx, sp, ident, token_tree) + -> Box + { + (*self)(cx, sp, ident, token_tree) } } diff --git a/src/test/compile-fail/borrowck-autoref-3261.rs b/src/test/compile-fail/borrowck-autoref-3261.rs index 8c6e76e7746..1b4e5891f94 100644 --- a/src/test/compile-fail/borrowck-autoref-3261.rs +++ b/src/test/compile-fail/borrowck-autoref-3261.rs @@ -20,7 +20,7 @@ impl X { } fn main() { - let mut x = X(Either::Right(main)); + let mut x = X(Either::Right(main as fn())); (&mut x).with( |opt| { //~ ERROR cannot borrow `x` as mutable more than once at a time match opt { diff --git a/src/test/compile-fail/cast-to-bare-fn.rs b/src/test/compile-fail/cast-to-bare-fn.rs index 10a829fd794..1db813292b0 100644 --- a/src/test/compile-fail/cast-to-bare-fn.rs +++ b/src/test/compile-fail/cast-to-bare-fn.rs @@ -13,7 +13,7 @@ fn foo(_x: int) { } fn main() { let v: u64 = 5; let x = foo as extern "C" fn() -> int; - //~^ ERROR non-scalar cast + //~^ ERROR mismatched types let y = v as extern "Rust" fn(int) -> (int, int); //~^ ERROR non-scalar cast y(x()); diff --git a/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs b/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs index 27e339180a6..52f4c4749e2 100644 --- a/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs +++ b/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs @@ -8,12 +8,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// Test that coercions from fn item types are ok, but not fn pointer +// types to closures/procs are not allowed. + fn foo() {} -fn main() { +fn fn_item_type() { let f = foo; let f_closure: || = f; - //~^ ERROR: cannot coerce non-statically resolved bare fn to closure - //~^^ HELP: consider embedding the function in a closure } + +fn fn_pointer_type() { + let f = foo as fn(); + let f_closure: || = f; + //~^ ERROR: mismatched types +} + +fn main() { } diff --git a/src/test/compile-fail/issue-10764.rs b/src/test/compile-fail/issue-10764.rs index 0733744b652..cd4ec495556 100644 --- a/src/test/compile-fail/issue-10764.rs +++ b/src/test/compile-fail/issue-10764.rs @@ -12,4 +12,4 @@ fn f(_: extern "Rust" fn()) {} extern fn bar() {} fn main() { f(bar) } -//~^ ERROR: expected `fn()`, found `extern "C" fn()` +//~^ ERROR mismatched types diff --git a/src/test/compile-fail/issue-9575.rs b/src/test/compile-fail/issue-9575.rs index aa3d9d9fef0..6e8f7ffb68d 100644 --- a/src/test/compile-fail/issue-9575.rs +++ b/src/test/compile-fail/issue-9575.rs @@ -10,6 +10,6 @@ #[start] fn start(argc: int, argv: *const *const u8, crate_map: *const u8) -> int { - //~^ ERROR start function expects type: `fn(int, *const *const u8) -> int` + //~^ ERROR incorrect number of function parameters 0 } diff --git a/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs b/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs index 773d6e2c703..4a42728da6f 100644 --- a/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs +++ b/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs @@ -15,7 +15,7 @@ fn a<'a, 'b:'a>(x: &mut &'a int, y: &mut &'b int) { fn b<'a, 'b>(x: &mut &'a int, y: &mut &'b int) { // Illegal now because there is no `'b:'a` declaration. - *x = *y; //~ ERROR mismatched types + *x = *y; //~ ERROR cannot infer } fn c<'a,'b>(x: &mut &'a int, y: &mut &'b int) { diff --git a/src/test/compile-fail/regions-nested-fns.rs b/src/test/compile-fail/regions-nested-fns.rs index cf0b615bb01..f4654367970 100644 --- a/src/test/compile-fail/regions-nested-fns.rs +++ b/src/test/compile-fail/regions-nested-fns.rs @@ -12,10 +12,10 @@ fn ignore(t: T) {} fn nested<'x>(x: &'x int) { let y = 3; - let mut ay = &y; //~ ERROR cannot infer + let mut ay = &y; ignore::< for<'z>|&'z int|>(|z| { - ay = x; + ay = x; //~ ERROR cannot infer ay = &y; ay = z; }); diff --git a/src/test/compile-fail/static-reference-to-fn-1.rs b/src/test/compile-fail/static-reference-to-fn-1.rs index c0d430908a1..bce397c4793 100644 --- a/src/test/compile-fail/static-reference-to-fn-1.rs +++ b/src/test/compile-fail/static-reference-to-fn-1.rs @@ -24,7 +24,7 @@ fn foo() -> Option { fn create() -> A<'static> { A { - func: &foo, //~ ERROR borrowed value does not live long enough + func: &foo, //~ ERROR mismatched types } } diff --git a/src/test/compile-fail/static-reference-to-fn-2.rs b/src/test/compile-fail/static-reference-to-fn-2.rs index 3a0f0a193cf..d7255c3ba06 100644 --- a/src/test/compile-fail/static-reference-to-fn-2.rs +++ b/src/test/compile-fail/static-reference-to-fn-2.rs @@ -9,9 +9,11 @@ // except according to those terms. struct StateMachineIter<'a> { - statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str> + statefn: &'a StateMachineFunc<'a> } +type StateMachineFunc<'a> = fn(&mut StateMachineIter<'a>) -> Option<&'static str>; + impl<'a> Iterator<&'static str> for StateMachineIter<'a> { fn next(&mut self) -> Option<&'static str> { return (*self.statefn)(self); @@ -19,19 +21,19 @@ impl<'a> Iterator<&'static str> for StateMachineIter<'a> { } fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { - self_.statefn = &state2; + self_.statefn = &(state2 as StateMachineFunc); //~^ ERROR borrowed value does not live long enough return Some("state1"); } fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { - self_.statefn = &state3; + self_.statefn = &(state3 as StateMachineFunc); //~^ ERROR borrowed value does not live long enough return Some("state2"); } fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { - self_.statefn = &finished; + self_.statefn = &(finished as StateMachineFunc); //~^ ERROR borrowed value does not live long enough return Some("state3"); } @@ -42,7 +44,7 @@ fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { fn state_iter() -> StateMachineIter<'static> { StateMachineIter { - statefn: &state1 //~ ERROR borrowed value does not live long enough + statefn: &(state1 as StateMachineFunc) //~ ERROR borrowed value does not live long enough } } diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index 974af1e6f3e..e4389cd69dd 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -50,20 +50,20 @@ pub fn bar() { ((::std::fmt::format as - fn(&core::fmt::Arguments<'_>) -> collections::string::String)((&((::std::fmt::Arguments::new - as - fn(&[&str], &[core::fmt::Argument<'_>]) -> core::fmt::Arguments<'_>)((__STATIC_FMTSTR - as - &'static [&'static str]), - (&([] - as - [core::fmt::Argument<'_>; 0]) - as - &[core::fmt::Argument<'_>; 0])) - as - core::fmt::Arguments<'_>) - as - &core::fmt::Arguments<'_>)) + fn(&core::fmt::Arguments<'_>) -> collections::string::String {std::fmt::format})((&((::std::fmt::Arguments::new + as + fn(&[&str], &[core::fmt::Argument<'_>]) -> core::fmt::Arguments<'_> {core::fmt::Arguments<'a>::new})((__STATIC_FMTSTR + as + &'static [&'static str]), + (&([] + as + [core::fmt::Argument<'_>; 0]) + as + &[core::fmt::Argument<'_>; 0])) + as + core::fmt::Arguments<'_>) + as + &core::fmt::Arguments<'_>)) as collections::string::String) } } as collections::string::String); @@ -78,7 +78,8 @@ pub fn id(x: T) -> T { (x as T) } pub fn use_id() { let _ = ((id::<[int; (3u as uint)]> as - fn([int; 3]) -> [int; 3])(([(1 as int), (2 as int), (3 as int)] - as [int; 3])) as [int; 3]); + fn([int; 3]) -> [int; 3] {id})(([(1 as int), (2 as int), + (3 as int)] as [int; 3])) as + [int; 3]); } fn main() { } diff --git a/src/test/run-pass/const-extern-function.rs b/src/test/run-pass/const-extern-function.rs index be7c47dafc0..069ca6ecf49 100644 --- a/src/test/run-pass/const-extern-function.rs +++ b/src/test/run-pass/const-extern-function.rs @@ -18,6 +18,6 @@ struct S { } pub fn main() { - assert!(foopy == f); + assert!(foopy as extern "C" fn() == f); assert!(f == s.f); } diff --git a/src/test/run-pass/extern-compare-with-return-type.rs b/src/test/run-pass/extern-compare-with-return-type.rs index 057394b2624..3febff18704 100644 --- a/src/test/run-pass/extern-compare-with-return-type.rs +++ b/src/test/run-pass/extern-compare-with-return-type.rs @@ -18,15 +18,17 @@ extern fn uintret() -> uint { 22 } extern fn uintvoidret(_x: uint) {} extern fn uintuintuintuintret(x: uint, y: uint, z: uint) -> uint { x+y+z } +type uintuintuintuintret = extern fn(uint,uint,uint) -> uint; pub fn main() { - assert!(voidret1 == voidret1); - assert!(voidret1 != voidret2); + assert!(voidret1 as extern fn() == voidret1 as extern fn()); + assert!(voidret1 as extern fn() != voidret2 as extern fn()); - assert!(uintret == uintret); + assert!(uintret as extern fn() -> uint == uintret as extern fn() -> uint); - assert!(uintvoidret == uintvoidret); + assert!(uintvoidret as extern fn(uint) == uintvoidret as extern fn(uint)); - assert!(uintuintuintuintret == uintuintuintuintret); + assert!(uintuintuintuintret as uintuintuintuintret == + uintuintuintuintret as uintuintuintuintret); } diff --git a/src/test/run-pass/issue-10767.rs b/src/test/run-pass/issue-10767.rs index a30eb8120ea..d2895024187 100644 --- a/src/test/run-pass/issue-10767.rs +++ b/src/test/run-pass/issue-10767.rs @@ -12,5 +12,5 @@ pub fn main() { fn f() { }; - let _: Box = box f; + let _: Box = box() (f as fn()); } diff --git a/src/test/run-pass/issue-15444.rs b/src/test/run-pass/issue-15444.rs index f5618c2c7a3..0f4978d78dd 100644 --- a/src/test/run-pass/issue-15444.rs +++ b/src/test/run-pass/issue-15444.rs @@ -25,5 +25,6 @@ fn thing(a: int, b: int) -> int { } fn main() { + let thing: fn(int, int) -> int = thing; // coerce to fn type bar(&thing); }