www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is this a bug?

reply "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
I /think/ this is a bug, but I'm not 100% sure. The following 
compiles without any problems, as it should:

import std.typecons;

alias Handle(T) = RefCounted!(T, RefCountedAutoInitialize.no);

auto initialized(T)() if(is(T == RefCounted!S, S...))
{
	T refCounted;
	refCounted.refCountedStore.ensureInitialized();
	return refCounted;
}

alias S = Handle!S_Impl;
struct S_Impl
{
}

void main()
{
	auto s = initialized!S;
}


Change 'initialized' to:
auto initialized(T)() if(is(T == Handle!S, S))
and the compiler will complain:

Error: template instance test.initialized!(RefCounted!(S_Impl, 
cast(RefCountedAutoInitialize)0)) does not match template 
declaration initialized(T)() if (is(T == Handle!S, S))
Jun 26 2014
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 26 June 2014 at 10:09:53 UTC, Rene Zwanenburg wrote:
 I /think/ this is a bug, but I'm not 100% sure. The following 
 compiles without any problems, as it should:

 import std.typecons;

 alias Handle(T) = RefCounted!(T, RefCountedAutoInitialize.no);

 auto initialized(T)() if(is(T == RefCounted!S, S...))
 {
 	T refCounted;
 	refCounted.refCountedStore.ensureInitialized();
 	return refCounted;
 }

 alias S = Handle!S_Impl;
 struct S_Impl
 {
 }

 void main()
 {
 	auto s = initialized!S;
 }


 Change 'initialized' to:
 auto initialized(T)() if(is(T == Handle!S, S))
 and the compiler will complain:

 Error: template instance test.initialized!(RefCounted!(S_Impl, 
 cast(RefCountedAutoInitialize)0)) does not match template 
 declaration initialized(T)() if (is(T == Handle!S, S))

I don't think that's a bug, but I think the template constraint itself shouldn't be legal to write. It's not possible to support the general case of a template A in is(T == A!X, X) as it would require following all possible instantiation paths of A. The compiler could keep track of how a type was created on a per-identifier basis and then use that to check, but that would mean rejecting types that had a different instantiation path (e.g. is(RefCounted!(int, RefCountedAutoInitialize.no) == Handle!S, S) == false). What might be feasible would be to extend is(T == A!X, X) to work with simple tmeplates and paramterised aliases like Handle, while statically disallowing more complicated / undecidable ones..
Jun 26 2014
prev sibling next sibling parent "hane" <han.ehit.suzi.0 gmail.com> writes:
On Thursday, 26 June 2014 at 10:09:53 UTC, Rene Zwanenburg wrote:
 I /think/ this is a bug, but I'm not 100% sure. The following 
 compiles without any problems, as it should:

 import std.typecons;

 alias Handle(T) = RefCounted!(T, RefCountedAutoInitialize.no);

 auto initialized(T)() if(is(T == RefCounted!S, S...))
 {
 	T refCounted;
 	refCounted.refCountedStore.ensureInitialized();
 	return refCounted;
 }

 alias S = Handle!S_Impl;
 struct S_Impl
 {
 }

 void main()
 {
 	auto s = initialized!S;
 }


 Change 'initialized' to:
 auto initialized(T)() if(is(T == Handle!S, S))
 and the compiler will complain:

 Error: template instance test.initialized!(RefCounted!(S_Impl, 
 cast(RefCountedAutoInitialize)0)) does not match template 
 declaration initialized(T)() if (is(T == Handle!S, S))

DMD 2.066(git head) compiled both without error.
Jun 26 2014
prev sibling next sibling parent "Meta" <jared771 gmail.com> writes:
On Thursday, 26 June 2014 at 10:09:53 UTC, Rene Zwanenburg wrote:
 I /think/ this is a bug, but I'm not 100% sure. The following 
 compiles without any problems, as it should:

 import std.typecons;

 alias Handle(T) = RefCounted!(T, RefCountedAutoInitialize.no);

 auto initialized(T)() if(is(T == RefCounted!S, S...))
 {
 	T refCounted;
 	refCounted.refCountedStore.ensureInitialized();
 	return refCounted;
 }

 alias S = Handle!S_Impl;
 struct S_Impl
 {
 }

 void main()
 {
 	auto s = initialized!S;
 }


 Change 'initialized' to:
 auto initialized(T)() if(is(T == Handle!S, S))
 and the compiler will complain:

 Error: template instance test.initialized!(RefCounted!(S_Impl, 
 cast(RefCountedAutoInitialize)0)) does not match template 
 declaration initialized(T)() if (is(T == Handle!S, S))

Yes, this is a bug. This code should work. If it doesn't compile with Git HEAD, you should file a bug report.
Jun 26 2014
prev sibling next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 26 June 2014 at 12:38:40 UTC, John Colvin wrote:
 On Thursday, 26 June 2014 at 10:09:53 UTC, Rene Zwanenburg 
 wrote:
 I /think/ this is a bug, but I'm not 100% sure. The following 
 compiles without any problems, as it should:

 import std.typecons;

 alias Handle(T) = RefCounted!(T, RefCountedAutoInitialize.no);

 auto initialized(T)() if(is(T == RefCounted!S, S...))
 {
 	T refCounted;
 	refCounted.refCountedStore.ensureInitialized();
 	return refCounted;
 }

 alias S = Handle!S_Impl;
 struct S_Impl
 {
 }

 void main()
 {
 	auto s = initialized!S;
 }


 Change 'initialized' to:
 auto initialized(T)() if(is(T == Handle!S, S))
 and the compiler will complain:

 Error: template instance test.initialized!(RefCounted!(S_Impl, 
 cast(RefCountedAutoInitialize)0)) does not match template 
 declaration initialized(T)() if (is(T == Handle!S, S))

I don't think that's a bug, but I think the template constraint itself shouldn't be legal to write. It's not possible to support the general case of a template A in is(T == A!X, X) as it would require following all possible instantiation paths of A. The compiler could keep track of how a type was created on a per-identifier basis and then use that to check, but that would mean rejecting types that had a different instantiation path (e.g. is(RefCounted!(int, RefCountedAutoInitialize.no) == Handle!S, S) == false). What might be feasible would be to extend is(T == A!X, X) to work with simple tmeplates and paramterised aliases like Handle, while statically disallowing more complicated / undecidable ones..

Ah, it appears that this has already been done. Good. If I've misunderstood the situation, somebody please correct me.
Jun 26 2014
prev sibling next sibling parent "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
On Thursday, 26 June 2014 at 13:25:00 UTC, Meta wrote:
 Yes, this is a bug. This code should work. If it doesn't 
 compile with Git HEAD, you should file a bug report.

Apparently it does. I'm not set up to build DMD myself so I'm always just using the latest release.
Jun 26 2014
prev sibling parent "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
On Thursday, 26 June 2014 at 12:52:54 UTC, hane wrote:
 DMD 2.066(git head) compiled both without error.

Thanks for checking!
Jun 26 2014