@@ -79,7 +79,7 @@ private Expression MakeFromRangeEndpoint(ExpressionSyntax syntax, IExpressionPar
7979 /// </summary>
8080 /// <param name="method">The method symbol to check.</param>
8181 /// <returns>True if the method is a slice method; false otherwise.</returns>
82- private bool IsSliceWithRange ( IMethodSymbol method , [ NotNullWhen ( true ) ] out RangeExpressionSyntax ? range )
82+ private bool IsSlice ( IMethodSymbol method , out RangeExpressionSyntax ? range )
8383 {
8484 range = null ;
8585
@@ -89,8 +89,7 @@ private bool IsSliceWithRange(IMethodSymbol method, [NotNullWhen(true)] out Rang
8989 }
9090
9191 return ( method . Name == "Slice" || method . Name == "Substring" )
92- && method . Parameters . Length == 2
93- && range is not null ;
92+ && method . Parameters . Length == 2 ;
9493 }
9594
9695 /// <summary>
@@ -111,21 +110,31 @@ private bool IsSliceWithRange(IMethodSymbol method, [NotNullWhen(true)] out Rang
111110 ///
112111 /// Even though index expressions can't technically be used in this way, they signal that we
113112 /// could perceive ^b as "length - b".
113+ ///
114+ /// Call arguments are only populated when a range expression is directly available in
115+ /// the list of arguments.
116+ /// This means that cases like below are not handled.
117+ /// System.Range x = 1..3;
118+ /// s[x]
114119 /// </summary>
115120 /// <param name="trapFile">The trap file to write to.</param>
116121 /// <param name="slice">The slice method symbol.</param>
117122 /// <param name="range">The range expression syntax.</param>
118- private void PopulateSlice ( TextWriter trapFile , IMethodSymbol slice , RangeExpressionSyntax range )
123+ private void PopulateSlice ( TextWriter trapFile , IMethodSymbol slice , RangeExpressionSyntax ? range )
119124 {
120- var left = range . LeftOperand is ExpressionSyntax lsyntax
121- ? MakeFromRangeEndpoint ( lsyntax , this , 0 )
122- : MakeZeroLiteral ( this , 0 ) ;
125+ if ( range is not null )
126+ {
127+ // Populate the call arguments in case
128+ var left = range . LeftOperand is ExpressionSyntax lsyntax
129+ ? MakeFromRangeEndpoint ( lsyntax , this , 0 )
130+ : MakeZeroLiteral ( this , 0 ) ;
123131
124- var right = range . RightOperand is ExpressionSyntax rsyntax
125- ? MakeFromRangeEndpoint ( rsyntax , this , 1 )
126- : MakeZeroFromEndExpression ( this , 1 ) ;
132+ var right = range . RightOperand is ExpressionSyntax rsyntax
133+ ? MakeFromRangeEndpoint ( rsyntax , this , 1 )
134+ : MakeZeroFromEndExpression ( this , 1 ) ;
127135
128- SetExprArgument ( trapFile , left , right ) ;
136+ SetExprArgument ( trapFile , left , right ) ;
137+ }
129138 trapFile . expr_call ( this , Method . Create ( Context , slice ) ) ;
130139 }
131140
@@ -144,7 +153,7 @@ protected override void PopulateExpression(TextWriter trapFile)
144153 Create ( Context , qualifier , this , - 1 ) ;
145154
146155 var target = GetTargetSymbol ( ) ;
147- if ( target is IMethodSymbol method && IsSliceWithRange ( method , out var range ) )
156+ if ( target is IMethodSymbol method && IsSlice ( method , out var range ) )
148157 {
149158 // When an indexer on a span or string is used in conjunction with a range expression, the compiler translates
150159 // this into a call to the "Slice" or "Substring" method.
0 commit comments