Bug 36418 - GetProperty fails for indexer properties on instantiations of generic types
Summary: GetProperty fails for indexer properties on instantiations of generic types
Status: VERIFIED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: Reflection ()
Version: 4.2.0 (C6)
Hardware: All All
: Normal normal
Target Milestone: (C6SR1)
Assignee: Aleksey Kliger
URL:
Depends on:
Blocks:
 
Reported: 2015-12-01 12:55 UTC by donsyme
Modified: 2016-01-28 19:23 UTC (History)
6 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED FIXED

Description donsyme 2015-12-01 12:55:18 UTC
There is a serious regression in Mono when binding indexer properties on generic types.  This is exposed via the F# code to get a quotation which indexes into a list:

    let q = <@ let xs = [1] in xs.[0] @>

A simpler repro calling GetProperty directly is shown below. The problem appears to be when we give exact instantiated return and argument types when getting the indexer property off the instantiated type list<int>:


----

open System.Reflection

let ty = typeof<int list>
let staticOrInstanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly

// This is ok on both Mono and .NET:
let p1 = ty.GetProperty("Item") 

// This is ok on both Mono and .NET:
let p2 = ty.GetProperty("Item", staticOrInstanceBindingFlags) 

// This doesn't work correctly on Mono:
let p3 = ty.GetProperty("Item", staticOrInstanceBindingFlags, null, typeof<int>, [| typeof<int> |], null) 

printfn "p1 = %A" p1   // expect non-null, observe non-null
printfn "p2 = %A" p2  // expect non-null, observe non-null
printfn "p3 = %A" p3  // expect non-null, observe null  <<---- BUG

----


This is causing unit tests to fail in http://github.com/fsharp/fsharp
Comment 1 Alexander Köplinger [MSFT] 2015-12-01 22:04:30 UTC
I can confirm this is a regression in 4.2, it's working fine on Mono 4.0.

For sake of simplicity, here's the C# code I used:

> using System;
> using System.Collections.Generic;
> using System.Reflection;
> 
> class Program
> {
> 	public static void Main (string[] args)
> 	{
> 		var ty = typeof(List<int>);
> 		var staticOrInstanceBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
> 		
> 		// This is ok on both Mono and .NET:
> 		var p1 = ty.GetProperty("Item");
> 		
> 		// This is ok on both Mono and .NET:
> 		var p2 = ty.GetProperty("Item", staticOrInstanceBindingFlags);
> 		
> 		// This doesn't work correctly on Mono:
> 		var p3 = ty.GetProperty("Item", staticOrInstanceBindingFlags, null, typeof(int), new Type[] { typeof(int) }, null);
> 		
> 		Console.WriteLine("p1 = {0}", p1);  // expect non-null, observe non-null
> 		Console.WriteLine("p2 = {0}", p2);  // expect non-null, observe non-null
> 		Console.WriteLine("p3 = {0}", p3);  // expect non-null, observe null  <<---- BUG
> 	}
> }
Comment 2 Aleksey Kliger 2015-12-02 19:17:43 UTC
Looks like Mono's System.DefaultBinder.CanComparePrimitive() is not reflexive, which makes System.DefaultBinder.SelectProperty() rule out the indexer based on its return type.
Comment 3 Aleksey Kliger 2015-12-02 21:51:14 UTC
Fixed on master cc5c9a49ca256b41425c0aec59c9817d8ebfff31
Comment 4 Arpit Jha 2015-12-10 10:15:10 UTC
*****************************
Reproduce Status: Reproduced
****************************

I have checked this issue and able to reproduce this issue with the help of comment  https://bugzilla.xamarin.com/show_bug.cgi?id=36418#c1 mentioned in bug.


Steps I have followed:
1.Create a Console App in XS 
2.Implement the code mentioned in https://bugzilla.xamarin.com/show_bug.cgi?id=36418#c1
3. Run the application

Observation: Observed that variable p3 return null value in console.

Console Output:
 
p1 = Int32 Item [Int32]
p2 = Int32 Item [Int32]
p3 = 

Screencast: http://www.screencast.com/t/I684w94mU
Environment Info:
https://gist.github.com/Arpit360/6966abbc3cebc91c2b57


*******************************
Verify Status: Verified 
*******************************

I have checked the same with latest master build ( MonoFramework-MDK-4.3.0.2348.macos10.xamarin.universal_f1c147af8f1f823014163d4c021a2717cdc2a1da + XamarinStudio-6.0.0.2371_7d04547a1abe01391360d74a79672f727c3dcadc )

observed that its working fine ,now p3 return the  value  Int32 Item [Int32]

Console Output:
p1 = Int32 Item [Int32]
p2 = Int32 Item [Int32]
p3 = Int32 Item [Int32]

Screencast : http://www.screencast.com/t/JneP0qJlbc4B

Environment Info:
https://gist.github.com/Arpit360/122ddb0cca3dcc49c1de
Comment 5 Arpit Jha 2015-12-10 10:16:36 UTC
As per comment 4, I am closing this issue.
Comment 6 Aleksey Kliger 2015-12-14 20:07:23 UTC
Fixed on mono-4.2.0-branch in commit 7ad84f7adc5b9d33d4d0a813dde4e032ad7215a9
Comment 7 Parmendra Kumar 2015-12-17 11:54:30 UTC
I have checked this issue with latest C6SR1 build and its working fine.

Screencast: http://www.screencast.com/t/yKTBmFcGVd

Environment Info:

https://gist.github.com/Parmendrak/8711c8b23a56f6952af1