diff --git a/bevy_lint/src/lints/duplicate_bevy_dependencies.rs b/bevy_lint/src/lints/duplicate_bevy_dependencies.rs new file mode 100644 index 0000000..d66ed3b --- /dev/null +++ b/bevy_lint/src/lints/duplicate_bevy_dependencies.rs @@ -0,0 +1,50 @@ +//! Checks for multiple versions of `bevy` in the dependencies. +//! +//! # Motivation +//! +//! When different third party crates use incompatible versions of Bevy, it can lead to confusing +//! errors and type incompatibilities. + +use crate::declare_bevy_lint; +use clippy_utils::{diagnostics::span_lint, find_crates, sym}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::impl_lint_pass; +use rustc_span::Symbol; + +declare_bevy_lint! { + pub DUPLICATE_BEVY_DEPENDENCIES, + CORRECTNESS, + "duplicate bevy dependencies", +} + +pub(crate) struct DuplicateBevyDependencies { + bevy_symbol: Symbol, +} + +impl Default for DuplicateBevyDependencies { + fn default() -> Self { + Self { + bevy_symbol: sym!(bevy), + } + } +} + +impl_lint_pass! { + DuplicateBevyDependencies => [DUPLICATE_BEVY_DEPENDENCIES.lint] +} + +impl<'tcx> LateLintPass<'tcx> for DuplicateBevyDependencies { + fn check_crate(&mut self, cx: &LateContext<'tcx>) { + let bevy_crates = find_crates(cx.tcx, self.bevy_symbol); + + if bevy_crates.len() > 1 { + let span = cx.tcx.def_span(bevy_crates[1].def_id()); + span_lint( + cx, + DUPLICATE_BEVY_DEPENDENCIES.lint, + span, + "Multiple versions of `bevy` found", + ); + } + } +} diff --git a/bevy_lint/src/lints/mod.rs b/bevy_lint/src/lints/mod.rs index 22b9012..4af1153 100644 --- a/bevy_lint/src/lints/mod.rs +++ b/bevy_lint/src/lints/mod.rs @@ -7,6 +7,7 @@ use crate::lint::BevyLint; use rustc_lint::{Lint, LintStore}; +pub mod duplicate_bevy_dependencies; pub mod insert_event_resource; pub mod main_return_without_appexit; pub mod missing_reflect; @@ -22,6 +23,7 @@ pub(crate) static LINTS: &[&BevyLint] = &[ panicking_methods::PANICKING_WORLD_METHODS, plugin_not_ending_in_plugin::PLUGIN_NOT_ENDING_IN_PLUGIN, zst_query::ZST_QUERY, + duplicate_bevy_dependencies::DUPLICATE_BEVY_DEPENDENCIES, ]; pub(crate) fn register_lints(store: &mut LintStore) { @@ -36,4 +38,7 @@ pub(crate) fn register_passes(store: &mut LintStore) { store.register_late_pass(|_| Box::new(panicking_methods::PanickingMethods)); store.register_late_pass(|_| Box::new(plugin_not_ending_in_plugin::PluginNotEndingInPlugin)); store.register_late_pass(|_| Box::new(zst_query::ZstQuery)); + store.register_late_pass(|_| { + Box::new(duplicate_bevy_dependencies::DuplicateBevyDependencies::default()) + }); }