Bug 3142 - Type inference is failing to resolve method reference
Summary: Type inference is failing to resolve method reference
Status: RESOLVED FIXED
Alias: None
Product: Compilers
Classification: Mono
Component: C# ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Marek Safar
URL:
Depends on:
Blocks:
 
Reported: 2012-01-30 12:14 UTC by David Ferguson
Modified: 2012-01-31 05:47 UTC (History)
1 user (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:
RESOLVED FIXED

Description David Ferguson 2012-01-30 12:14:54 UTC
The following code will fail with the mono (dmcs compiler). The MS compiler handles it fine.

_configurationService.RegisterCallback((ConfigurationChange<TConfig> change) => OnConfigurationChanged(change));

The following code will compile with the mono (dmcs compiler).

_configurationService.RegisterCallback<TConfig>((ConfigurationChange<TConfig> change) => OnConfigurationChanged(change));


RegisterCallback is a generic method on an interface whose signature is:

void RegisterCallback<T>(Action<ConfigurationChange<T>> changedCallback) where T : new();

Using (master) as of Fri, Jan 27.

$ dmcs --version
Mono C# compiler version 2.11.0.0

$ mono --version
Mono JIT compiler version 2.11 (master/8d817df Fri Jan 27 15:04:27 EST 2012)
Copyright (C) 2002-2011 Novell, Inc, Xamarin, Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            Included Boehm (with typed GC and Parallel Mark)
Comment 1 Marek Safar 2012-01-30 12:28:58 UTC
Could you provide the error message and code snippet or at least type of _configurationService and method signature of OnConfigurationChanged
Comment 2 David Ferguson 2012-01-30 14:10:51 UTC
The error messages from the compiler are:

Error 1:

replaced/Development/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(54,54): Error CS1678: Parameter `1' is declared as type `Replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<TConfig>' but should be `Replaced.ServiceHost.Contracts.Configuration.ConfigurationChange' (CS1678) (ServiceHost.Implementation)

Error 2:

replaced/Development/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(54,54): Error CS1661: Cannot convert `lambda expression' to delegate type `System.Action<Replaced.ServiceHost.Contracts.Configuration.ConfigurationChange>' since there is a parameter mismatch (CS1661) (ServiceHost.Implementation)

Error 3:

replaced/Development/replay5/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(35,35): Error CS1502: The best overloaded method match for `Replaced.ServiceHost.Contracts.Configuration.IConfigurationService.UnregisterCallback(System.Action<Replaced.ServiceHost.Contracts.Configuration.ConfigurationChange>)' has some invalid arguments (CS1502) (ServiceHost.Implementation)

Error 4:

replaced/Development/replay5/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(35,35): Error CS1503: Argument `#1' cannot convert `anonymous method' expression to type `System.Action<Replaced.ServiceHost.Contracts.Configuration.ConfigurationChange>' (CS1503) (ServiceHost.Implementation)

The method signature for OnConfigurationChanged is:
private void OnConfigurationChanged(ConfigurationChange<TConfig> change)

_configurationService is an instance of the IConfigurationService interface.  The method signature on that interface in question is:

public interface IConfigurationService : IDisposable
{
...
    void UnregisterCallback<T>(Action<ConfigurationChange<T>> changedCallback) where T : new();
...
}

I'll see about reproducing outside of the code base.
Comment 3 David Ferguson 2012-01-30 14:20:17 UTC
Here's the definition for ConfigurationChangeT

    public class ConfigurationChange<T> where T : new()
    {
        public ConfigurationChange()
        {
        }

        public ConfigurationChange(string name, T oldValue, T newValue)
        {
            Name = name;
            OldValue = oldValue;
            NewValue = newValue;
        }

        public string Name { get; set; }

        public T OldValue { get; set; }

        public T NewValue { get; set; }
    }

Note that there is also a ConfigurationChange without the T.

    public class ConfigurationChange
    {
        public ConfigurationChange()
        {
        }

        public ConfigurationChange(string name, object oldValue, object newValue)
        {
            Name = name;
            OldValue = oldValue;
            NewValue = newValue;
        }

        public string Name { get; set; }
        
        public object OldValue { get; set; }
        
        public object NewValue { get; set; }
    }
Comment 4 David Ferguson 2012-01-30 15:10:33 UTC
The signature for the class the original code is in:

public abstract class ConfigurableService<TConfig> : BaseService, IConfigurableService<TConfig> where TConfig : class, new()
{
...

protected ConfigurableService(IConfigurationService configurationService, string configurationName, bool persistDefaultConfiguration)
        {
            _configurationService = configurationService;
            _configurationName = configurationName;
            _persistDefaultConfiguration = persistDefaultConfiguration;
        }
...

        public override void Initialize()
        {
            // We want to initialize first, then register the callback.
            _configurationService.UnregisterCallback ((ConfigurationChange<TConfig> change) => OnConfigurationChanged(change));

            base.Initialize();

            _currentConfiguration = ReadConfiguration();  // If no config, this will create a new one, which would in other situations trigger the callback
            ApplyConfigurationInternal(default(TConfig), _currentConfiguration);

            // We want to initialize first, then register the callback.
            _configurationService.RegisterCallback ((ConfigurationChange<TConfig> change) => OnConfigurationChanged(change));
        }
...
}
Comment 5 David Ferguson 2012-01-30 15:30:45 UTC
When changing the code to:

_configurationService.UnregisterCallback<object>((ConfigurationChange<TConfig> change) => OnConfigurationChanged(change));


replaced/Development/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,62): error CS1678: Parameter `1' is declared as type `replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<TConfig>' but should be `replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<object>'

replaced/Development/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,62): error CS1661: Cannot convert `lambda expression' to delegate type `System.Action<replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<object>>' since there is a parameter mismatch

replaced/Development/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,35): error CS1502: The best overloaded method match for `replaced.ServiceHost.Contracts.Configuration.IConfigurationService.UnregisterCallback<object>(System.Action<replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<object>>)' has some invalid arguments

replaced/Development/replaced/common/ServiceHost/ServiceHost.Contracts/bin/Debug/ServiceHost.Contracts.dll (Location of the symbol related to previous error)

replaced/Development/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,35): error CS1503: Argument `#1' cannot convert `anonymous method' expression to type `System.Action<replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<object>>'


When changing the code to:

_configurationService.UnregisterCallback<string>((ConfigurationChange<TConfig> change) => OnConfigurationChanged(change));

replacedDevelopment/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,35): error CS0310: The type `string' must have a public parameterless constructor in order to use it as parameter `T' in the generic type or method `replaced.ServiceHost.Contracts.Configuration.IConfigurationService.UnregisterCallback<T>(System.Action<replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<T>>)'

replaced.local/lib/mono/4.0/mscorlib.dll (Location of the symbol related to previous error)

replacedDevelopment/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,62): error CS1678: Parameter `1' is declared as type `replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<TConfig>' but should be `replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<string>'

replacedDevelopment/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,62): error CS1661: Cannot convert `lambda expression' to delegate type `System.Action<replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<string>>' since there is a parameter mismatch

replacedDevelopment/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,35): error CS1502: The best overloaded method match for `replaced.ServiceHost.Contracts.Configuration.IConfigurationService.UnregisterCallback<string>(System.Action<replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<string>>)' has some invalid arguments

replacedDevelopment/replaced/common/ServiceHost/ServiceHost.Contracts/bin/Debug/ServiceHost.Contracts.dll (Location of the symbol related to previous error)

replacedDevelopment/replaced/common/ServiceHost/ServiceHost.Implementation/Services/ConfigurableService.cs(62,35): error CS1503: Argument `#1' cannot convert `anonymous method' expression to type `System.Action<replaced.ServiceHost.Contracts.Configuration.ConfigurationChange<string>>'
Comment 6 Marek Safar 2012-01-31 05:47:28 UTC
It should be fixed in master