Skip to content

Commit 48d4897

Browse files
committed
---
yaml --- r: 5815 b: refs/heads/master c: bc4c3df h: refs/heads/master i: 5813: 9e74449 5811: 5e7687b 5807: ee2dee2 v: v3
1 parent 59e18a9 commit 48d4897

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 89466ffd745547ee8b9c75a12a998dd16ef3bf2a
2+
refs/heads/master: bc4c3df1bf98443411f96112b4ced136e1abcdf1

trunk/src/comp/middle/fn_usage.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export check_crate_fn_usage;
77

88
type fn_usage_ctx = {
99
tcx: ty::ctxt,
10-
unsafe_fn_legal: bool
10+
unsafe_fn_legal: bool,
11+
generic_bare_fn_legal: bool
1112
};
1213

1314
fn fn_usage_view_item(_vi: @ast::view_item,
@@ -34,18 +35,44 @@ fn fn_usage_expr(expr: @ast::expr,
3435
_ {}
3536
}
3637
}
38+
if !ctx.generic_bare_fn_legal
39+
&& ty::expr_has_ty_params(ctx.tcx, expr) {
40+
alt ty::struct(ctx.tcx, ty::expr_ty(ctx.tcx, expr)) {
41+
ty::ty_fn(ast::proto_bare., _, _, _, _) {
42+
ctx.tcx.sess.span_fatal(
43+
expr.span,
44+
"generic bare functions can only be called or bound");
45+
}
46+
_ { }
47+
}
48+
}
3749
}
3850

3951
ast::expr_call(f, args) {
40-
let f_ctx = {unsafe_fn_legal: true with ctx};
52+
let f_ctx = {unsafe_fn_legal: true,
53+
generic_bare_fn_legal: true with ctx};
4154
visit::visit_expr(f, f_ctx, v);
4255

43-
let args_ctx = {unsafe_fn_legal: false with ctx};
56+
let args_ctx = {unsafe_fn_legal: false,
57+
generic_bare_fn_legal: false with ctx};
4458
visit::visit_exprs(args, args_ctx, v);
4559
}
4660

61+
ast::expr_bind(f, args) {
62+
let f_ctx = {unsafe_fn_legal: false,
63+
generic_bare_fn_legal: true with ctx};
64+
v.visit_expr(f, f_ctx, v);
65+
66+
let args_ctx = {unsafe_fn_legal: false,
67+
generic_bare_fn_legal: false with ctx};
68+
for arg in args {
69+
visit::visit_expr_opt(arg, args_ctx, v);
70+
}
71+
}
72+
4773
_ {
48-
let subctx = {unsafe_fn_legal: false with ctx};
74+
let subctx = {unsafe_fn_legal: false,
75+
generic_bare_fn_legal: false with ctx};
4976
visit::visit_expr(expr, subctx, v);
5077
}
5178
}
@@ -57,7 +84,11 @@ fn check_crate_fn_usage(tcx: ty::ctxt, crate: @ast::crate) {
5784
@{visit_expr: fn_usage_expr,
5885
visit_view_item: fn_usage_view_item
5986
with *visit::default_visitor()});
60-
let ctx = {tcx: tcx, unsafe_fn_legal: false};
87+
let ctx = {
88+
tcx: tcx,
89+
unsafe_fn_legal: false,
90+
generic_bare_fn_legal: false
91+
};
6192
visit::visit_crate(*crate, ctx, visit);
6293
}
6394

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// error-pattern: generic bare functions can only be called or bound
2+
// Issue #1038
3+
4+
fn main() {
5+
fn# foo<T>() { }
6+
7+
// This wants to build a closure over type int,
8+
// but there's no way to do that while still being a bare function
9+
let f: fn#() = foo::<int>;
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// error-pattern: generic bare functions can only be called or bound
2+
// Issue #1038
3+
4+
fn main() {
5+
fn# foo<T>(i: T) { }
6+
7+
// This wants to build a closure over type int,
8+
// but there's no way to do that while still being a bare function
9+
f(foo);
10+
}
11+
12+
fn f(i: fn#(&&int)) {
13+
}

0 commit comments

Comments
 (0)