about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2019-10-25 13:23:18 -0400
committerMark Rousskov <mark.simulacrum@gmail.com>2019-11-03 21:52:42 -0500
commitc0fdddcb6001b6bd0cd7a6397b9e01e019e553ff (patch)
treef8c78bda306b04a8658b32e188c4d0b260347022
parentea1ff8c07c3937cab6e8d02c2a9f0fbb508046a5 (diff)
downloadrust-c0fdddcb6001b6bd0cd7a6397b9e01e019e553ff.tar.gz
rust-c0fdddcb6001b6bd0cd7a6397b9e01e019e553ff.zip
Move crate type checking later
This allows us to directly pass in a lint buffer
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc_interface/passes.rs2
-rw-r--r--src/librustc_interface/util.rs109
3 files changed, 62 insertions, 51 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 33b9ddaa622..2bcddeaf196 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1469,7 +1469,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
          (such as entering an empty infinite loop) by inserting llvm.sideeffect"),
 }
 
-pub fn default_lib_output() -> CrateType {
+pub const fn default_lib_output() -> CrateType {
     CrateType::Rlib
 }
 
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index a5b00568b53..b6395ccb500 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -295,6 +295,8 @@ fn configure_and_expand_inner<'a>(
         krate
     });
 
+    util::check_attr_crate_type(&krate.attrs, &mut resolver.lint_buffer);
+
     syntax_ext::plugin_macro_defs::inject(
         &mut krate, &mut resolver, plugin_info.syntax_exts, sess.edition()
     );
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 19674659325..d0c15073f16 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -526,6 +526,63 @@ pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguat
     CrateDisambiguator::from(hasher.finish::<Fingerprint>())
 }
 
+pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut lint::LintBuffer) {
+    // Unconditionally collect crate types from attributes to make them used
+    for a in attrs.iter() {
+        if a.check_name(sym::crate_type) {
+            if let Some(n) = a.value_str() {
+                if let Some(_) = categorize_crate_type(n) {
+                    return;
+                }
+
+                if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().kind {
+                    let span = spanned.span;
+                    let lev_candidate = find_best_match_for_name(
+                        CRATE_TYPES.iter().map(|(k, _)| k),
+                        &n.as_str(),
+                        None
+                    );
+                    if let Some(candidate) = lev_candidate {
+                        lint_buffer.buffer_lint_with_diagnostic(
+                            lint::builtin::UNKNOWN_CRATE_TYPES,
+                            ast::CRATE_NODE_ID,
+                            span,
+                            "invalid `crate_type` value",
+                            lint::builtin::BuiltinLintDiagnostics::
+                                UnknownCrateTypes(
+                                    span,
+                                    "did you mean".to_string(),
+                                    format!("\"{}\"", candidate)
+                                )
+                        );
+                    } else {
+                        lint_buffer.buffer_lint(
+                            lint::builtin::UNKNOWN_CRATE_TYPES,
+                            ast::CRATE_NODE_ID,
+                            span,
+                            "invalid `crate_type` value"
+                        );
+                    }
+                }
+            }
+        }
+    }
+}
+
+const CRATE_TYPES: &[(Symbol, config::CrateType)] = &[
+    (sym::rlib, config::CrateType::Rlib),
+    (sym::dylib, config::CrateType::Dylib),
+    (sym::cdylib, config::CrateType::Cdylib),
+    (sym::lib, config::default_lib_output()),
+    (sym::staticlib, config::CrateType::Staticlib),
+    (sym::proc_dash_macro, config::CrateType::ProcMacro),
+    (sym::bin, config::CrateType::Executable),
+];
+
+fn categorize_crate_type(s: Symbol) -> Option<config::CrateType> {
+    Some(CRATE_TYPES.iter().find(|(key, _)| *key == s)?.1)
+}
+
 pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<config::CrateType> {
     // Unconditionally collect crate types from attributes to make them used
     let attr_types: Vec<config::CrateType> = attrs
@@ -533,56 +590,8 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
         .filter_map(|a| {
             if a.check_name(sym::crate_type) {
                 match a.value_str() {
-                    Some(sym::rlib) => Some(config::CrateType::Rlib),
-                    Some(sym::dylib) => Some(config::CrateType::Dylib),
-                    Some(sym::cdylib) => Some(config::CrateType::Cdylib),
-                    Some(sym::lib) => Some(config::default_lib_output()),
-                    Some(sym::staticlib) => Some(config::CrateType::Staticlib),
-                    Some(sym::proc_dash_macro) => Some(config::CrateType::ProcMacro),
-                    Some(sym::bin) => Some(config::CrateType::Executable),
-                    Some(n) => {
-                        let crate_types = vec![
-                            sym::rlib,
-                            sym::dylib,
-                            sym::cdylib,
-                            sym::lib,
-                            sym::staticlib,
-                            sym::proc_dash_macro,
-                            sym::bin
-                        ];
-
-                        if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().kind {
-                            let span = spanned.span;
-                            let lev_candidate = find_best_match_for_name(
-                                crate_types.iter(),
-                                &n.as_str(),
-                                None
-                            );
-                            if let Some(candidate) = lev_candidate {
-                                session.buffer_lint_with_diagnostic_late(
-                                    lint::builtin::UNKNOWN_CRATE_TYPES,
-                                    ast::CRATE_NODE_ID,
-                                    span,
-                                    "invalid `crate_type` value",
-                                    lint::builtin::BuiltinLintDiagnostics::
-                                        UnknownCrateTypes(
-                                            span,
-                                            "did you mean".to_string(),
-                                            format!("\"{}\"", candidate)
-                                        )
-                                );
-                            } else {
-                                session.buffer_lint_late(
-                                    lint::builtin::UNKNOWN_CRATE_TYPES,
-                                    ast::CRATE_NODE_ID,
-                                    span,
-                                    "invalid `crate_type` value"
-                                );
-                            }
-                        }
-                        None
-                    }
-                    None => None
+                    Some(s) => categorize_crate_type(s),
+                    _ => None,
                 }
             } else {
                 None