Thread overview | |||||
---|---|---|---|---|---|
|
December 29, 2010 [dmd-internals] Type matching / type deduction with pointers | ||||
---|---|---|---|---|
| ||||
I was looking at improving my patch for the "const(Object)ref" syntax so it works correctly with type matching and type deduction. To get a feel of how things should work, I built a few test cases with pointers with the intent to use them as a reference for how it should behave with classes. **The problem is that the results for pointers don't make any sense.** First, type matching. All the static asserts below passes. That doesn't look normal. // Type matching template cp(T : const(int)*) { enum cp = 1; } static assert(cp!(int*)); static assert(cp!(const(int*))); static assert(cp!(const(int)*)); static assert(cp!(immutable(int*))); static assert(cp!(immutable(int)*)); static assert(cp!(shared(int*))); static assert(cp!(shared(int)*)); I'd expect at least the 'shared' ones to fail, and also those where the pointer is not mutable. Second, type deduction. All of these pragma(msg) print "int", except the last one where the template doesn't match. // Type deduction template ep(T : const(U)*, U) { alias U ep; } pragma(msg, ep!(int*).stringof); // int pragma(msg, ep!(const(int)*).stringof); // int pragma(msg, ep!(const(int*)).stringof); // int pragma(msg, ep!(immutable(int*)).stringof); // int pragma(msg, ep!(immutable(int)*).stringof); // int pragma(msg, ep!(shared(int*)).stringof); // int pragma(msg, ep!(shared(int)*).stringof); // error: no match I'd have expected both tests with 'shared' to fail, as well as those where the pointer is not mutable. How am I supposed to make things work correctly for class references if it doesn't even work for pointers? :-) That said, with what I have now, type matching and type deduction seem to work equally well for class references and pointers (perhaps even a little better for class references). So I'm leaning on soon posting a new patch with what I have. And I should probably post the above as a separate bug. -- Michel Fortin michel.fortin at michelf.com http://michelf.com/ |
December 29, 2010 [dmd-internals] Type matching / type deduction with pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | Le 2010-12-29 ? 11:13, Michel Fortin a ?crit : > I was looking at improving my patch for the "const(Object)ref" syntax so it works correctly with type matching and type deduction. To get a feel of how things should work, I built a few test cases with pointers with the intent to use them as a reference for how it should behave with classes. > > **The problem is that the results for pointers don't make any sense.** Well, with a second look I see I got one thing wrong in my last message. But there's plenty of bugs that remains. I've made a big unit test that checks a lot of things. I rigged the test so it passes for everything but added FIXME annotations for the asserts I think aren't right. There are currently 17 FIXMEs for test cases involving pointers and 13 for test cases involving Object ref. I would appreciate if someone could pass through them all and validate whether or not I've put the FIXME annotations at the right place. // Template matching template a(T : Object) { enum a = 1; } static assert(a!(Object)); static assert(!is(typeof(a!(const(Object))))); // no match static assert(!is(typeof(a!(const(Object)ref)))); // no match static assert(!is(typeof(a!(immutable(Object))))); // no match static assert(!is(typeof(a!(immutable(Object)ref)))); // no match static assert(!is(typeof(a!(shared(Object))))); // no match static assert(!is(typeof(a!(shared(Object)ref)))); // no match template ap(T : int*) { enum ap = 1; } static assert(ap!(int*)); static assert(ap!(const(int*))); // FIXME: should not match static assert(ap!(const(int)*)); // FIXME: should not match static assert(ap!(immutable(int*))); // FIXME: should not match static assert(ap!(immutable(int)*)); // FIXME: should not match static assert(ap!(shared(int*))); // FIXME: should not match static assert(ap!(shared(int)*)); // FIXME: should not match template b(T : const(Object)) { enum b = 1; } static assert(b!(Object)); static assert(b!(const(Object))); static assert(b!(const(Object)ref)); static assert(b!(immutable(Object))); static assert(b!(immutable(Object)ref)); static assert(!is(typeof(b!(shared(Object))))); // no match static assert(!is(typeof(b!(shared(Object)ref)))); // no match template bp(T : const(int*)) { enum bp = 1; } static assert(bp!(int*)); static assert(bp!(const(int*))); static assert(bp!(const(int)*)); static assert(bp!(immutable(int*))); static assert(bp!(immutable(int)*)); static assert(bp!(shared(int*))); // FIXME: should not match static assert(bp!(shared(int)*)); // FIXME: should not match template c(T : const(Object)ref) { enum c = 1; } static assert(c!(Object)); static assert(c!(const(Object))); // FIXME: should not match (const ref) static assert(c!(const(Object)ref)); static assert(c!(immutable(Object))); // FIXME: should not match (immutable ref) static assert(c!(immutable(Object)ref)); static assert(!is(typeof(c!(shared(Object))))); // no match static assert(!is(typeof(c!(shared(Object)ref)))); // no match template cp(T : const(int)*) { enum cp = 1; } static assert(cp!(int*)); static assert(cp!(const(int*))); // FIXME: should not match (const ptr) static assert(cp!(const(int)*)); static assert(cp!(immutable(int*))); // FIXME: should not match (immutable ptr) static assert(cp!(immutable(int)*)); static assert(cp!(shared(int*))); // FIXME: should not match static assert(cp!(shared(int)*)); // FIXME: should not match // Type deduction template d(T : U ref, U) { alias U d; } static assert(is(d!(Object) == Object)); static assert(is(d!(const(Object)) == const(Object))); // FIXME: should not match (const ref) static assert(is(d!(const(Object)ref) == const(Object)ref)); static assert(is(d!(immutable(Object)) == immutable(Object))); // FIXME: should not match (immutable ref) static assert(is(d!(immutable(Object)ref) == immutable(Object)ref)); static assert(is(d!(shared(Object)) == shared(Object))); // FIXME: should not match (shared ref) static assert(is(d!(shared(Object)ref) == shared(Object)ref)); static assert(!is(d!(int))); // no match: 'ref' prevents matching non-class template dp(T : U*, U) { alias U dp; } static assert(is(dp!(int*) == int)); static assert(is(dp!(const(int*)) == const(int))); // FIXME: should not match (const ptr) static assert(is(dp!(const(int)*) == const(int))); static assert(is(dp!(immutable(int*)) == immutable(int))); // FIXME: should not match (immutable ptr) static assert(is(dp!(immutable(int)*) == immutable(int))); static assert(is(dp!(shared(int*)) == shared(int))); // FIXME: should not match (shared ptr) static assert(is(dp!(shared(int)*) == shared(int))); template e(T : const(U), U) { alias U e; } static assert(is(e!(Object) == Object)); static assert(is(e!(const(Object)) == const(Object)ref)); // FIXME: should == Object static assert(is(e!(const(Object)ref) == const(Object)ref)); // FIXME: should == Object static assert(is(e!(immutable(Object)) == immutable(Object)ref)); // FIXME: should == Object static assert(is(e!(immutable(Object)ref) == immutable(Object)ref)); // FIXME: should == Object static assert(!is(e!(shared(Object)))); // no match static assert(!is(e!(shared(Object)ref))); // no match template ep(T : const(U*), U) { alias U ep; } static assert(is(ep!(int*) == int)); static assert(is(ep!(const(int*)) == int)); static assert(is(ep!(const(int)*) == int)); static assert(is(ep!(immutable(int*)) == int)); static assert(is(ep!(immutable(int)*) == int)); static assert(!is(ep!(shared(int*)))); // no match static assert(!is(ep!(shared(int)*))); // no match template f(T : const(U)ref, U) { alias U f; } static assert(is(f!(Object) == Object)); static assert(is(f!(const(Object)) == const(Object)ref)); // FIXME: should not match (const ref) static assert(is(f!(const(Object)ref) == const(Object)ref)); // FIXME: should == Object static assert(is(f!(immutable(Object)) == immutable(Object)ref)); // FIXME: should not match (immutable ref) static assert(is(f!(immutable(Object)ref) == immutable(Object)ref)); // FIXME: should == Object static assert(!is(f!(shared(Object)))); // no match static assert(!is(f!(shared(Object)ref))); // no match template fp(T : const(U)*, U) { alias U fp; } static assert(is(fp!(int*) == int)); static assert(is(fp!(const(int*)) == int)); // FIXME: should not match (const ptr) static assert(is(fp!(const(int)*) == int)); static assert(is(fp!(immutable(int*)) == int)); // FIXME: should not match (immutable ptr) static assert(is(fp!(immutable(int)*) == int)); static assert(!is(fp!(shared(int*)))); // no match static assert(!is(fp!(shared(int)*))); // no match -- Michel Fortin michel.fortin at michelf.com http://michelf.com/ |
December 29, 2010 [dmd-internals] Type matching / type deduction with pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | Please add these to bugzilla! Thanks, -Walter
Michel Fortin wrote:
> Le 2010-12-29 ? 11:13, Michel Fortin a ?crit :
>
>
>> I was looking at improving my patch for the "const(Object)ref" syntax so it works correctly with type matching and type deduction. To get a feel of how things should work, I built a few test cases with pointers with the intent to use them as a reference for how it should behave with classes.
>>
>> **The problem is that the results for pointers don't make any sense.**
>>
>
> Well, with a second look I see I got one thing wrong in my last message. But there's plenty of bugs that remains.
>
> I've made a big unit test that checks a lot of things. I rigged the test so it passes for everything but added FIXME annotations for the asserts I think aren't right. There are currently 17 FIXMEs for test cases involving pointers and 13 for test cases involving Object ref.
>
> I would appreciate if someone could pass through them all and validate whether or not I've put the FIXME annotations at the right place.
>
>
> // Template matching
>
> template a(T : Object) {
> enum a = 1;
> }
>
> static assert(a!(Object));
> static assert(!is(typeof(a!(const(Object))))); // no match
> static assert(!is(typeof(a!(const(Object)ref)))); // no match
> static assert(!is(typeof(a!(immutable(Object))))); // no match
> static assert(!is(typeof(a!(immutable(Object)ref)))); // no match
> static assert(!is(typeof(a!(shared(Object))))); // no match
> static assert(!is(typeof(a!(shared(Object)ref)))); // no match
>
> template ap(T : int*) {
> enum ap = 1;
> }
>
> static assert(ap!(int*));
> static assert(ap!(const(int*))); // FIXME: should not match
> static assert(ap!(const(int)*)); // FIXME: should not match
> static assert(ap!(immutable(int*))); // FIXME: should not match
> static assert(ap!(immutable(int)*)); // FIXME: should not match
> static assert(ap!(shared(int*))); // FIXME: should not match
> static assert(ap!(shared(int)*)); // FIXME: should not match
>
>
> template b(T : const(Object)) {
> enum b = 1;
> }
>
> static assert(b!(Object));
> static assert(b!(const(Object)));
> static assert(b!(const(Object)ref));
> static assert(b!(immutable(Object)));
> static assert(b!(immutable(Object)ref));
> static assert(!is(typeof(b!(shared(Object))))); // no match
> static assert(!is(typeof(b!(shared(Object)ref)))); // no match
>
> template bp(T : const(int*)) {
> enum bp = 1;
> }
>
> static assert(bp!(int*));
> static assert(bp!(const(int*)));
> static assert(bp!(const(int)*));
> static assert(bp!(immutable(int*)));
> static assert(bp!(immutable(int)*));
> static assert(bp!(shared(int*))); // FIXME: should not match
> static assert(bp!(shared(int)*)); // FIXME: should not match
>
>
> template c(T : const(Object)ref) {
> enum c = 1;
> }
>
> static assert(c!(Object));
> static assert(c!(const(Object))); // FIXME: should not match (const ref)
> static assert(c!(const(Object)ref));
> static assert(c!(immutable(Object))); // FIXME: should not match (immutable ref)
> static assert(c!(immutable(Object)ref));
> static assert(!is(typeof(c!(shared(Object))))); // no match
> static assert(!is(typeof(c!(shared(Object)ref)))); // no match
>
> template cp(T : const(int)*) {
> enum cp = 1;
> }
>
> static assert(cp!(int*));
> static assert(cp!(const(int*))); // FIXME: should not match (const ptr)
> static assert(cp!(const(int)*));
> static assert(cp!(immutable(int*))); // FIXME: should not match (immutable ptr)
> static assert(cp!(immutable(int)*));
> static assert(cp!(shared(int*))); // FIXME: should not match
> static assert(cp!(shared(int)*)); // FIXME: should not match
>
>
> // Type deduction
>
> template d(T : U ref, U) {
> alias U d;
> }
>
> static assert(is(d!(Object) == Object));
> static assert(is(d!(const(Object)) == const(Object))); // FIXME: should not match (const ref)
> static assert(is(d!(const(Object)ref) == const(Object)ref));
> static assert(is(d!(immutable(Object)) == immutable(Object))); // FIXME: should not match (immutable ref)
> static assert(is(d!(immutable(Object)ref) == immutable(Object)ref));
> static assert(is(d!(shared(Object)) == shared(Object))); // FIXME: should not match (shared ref)
> static assert(is(d!(shared(Object)ref) == shared(Object)ref));
>
> static assert(!is(d!(int))); // no match: 'ref' prevents matching non-class
>
> template dp(T : U*, U) {
> alias U dp;
> }
>
> static assert(is(dp!(int*) == int));
> static assert(is(dp!(const(int*)) == const(int))); // FIXME: should not match (const ptr)
> static assert(is(dp!(const(int)*) == const(int)));
> static assert(is(dp!(immutable(int*)) == immutable(int))); // FIXME: should not match (immutable ptr)
> static assert(is(dp!(immutable(int)*) == immutable(int)));
> static assert(is(dp!(shared(int*)) == shared(int))); // FIXME: should not match (shared ptr)
> static assert(is(dp!(shared(int)*) == shared(int)));
>
>
> template e(T : const(U), U) {
> alias U e;
> }
>
> static assert(is(e!(Object) == Object));
> static assert(is(e!(const(Object)) == const(Object)ref)); // FIXME: should == Object
> static assert(is(e!(const(Object)ref) == const(Object)ref)); // FIXME: should == Object
> static assert(is(e!(immutable(Object)) == immutable(Object)ref)); // FIXME: should == Object
> static assert(is(e!(immutable(Object)ref) == immutable(Object)ref)); // FIXME: should == Object
> static assert(!is(e!(shared(Object)))); // no match
> static assert(!is(e!(shared(Object)ref))); // no match
>
> template ep(T : const(U*), U) {
> alias U ep;
> }
>
> static assert(is(ep!(int*) == int));
> static assert(is(ep!(const(int*)) == int));
> static assert(is(ep!(const(int)*) == int));
> static assert(is(ep!(immutable(int*)) == int));
> static assert(is(ep!(immutable(int)*) == int));
> static assert(!is(ep!(shared(int*)))); // no match
> static assert(!is(ep!(shared(int)*))); // no match
>
>
> template f(T : const(U)ref, U) {
> alias U f;
> }
>
> static assert(is(f!(Object) == Object));
> static assert(is(f!(const(Object)) == const(Object)ref)); // FIXME: should not match (const ref)
> static assert(is(f!(const(Object)ref) == const(Object)ref)); // FIXME: should == Object
> static assert(is(f!(immutable(Object)) == immutable(Object)ref)); // FIXME: should not match (immutable ref)
> static assert(is(f!(immutable(Object)ref) == immutable(Object)ref)); // FIXME: should == Object
> static assert(!is(f!(shared(Object)))); // no match
> static assert(!is(f!(shared(Object)ref))); // no match
>
> template fp(T : const(U)*, U) {
> alias U fp;
> }
>
> static assert(is(fp!(int*) == int));
> static assert(is(fp!(const(int*)) == int)); // FIXME: should not match (const ptr)
> static assert(is(fp!(const(int)*) == int));
> static assert(is(fp!(immutable(int*)) == int)); // FIXME: should not match (immutable ptr)
> static assert(is(fp!(immutable(int)*) == int));
> static assert(!is(fp!(shared(int*)))); // no match
> static assert(!is(fp!(shared(int)*))); // no match
>
>
>
>
>
|
Copyright © 1999-2021 by the D Language Foundation