Skip to content

Commit

Permalink
feat: insert_unit_bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
DaAlbrecht committed Feb 8, 2025
1 parent 9aaf92a commit 6e2820c
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 20 deletions.
15 changes: 10 additions & 5 deletions bevy_lint/src/lints/insert_unit_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@
//! # bevy::ecs::system::assert_is_system(spawn_decal);
//! ```
use clippy_utils::{diagnostics::span_lint_hir_and_then, sym, ty::match_type};
use clippy_utils::{diagnostics::span_lint_hir_and_then, source::HasSession, sym, ty::match_type};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{Ty, TyKind};
use rustc_middle::{
lint::in_external_macro,
ty::{Ty, TyKind},
};
use rustc_span::Symbol;

use crate::{declare_bevy_lint, declare_bevy_lint_pass, utils::hir_parse::MethodCall};
Expand Down Expand Up @@ -95,9 +98,11 @@ impl<'tcx> LateLintPass<'tcx> for InsertUnitBundle {

let src_ty = cx.typeck_results().expr_ty(receiver).peel_refs();

// If the method call was not to `Commands::spawn()` we skip it.
if !(match_type(cx, src_ty, &crate::paths::COMMANDS)
&& method_path.ident.name == self.spawn)
// If the method call was not to `Commands::spawn()` or originates from an external macro,
// we skip it.
if !(in_external_macro(cx.sess(), span)
|| match_type(cx, src_ty, &crate::paths::COMMANDS)
&& method_path.ident.name == self.spawn)
{
return;
}
Expand Down
47 changes: 47 additions & 0 deletions bevy_lint/tests/ui/insert_unit_bundle/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
//@aux-build:../auxiliary/proc_macros.rs
#![feature(register_tool)]
#![register_tool(bevy)]
#![deny(bevy::insert_unit_bundle)]

use bevy::prelude::*;
extern crate proc_macros;
use proc_macros::external;
use std::f32::consts::PI;

macro_rules! local_macro {
($c:expr) => {
$c.spawn((
Name::new("Decal"),
Transform::from_translation(Vec3::new(0.75, 0.0, 0.0)).rotate_z(PI / 4.0),
//~^ ERROR: inserted a `Bundle` containing a unit `()` type
(
no_op(),
//~^ ERROR: inserted a `Bundle` containing a unit `()` type
GlobalTransform::IDENTITY,
(
(),
//~^ ERROR: inserted a `Bundle` containing a unit `()` type
),
{
no_op();
Transform::default()
},
),
));
};
}

fn main() {
App::new().add_systems(Startup, my_system);
}
Expand Down Expand Up @@ -49,6 +75,27 @@ fn my_system(mut commands: Commands) {
),
),
);
local_macro!(commands);
}

fn no_op() {}

external! {
fn my_system_external(mut commands: Commands) {
commands.spawn((
Name::new("Decal"),
Transform::from_translation(Vec3::new(0.75, 0.0, 0.0)).rotate_z(PI / 4.0),
(
no_op(),
GlobalTransform::IDENTITY,
(
(),
),
{
no_op();
Transform::default()
},
),
));
}
}
66 changes: 51 additions & 15 deletions bevy_lint/tests/ui/insert_unit_bundle/main.stderr
Original file line number Diff line number Diff line change
@@ -1,55 +1,91 @@
error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:15:9
--> tests/ui/insert_unit_bundle/main.rs:41:9
|
15 | Transform::from_translation(Vec3::new(0.75, 0.0, 0.0)).rotate_z(PI / 4.0),
41 | Transform::from_translation(Vec3::new(0.75, 0.0, 0.0)).rotate_z(PI / 4.0),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: unit `()` types are skipped instead of spawned
note: the lint level is defined here
--> tests/ui/insert_unit_bundle/main.rs:3:9
--> tests/ui/insert_unit_bundle/main.rs:4:9
|
3 | #![deny(bevy::insert_unit_bundle)]
4 | #![deny(bevy::insert_unit_bundle)]
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:18:13
--> tests/ui/insert_unit_bundle/main.rs:44:13
|
18 | no_op(),
44 | no_op(),
| ^^^^^^^
|
= note: unit `()` types are skipped instead of spawned

error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:22:17
--> tests/ui/insert_unit_bundle/main.rs:48:17
|
22 | (),
48 | (),
| ^^
|
= note: unit `()` types are skipped instead of spawned

error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:35:13
--> tests/ui/insert_unit_bundle/main.rs:61:13
|
35 | Transform::from_translation(Vec3::new(0.75, 0.0, 0.0)).rotate_z(PI / 4.0),
61 | Transform::from_translation(Vec3::new(0.75, 0.0, 0.0)).rotate_z(PI / 4.0),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: unit `()` types are skipped instead of spawned

error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:38:17
--> tests/ui/insert_unit_bundle/main.rs:64:17
|
38 | no_op(),
64 | no_op(),
| ^^^^^^^
|
= note: unit `()` types are skipped instead of spawned

error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:42:21
--> tests/ui/insert_unit_bundle/main.rs:68:21
|
42 | (),
68 | (),
| ^^
|
= note: unit `()` types are skipped instead of spawned

error: aborting due to 6 previous errors
error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:15:13
|
15 | Transform::from_translation(Vec3::new(0.75, 0.0, 0.0)).rotate_z(PI / 4.0),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
78 | local_macro!(commands);
| ---------------------- in this macro invocation
|
= note: unit `()` types are skipped instead of spawned
= note: this error originates in the macro `local_macro` (in Nightly builds, run with -Z macro-backtrace for more info)

error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:18:17
|
18 | no_op(),
| ^^^^^^^
...
78 | local_macro!(commands);
| ---------------------- in this macro invocation
|
= note: unit `()` types are skipped instead of spawned
= note: this error originates in the macro `local_macro` (in Nightly builds, run with -Z macro-backtrace for more info)

error: inserted a `Bundle` containing a unit `()` type
--> tests/ui/insert_unit_bundle/main.rs:22:21
|
22 | (),
| ^^
...
78 | local_macro!(commands);
| ---------------------- in this macro invocation
|
= note: unit `()` types are skipped instead of spawned
= note: this error originates in the macro `local_macro` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 9 previous errors

0 comments on commit 6e2820c

Please sign in to comment.