@@ -9175,5 +9175,223 @@ public void F(int x)
9175
9175
}" ) ;
9176
9176
Assert . Equal ( "x, a" , GetSymbolNamesJoined ( analysis . DataFlowsIn ) ) ;
9177
9177
}
9178
+
9179
+ [ Fact , WorkItem ( 59738 , "https://github.com/dotnet/roslyn/issues/59738" ) ]
9180
+ public void TestDataFlowsOfIdentifierWithDelegateConversion ( )
9181
+ {
9182
+ var results = CompileAndAnalyzeDataFlowExpression ( @"
9183
+ using System;
9184
+
9185
+ internal static class NoExtensionMethods
9186
+ {
9187
+ internal static Func<T> AsFunc<T>(this T value) where T : class
9188
+ {
9189
+ return new Func<T>(/*<bind>*/ value /*</bind>*/.Return);
9190
+ }
9191
+
9192
+ private static T Return<T>(this T value)
9193
+ {
9194
+ return value;
9195
+ }
9196
+
9197
+ static void Main()
9198
+ {
9199
+ Console.WriteLine(((object)42).AsFunc()());
9200
+ }
9201
+ }
9202
+ " ) ;
9203
+ Assert . True ( results . Succeeded ) ;
9204
+ Assert . Null ( GetSymbolNamesJoined ( results . Captured ) ) ;
9205
+ Assert . Null ( GetSymbolNamesJoined ( results . CapturedInside ) ) ;
9206
+ Assert . Null ( GetSymbolNamesJoined ( results . CapturedOutside ) ) ;
9207
+ Assert . Null ( GetSymbolNamesJoined ( results . VariablesDeclared ) ) ;
9208
+ Assert . Null ( GetSymbolNamesJoined ( results . DataFlowsOut ) ) ;
9209
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( results . DefinitelyAssignedOnEntry ) ) ;
9210
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( results . DefinitelyAssignedOnExit ) ) ;
9211
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( results . ReadInside ) ) ;
9212
+ Assert . Null ( GetSymbolNamesJoined ( results . WrittenInside ) ) ;
9213
+ Assert . Null ( GetSymbolNamesJoined ( results . ReadOutside ) ) ;
9214
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( results . WrittenOutside ) ) ;
9215
+ Assert . Null ( GetSymbolNamesJoined ( results . UsedLocalFunctions ) ) ;
9216
+ }
9217
+
9218
+ [ Fact ]
9219
+ public void TestDataFlowsOfIdentifierWithDelegateConversionCast ( )
9220
+ {
9221
+ var analysis = CompileAndAnalyzeDataFlowExpression ( @"
9222
+ using System;
9223
+
9224
+ internal static class NoExtensionMethods
9225
+ {
9226
+ internal static Func<T> AsFunc<T>(this T value) where T : class
9227
+ {
9228
+ return (Func<T>)/*<bind>*/ value /*</bind>*/.Return;
9229
+ }
9230
+
9231
+ private static T Return<T>(this T value)
9232
+ {
9233
+ return value;
9234
+ }
9235
+ }
9236
+ " ) ;
9237
+ Assert . True ( analysis . Succeeded ) ;
9238
+ Assert . Null ( GetSymbolNamesJoined ( analysis . AlwaysAssigned ) ) ;
9239
+ Assert . Null ( GetSymbolNamesJoined ( analysis . Captured ) ) ;
9240
+ Assert . Null ( GetSymbolNamesJoined ( analysis . CapturedInside ) ) ;
9241
+ Assert . Null ( GetSymbolNamesJoined ( analysis . CapturedOutside ) ) ;
9242
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . DataFlowsIn ) ) ;
9243
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . DefinitelyAssignedOnEntry ) ) ;
9244
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . DefinitelyAssignedOnExit ) ) ;
9245
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . ReadInside ) ) ;
9246
+ Assert . Null ( GetSymbolNamesJoined ( analysis . ReadOutside ) ) ;
9247
+ Assert . Null ( GetSymbolNamesJoined ( analysis . VariablesDeclared ) ) ;
9248
+ Assert . Null ( GetSymbolNamesJoined ( analysis . WrittenInside ) ) ;
9249
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . WrittenOutside ) ) ;
9250
+ }
9251
+
9252
+ [ Fact ]
9253
+ public void TestDataFlowsOfIdentifierWithDelegateConversionTarget ( )
9254
+ {
9255
+ var analysis = CompileAndAnalyzeDataFlowExpression ( @"
9256
+ using System;
9257
+
9258
+ internal static class NoExtensionMethods
9259
+ {
9260
+ internal static Func<T> AsFunc<T>(this T value) where T : class
9261
+ {
9262
+ Func<T> result =/*<bind>*/ value /*</bind>*/.Return;
9263
+ return result;
9264
+ }
9265
+
9266
+ private static T Return<T>(this T value)
9267
+ {
9268
+ return value;
9269
+ }
9270
+ }
9271
+ " ) ;
9272
+ Assert . True ( analysis . Succeeded ) ;
9273
+ Assert . Null ( GetSymbolNamesJoined ( analysis . AlwaysAssigned ) ) ;
9274
+ Assert . Null ( GetSymbolNamesJoined ( analysis . Captured ) ) ;
9275
+ Assert . Null ( GetSymbolNamesJoined ( analysis . CapturedInside ) ) ;
9276
+ Assert . Null ( GetSymbolNamesJoined ( analysis . CapturedOutside ) ) ;
9277
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . DataFlowsIn ) ) ;
9278
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . DefinitelyAssignedOnEntry ) ) ;
9279
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . DefinitelyAssignedOnExit ) ) ;
9280
+ Assert . Equal ( "value" , GetSymbolNamesJoined ( analysis . ReadInside ) ) ;
9281
+ Assert . Equal ( "result" , GetSymbolNamesJoined ( analysis . ReadOutside ) ) ;
9282
+ Assert . Null ( GetSymbolNamesJoined ( analysis . VariablesDeclared ) ) ;
9283
+ Assert . Null ( GetSymbolNamesJoined ( analysis . WrittenInside ) ) ;
9284
+ Assert . Equal ( "value, result" , GetSymbolNamesJoined ( analysis . WrittenOutside ) ) ;
9285
+ }
9286
+
9287
+ [ Fact , WorkItem ( 59738 , "https://github.com/dotnet/roslyn/issues/59738" ) ]
9288
+ public void DefiniteAssignmentInReceiverOfExtensionMethodInDelegateCreation ( )
9289
+ {
9290
+ var comp = CreateCompilation ( @"
9291
+ using System;
9292
+ bool b = true;
9293
+ _ = new Func<string>((b ? M(out var i) : i.ToString()).ExtensionMethod);
9294
+
9295
+ string M(out int i)
9296
+ {
9297
+ throw null;
9298
+ }
9299
+
9300
+ static class Extension
9301
+ {
9302
+ public static string ExtensionMethod(this string s) => throw null;
9303
+ }
9304
+ " ) ;
9305
+ comp . VerifyDiagnostics (
9306
+ // (4,42): error CS0165: Use of unassigned local variable 'i'
9307
+ // _ = new Func<string>((b ? M(out var i) : i.ToString()).ExtensionMethod);
9308
+ Diagnostic ( ErrorCode . ERR_UseDefViolation , "i" ) . WithArguments ( "i" ) . WithLocation ( 4 , 42 )
9309
+ ) ;
9310
+ }
9311
+
9312
+ [ Fact , WorkItem ( 59738 , "https://github.com/dotnet/roslyn/issues/59738" ) ]
9313
+ public void DefiniteAssignmentShouldSkipImplicitThisInStaticMethodConversion ( )
9314
+ {
9315
+ var comp = CreateCompilation ( @"
9316
+ using System;
9317
+ public struct C
9318
+ {
9319
+ private object field;
9320
+ public C(Action a)
9321
+ {
9322
+ // implicit `this` receiver should be ignored in definite assignment
9323
+ a = new(M);
9324
+ field = 1;
9325
+ }
9326
+
9327
+ public C(Action a, int ignored)
9328
+ {
9329
+ // implicit `this` receiver should be ignored in definite assignment
9330
+ a = new Action(M);
9331
+ field = 1;
9332
+ }
9333
+
9334
+ public void Method1(Action a)
9335
+ {
9336
+ // explicit `this` disallowed
9337
+ a = new Action(this.M);
9338
+ }
9339
+
9340
+ public void Method2(Action a, C c)
9341
+ {
9342
+ // instance receiver disallowed
9343
+ a = new Action(c.M);
9344
+ }
9345
+
9346
+ private static void M()
9347
+ {
9348
+ }
9349
+ }
9350
+ " ) ;
9351
+ comp . VerifyDiagnostics (
9352
+ // (23,24): error CS0176: Member 'C.M()' cannot be accessed with an instance reference; qualify it with a type name instead
9353
+ // a = new Action(this.M);
9354
+ Diagnostic ( ErrorCode . ERR_ObjectProhibited , "this.M" ) . WithArguments ( "C.M()" ) . WithLocation ( 23 , 24 ) ,
9355
+ // (29,24): error CS0176: Member 'C.M()' cannot be accessed with an instance reference; qualify it with a type name instead
9356
+ // a = new Action(c.M);
9357
+ Diagnostic ( ErrorCode . ERR_ObjectProhibited , "c.M" ) . WithArguments ( "C.M()" ) . WithLocation ( 29 , 24 )
9358
+ ) ;
9359
+ }
9360
+
9361
+ [ Fact , WorkItem ( 59738 , "https://github.com/dotnet/roslyn/issues/59738" ) ]
9362
+ public void DefiniteAssignmentWithExplicitThisInStaticMethodConversion ( )
9363
+ {
9364
+ var comp = CreateCompilation ( @"
9365
+ using System;
9366
+ public struct C
9367
+ {
9368
+ private object field;
9369
+ public void Method1(Action a)
9370
+ {
9371
+ a = new Action(this.M);
9372
+ field = 1;
9373
+ }
9374
+
9375
+ public void Method2(Action a, C c)
9376
+ {
9377
+ a = new Action(c.M);
9378
+ }
9379
+ }
9380
+ public static class Extension
9381
+ {
9382
+ public static void M(this C c)
9383
+ {
9384
+ }
9385
+ }
9386
+ " ) ;
9387
+ comp . VerifyDiagnostics (
9388
+ // (8,24): error CS1113: Extension method 'Extension.M(C)' defined on value type 'C' cannot be used to create delegates
9389
+ // a = new Action(this.M);
9390
+ Diagnostic ( ErrorCode . ERR_ValueTypeExtDelegate , "this.M" ) . WithArguments ( "Extension.M(C)" , "C" ) . WithLocation ( 8 , 24 ) ,
9391
+ // (14,24): error CS1113: Extension method 'Extension.M(C)' defined on value type 'C' cannot be used to create delegates
9392
+ // a = new Action(c.M);
9393
+ Diagnostic ( ErrorCode . ERR_ValueTypeExtDelegate , "c.M" ) . WithArguments ( "Extension.M(C)" , "C" ) . WithLocation ( 14 , 24 )
9394
+ ) ;
9395
+ }
9178
9396
}
9179
9397
}
0 commit comments