@@ -72,11 +72,10 @@ fn extract_unused_type(message: &str) -> Option<&str> {
7272/// Also handles `?Type` (nullable shorthand): `?string` with unused
7373/// `null` becomes `string`, and `?string` with unused `string` becomes
7474/// `null`.
75- fn remove_type_from_union ( full_type : & str , unused_type : & str ) -> Option < PhpType > {
76- let parsed = PhpType :: parse ( full_type) ;
75+ fn remove_type_from_union ( full_type : & PhpType , unused_type : & str ) -> Option < PhpType > {
7776 let unused_parsed = PhpType :: parse ( unused_type) ;
7877
79- match & parsed {
78+ match full_type {
8079 PhpType :: Union ( members) => {
8180 let remaining: Vec < & PhpType > = members
8281 . iter ( )
@@ -411,7 +410,7 @@ impl Backend {
411410 let native_type = extract_native_return_type ( & lines, paren_line, paren_col, brace_line) ;
412411 let has_native_match = native_type
413412 . as_ref ( )
414- . is_some_and ( |t| remove_type_from_union ( & t . to_string ( ) , unused_type) . is_some ( ) ) ;
413+ . is_some_and ( |t| remove_type_from_union ( t , unused_type) . is_some ( ) ) ;
415414
416415 // Check the docblock @return tag.
417416 let func_line = find_func_keyword_line ( & lines, paren_line) . unwrap_or ( diag_line) ;
@@ -427,7 +426,7 @@ impl Backend {
427426 } ;
428427 let has_doc_match = doc_return_type
429428 . as_ref ( )
430- . is_some_and ( |t| remove_type_from_union ( & t . to_string ( ) , unused_type) . is_some ( ) ) ;
429+ . is_some_and ( |t| remove_type_from_union ( t , unused_type) . is_some ( ) ) ;
431430
432431 // Only offer the action if we can actually remove the type
433432 // from at least one location.
@@ -484,7 +483,7 @@ impl Backend {
484483 // ── Update native return type ───────────────────────────────
485484 if let Some ( native_type) =
486485 extract_native_return_type ( & lines, paren_line, paren_col, brace_line)
487- && let Some ( new_type) = remove_type_from_union ( & native_type. to_string ( ) , unused_type)
486+ && let Some ( new_type) = remove_type_from_union ( & native_type, unused_type)
488487 {
489488 // Convert the new type to a valid native hint.
490489 let native_hint = new_type
@@ -513,7 +512,7 @@ impl Backend {
513512 docblock_info. doc_start_line ,
514513 docblock_info. doc_end_line ,
515514 )
516- && let Some ( new_type) = remove_type_from_union ( & doc_type. to_string ( ) , unused_type)
515+ && let Some ( new_type) = remove_type_from_union ( & doc_type, unused_type)
517516 && let Some ( edit) = find_and_replace_return_tag_type (
518517 & lines,
519518 docblock_info. doc_start_line ,
@@ -578,7 +577,7 @@ pub(crate) fn is_remove_unused_return_type_stale(
578577
579578 // Check native return type.
580579 if let Some ( native_type) = extract_native_return_type ( & lines, paren_line, paren_col, brace_line)
581- && remove_type_from_union ( & native_type. to_string ( ) , unused_type) . is_some ( )
580+ && remove_type_from_union ( & native_type, unused_type) . is_some ( )
582581 {
583582 // The unused type is still present → not stale.
584583 return false ;
@@ -594,7 +593,7 @@ pub(crate) fn is_remove_unused_return_type_stale(
594593 docblock_info. doc_start_line ,
595594 docblock_info. doc_end_line ,
596595 )
597- && remove_type_from_union ( & doc_type. to_string ( ) , unused_type) . is_some ( )
596+ && remove_type_from_union ( & doc_type, unused_type) . is_some ( )
598597 {
599598 return false ;
600599 }
@@ -640,67 +639,73 @@ mod tests {
640639 #[ test]
641640 fn removes_null_from_string_null ( ) {
642641 assert_eq ! (
643- remove_type_from_union( "string|null" , "null" ) ,
642+ remove_type_from_union( & PhpType :: parse ( "string|null" ) , "null" ) ,
644643 Some ( PhpType :: parse( "string" ) )
645644 ) ;
646645 }
647646
648647 #[ test]
649648 fn removes_string_from_string_null ( ) {
650649 assert_eq ! (
651- remove_type_from_union( "string|null" , "string" ) ,
650+ remove_type_from_union( & PhpType :: parse ( "string|null" ) , "string" ) ,
652651 Some ( PhpType :: parse( "null" ) )
653652 ) ;
654653 }
655654
656655 #[ test]
657656 fn removes_from_three_member_union ( ) {
658657 assert_eq ! (
659- remove_type_from_union( "string|int|null" , "null" ) ,
658+ remove_type_from_union( & PhpType :: parse ( "string|int|null" ) , "null" ) ,
660659 Some ( PhpType :: parse( "string|int" ) )
661660 ) ;
662661 }
663662
664663 #[ test]
665664 fn removes_middle_member ( ) {
666665 assert_eq ! (
667- remove_type_from_union( "string|int|bool" , "int" ) ,
666+ remove_type_from_union( & PhpType :: parse ( "string|int|bool" ) , "int" ) ,
668667 Some ( PhpType :: parse( "string|bool" ) )
669668 ) ;
670669 }
671670
672671 #[ test]
673672 fn removes_from_intersection ( ) {
674673 assert_eq ! (
675- remove_type_from_union( "Foo&Bar" , "Bar" ) ,
674+ remove_type_from_union( & PhpType :: parse ( "Foo&Bar" ) , "Bar" ) ,
676675 Some ( PhpType :: parse( "Foo" ) )
677676 ) ;
678677 }
679678
680679 #[ test]
681680 fn removes_null_from_nullable ( ) {
682681 assert_eq ! (
683- remove_type_from_union( "?string" , "null" ) ,
682+ remove_type_from_union( & PhpType :: parse ( "?string" ) , "null" ) ,
684683 Some ( PhpType :: parse( "string" ) )
685684 ) ;
686685 }
687686
688687 #[ test]
689688 fn removes_inner_from_nullable ( ) {
690689 assert_eq ! (
691- remove_type_from_union( "?string" , "string" ) ,
690+ remove_type_from_union( & PhpType :: parse ( "?string" ) , "string" ) ,
692691 Some ( PhpType :: parse( "null" ) )
693692 ) ;
694693 }
695694
696695 #[ test]
697696 fn returns_none_when_not_found ( ) {
698- assert_eq ! ( remove_type_from_union( "string|int" , "bool" ) , None ) ;
697+ assert_eq ! (
698+ remove_type_from_union( & PhpType :: parse( "string|int" ) , "bool" ) ,
699+ None
700+ ) ;
699701 }
700702
701703 #[ test]
702704 fn returns_none_for_single_type ( ) {
703- assert_eq ! ( remove_type_from_union( "string" , "string" ) , None ) ;
705+ assert_eq ! (
706+ remove_type_from_union( & PhpType :: parse( "string" ) , "string" ) ,
707+ None
708+ ) ;
704709 }
705710
706711 // ── stale detection ────────────────────────────────────────────
0 commit comments