Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d883327
fix: copy in README of lint
J4CKVVH173 Oct 25, 2025
caa0fd1
init lint: added new lint -
J4CKVVH173 Oct 25, 2025
2f822f9
update: the linter logic and tests have been written
J4CKVVH173 Oct 26, 2025
f2c951f
fix: doc strings to fix the tests
J4CKVVH173 Oct 26, 2025
1f8bbdf
Merge branch 'master' into master
J4CKVVH173 Oct 26, 2025
820886c
make doc tests happy
J4CKVVH173 Oct 26, 2025
f003009
Merge branch 'master' of https://github.com/J4CKVVH173/dylint
J4CKVVH173 Oct 26, 2025
297629e
Merge branch 'master' into master
J4CKVVH173 Oct 27, 2025
e0c476c
rallback README fix
J4CKVVH173 Oct 27, 2025
4d27e4d
fix: non_topologically_sorted_functions
J4CKVVH173 Oct 27, 2025
1e54ea2
fix dylint lints
J4CKVVH173 Oct 27, 2025
2565edd
update: examples' README
J4CKVVH173 Oct 27, 2025
5e5d55c
Merge branch 'master' into master
J4CKVVH173 Oct 27, 2025
9434bd4
make the last dylint happy
J4CKVVH173 Oct 27, 2025
0fd99ca
Merge branch 'master' of https://github.com/J4CKVVH173/dylint
J4CKVVH173 Oct 27, 2025
69f18c5
fix extra two problems
J4CKVVH173 Oct 27, 2025
6b99dd4
empty commit
J4CKVVH173 Oct 27, 2025
f62862a
Format lib.rs according to `rustdoc-prettier`
smoelius Oct 28, 2025
17cb027
reduce complexity of logic
J4CKVVH173 Oct 29, 2025
7d2cda6
remove commented code
J4CKVVH173 Oct 29, 2025
89eac23
make readme lint happy
J4CKVVH173 Oct 29, 2025
71ee801
fix: prettier_all_but_examples_and_template
J4CKVVH173 Oct 30, 2025
8a8d6c7
Update examples/restriction/non_topologically_sorted_functions/src/li…
J4CKVVH173 Nov 10, 2025
e2bc1c0
chore: review suggestion of reduce nested of if statement
J4CKVVH173 Nov 10, 2025
579c9a6
fix: clean up forgotten code
J4CKVVH173 Nov 10, 2025
7106705
replace find_caller_body with build in function
J4CKVVH173 Nov 22, 2025
bf5eb85
replace span has map with cx.tcx.def_span
J4CKVVH173 Nov 22, 2025
2f744ac
rall back spans
J4CKVVH173 Nov 22, 2025
50c1b1c
update: return iformation with were the function called
J4CKVVH173 Nov 22, 2025
a1c6e60
make the linter happy
J4CKVVH173 Nov 22, 2025
1aee8dc
Merge branch 'master' into master
J4CKVVH173 Nov 22, 2025
455626e
improve var's name
J4CKVVH173 Nov 23, 2025
e056753
Merge branch 'master' of https://github.com/J4CKVVH173/dylint
J4CKVVH173 Nov 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ updates:
time: "03:00"
allow:
- dependency-type: direct

22 changes: 11 additions & 11 deletions cargo-dylint/tests/integration/fix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@ use tempfile::tempdir;
const CATEGORY: &str = "restriction";
const LIB_NAME: &str = "const_path_join";

fn workspace_metadata(path_spec: &str) -> String {
format!(
r#"
[workspace.metadata.dylint]
libraries = [
{{ path = "{path_spec}" }},
]
"#,
)
}

const MAIN_RS: &str = r#"
fn main() {
let _ = std::path::Path::new("..").join("target");
Expand Down Expand Up @@ -96,3 +85,14 @@ fn append_workspace_metadata(path: &Path) -> Result<()> {

Ok(())
}

fn workspace_metadata(path_spec: &str) -> String {
format!(
r#"
[workspace.metadata.dylint]
libraries = [
{{ path = "{path_spec}" }},
]
"#,
)
}
52 changes: 26 additions & 26 deletions dylint/src/driver_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,6 @@ Deleting this directory will cause Dylint to rebuild the drivers
the next time it needs them, but will have no ill effects.
";

fn cargo_toml(toolchain: &str, dylint_driver_spec: &str) -> String {
format!(
r#"
[package]
name = "dylint_driver-{toolchain}"
version = "0.1.0"
edition = "2018"

[dependencies]
anyhow = "1.0"
env_logger = "0.11"
dylint_driver = {{ {dylint_driver_spec} }}
"#,
)
}

fn rust_toolchain(toolchain: &str) -> String {
format!(
r#"
[toolchain]
channel = "{toolchain}"
components = ["llvm-tools-preview", "rustc-dev"]
"#,
)
}

// smoelius: We need `#![feature(rustc_private)]` as it changes `dylib` linking behavior and allows
// us to link to `rustc_driver`. See: https://github.com/rust-lang/rust/pull/122362
const MAIN_RS: &str = r"
Expand Down Expand Up @@ -238,6 +212,32 @@ fn initialize(toolchain: &str, package: &Path) -> Result<()> {
Ok(())
}

fn cargo_toml(toolchain: &str, dylint_driver_spec: &str) -> String {
format!(
r#"
[package]
name = "dylint_driver-{toolchain}"
version = "0.1.0"
edition = "2018"

[dependencies]
anyhow = "1.0"
env_logger = "0.11"
dylint_driver = {{ {dylint_driver_spec} }}
"#,
)
}

fn rust_toolchain(toolchain: &str) -> String {
format!(
r#"
[toolchain]
channel = "{toolchain}"
components = ["llvm-tools-preview", "rustc-dev"]
"#,
)
}

#[allow(clippy::unwrap_used)]
#[cfg(test)]
mod test {
Expand Down
120 changes: 60 additions & 60 deletions dylint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,57 +308,6 @@ fn name_as_path(name: &str, as_path_only: bool) -> Result<Option<(String, PathBu
Ok(None)
}

fn list_lints(opts: &opts::Dylint, resolved: &ToolchainMap) -> Result<()> {
for (toolchain, paths) in resolved {
for path in paths {
let driver = driver_builder::get(opts, toolchain)?;
let dylint_libs = serde_json::to_string(&[path])?;
let (name, _) =
parse_path_filename(path).ok_or_else(|| anyhow!("Could not parse path"))?;

print!("{name}");
if resolved.keys().len() >= 2 {
print!("@{toolchain}");
}
if paths.len() >= 2 {
let location = display_location(path)?;
print!(" ({location})");
}
println!();

// smoelius: `-W help` is the normal way to list lints, so we can be sure it
// gets the lints loaded. However, we don't actually use it to list the lints.
let mut command = dylint_driver(toolchain, &driver)?;
command
.envs([
(env::DYLINT_LIBS, dylint_libs.as_str()),
(env::DYLINT_LIST, "1"),
])
.args(["rustc", "-W", "help"])
.success()?;

println!();
}
}

Ok(())
}

fn display_location(path: &Path) -> Result<String> {
let current_dir = current_dir().with_context(|| "Could not get current directory")?;
let Ok(path_buf) = path.canonicalize() else {
return Ok("<unbuilt>".to_owned());
};
let parent = path_buf
.parent()
.ok_or_else(|| anyhow!("Could not get parent directory"))?;
Ok(parent
.strip_prefix(&current_dir)
.unwrap_or(parent)
.to_string_lossy()
.to_string())
}

fn check_or_fix(
opts: &opts::Dylint,
check_opts: &opts::Check,
Expand Down Expand Up @@ -471,6 +420,62 @@ fn check_or_fix(
}
}

fn list_lints(opts: &opts::Dylint, resolved: &ToolchainMap) -> Result<()> {
for (toolchain, paths) in resolved {
for path in paths {
let driver = driver_builder::get(opts, toolchain)?;
let dylint_libs = serde_json::to_string(&[path])?;
let (name, _) =
parse_path_filename(path).ok_or_else(|| anyhow!("Could not parse path"))?;

print!("{name}");
if resolved.keys().len() >= 2 {
print!("@{toolchain}");
}
if paths.len() >= 2 {
let location = display_location(path)?;
print!(" ({location})");
}
println!();

// smoelius: `-W help` is the normal way to list lints, so we can be sure it
// gets the lints loaded. However, we don't actually use it to list the lints.
let mut command = dylint_driver(toolchain, &driver)?;
command
.envs([
(env::DYLINT_LIBS, dylint_libs.as_str()),
(env::DYLINT_LIST, "1"),
])
.args(["rustc", "-W", "help"])
.success()?;

println!();
}
}

Ok(())
}

fn display_location(path: &Path) -> Result<String> {
let current_dir = current_dir().with_context(|| "Could not get current directory")?;
let Ok(path_buf) = path.canonicalize() else {
return Ok("<unbuilt>".to_owned());
};
let parent = path_buf
.parent()
.ok_or_else(|| anyhow!("Could not get parent directory"))?;
Ok(parent
.strip_prefix(&current_dir)
.unwrap_or(parent)
.to_string_lossy()
.to_string())
}

fn clippy_disable_docs_links() -> Result<String> {
let val = env::var(env::CLIPPY_DISABLE_DOCS_LINKS).ok();
serde_json::to_string(&val).map_err(Into::into)
}

fn target_dir(opts: &opts::Dylint, toolchain: &str) -> Result<PathBuf> {
let mut command = MetadataCommand::new();
if let Some(path) = &opts.library_selection().manifest_path {
Expand All @@ -484,11 +489,6 @@ fn target_dir(opts: &opts::Dylint, toolchain: &str) -> Result<PathBuf> {
.into())
}

fn clippy_disable_docs_links() -> Result<String> {
let val = env::var(env::CLIPPY_DISABLE_DOCS_LINKS).ok();
serde_json::to_string(&val).map_err(Into::into)
}

#[allow(clippy::unwrap_used)]
#[cfg(all(test, __library_packages))]
mod test {
Expand All @@ -511,10 +511,6 @@ mod test {
..Default::default()
});

fn name_toolchain_map() -> NameToolchainMap<'static> {
NameToolchainMap::new(&OPTS)
}

#[cfg_attr(dylint_lib = "general", allow(non_thread_safe_call_in_test))]
#[test]
fn multiple_libraries_multiple_toolchains() {
Expand Down Expand Up @@ -600,4 +596,8 @@ mod test {

run_with_name_toolchain_map(&opts, &name_toolchain_map).unwrap();
}

fn name_toolchain_map() -> NameToolchainMap<'static> {
NameToolchainMap::new(&OPTS)
}
}
38 changes: 19 additions & 19 deletions dylint/src/library_packages/cargo_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,25 @@ publish = false
))
}

// smoelius: `ident` is based on the function of the same name at:
// https://github.com/rust-lang/cargo/blob/1a498b6c1c119a79d677553862bffae96b97ad7f/src/cargo/sources/git/source.rs#L136-L147
#[allow(clippy::manual_next_back)]
fn ident(url: &str) -> Result<String> {
let url = Url::parse(url)?;

let canonical_url = CanonicalUrl::new(&url)?;

let ident = canonical_url
.raw_canonicalized_url()
.path_segments()
.and_then(|s| s.rev().next())
.unwrap_or("");

let ident = if ident.is_empty() { "_empty" } else { ident };

Ok(format!("{}-{}", ident, short_hash(&canonical_url)))
}

fn inject_dummy_dependencies(
dep_path: &Path,
dep_name: &str,
Expand Down Expand Up @@ -296,25 +315,6 @@ fn cargo_metadata(path: &Path) -> Result<Metadata> {
.map_err(Into::into)
}

// smoelius: `ident` is based on the function of the same name at:
// https://github.com/rust-lang/cargo/blob/1a498b6c1c119a79d677553862bffae96b97ad7f/src/cargo/sources/git/source.rs#L136-L147
#[allow(clippy::manual_next_back)]
fn ident(url: &str) -> Result<String> {
let url = Url::parse(url)?;

let canonical_url = CanonicalUrl::new(&url)?;

let ident = canonical_url
.raw_canonicalized_url()
.path_segments()
.and_then(|s| s.rev().next())
.unwrap_or("");

let ident = if ident.is_empty() { "_empty" } else { ident };

Ok(format!("{}-{}", ident, short_hash(&canonical_url)))
}

fn find_accessed_subdir<'a>(
dep_name: &str,
checkout_path: &Path,
Expand Down
20 changes: 10 additions & 10 deletions dylint/src/library_packages/cargo_cli/util/hex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,6 @@ use std::fs::File;
use std::hash::{Hash, Hasher};
use std::io::Read;

pub fn to_hex(num: u64) -> String {
hex::encode(num.to_le_bytes())
}

pub fn hash_u64<H: Hash>(hashable: H) -> u64 {
let mut hasher = StableHasher::new();
hashable.hash(&mut hasher);
Hasher::finish(&hasher)
}

pub fn hash_u64_file(mut file: &File) -> std::io::Result<u64> {
let mut hasher = StableHasher::new();
let mut buf = [0; 64 * 1024];
Expand All @@ -37,3 +27,13 @@ pub fn hash_u64_file(mut file: &File) -> std::io::Result<u64> {
pub fn short_hash<H: Hash>(hashable: &H) -> String {
to_hex(hash_u64(hashable))
}

pub fn to_hex(num: u64) -> String {
hex::encode(num.to_le_bytes())
}

pub fn hash_u64<H: Hash>(hashable: H) -> u64 {
let mut hasher = StableHasher::new();
hashable.hash(&mut hasher);
Hasher::finish(&hasher)
}
Loading
Loading