Wiki

Ticket #39 (assigned enhancement)

Opened 9 years ago

Last modified 4 years ago

Infer types for method references

Reported by: Chuck Owned by: Chuck
Priority: minor Milestone:
Component: Cobra Compiler Version: 0.8.0
Keywords: Cc:

Description

Types for method references are not inferred. For example:

x = X()
m = ref x.bar
# error: Cannot infer type for "m" because
# the type of the right hand expression is unknown.

Cobra should infer the type. A search for a compatible type sig should start in the current box and proceed out to the declared and used namespaces. If no match is found, a private, generated method sig should be created.

Attachments

ref-type-inference.patch Download (27.0 KB) - added by hopscc 7 years ago.
ref-lambda-type-inference.patch Download (35.8 KB) - added by hopscc 7 years ago.
ref-lambda-type-inference-target-local.patch Download (41.2 KB) - added by hopscc 7 years ago.

Change History

Changed 7 years ago by hopscc

Working on this (also ticket:138 and ticket:140)

Changed 7 years ago by hopscc

  • status changed from new to assigned
  • owner set to hopscc

Changed 7 years ago by Chuck

ticket:138 is a duplicate and can be closed, right?

Changed 7 years ago by hopscc

They're all dups for the same problem.
I'll coalesce them when I get a patch generated.

Changed 7 years ago by hopscc

Changed 7 years ago by hopscc

  • owner changed from hopscc to Chuck

Patch for ref type inference and signature storage and matching.
Not finding a matching signature in the inheritance hierarchy and 'use'd assemblies
causes autogeneration of a suitable signature and insertion of it in the enclosing Box.

Rel note and mods to existing tests (adding or hoisting necessary signatures).
New Tests for testing finding matching signatures or creation and insertion of
autogenerated signatures.

I've left commented print diagnostics in the patch for the moment cos I think there may be additional tweaking required around the signature search and matching.

Delegates with generic params (in system assemblies) proved to be something of an issue with refs to simple methods finding matches on suitable but arguably incorrect delegate/signatures...( any 2 arg method, no return type -> EventHandler)
I've suppressed the recognition of the simpler cases of these rather than try a more complex matching strategy (whatever that may be). (see ScanClrType)

It may be better (backwards compat) to
a) Not autogenerate a signature if no matches ( or not emit a warning) leaving it to backend compiler fallthrough behaviour as it was

and/or

b) not search the 'use'd assemblies for possible matches and rely on explicit or
autogenerated signatures that happen to be compatible with the System supplied ones ( this would make any existing working IComparable coding for sorting more verbose/repetitive).

Probably need a similar exercise done for inferring Sig typing for lambdas and
anon methods
If you want more discussion/description lets open a Discussion topic.

Changed 7 years ago by hopscc

Changed 7 years ago by hopscc

Second patch has slightly reworked original patch plus patches/tests etc for fix for ticket:204 - Correctly infer types for lambdas and anon methods.

Changed 7 years ago by Charles

  • owner changed from Chuck to hopscc

This patch breaks the following test case which works fine in pre-patch Cobra. The equivalent C# also works fine. Note that the "sig" in question is public and therefore accessible to the call site. Most importantly, C# allows the convenience of passing a method reference where a delegate is expected, even if the delegate type is declared in another class. Cobra should not generally be less convenient than C#.

# derived from
# CobraWorkSpace/Tests/120-classes/320-construct-prop-set.cobra

class X

    shared
    
        var _counter = 0
        
        get counter from var
    
        def incCounter
            _counter += 1

        def main
            s = Stuff(doSomething = ref .incCounter)  # pass a method reference
            assert .counter == 0
            ds = s.doSomething
            ds()
            assert .counter == 1


class Stuff

    sig DoSomethingSig

    pro doSomething from var as DoSomethingSig?

The patch addresses the above by changing the test case, but that's not acceptable. Here is the C# which conveniently allows the method to be passed:

using System;
class X {
	private static int _counter = 0;
	public static int Counter { get { return _counter; } }
	public static void IncCounter() { _counter += 1; }
	public static void Main() {
		// *** The next line does not require the delegate declaration to be moved.
		var s = new Stuff() { DoSomething = IncCounter };
		if (Counter!=0) throw new Exception("1");
		var ds = s.DoSomething;
		ds();
		if (Counter!=1) throw new Exception("2");
	}
}
class Stuff {
	public delegate void DoSomethingSig();
	public static DoSomethingSig _doSomething;
	public DoSomethingSig DoSomething {
		get { return _doSomething; }
		set { _doSomething = value; }
	}
}

Changed 7 years ago by hopscc

Changed 7 years ago by hopscc

  • owner changed from hopscc to Chuck

Well I disagree with the premise that this leakage of a non in-scope class-local (even if public) Type dcl (and inferring/casting the Type on assignment) is desirable or convenient even in C# and even more so wrt cobra with its total use of type inference and with the specified desire to search the inheritance and used namespace scope and synthesize a method sig on a search miss (hence the sig hoisting in the changed tests)

but heres a new patch anyway.

( I'm calling the case you wanted supported above as target typing in the following)

Theres additional tests for the 3 init cases (you describe one above and gave a code example of a different one) plus some error and combination inscope/target type Sigs.

I'm not convinced that the changes cover all the cases but it hits the common ones and all the tests I could come up with. I'll address any pieces as they surface

I've left it as using the inheritance hierarchy lookup first and using a target type lookup if that fails (other strategies are perhaps equally reasonable) which means that if there are matching Sigs in each scope
you'll have to explicitly type in cobra to the one you want (which would have been my preference for supporting Target typing in the first place) - theres an example of this in one of the 176 thru 178 tests.

You'll note the patch has increased in size by about a fifth and the code around
detecting and handling this case become grandly complex.

Changed 7 years ago by Charles

Looking now.

Changed 4 years ago by Charles

bump

Note: See TracTickets for help on using tickets.