aboutsummaryrefslogtreecommitdiffstats
path: root/support/crown/src/main.rs
blob: cd64ca7331fda963af6b83755d3ed1e2c0272ed7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#![feature(rustc_private)]
#![warn(rustc::internal)]
#![allow(rustc::potential_query_instability)]

// This rustc crates are private so they must be manually imported.
extern crate rustc_ast;
extern crate rustc_driver;
extern crate rustc_error_messages;
extern crate rustc_errors;
extern crate rustc_hir;
extern crate rustc_infer;
extern crate rustc_interface;
extern crate rustc_lint;
extern crate rustc_log;
extern crate rustc_middle;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_trait_selection;
extern crate rustc_type_ir;

use std::path::Path;
use std::process::ExitCode;

use rustc_driver::Callbacks;
use rustc_interface::interface::Config;

mod common;

#[cfg(feature = "unrooted_must_root_lint")]
mod unrooted_must_root;

#[cfg(feature = "trace_in_no_trace_lint")]
mod trace_in_no_trace;

mod crown_is_not_used;

struct MyCallbacks;

impl Callbacks for MyCallbacks {
    fn config(&mut self, config: &mut Config) {
        config.register_lints = Some(Box::new(move |sess, lint_store| {
            // Skip checks for proc-macro crates.
            if sess
                .opts
                .crate_types
                .contains(&rustc_session::config::CrateType::ProcMacro)
            {
                return;
            }

            crown_is_not_used::register(lint_store);
            #[cfg(feature = "unrooted_must_root_lint")]
            unrooted_must_root::register(lint_store);
            #[cfg(feature = "trace_in_no_trace_lint")]
            trace_in_no_trace::register(lint_store);
        }));
    }
}

fn main() -> ExitCode {
    let handler =
        rustc_session::EarlyDiagCtxt::new(rustc_session::config::ErrorOutputType::default());
    rustc_driver::init_logger(&handler, rustc_log::LoggerConfig::from_env("CROWN_LOG"));
    let mut args: Vec<_> = std::env::args().collect();

    // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
    // We're invoking the compiler programmatically, so we ignore this
    if args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref()) {
        args.remove(1);
    }

    // Pass cfg(crown) to rustc
    args.extend(["--cfg".to_owned(), "crown".to_owned()]);

    match rustc_driver::RunCompiler::new(&args, &mut MyCallbacks).run() {
        Ok(_) => ExitCode::SUCCESS,
        Err(_) => ExitCode::FAILURE,
    }
}