]> git.lizzy.rs Git - rust.git/commitdiff
middle::entry -> rustc_passes
authorMark Rousskov <mark.simulacrum@gmail.com>
Fri, 4 Oct 2019 14:37:40 +0000 (10:37 -0400)
committerMark Rousskov <mark.simulacrum@gmail.com>
Fri, 4 Oct 2019 15:11:33 +0000 (11:11 -0400)
src/librustc/error_codes.rs
src/librustc/lib.rs
src/librustc/middle/entry.rs [deleted file]
src/librustc_interface/passes.rs
src/librustc_passes/entry.rs [new file with mode: 0644]
src/librustc_passes/error_codes.rs
src/librustc_passes/lib.rs

index 968b0b9f2f2b73eab1e5b67b62fbf7ea0d4d93af..9b04c2db9ff3207b2c810605799ea595b245004b 100644 (file)
@@ -466,66 +466,6 @@ fn main() {
 ```
 "##,
 
-// This shouldn't really ever trigger since the repeated value error comes first
-E0136: r##"
-A binary can only have one entry point, and by default that entry point is the
-function `main()`. If there are multiple such functions, please rename one.
-"##,
-
-E0137: r##"
-More than one function was declared with the `#[main]` attribute.
-
-Erroneous code example:
-
-```compile_fail,E0137
-#![feature(main)]
-
-#[main]
-fn foo() {}
-
-#[main]
-fn f() {} // error: multiple functions with a `#[main]` attribute
-```
-
-This error indicates that the compiler found multiple functions with the
-`#[main]` attribute. This is an error because there must be a unique entry
-point into a Rust program. Example:
-
-```
-#![feature(main)]
-
-#[main]
-fn f() {} // ok!
-```
-"##,
-
-E0138: r##"
-More than one function was declared with the `#[start]` attribute.
-
-Erroneous code example:
-
-```compile_fail,E0138
-#![feature(start)]
-
-#[start]
-fn foo(argc: isize, argv: *const *const u8) -> isize {}
-
-#[start]
-fn f(argc: isize, argv: *const *const u8) -> isize {}
-// error: multiple 'start' functions
-```
-
-This error indicates that the compiler found multiple functions with the
-`#[start]` attribute. This is an error because there must be a unique entry
-point into a Rust program. Example:
-
-```
-#![feature(start)]
-
-#[start]
-fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
-```
-"##,
 
 E0139: r##"
 #### Note: this error code is no longer emitted by the compiler.
@@ -1941,21 +1881,6 @@ fn main() {
 ```
 "##,
 
-E0601: r##"
-No `main` function was found in a binary crate. To fix this error, add a
-`main` function. For example:
-
-```
-fn main() {
-    // Your program will start here.
-    println!("Hello world!");
-}
-```
-
-If you don't know the basics of Rust, you can go look to the Rust Book to get
-started: https://doc.rust-lang.org/book/
-"##,
-
 E0602: r##"
 An unknown lint was used on the command line.
 
index 46e39bec3249eb4018c056b4ef1443922d762056..197792eebb32c399a825777a93a3dbb033fcd827 100644 (file)
@@ -104,7 +104,6 @@ pub mod middle {
     pub mod cstore;
     pub mod dependency_format;
     pub mod diagnostic_items;
-    pub mod entry;
     pub mod exported_symbols;
     pub mod free_region;
     pub mod intrinsicck;
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
deleted file mode 100644 (file)
index 660fe14..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-use crate::hir::map as hir_map;
-use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
-use crate::session::{config, Session};
-use crate::session::config::EntryFnType;
-use syntax::attr;
-use syntax::entry::EntryPointType;
-use syntax::symbol::sym;
-use syntax_pos::Span;
-use crate::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
-use crate::hir::itemlikevisit::ItemLikeVisitor;
-use crate::ty::TyCtxt;
-use crate::ty::query::Providers;
-
-struct EntryContext<'a, 'tcx> {
-    session: &'a Session,
-
-    map: &'a hir_map::Map<'tcx>,
-
-    /// The top-level function called `main`.
-    main_fn: Option<(HirId, Span)>,
-
-    /// The function that has attribute named `main`.
-    attr_main_fn: Option<(HirId, Span)>,
-
-    /// The function that has the attribute 'start' on it.
-    start_fn: Option<(HirId, Span)>,
-
-    /// The functions that one might think are `main` but aren't, e.g.
-    /// main functions not defined at the top level. For diagnostics.
-    non_main_fns: Vec<(HirId, Span)> ,
-}
-
-impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
-    fn visit_item(&mut self, item: &'tcx Item) {
-        let def_id = self.map.local_def_id(item.hir_id);
-        let def_key = self.map.def_key(def_id);
-        let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
-        find_item(item, self, at_root);
-    }
-
-    fn visit_trait_item(&mut self, _trait_item: &'tcx TraitItem) {
-        // Entry fn is never a trait item.
-    }
-
-    fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) {
-        // Entry fn is never a trait item.
-    }
-}
-
-fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> {
-    assert_eq!(cnum, LOCAL_CRATE);
-
-    let any_exe = tcx.sess.crate_types.borrow().iter().any(|ty| {
-        *ty == config::CrateType::Executable
-    });
-    if !any_exe {
-        // No need to find a main function.
-        return None;
-    }
-
-    // If the user wants no main function at all, then stop here.
-    if attr::contains_name(&tcx.hir().krate().attrs, sym::no_main) {
-        return None;
-    }
-
-    let mut ctxt = EntryContext {
-        session: tcx.sess,
-        map: tcx.hir(),
-        main_fn: None,
-        attr_main_fn: None,
-        start_fn: None,
-        non_main_fns: Vec::new(),
-    };
-
-    tcx.hir().krate().visit_all_item_likes(&mut ctxt);
-
-    configure_main(tcx, &ctxt)
-}
-
-// Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep
-// them in sync.
-fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
-    match item.kind {
-        ItemKind::Fn(..) => {
-            if attr::contains_name(&item.attrs, sym::start) {
-                EntryPointType::Start
-            } else if attr::contains_name(&item.attrs, sym::main) {
-                EntryPointType::MainAttr
-            } else if item.ident.name == sym::main {
-                if at_root {
-                    // This is a top-level function so can be `main`.
-                    EntryPointType::MainNamed
-                } else {
-                    EntryPointType::OtherMain
-                }
-            } else {
-                EntryPointType::None
-            }
-        }
-        _ => EntryPointType::None,
-    }
-}
-
-
-fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
-    match entry_point_type(item, at_root) {
-        EntryPointType::MainNamed => {
-            if ctxt.main_fn.is_none() {
-                ctxt.main_fn = Some((item.hir_id, item.span));
-            } else {
-                span_err!(ctxt.session, item.span, E0136,
-                          "multiple `main` functions");
-            }
-        },
-        EntryPointType::OtherMain => {
-            ctxt.non_main_fns.push((item.hir_id, item.span));
-        },
-        EntryPointType::MainAttr => {
-            if ctxt.attr_main_fn.is_none() {
-                ctxt.attr_main_fn = Some((item.hir_id, item.span));
-            } else {
-                struct_span_err!(ctxt.session, item.span, E0137,
-                                 "multiple functions with a `#[main]` attribute")
-                .span_label(item.span, "additional `#[main]` function")
-                .span_label(ctxt.attr_main_fn.unwrap().1, "first `#[main]` function")
-                .emit();
-            }
-        },
-        EntryPointType::Start => {
-            if ctxt.start_fn.is_none() {
-                ctxt.start_fn = Some((item.hir_id, item.span));
-            } else {
-                struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions")
-                    .span_label(ctxt.start_fn.unwrap().1, "previous `start` function here")
-                    .span_label(item.span, "multiple `start` functions")
-                    .emit();
-            }
-        }
-        EntryPointType::None => (),
-    }
-}
-
-fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(DefId, EntryFnType)> {
-    if let Some((hir_id, _)) = visitor.start_fn {
-        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Start))
-    } else if let Some((hir_id, _)) = visitor.attr_main_fn {
-        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
-    } else if let Some((hir_id, _)) = visitor.main_fn {
-        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
-    } else {
-        no_main_err(tcx, visitor);
-        None
-    }
-}
-
-fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
-    // There is no main function.
-    let mut err = struct_err!(tcx.sess, E0601,
-        "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
-    let filename = &tcx.sess.local_crate_source_file;
-    let note = if !visitor.non_main_fns.is_empty() {
-        for &(_, span) in &visitor.non_main_fns {
-            err.span_note(span, "here is a function named `main`");
-        }
-        err.note("you have one or more functions named `main` not defined at the crate level");
-        err.help("either move the `main` function definitions or attach the `#[main]` attribute \
-                  to one of them");
-        // There were some functions named `main` though. Try to give the user a hint.
-        format!("the main function must be defined at the crate level{}",
-                 filename.as_ref().map(|f| format!(" (in `{}`)", f.display())).unwrap_or_default())
-    } else if let Some(filename) = filename {
-        format!("consider adding a `main` function to `{}`", filename.display())
-    } else {
-        String::from("consider adding a `main` function at the crate level")
-    };
-    let sp = tcx.hir().krate().span;
-    // The file may be empty, which leads to the diagnostic machinery not emitting this
-    // note. This is a relatively simple way to detect that case and emit a span-less
-    // note instead.
-    if let Ok(_) = tcx.sess.source_map().lookup_line(sp.lo()) {
-        err.set_span(sp);
-        err.span_label(sp, &note);
-    } else {
-        err.note(&note);
-    }
-    if tcx.sess.teach(&err.get_code().unwrap()) {
-        err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
-                  to get started: https://doc.rust-lang.org/book/");
-    }
-    err.emit();
-}
-
-pub fn find_entry_point(tcx: TyCtxt<'_>) -> Option<(DefId, EntryFnType)> {
-    tcx.entry_fn(LOCAL_CRATE)
-}
-
-pub fn provide(providers: &mut Providers<'_>) {
-    *providers = Providers {
-        entry_fn,
-        ..*providers
-    };
-}
index 2fa6edb46b1c04088fc49743d45d4fc04d5d21c8..6d90d1c839ffc52c607f0aeda784cf7a3671ada8 100644 (file)
@@ -785,7 +785,6 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
     rustc_passes::provide(providers);
     rustc_traits::provide(providers);
     middle::region::provide(providers);
-    middle::entry::provide(providers);
     cstore::provide(providers);
     lint::provide(providers);
     rustc_lint::provide(providers);
@@ -891,7 +890,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
     time(sess, "misc checking 1", || {
         parallel!({
             entry_point = time(sess, "looking for entry point", || {
-                middle::entry::find_entry_point(tcx)
+                rustc_passes::entry::find_entry_point(tcx)
             });
 
             time(sess, "looking for plugin registrar", || {
diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs
new file mode 100644 (file)
index 0000000..bf68807
--- /dev/null
@@ -0,0 +1,202 @@
+use rustc::hir::map as hir_map;
+use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
+use rustc::session::{config, Session};
+use rustc::session::config::EntryFnType;
+use syntax::attr;
+use syntax::entry::EntryPointType;
+use syntax::symbol::sym;
+use syntax_pos::Span;
+use rustc::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::ty::TyCtxt;
+use rustc::ty::query::Providers;
+
+struct EntryContext<'a, 'tcx> {
+    session: &'a Session,
+
+    map: &'a hir_map::Map<'tcx>,
+
+    /// The top-level function called `main`.
+    main_fn: Option<(HirId, Span)>,
+
+    /// The function that has attribute named `main`.
+    attr_main_fn: Option<(HirId, Span)>,
+
+    /// The function that has the attribute 'start' on it.
+    start_fn: Option<(HirId, Span)>,
+
+    /// The functions that one might think are `main` but aren't, e.g.
+    /// main functions not defined at the top level. For diagnostics.
+    non_main_fns: Vec<(HirId, Span)> ,
+}
+
+impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
+    fn visit_item(&mut self, item: &'tcx Item) {
+        let def_id = self.map.local_def_id(item.hir_id);
+        let def_key = self.map.def_key(def_id);
+        let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
+        find_item(item, self, at_root);
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &'tcx TraitItem) {
+        // Entry fn is never a trait item.
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) {
+        // Entry fn is never a trait item.
+    }
+}
+
+fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> {
+    assert_eq!(cnum, LOCAL_CRATE);
+
+    let any_exe = tcx.sess.crate_types.borrow().iter().any(|ty| {
+        *ty == config::CrateType::Executable
+    });
+    if !any_exe {
+        // No need to find a main function.
+        return None;
+    }
+
+    // If the user wants no main function at all, then stop here.
+    if attr::contains_name(&tcx.hir().krate().attrs, sym::no_main) {
+        return None;
+    }
+
+    let mut ctxt = EntryContext {
+        session: tcx.sess,
+        map: tcx.hir(),
+        main_fn: None,
+        attr_main_fn: None,
+        start_fn: None,
+        non_main_fns: Vec::new(),
+    };
+
+    tcx.hir().krate().visit_all_item_likes(&mut ctxt);
+
+    configure_main(tcx, &ctxt)
+}
+
+// Beware, this is duplicated in `libsyntax/entry.rs`, so make sure to keep
+// them in sync.
+fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
+    match item.kind {
+        ItemKind::Fn(..) => {
+            if attr::contains_name(&item.attrs, sym::start) {
+                EntryPointType::Start
+            } else if attr::contains_name(&item.attrs, sym::main) {
+                EntryPointType::MainAttr
+            } else if item.ident.name == sym::main {
+                if at_root {
+                    // This is a top-level function so can be `main`.
+                    EntryPointType::MainNamed
+                } else {
+                    EntryPointType::OtherMain
+                }
+            } else {
+                EntryPointType::None
+            }
+        }
+        _ => EntryPointType::None,
+    }
+}
+
+
+fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
+    match entry_point_type(item, at_root) {
+        EntryPointType::MainNamed => {
+            if ctxt.main_fn.is_none() {
+                ctxt.main_fn = Some((item.hir_id, item.span));
+            } else {
+                span_err!(ctxt.session, item.span, E0136,
+                          "multiple `main` functions");
+            }
+        },
+        EntryPointType::OtherMain => {
+            ctxt.non_main_fns.push((item.hir_id, item.span));
+        },
+        EntryPointType::MainAttr => {
+            if ctxt.attr_main_fn.is_none() {
+                ctxt.attr_main_fn = Some((item.hir_id, item.span));
+            } else {
+                struct_span_err!(ctxt.session, item.span, E0137,
+                                 "multiple functions with a `#[main]` attribute")
+                .span_label(item.span, "additional `#[main]` function")
+                .span_label(ctxt.attr_main_fn.unwrap().1, "first `#[main]` function")
+                .emit();
+            }
+        },
+        EntryPointType::Start => {
+            if ctxt.start_fn.is_none() {
+                ctxt.start_fn = Some((item.hir_id, item.span));
+            } else {
+                struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions")
+                    .span_label(ctxt.start_fn.unwrap().1, "previous `start` function here")
+                    .span_label(item.span, "multiple `start` functions")
+                    .emit();
+            }
+        }
+        EntryPointType::None => (),
+    }
+}
+
+fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(DefId, EntryFnType)> {
+    if let Some((hir_id, _)) = visitor.start_fn {
+        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Start))
+    } else if let Some((hir_id, _)) = visitor.attr_main_fn {
+        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
+    } else if let Some((hir_id, _)) = visitor.main_fn {
+        Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
+    } else {
+        no_main_err(tcx, visitor);
+        None
+    }
+}
+
+fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
+    // There is no main function.
+    let mut err = struct_err!(tcx.sess, E0601,
+        "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
+    let filename = &tcx.sess.local_crate_source_file;
+    let note = if !visitor.non_main_fns.is_empty() {
+        for &(_, span) in &visitor.non_main_fns {
+            err.span_note(span, "here is a function named `main`");
+        }
+        err.note("you have one or more functions named `main` not defined at the crate level");
+        err.help("either move the `main` function definitions or attach the `#[main]` attribute \
+                  to one of them");
+        // There were some functions named `main` though. Try to give the user a hint.
+        format!("the main function must be defined at the crate level{}",
+                 filename.as_ref().map(|f| format!(" (in `{}`)", f.display())).unwrap_or_default())
+    } else if let Some(filename) = filename {
+        format!("consider adding a `main` function to `{}`", filename.display())
+    } else {
+        String::from("consider adding a `main` function at the crate level")
+    };
+    let sp = tcx.hir().krate().span;
+    // The file may be empty, which leads to the diagnostic machinery not emitting this
+    // note. This is a relatively simple way to detect that case and emit a span-less
+    // note instead.
+    if let Ok(_) = tcx.sess.source_map().lookup_line(sp.lo()) {
+        err.set_span(sp);
+        err.span_label(sp, &note);
+    } else {
+        err.note(&note);
+    }
+    if tcx.sess.teach(&err.get_code().unwrap()) {
+        err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
+                  to get started: https://doc.rust-lang.org/book/");
+    }
+    err.emit();
+}
+
+pub fn find_entry_point(tcx: TyCtxt<'_>) -> Option<(DefId, EntryFnType)> {
+    tcx.entry_fn(LOCAL_CRATE)
+}
+
+pub fn provide(providers: &mut Providers<'_>) {
+    *providers = Providers {
+        entry_fn,
+        ..*providers
+    };
+}
index af07c790e2a8799a35e82878719ab7d1af97d0f4..78260bd82456f589e40724e6fc1184289792a82d 100644 (file)
@@ -319,6 +319,83 @@ async fn foo() {}
 
 Switch to the Rust 2018 edition to use `async fn`.
 "##,
+
+// This shouldn't really ever trigger since the repeated value error comes first
+E0136: r##"
+A binary can only have one entry point, and by default that entry point is the
+function `main()`. If there are multiple such functions, please rename one.
+"##,
+
+E0137: r##"
+More than one function was declared with the `#[main]` attribute.
+
+Erroneous code example:
+
+```compile_fail,E0137
+#![feature(main)]
+
+#[main]
+fn foo() {}
+
+#[main]
+fn f() {} // error: multiple functions with a `#[main]` attribute
+```
+
+This error indicates that the compiler found multiple functions with the
+`#[main]` attribute. This is an error because there must be a unique entry
+point into a Rust program. Example:
+
+```
+#![feature(main)]
+
+#[main]
+fn f() {} // ok!
+```
+"##,
+
+E0138: r##"
+More than one function was declared with the `#[start]` attribute.
+
+Erroneous code example:
+
+```compile_fail,E0138
+#![feature(start)]
+
+#[start]
+fn foo(argc: isize, argv: *const *const u8) -> isize {}
+
+#[start]
+fn f(argc: isize, argv: *const *const u8) -> isize {}
+// error: multiple 'start' functions
+```
+
+This error indicates that the compiler found multiple functions with the
+`#[start]` attribute. This is an error because there must be a unique entry
+point into a Rust program. Example:
+
+```
+#![feature(start)]
+
+#[start]
+fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
+```
+"##,
+
+E0601: r##"
+No `main` function was found in a binary crate. To fix this error, add a
+`main` function. For example:
+
+```
+fn main() {
+    // Your program will start here.
+    println!("Hello world!");
+}
+```
+
+If you don't know the basics of Rust, you can go look to the Rust Book to get
+started: https://doc.rust-lang.org/book/
+"##,
+
 ;
     E0226, // only a single explicit lifetime bound is permitted
     E0472, // asm! is unsupported on this target
index c0b4a317cf947dcb48c3b629aaaca20e693c349f..1000770fb41e7dfe773d1b3ddc9c8405d5d38709 100644 (file)
 
 #[macro_use]
 extern crate rustc;
+#[macro_use]
+extern crate log;
+#[macro_use]
+extern crate syntax;
 
 use rustc::ty::query::Providers;
 
 pub mod layout_test;
 pub mod loops;
 pub mod dead;
+pub mod entry;
 mod liveness;
 
 pub fn provide(providers: &mut Providers<'_>) {
+    entry::provide(providers);
     loops::provide(providers);
     liveness::provide(providers);
 }