auto cstore = cstore::mk_cstore();
ret session::session(target_cfg, sopts, cstore,
@rec(cm=codemap::new_codemap(), mutable next_id=0),
- 0u);
+ none, 0u);
}
fn parse_pretty(session::session sess, &str name) -> pp_mode {
import syntax::ast;
+import syntax::ast::node_id;
import syntax::codemap;
import codemap::span;
import syntax::ast::ty_mach;
@options opts,
metadata::cstore::cstore cstore,
parse_sess parse_sess,
+ // For a library crate, this is always none
+ mutable option::t[node_id] main_fn,
mutable uint err_count) {
fn get_targ_cfg() -> @config { ret targ_cfg; }
fn get_opts() -> @options { ret opts; }
fn span_str(span sp) -> str {
ret codemap::span_to_str(sp, self.get_codemap());
}
+ fn set_main_id(node_id d) {
+ main_fn = some(d);
+ }
+ fn get_main_id() -> option::t[node_id] { main_fn }
}
// Local Variables:
// fill-column: 78;
import metadata::csearch;
import metadata::cstore;
import driver::session::session;
-import util::common::new_def_hash;
+import util::common::*;
import std::map::new_int_hash;
import std::map::new_str_hash;
import syntax::codemap::span;
fn visit_fn_with_scope(&@env e, &ast::_fn f, &ast::ty_param[] tp, &span sp,
&fn_ident name, node_id id, &scopes sc,
&vt[scopes] v) {
+ // is this a main fn declaration?
+ alt (name) {
+ case (some(?nm)) {
+ if (is_main_name(~[nm]) && !e.sess.get_opts().library) {
+ // This is a main function -- set it in the session
+ // as the main ID
+ e.sess.set_main_id(id);
+ }
+ }
+ case (_) {}
+ }
+
// here's where we need to set up the mapping
// for f's constrs in the table.
import syntax::visit;
import visit::vt;
import util::common;
-import util::common::new_def_hash;
+import util::common::*;
import std::map::new_int_hash;
import std::map::new_str_hash;
-import util::common::local_rhs_span;
import syntax::codemap::span;
import lib::llvm::llvm;
import lib::llvm::builder;
ccx.sess.bug("decl_fn_and_pair(): fn item doesn't have fn type!");
}
}
- let bool is_main =
- str::eq(option::get(std::ivec::last(path)), "main") &&
- !ccx.sess.get_opts().library;
+ let bool is_main = is_main_name(path) && !ccx.sess.get_opts().library;
// Declare the function itself.
let str s =
alt (operator.node) {
case (ast::expr_path(?oper_name)) {
alt (fcx.ccx.tcx.def_map.find(operator.id)) {
- case (some(ast::def_fn(?_d_id,
- ast::pure_fn))) {
+ case (some(ast::def_fn(_, ast::pure_fn))) {
// do nothing
}
case (_) {
}
}
+fn arg_is_argv_ty(&ty::ctxt tcx, &ty::arg a) -> bool {
+ alt (ty::struct(tcx, a.ty)) {
+ case (ty::ty_vec(?mt)) {
+ if (mt.mut != ast::imm) { ret false; }
+ alt (ty::struct(tcx, mt.ty)) {
+ case (ty::ty_str) { ret true; }
+ case (_) { ret false; }
+ }
+ }
+ case (_) { ret false; }
+ }
+}
+
+fn check_main_fn_ty(&ty::ctxt tcx, &ast::node_id main_id) {
+ auto main_t = ty::node_id_to_monotype(tcx, main_id);
+ alt (ty::struct(tcx, main_t)) {
+ case (ty::ty_fn(ast::proto_fn, ?args, ?rs, ast::return, ?constrs)) {
+ auto ok = ivec::len(constrs) == 0u;
+ ok &= ty::type_is_nil(tcx, rs);
+ auto num_args = ivec::len(args);
+ ok &= num_args == 0u || (num_args == 1u &&
+ arg_is_argv_ty(tcx, args.(0)));
+ if (!ok) {
+ tcx.sess.err("Wrong type in main function: found "
+ + ty_to_str(tcx, main_t));
+ }
+ }
+ case (_) {
+ tcx.sess.err("Main has a non-function type: found"
+ + ty_to_str(tcx, main_t));
+ }
+ }
+}
+
+fn check_for_main_fn(&ty::ctxt tcx, &@ast::crate crate) {
+ if (!tcx.sess.get_opts().library) {
+ alt (tcx.sess.get_main_id()) {
+ case (some(?id)) {
+ check_main_fn_ty(tcx, id);
+ }
+ case (none) {
+ tcx.sess.span_err(crate.span,
+ "Main function not found");
+ }
+ }
+ }
+}
+
fn check_crate(&ty::ctxt tcx, &@ast::crate crate) {
collect::collect_item_types(tcx, crate);
rec(visit_item_pre=bind check_item(ccx, _)
with walk::default_visitor());
walk::walk_crate(visit, *crate);
+ check_for_main_fn(tcx, crate);
tcx.sess.abort_if_errors();
}
//
-
+import std::str;
import std::map;
import std::map::hashmap;
import std::uint;
}
}
+fn is_main_name(&str[] path) -> bool {
+ str::eq(option::get(std::ivec::last(path)), "main")
+}
//
// Local Variables:
// mode: rust
--- /dev/null
+// xfail-stage0
+// error-pattern:Wrong type in main function: found fn() -> char
+fn main() -> char {
+}
--- /dev/null
+// xfail-stage0
+// error-pattern:Wrong type in main function: found fn(rec(int x
+fn main(rec(int x, int y) foo) {
+}
--- /dev/null
+// xfail-stage0
+// error-pattern:Main function not found
+fn mian() {
+}