Skip to content

Commit 7f6177e

Browse files
committed
Fix fallout from changes. In cases where stage0 compiler is needed, we
cannot use an `as` expression to coerce, so I used a one-off function instead (this is a no-op in stage0, but in stage1+ it triggers coercion from the fn pointer to the fn item type).
1 parent 211782f commit 7f6177e

19 files changed

+120
-60
lines changed

src/libcore/str.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use iter::range;
3030
use kinds::Sized;
3131
use mem;
3232
use num::Int;
33+
use ops::FnMut;
3334
use option::Option;
3435
use option::Option::{None, Some};
3536
use ops::{Fn, FnMut};

src/librustdoc/html/markdown.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,21 @@ const HOEDOWN_EXTENSIONS: libc::c_uint =
6565

6666
type hoedown_document = libc::c_void; // this is opaque to us
6767

68+
type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
69+
*const hoedown_buffer, *mut libc::c_void);
70+
71+
type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
72+
libc::c_int, *mut libc::c_void);
73+
6874
#[repr(C)]
6975
struct hoedown_renderer {
7076
opaque: *mut hoedown_html_renderer_state,
71-
blockcode: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
72-
*const hoedown_buffer, *mut libc::c_void)>,
77+
blockcode: Option<blockcodefn>,
7378
blockquote: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
7479
*mut libc::c_void)>,
7580
blockhtml: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
7681
*mut libc::c_void)>,
77-
header: Option<extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
78-
libc::c_int, *mut libc::c_void)>,
82+
header: Option<headerfn>,
7983
other: [libc::size_t, ..28],
8084
}
8185

@@ -281,8 +285,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
281285
toc_builder: if print_toc {Some(TocBuilder::new())} else {None}
282286
};
283287
(*(*renderer).opaque).opaque = &mut opaque as *mut _ as *mut libc::c_void;
284-
(*renderer).blockcode = Some(block);
285-
(*renderer).header = Some(header);
288+
(*renderer).blockcode = Some(block as blockcodefn);
289+
(*renderer).header = Some(header as headerfn);
286290

287291
let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
288292
hoedown_document_render(document, ob, s.as_ptr(),
@@ -354,8 +358,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
354358
unsafe {
355359
let ob = hoedown_buffer_new(DEF_OUNIT);
356360
let renderer = hoedown_html_renderer_new(0, 0);
357-
(*renderer).blockcode = Some(block);
358-
(*renderer).header = Some(header);
361+
(*renderer).blockcode = Some(block as blockcodefn);
362+
(*renderer).header = Some(header as headerfn);
359363
(*(*renderer).opaque).opaque = tests as *mut _ as *mut libc::c_void;
360364

361365
let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);

src/libstd/path/windows.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,12 @@ impl Path {
829829
let s = if self.has_nonsemantic_trailing_slash() {
830830
self.repr.slice_to(self.repr.len()-1)
831831
} else { self.repr.as_slice() };
832-
let idx = s.rfind(if !prefix_is_verbatim(self.prefix) { is_sep }
833-
else { is_sep_verbatim });
832+
let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) {
833+
is_sep
834+
} else {
835+
is_sep_verbatim
836+
};
837+
let idx = s.rfind(sep_test);
834838
let prefixlen = self.prefix_len();
835839
self.sepidx = idx.and_then(|x| if x < prefixlen { None } else { Some(x) });
836840
}
@@ -1048,7 +1052,11 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
10481052

10491053
// None result means the string didn't need normalizing
10501054
fn normalize_helper<'a>(s: &'a str, prefix: Option<PathPrefix>) -> (bool, Option<Vec<&'a str>>) {
1051-
let f = if !prefix_is_verbatim(prefix) { is_sep } else { is_sep_verbatim };
1055+
let f: fn(char) -> bool = if !prefix_is_verbatim(prefix) {
1056+
is_sep
1057+
} else {
1058+
is_sep_verbatim
1059+
};
10521060
let is_abs = s.len() > prefix_len(prefix) && f(s.char_at(prefix_len(prefix)));
10531061
let s_ = s.slice_from(prefix_len(prefix));
10541062
let s_ = if is_abs { s_.slice_from(1) } else { s_ };

src/libstd/thread_local/mod.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,12 @@ macro_rules! __thread_local_inner {
189189
}
190190
};
191191

192-
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
192+
#[cfg(all(stage0, not(any(target_os = "macos", target_os = "linux"))))]
193193
const INIT: ::std::thread_local::KeyInner<$t> = {
194194
unsafe extern fn __destroy(ptr: *mut u8) {
195195
::std::thread_local::destroy_value::<$t>(ptr);
196196
}
197+
197198
::std::thread_local::KeyInner {
198199
inner: ::std::cell::UnsafeCell { value: $init },
199200
os: ::std::thread_local::OsStaticKey {
@@ -203,6 +204,21 @@ macro_rules! __thread_local_inner {
203204
}
204205
};
205206

207+
#[cfg(all(not(stage0), not(any(target_os = "macos", target_os = "linux"))))]
208+
const INIT: ::std::thread_local::KeyInner<$t> = {
209+
unsafe extern fn __destroy(ptr: *mut u8) {
210+
::std::thread_local::destroy_value::<$t>(ptr);
211+
}
212+
213+
::std::thread_local::KeyInner {
214+
inner: ::std::cell::UnsafeCell { value: $init },
215+
os: ::std::thread_local::OsStaticKey {
216+
inner: ::std::thread_local::OS_INIT_INNER,
217+
dtor: ::std::option::Option::Some(__destroy as unsafe extern fn(*mut u8)),
218+
},
219+
}
220+
};
221+
206222
INIT
207223
});
208224
}
@@ -323,6 +339,12 @@ mod imp {
323339
// *should* be the case that this loop always terminates because we
324340
// provide the guarantee that a TLS key cannot be set after it is
325341
// flagged for destruction.
342+
#[cfg(not(stage0))]
343+
static DTORS: os::StaticKey = os::StaticKey {
344+
inner: os::INIT_INNER,
345+
dtor: Some(run_dtors as unsafe extern "C" fn(*mut u8)),
346+
};
347+
#[cfg(stage0)]
326348
static DTORS: os::StaticKey = os::StaticKey {
327349
inner: os::INIT_INNER,
328350
dtor: Some(run_dtors),

src/libsyntax/ext/base.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,16 @@ pub trait ItemDecorator {
5050
push: |P<ast::Item>|);
5151
}
5252

53-
impl ItemDecorator for fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P<ast::Item>|) {
53+
impl<F> ItemDecorator for F
54+
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P<ast::Item>|)
55+
{
5456
fn expand(&self,
5557
ecx: &mut ExtCtxt,
5658
sp: Span,
5759
meta_item: &ast::MetaItem,
5860
item: &ast::Item,
5961
push: |P<ast::Item>|) {
60-
self.clone()(ecx, sp, meta_item, item, push)
62+
(*self)(ecx, sp, meta_item, item, push)
6163
}
6264
}
6365

@@ -70,14 +72,16 @@ pub trait ItemModifier {
7072
-> P<ast::Item>;
7173
}
7274

73-
impl ItemModifier for fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<ast::Item> {
75+
impl<F> ItemModifier for F
76+
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<ast::Item>
77+
{
7478
fn expand(&self,
7579
ecx: &mut ExtCtxt,
7680
span: Span,
7781
meta_item: &ast::MetaItem,
7882
item: P<ast::Item>)
7983
-> P<ast::Item> {
80-
self.clone()(ecx, span, meta_item, item)
84+
(*self)(ecx, span, meta_item, item)
8185
}
8286
}
8387

@@ -93,13 +97,15 @@ pub trait TTMacroExpander {
9397
pub type MacroExpanderFn =
9498
for<'cx> fn(&'cx mut ExtCtxt, Span, &[ast::TokenTree]) -> Box<MacResult+'cx>;
9599

96-
impl TTMacroExpander for MacroExpanderFn {
100+
impl<F> TTMacroExpander for F
101+
where F : for<'cx> Fn(&'cx mut ExtCtxt, Span, &[ast::TokenTree]) -> Box<MacResult+'cx>
102+
{
97103
fn expand<'cx>(&self,
98104
ecx: &'cx mut ExtCtxt,
99105
span: Span,
100106
token_tree: &[ast::TokenTree])
101107
-> Box<MacResult+'cx> {
102-
self.clone()(ecx, span, token_tree)
108+
(*self)(ecx, span, token_tree)
103109
}
104110
}
105111

@@ -115,14 +121,18 @@ pub trait IdentMacroExpander {
115121
pub type IdentMacroExpanderFn =
116122
for<'cx> fn(&'cx mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult+'cx>;
117123

118-
impl IdentMacroExpander for IdentMacroExpanderFn {
124+
impl<F> IdentMacroExpander for F
125+
where F : for<'cx> Fn(&'cx mut ExtCtxt, Span, ast::Ident,
126+
Vec<ast::TokenTree>) -> Box<MacResult+'cx>
127+
{
119128
fn expand<'cx>(&self,
120129
cx: &'cx mut ExtCtxt,
121130
sp: Span,
122131
ident: ast::Ident,
123132
token_tree: Vec<ast::TokenTree> )
124-
-> Box<MacResult+'cx> {
125-
self.clone()(cx, sp, ident, token_tree)
133+
-> Box<MacResult+'cx>
134+
{
135+
(*self)(cx, sp, ident, token_tree)
126136
}
127137
}
128138

src/test/compile-fail/borrowck-autoref-3261.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl X {
2020
}
2121

2222
fn main() {
23-
let mut x = X(Either::Right(main));
23+
let mut x = X(Either::Right(main as fn()));
2424
(&mut x).with(
2525
|opt| { //~ ERROR cannot borrow `x` as mutable more than once at a time
2626
match opt {

src/test/compile-fail/cast-to-bare-fn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn foo(_x: int) { }
1313
fn main() {
1414
let v: u64 = 5;
1515
let x = foo as extern "C" fn() -> int;
16-
//~^ ERROR non-scalar cast
16+
//~^ ERROR mismatched types
1717
let y = v as extern "Rust" fn(int) -> (int, int);
1818
//~^ ERROR non-scalar cast
1919
y(x());

src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// Test that coercions from fn item types are ok, but not fn pointer
12+
// types to closures/procs are not allowed.
13+
1114
fn foo() {}
1215

13-
fn main() {
16+
fn fn_item_type() {
1417
let f = foo;
1518

1619
let f_closure: || = f;
17-
//~^ ERROR: cannot coerce non-statically resolved bare fn to closure
18-
//~^^ HELP: consider embedding the function in a closure
1920
}
21+
22+
fn fn_pointer_type() {
23+
let f = foo as fn();
24+
let f_closure: || = f;
25+
//~^ ERROR: mismatched types
26+
}
27+
28+
fn main() { }

src/test/compile-fail/issue-10764.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ fn f(_: extern "Rust" fn()) {}
1212
extern fn bar() {}
1313

1414
fn main() { f(bar) }
15-
//~^ ERROR: expected `fn()`, found `extern "C" fn()`
15+
//~^ ERROR mismatched types

src/test/compile-fail/issue-9575.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010

1111
#[start]
1212
fn start(argc: int, argv: *const *const u8, crate_map: *const u8) -> int {
13-
//~^ ERROR start function expects type: `fn(int, *const *const u8) -> int`
13+
//~^ ERROR incorrect number of function parameters
1414
0
1515
}

src/test/compile-fail/regions-lifetime-bounds-on-fns.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn a<'a, 'b:'a>(x: &mut &'a int, y: &mut &'b int) {
1515

1616
fn b<'a, 'b>(x: &mut &'a int, y: &mut &'b int) {
1717
// Illegal now because there is no `'b:'a` declaration.
18-
*x = *y; //~ ERROR mismatched types
18+
*x = *y; //~ ERROR cannot infer
1919
}
2020

2121
fn c<'a,'b>(x: &mut &'a int, y: &mut &'b int) {

src/test/compile-fail/regions-nested-fns.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ fn ignore<T>(t: T) {}
1212

1313
fn nested<'x>(x: &'x int) {
1414
let y = 3;
15-
let mut ay = &y; //~ ERROR cannot infer
15+
let mut ay = &y;
1616

1717
ignore::< for<'z>|&'z int|>(|z| {
18-
ay = x;
18+
ay = x; //~ ERROR cannot infer
1919
ay = &y;
2020
ay = z;
2121
});

src/test/compile-fail/static-reference-to-fn-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn foo() -> Option<int> {
2424

2525
fn create() -> A<'static> {
2626
A {
27-
func: &foo, //~ ERROR borrowed value does not live long enough
27+
func: &foo, //~ ERROR mismatched types
2828
}
2929
}
3030

src/test/compile-fail/static-reference-to-fn-2.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,31 @@
99
// except according to those terms.
1010

1111
struct StateMachineIter<'a> {
12-
statefn: &'a fn(&mut StateMachineIter<'a>) -> Option<&'static str>
12+
statefn: &'a StateMachineFunc<'a>
1313
}
1414

15+
type StateMachineFunc<'a> = fn(&mut StateMachineIter<'a>) -> Option<&'static str>;
16+
1517
impl<'a> Iterator<&'static str> for StateMachineIter<'a> {
1618
fn next(&mut self) -> Option<&'static str> {
1719
return (*self.statefn)(self);
1820
}
1921
}
2022

2123
fn state1(self_: &mut StateMachineIter) -> Option<&'static str> {
22-
self_.statefn = &state2;
24+
self_.statefn = &(state2 as StateMachineFunc);
2325
//~^ ERROR borrowed value does not live long enough
2426
return Some("state1");
2527
}
2628

2729
fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> {
28-
self_.statefn = &state3;
30+
self_.statefn = &(state3 as StateMachineFunc);
2931
//~^ ERROR borrowed value does not live long enough
3032
return Some("state2");
3133
}
3234

3335
fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> {
34-
self_.statefn = &finished;
36+
self_.statefn = &(finished as StateMachineFunc);
3537
//~^ ERROR borrowed value does not live long enough
3638
return Some("state3");
3739
}
@@ -42,7 +44,7 @@ fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> {
4244

4345
fn state_iter() -> StateMachineIter<'static> {
4446
StateMachineIter {
45-
statefn: &state1 //~ ERROR borrowed value does not live long enough
47+
statefn: &(state1 as StateMachineFunc) //~ ERROR borrowed value does not live long enough
4648
}
4749
}
4850

src/test/pretty/issue-4264.pp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,20 @@
5050

5151

5252
((::std::fmt::format as
53-
fn(&core::fmt::Arguments<'_>) -> collections::string::String)((&((::std::fmt::Arguments::new
54-
as
55-
fn(&[&str], &[core::fmt::Argument<'_>]) -> core::fmt::Arguments<'_>)((__STATIC_FMTSTR
56-
as
57-
&'static [&'static str]),
58-
(&([]
59-
as
60-
[core::fmt::Argument<'_>; 0])
61-
as
62-
&[core::fmt::Argument<'_>; 0]))
63-
as
64-
core::fmt::Arguments<'_>)
65-
as
66-
&core::fmt::Arguments<'_>))
53+
fn(&core::fmt::Arguments<'_>) -> collections::string::String {std::fmt::format})((&((::std::fmt::Arguments::new
54+
as
55+
fn(&[&str], &[core::fmt::Argument<'_>]) -> core::fmt::Arguments<'_> {core::fmt::Arguments<'a>::new})((__STATIC_FMTSTR
56+
as
57+
&'static [&'static str]),
58+
(&([]
59+
as
60+
[core::fmt::Argument<'_>; 0])
61+
as
62+
&[core::fmt::Argument<'_>; 0]))
63+
as
64+
core::fmt::Arguments<'_>)
65+
as
66+
&core::fmt::Arguments<'_>))
6767
as collections::string::String)
6868
}
6969
} as collections::string::String);
@@ -78,7 +78,8 @@
7878
pub fn use_id() {
7979
let _ =
8080
((id::<[int; (3u as uint)]> as
81-
fn([int; 3]) -> [int; 3])(([(1 as int), (2 as int), (3 as int)]
82-
as [int; 3])) as [int; 3]);
81+
fn([int; 3]) -> [int; 3] {id})(([(1 as int), (2 as int),
82+
(3 as int)] as [int; 3])) as
83+
[int; 3]);
8384
}
8485
fn main() { }

src/test/run-pass/const-extern-function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ struct S {
1818
}
1919

2020
pub fn main() {
21-
assert!(foopy == f);
21+
assert!(foopy as extern "C" fn() == f);
2222
assert!(f == s.f);
2323
}

0 commit comments

Comments
 (0)