66use PHPStan \Analyser \Scope ;
77use PHPStan \DependencyInjection \AutowiredParameter ;
88use PHPStan \DependencyInjection \AutowiredService ;
9+ use PHPStan \Reflection \ParametersAcceptor ;
910use PHPStan \Reflection \ReflectionProvider ;
1011use PHPStan \Type \BenevolentUnionType ;
1112use PHPStan \Type \CallableType ;
1617use PHPStan \Type \MixedType ;
1718use PHPStan \Type \NeverType ;
1819use PHPStan \Type \NullType ;
20+ use PHPStan \Type \SimultaneousTypeTraverser ;
1921use PHPStan \Type \StrictMixedType ;
2022use PHPStan \Type \Type ;
2123use PHPStan \Type \TypeCombinator ;
@@ -84,18 +86,21 @@ private function transformCommonType(Type $type): Type
8486 /**
8587 * @return array{Type, bool}
8688 */
87- private function transformAcceptedType (Type $ acceptingType , Type $ acceptedType ): array
89+ private function transformAcceptedType (Type $ acceptingType , Type $ acceptedType, bool $ strictTypes ): array
8890 {
8991 $ checkForUnion = $ this ->checkUnionTypes ;
90- $ acceptedType = TypeTraverser ::map ($ acceptedType , function (Type $ acceptedType , callable $ traverse ) use ($ acceptingType , & $ checkForUnion ): Type {
92+ $ acceptedType = SimultaneousTypeTraverser ::map ($ acceptedType , $ acceptingType , function (Type $ acceptedType , Type $ acceptingType , callable $ traverse ) use (& $ checkForUnion , $ strictTypes ): Type {
9193 if ($ acceptedType instanceof CallableType) {
9294 if ($ acceptedType ->isCommonCallable ()) {
9395 return $ acceptedType ;
9496 }
97+ if (!$ acceptingType instanceof ParametersAcceptor) {
98+ return $ acceptedType ;
99+ }
95100
96101 return new CallableType (
97102 $ acceptedType ->getParameters (),
98- $ traverse ($ this ->transformCommonType ($ acceptedType ->getReturnType ())),
103+ $ traverse ($ this ->transformCommonType ($ acceptedType ->getReturnType ()), $ acceptingType -> getReturnType () ),
99104 $ acceptedType ->isVariadic (),
100105 $ acceptedType ->getTemplateTypeMap (),
101106 $ acceptedType ->getResolvedTemplateTypeMap (),
@@ -109,9 +114,13 @@ private function transformAcceptedType(Type $acceptingType, Type $acceptedType):
109114 return $ acceptedType ;
110115 }
111116
117+ if (!$ acceptingType instanceof ParametersAcceptor) {
118+ return $ acceptedType ;
119+ }
120+
112121 return new ClosureType (
113122 $ acceptedType ->getParameters (),
114- $ traverse ($ this ->transformCommonType ($ acceptedType ->getReturnType ())),
123+ $ traverse ($ this ->transformCommonType ($ acceptedType ->getReturnType ()), $ acceptingType -> getReturnType () ),
115124 $ acceptedType ->isVariadic (),
116125 $ acceptedType ->getTemplateTypeMap (),
117126 $ acceptedType ->getResolvedTemplateTypeMap (),
@@ -127,21 +136,22 @@ private function transformAcceptedType(Type $acceptingType, Type $acceptedType):
127136
128137 if (
129138 !$ this ->checkNullables
130- && !$ acceptingType instanceof NullType
131- && !$ acceptedType instanceof NullType
132139 && !$ acceptedType instanceof BenevolentUnionType
140+ && !$ acceptedType instanceof NullType
141+ && TypeCombinator::containsNull ($ acceptedType )
142+ && !TypeCombinator::containsNull ($ acceptingType )
133143 ) {
134- return $ traverse (TypeCombinator::removeNull ($ acceptedType ));
144+ return $ traverse (TypeCombinator::removeNull ($ acceptedType ), $ acceptingType );
135145 }
136146
137147 if ($ this ->checkBenevolentUnionTypes ) {
138148 if ($ acceptedType instanceof BenevolentUnionType) {
139149 $ checkForUnion = true ;
140- return $ traverse (TypeUtils::toStrictUnion ($ acceptedType ));
150+ return $ traverse (TypeUtils::toStrictUnion ($ acceptedType ), $ acceptingType );
141151 }
142152 }
143153
144- return $ traverse ($ this ->transformCommonType ($ acceptedType ));
154+ return $ traverse ($ this ->transformCommonType ($ acceptedType ), $ acceptingType );
145155 });
146156
147157 return [$ acceptedType , $ checkForUnion ];
@@ -150,7 +160,7 @@ private function transformAcceptedType(Type $acceptingType, Type $acceptedType):
150160 /** @api */
151161 public function accepts (Type $ acceptingType , Type $ acceptedType , bool $ strictTypes ): RuleLevelHelperAcceptsResult
152162 {
153- [$ acceptedType , $ checkForUnion ] = $ this ->transformAcceptedType ($ acceptingType , $ acceptedType );
163+ [$ acceptedType , $ checkForUnion ] = $ this ->transformAcceptedType ($ acceptingType , $ acceptedType, $ strictTypes );
154164 $ acceptingType = $ this ->transformCommonType ($ acceptingType );
155165
156166 $ accepts = $ acceptingType ->accepts ($ acceptedType , $ strictTypes );
0 commit comments