@@ -151,11 +151,17 @@ static AddressUse HandleCall(ILInstruction addressLoadingInstruction, ILVariable
151151 IType returnType = ( call is NewObj ) ? call . Method . DeclaringType : call . Method . ReturnType ;
152152 if ( returnType . IsByRefLike )
153153 {
154- // If the address is returned from the method, it check whether it's consumed immediately.
155- // This can still be fine, as long as we also check the consumer's other arguments for 'stloc targetVar'.
156- if ( DetermineAddressUse ( call , targetVar ) != AddressUse . Immediate )
157- return AddressUse . Unknown ;
154+ // We exclude Span<T>.Item[int index] and ReadOnlySpan<T>.Item[int index], because it is known that this
155+ // or members of this cannot be returned by the method.
156+ if ( ! IsSpanOfTIndexerAccessor ( call . Method ) )
157+ {
158+ // If the address is returned from the method, it check whether it's consumed immediately.
159+ // This can still be fine, as long as we also check the consumer's other arguments for 'stloc targetVar'.
160+ if ( DetermineAddressUse ( call , targetVar ) != AddressUse . Immediate )
161+ return AddressUse . Unknown ;
162+ }
158163 }
164+
159165 foreach ( var p in call . Method . Parameters )
160166 {
161167 // catch "out Span<int>" and similar
@@ -174,6 +180,16 @@ static AddressUse HandleCall(ILInstruction addressLoadingInstruction, ILVariable
174180 return AddressUse . Immediate ;
175181 }
176182
183+ static bool IsSpanOfTIndexerAccessor ( IMethod method )
184+ {
185+ var declaringType = method . DeclaringType ;
186+ if ( ! declaringType . IsKnownType ( KnownTypeCode . SpanOfT )
187+ && ! declaringType . IsKnownType ( KnownTypeCode . ReadOnlySpanOfT ) )
188+ return false ;
189+ return method . AccessorOwner is IProperty { IsIndexer : true , Name : "Item" , Parameters : [ var param ] , ReturnType : ByReferenceType { ElementType : var rt } }
190+ && param . Type . IsKnownType ( KnownTypeCode . Int32 ) && rt . Equals ( declaringType . TypeArguments [ 0 ] ) ;
191+ }
192+
177193 /// <summary>
178194 /// Given 'ldloc ref_local' and 'ldloca target; stloc ref_local', returns the ldloca.
179195 /// This function must return a non-null LdLoca for every use of a SupportedRefLocal.
0 commit comments