type fn_usage_ctx = {
tcx: ty::ctxt,
- unsafe_fn_legal: bool
+ unsafe_fn_legal: bool,
+ generic_bare_fn_legal: bool
};
fn fn_usage_view_item(_vi: @ast::view_item,
_ {}
}
}
+ if !ctx.generic_bare_fn_legal
+ && ty::expr_has_ty_params(ctx.tcx, expr) {
+ alt ty::struct(ctx.tcx, ty::expr_ty(ctx.tcx, expr)) {
+ ty::ty_fn(ast::proto_bare., _, _, _, _) {
+ ctx.tcx.sess.span_fatal(
+ expr.span,
+ "generic bare functions can only be called or bound");
+ }
+ _ { }
+ }
+ }
}
ast::expr_call(f, args) {
- let f_ctx = {unsafe_fn_legal: true with ctx};
+ let f_ctx = {unsafe_fn_legal: true,
+ generic_bare_fn_legal: true with ctx};
visit::visit_expr(f, f_ctx, v);
- let args_ctx = {unsafe_fn_legal: false with ctx};
+ let args_ctx = {unsafe_fn_legal: false,
+ generic_bare_fn_legal: false with ctx};
visit::visit_exprs(args, args_ctx, v);
}
+ ast::expr_bind(f, args) {
+ let f_ctx = {unsafe_fn_legal: false,
+ generic_bare_fn_legal: true with ctx};
+ v.visit_expr(f, f_ctx, v);
+
+ let args_ctx = {unsafe_fn_legal: false,
+ generic_bare_fn_legal: false with ctx};
+ for arg in args {
+ visit::visit_expr_opt(arg, args_ctx, v);
+ }
+ }
+
_ {
- let subctx = {unsafe_fn_legal: false with ctx};
+ let subctx = {unsafe_fn_legal: false,
+ generic_bare_fn_legal: false with ctx};
visit::visit_expr(expr, subctx, v);
}
}
@{visit_expr: fn_usage_expr,
visit_view_item: fn_usage_view_item
with *visit::default_visitor()});
- let ctx = {tcx: tcx, unsafe_fn_legal: false};
+ let ctx = {
+ tcx: tcx,
+ unsafe_fn_legal: false,
+ generic_bare_fn_legal: false
+ };
visit::visit_crate(*crate, ctx, visit);
}