mirror of
https://github.com/Noratrieb/cargo-minimize.git
synced 2026-01-14 16:35:01 +01:00
things
This commit is contained in:
parent
a9e488f3e3
commit
0f05ef625a
11 changed files with 153 additions and 70 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
|
@ -156,6 +156,7 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustfix",
|
"rustfix",
|
||||||
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"syn",
|
"syn",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
|
|
@ -1107,18 +1108,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.145"
|
version = "1.0.151"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.145"
|
version = "1.0.151"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
|
checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -1194,9 +1195,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.102"
|
version = "1.0.106"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
|
checksum = "09ee3a69cd2c7e06684677e5629b3878b253af05e4714964204279c6bc02cf0b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ prettyplease = "0.1.19"
|
||||||
proc-macro2 = { version = "1.0.48", features = ["span-locations"] }
|
proc-macro2 = { version = "1.0.48", features = ["span-locations"] }
|
||||||
quote = "1.0.21"
|
quote = "1.0.21"
|
||||||
rustfix = "0.6.1"
|
rustfix = "0.6.1"
|
||||||
|
serde = { version = "1.0.151", features = ["derive"] }
|
||||||
serde_json = "1.0.90"
|
serde_json = "1.0.90"
|
||||||
syn = { version = "1.0.101", features = ["full", "visit", "visit-mut"] }
|
syn = { version = "1.0.101", features = ["full", "visit", "visit-mut"] }
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
|
|
|
||||||
67
src/build.rs
67
src/build.rs
|
|
@ -1,6 +1,7 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use rustfix::diagnostics::Diagnostic;
|
use rustfix::diagnostics::Diagnostic;
|
||||||
use std::{collections::HashSet, fmt::Display, path::PathBuf};
|
use serde::Deserialize;
|
||||||
|
use std::{collections::HashSet, fmt::Display, path::PathBuf, process::Command};
|
||||||
|
|
||||||
use crate::Options;
|
use crate::Options;
|
||||||
|
|
||||||
|
|
@ -35,9 +36,16 @@ impl Build {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&self) -> Result<BuildResult> {
|
pub fn build(&self) -> Result<BuildResult> {
|
||||||
|
if self.no_verify {
|
||||||
|
return Ok(BuildResult {
|
||||||
|
reproduces_issue: false,
|
||||||
|
no_verify: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let reproduces_issue = match &self.mode {
|
let reproduces_issue = match &self.mode {
|
||||||
BuildMode::Cargo => {
|
BuildMode::Cargo => {
|
||||||
let mut cmd = std::process::Command::new("cargo");
|
let mut cmd = Command::new("cargo");
|
||||||
cmd.arg("build");
|
cmd.arg("build");
|
||||||
|
|
||||||
let output =
|
let output =
|
||||||
|
|
@ -47,12 +55,12 @@ impl Build {
|
||||||
output.contains("internal compiler error")
|
output.contains("internal compiler error")
|
||||||
}
|
}
|
||||||
BuildMode::Script(script_path) => {
|
BuildMode::Script(script_path) => {
|
||||||
let mut cmd = std::process::Command::new(script_path);
|
let mut cmd = Command::new(script_path);
|
||||||
|
|
||||||
cmd.output().context("spawning script")?.status.success()
|
cmd.output().context("spawning script")?.status.success()
|
||||||
}
|
}
|
||||||
BuildMode::Rustc => {
|
BuildMode::Rustc => {
|
||||||
let mut cmd = std::process::Command::new("rustc");
|
let mut cmd = Command::new("rustc");
|
||||||
cmd.args(["--edition", "2018"]);
|
cmd.args(["--edition", "2018"]);
|
||||||
cmd.arg(&self.input_path);
|
cmd.arg(&self.input_path);
|
||||||
|
|
||||||
|
|
@ -71,11 +79,26 @@ impl Build {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_suggestions(&self) -> Result<(Vec<Diagnostic>, Vec<rustfix::Suggestion>)> {
|
pub fn get_suggestions(&self) -> Result<(Vec<Diagnostic>, Vec<rustfix::Suggestion>)> {
|
||||||
match self.mode {
|
let diags = match self.mode {
|
||||||
BuildMode::Cargo => {
|
BuildMode::Cargo => {
|
||||||
todo!();
|
let mut cmd = Command::new("cargo");
|
||||||
|
cmd.args(["build", "--message-format=json"]);
|
||||||
|
|
||||||
|
let cmd_output = cmd.output()?;
|
||||||
|
let output = String::from_utf8(cmd_output.stdout.clone())?;
|
||||||
|
|
||||||
|
let messages = serde_json::Deserializer::from_str(&output)
|
||||||
|
.into_iter::<CargoJsonCompileMessage>()
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
let diags = messages
|
||||||
|
.into_iter()
|
||||||
|
.filter(|msg| msg.reason == "compiler-message")
|
||||||
|
.flat_map(|msg| msg.message)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
diags
|
||||||
}
|
}
|
||||||
BuildMode::Script(_) => todo!(),
|
|
||||||
BuildMode::Rustc => {
|
BuildMode::Rustc => {
|
||||||
let mut cmd = std::process::Command::new("rustc");
|
let mut cmd = std::process::Command::new("rustc");
|
||||||
cmd.args(["--edition", "2018", "--error-format=json"]);
|
cmd.args(["--edition", "2018", "--error-format=json"]);
|
||||||
|
|
@ -84,19 +107,27 @@ impl Build {
|
||||||
let output = cmd.output()?.stderr;
|
let output = cmd.output()?.stderr;
|
||||||
let output = String::from_utf8(output)?;
|
let output = String::from_utf8(output)?;
|
||||||
|
|
||||||
let diags = serde_json::Deserializer::from_str(&output).into_iter::<Diagnostic>().collect::<Result<_, _>>()?;
|
let diags = serde_json::Deserializer::from_str(&output)
|
||||||
|
.into_iter::<Diagnostic>()
|
||||||
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
let suggestions = rustfix::get_suggestions_from_json(
|
diags
|
||||||
&output,
|
}
|
||||||
|
BuildMode::Script(_) => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut suggestions = Vec::new();
|
||||||
|
for cargo_msg in &diags {
|
||||||
|
// One diagnostic line might have multiple suggestions
|
||||||
|
suggestions.extend(rustfix::collect_suggestions(
|
||||||
|
cargo_msg,
|
||||||
&HashSet::new(),
|
&HashSet::new(),
|
||||||
rustfix::Filter::Everything,
|
rustfix::Filter::Everything,
|
||||||
)
|
));
|
||||||
.context("reading output as rustfix suggestions")?;
|
}
|
||||||
|
|
||||||
Ok((diags, suggestions))
|
Ok((diags, suggestions))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BuildResult {
|
pub struct BuildResult {
|
||||||
|
|
@ -114,8 +145,14 @@ impl Display for BuildResult {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match (self.reproduces_issue, self.no_verify) {
|
match (self.reproduces_issue, self.no_verify) {
|
||||||
(true, _) => f.write_str("yes"),
|
(true, _) => f.write_str("yes"),
|
||||||
(false, true) => f.write_str("no (ignore)"),
|
(false, true) => f.write_str("yes (no-verify)"),
|
||||||
(false, false) => f.write_str("no"),
|
(false, false) => f.write_str("no"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct CargoJsonCompileMessage {
|
||||||
|
pub reason: String,
|
||||||
|
pub message: Option<Diagnostic>,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use syn::{parse_quote, visit_mut::VisitMut};
|
use syn::{parse_quote, visit_mut::VisitMut};
|
||||||
|
|
||||||
use crate::processor::{ProcessChecker, Processor};
|
use crate::processor::{ProcessChecker, ProcessState, Processor};
|
||||||
|
|
||||||
struct Visitor<'a> {
|
struct Visitor<'a> {
|
||||||
current_path: Vec<String>,
|
current_path: Vec<String>,
|
||||||
checker: &'a mut ProcessChecker,
|
checker: &'a mut ProcessChecker,
|
||||||
|
|
||||||
loop_expr: syn::Block,
|
loop_expr: syn::Block,
|
||||||
has_made_change: bool,
|
process_state: ProcessState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Visitor<'a> {
|
impl<'a> Visitor<'a> {
|
||||||
|
|
@ -16,7 +16,7 @@ impl<'a> Visitor<'a> {
|
||||||
Self {
|
Self {
|
||||||
current_path: Vec::new(),
|
current_path: Vec::new(),
|
||||||
checker,
|
checker,
|
||||||
has_made_change: false,
|
process_state: ProcessState::NoChange,
|
||||||
loop_expr: parse_quote! { { loop {} } },
|
loop_expr: parse_quote! { { loop {} } },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +30,7 @@ impl VisitMut for Visitor<'_> {
|
||||||
}))] if loop_body.stmts.is_empty() => {}
|
}))] if loop_body.stmts.is_empty() => {}
|
||||||
_ => {
|
_ => {
|
||||||
*block = self.loop_expr.clone();
|
*block = self.loop_expr.clone();
|
||||||
self.has_made_change = true;
|
self.process_state = ProcessState::Changed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -65,10 +65,14 @@ impl VisitMut for Visitor<'_> {
|
||||||
pub struct EverybodyLoops;
|
pub struct EverybodyLoops;
|
||||||
|
|
||||||
impl Processor for EverybodyLoops {
|
impl Processor for EverybodyLoops {
|
||||||
fn process_file(&mut self, krate: &mut syn::File, checker: &mut ProcessChecker) -> bool {
|
fn process_file(
|
||||||
|
&mut self,
|
||||||
|
krate: &mut syn::File,
|
||||||
|
checker: &mut ProcessChecker,
|
||||||
|
) -> ProcessState {
|
||||||
let mut visitor = Visitor::new(checker);
|
let mut visitor = Visitor::new(checker);
|
||||||
visitor.visit_file_mut(krate);
|
visitor.visit_file_mut(krate);
|
||||||
visitor.has_made_change
|
visitor.process_state
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
use syn::{parse_quote, visit_mut::VisitMut, Visibility};
|
use syn::{parse_quote, visit_mut::VisitMut, Visibility};
|
||||||
|
|
||||||
use crate::processor::{ProcessChecker, Processor};
|
use crate::processor::{ProcessChecker, Processor, ProcessState};
|
||||||
|
|
||||||
struct Visitor {
|
struct Visitor {
|
||||||
pub_crate: Visibility,
|
pub_crate: Visibility,
|
||||||
has_made_change: bool,
|
process_state: ProcessState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitor {
|
impl Visitor {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
has_made_change: false,
|
process_state: ProcessState::NoChange,
|
||||||
pub_crate: parse_quote! { pub(crate) },
|
pub_crate: parse_quote! { pub(crate) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ impl Visitor {
|
||||||
impl VisitMut for Visitor {
|
impl VisitMut for Visitor {
|
||||||
fn visit_visibility_mut(&mut self, vis: &mut Visibility) {
|
fn visit_visibility_mut(&mut self, vis: &mut Visibility) {
|
||||||
if let Visibility::Public(_) = vis {
|
if let Visibility::Public(_) = vis {
|
||||||
self.has_made_change = true;
|
self.process_state = ProcessState::Changed;
|
||||||
*vis = self.pub_crate.clone();
|
*vis = self.pub_crate.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,10 +29,10 @@ impl VisitMut for Visitor {
|
||||||
pub struct Privatize {}
|
pub struct Privatize {}
|
||||||
|
|
||||||
impl Processor for Privatize {
|
impl Processor for Privatize {
|
||||||
fn process_file(&mut self, krate: &mut syn::File, _: &mut ProcessChecker) -> bool {
|
fn process_file(&mut self, krate: &mut syn::File, _: &mut ProcessChecker) -> ProcessState {
|
||||||
let mut visitor = Visitor::new();
|
let mut visitor = Visitor::new();
|
||||||
visitor.visit_file_mut(krate);
|
visitor.visit_file_mut(krate);
|
||||||
visitor.has_made_change
|
visitor.process_state
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct SourceFile {
|
pub struct SourceFile {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
mod files;
|
mod files;
|
||||||
mod reaper;
|
mod reaper;
|
||||||
|
|
||||||
use std::{ffi::OsStr, path::Path};
|
use std::{collections::HashSet, ffi::OsStr, path::Path};
|
||||||
|
|
||||||
use anyhow::{ensure, Context, Result};
|
use anyhow::{ensure, Context, Result};
|
||||||
|
|
||||||
|
|
@ -10,11 +10,19 @@ use crate::{build::Build, processor::files::Changes, Options};
|
||||||
use self::files::SourceFile;
|
use self::files::SourceFile;
|
||||||
|
|
||||||
pub trait Processor {
|
pub trait Processor {
|
||||||
fn process_file(&mut self, krate: &mut syn::File, checker: &mut ProcessChecker) -> bool;
|
fn process_file(&mut self, krate: &mut syn::File, checker: &mut ProcessChecker)
|
||||||
|
-> ProcessState;
|
||||||
|
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum ProcessState {
|
||||||
|
NoChange,
|
||||||
|
Changed,
|
||||||
|
FileInvalidated,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Minimizer {
|
pub struct Minimizer {
|
||||||
files: Vec<SourceFile>,
|
files: Vec<SourceFile>,
|
||||||
|
|
@ -61,12 +69,18 @@ impl Minimizer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut invalidated_files = HashSet::new();
|
||||||
|
|
||||||
for mut pass in passes {
|
for mut pass in passes {
|
||||||
'pass: loop {
|
'pass: loop {
|
||||||
println!("Starting a round of {}", pass.name());
|
println!("Starting a round of {}", pass.name());
|
||||||
let mut changes = Changes::default();
|
let mut changes = Changes::default();
|
||||||
|
|
||||||
for file in &self.files {
|
for file in &self.files {
|
||||||
|
if invalidated_files.contains(file) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let file_display = file.path.display();
|
let file_display = file.path.display();
|
||||||
|
|
||||||
let mut change = file.try_change(&mut changes)?;
|
let mut change = file.try_change(&mut changes)?;
|
||||||
|
|
@ -76,7 +90,8 @@ impl Minimizer {
|
||||||
|
|
||||||
let has_made_change = pass.process_file(&mut krate, &mut ProcessChecker {});
|
let has_made_change = pass.process_file(&mut krate, &mut ProcessChecker {});
|
||||||
|
|
||||||
if has_made_change {
|
match has_made_change {
|
||||||
|
ProcessState::Changed | ProcessState::FileInvalidated => {
|
||||||
let result = prettyplease::unparse(&krate);
|
let result = prettyplease::unparse(&krate);
|
||||||
|
|
||||||
change.write(&result)?;
|
change.write(&result)?;
|
||||||
|
|
@ -90,10 +105,16 @@ impl Minimizer {
|
||||||
} else {
|
} else {
|
||||||
change.rollback()?;
|
change.rollback()?;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
if has_made_change == ProcessState::FileInvalidated {
|
||||||
|
invalidated_files.insert(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProcessState::NoChange => {
|
||||||
println!("{file_display}: After {}: no change", pass.name());
|
println!("{file_display}: After {}: no change", pass.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !changes.had_changes() {
|
if !changes.had_changes() {
|
||||||
println!("Finished {}", pass.name());
|
println!("Finished {}", pass.name());
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//! Deletes dead code.
|
//! Deletes dead code.
|
||||||
|
|
||||||
use super::{files::Changes, Minimizer, Processor};
|
use super::{files::Changes, Minimizer, ProcessState, Processor};
|
||||||
use anyhow::{ensure, Context, Result};
|
use anyhow::{ensure, Context, Result};
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use rustfix::{diagnostics::Diagnostic, Suggestion};
|
use rustfix::{diagnostics::Diagnostic, Suggestion};
|
||||||
|
|
@ -38,7 +38,10 @@ impl Minimizer {
|
||||||
// Always unconditionally apply unused imports.
|
// Always unconditionally apply unused imports.
|
||||||
self.apply_unused_imports(&suggestions_for_file)?;
|
self.apply_unused_imports(&suggestions_for_file)?;
|
||||||
|
|
||||||
self.run_passes([Box::new(DeleteUnusedFunctions(diags)) as Box<dyn Processor>])
|
self.run_passes([Box::new(DeleteUnusedFunctions {
|
||||||
|
diags,
|
||||||
|
invalid: false,
|
||||||
|
}) as Box<dyn Processor>])
|
||||||
.context("deleting unused functions")?;
|
.context("deleting unused functions")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -49,11 +52,12 @@ impl Minimizer {
|
||||||
suggestions: &HashMap<&str, Vec<&Suggestion>>,
|
suggestions: &HashMap<&str, Vec<&Suggestion>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (file, suggestions) in suggestions {
|
for (file, suggestions) in suggestions {
|
||||||
let file = self
|
let Some(file) = self
|
||||||
.files
|
.files
|
||||||
.iter()
|
.iter()
|
||||||
.find(|source| source.path == Path::new(file))
|
.find(|source| source.path == Path::new(file)) else {
|
||||||
.expect("unknown file");
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
let mut changes = &mut Changes::default();
|
let mut changes = &mut Changes::default();
|
||||||
|
|
||||||
|
|
@ -85,14 +89,27 @@ impl Minimizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DeleteUnusedFunctions(Vec<Diagnostic>);
|
struct DeleteUnusedFunctions {
|
||||||
|
diags: Vec<Diagnostic>,
|
||||||
|
invalid: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl Processor for DeleteUnusedFunctions {
|
impl Processor for DeleteUnusedFunctions {
|
||||||
fn process_file(&mut self, krate: &mut syn::File, _: &mut super::ProcessChecker) -> bool {
|
fn process_file(
|
||||||
let mut visitor = FindUnusedFunction::new(self.0.iter());
|
&mut self,
|
||||||
|
krate: &mut syn::File,
|
||||||
|
_: &mut super::ProcessChecker,
|
||||||
|
) -> ProcessState {
|
||||||
|
assert!(!self.invalid, "processing with invalid state");
|
||||||
|
|
||||||
|
let mut visitor = FindUnusedFunction::new(self.diags.iter());
|
||||||
visitor.visit_file_mut(krate);
|
visitor.visit_file_mut(krate);
|
||||||
|
|
||||||
visitor.has_change
|
if visitor.process_state == ProcessState::FileInvalidated {
|
||||||
|
self.invalid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
visitor.process_state
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
|
|
@ -122,7 +139,7 @@ impl Unused {
|
||||||
|
|
||||||
struct FindUnusedFunction {
|
struct FindUnusedFunction {
|
||||||
unused_functions: Vec<Unused>,
|
unused_functions: Vec<Unused>,
|
||||||
has_change: bool,
|
process_state: ProcessState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FindUnusedFunction {
|
impl FindUnusedFunction {
|
||||||
|
|
@ -160,7 +177,7 @@ impl FindUnusedFunction {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
unused_functions,
|
unused_functions,
|
||||||
has_change: false,
|
process_state: ProcessState::NoChange,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,11 +191,11 @@ impl FindUnusedFunction {
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
span_matches < 2,
|
span_matches < 2,
|
||||||
"multiple dead_code spans matched identifier: {span_matches}"
|
"multiple dead_code spans matched identifier: {span_matches}."
|
||||||
);
|
);
|
||||||
|
|
||||||
if span_matches == 1 {
|
if span_matches == 1 {
|
||||||
self.has_change = true;
|
self.process_state = ProcessState::FileInvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
span_matches == 0
|
span_matches == 0
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,3 @@
|
||||||
name = "hello-world"
|
name = "hello-world"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
fn unused() {}
|
fn unused() {
|
||||||
|
loop {}
|
||||||
fn main() {
|
|
||||||
unused();
|
|
||||||
}
|
}
|
||||||
|
fn main() {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod other;
|
||||||
|
|
|
||||||
3
test-cases/unused-code/src/other.rs
Normal file
3
test-cases/unused-code/src/other.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn unused() {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue