www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Arrays of an interface

reply "Abdulhaq" <alynch4047 gmail.com> writes:
Hi all, hoping someone can help,

I'm used to coding to interfaces and I'm using them very lightly 
in an application I'm writing (a CPP wrapper like SWIG, except in 
D). Every now and then I touch a piece of code which seems almost 
unrelated and then get a bunch of compile errors such as the 
following (Method is the interface, MethodImpl is the 
implementation):

smidgen/ast/klass.d(108): Error: function 
smidgen.ast.klass.Klass.addMethod (Method method) is not callable 
using argument types (MethodImpl)
smidgen/ast/klass.d(113): Error: function 
smidgen.ast.klass.Klass.addMethod (Method method) is not callable 
using argument types (MethodImpl)
smidgen/ast/klass.d(293): Error: cannot append type 
smidgen.ast.method.Method to type Method[]
smidgen/ast/klass.d(322): Error: forward reference to 
getAllWrappedMethods
smidgen/ast/klass.d(360): Error: forward reference to type 
Method[]
smidgen/ast/klass.d(360): Error: cannot implicitly convert 
expression (baseMethods) of type Method[] to Method[]
smidgen/ast/klass.d(363): Error: cannot implicitly convert 
expression (baseKlass.methods) of type Method[] to Method[]
smidgen/ast/klass.d(542): Error: forward reference to 
getAllWrappedMethods
smidgen/ast/klass.d(636): Error: forward reference to 
getAllWrappedMethods
smidgen/ast/klass.d(672): Error: forward reference to 
getAllWrappedMethods
smidgen/ast/klass.d(15): Error: size of type Method is not known
smidgen/ast/klass.d(709): Error: function 
smidgen.ast.klass.Klass.isCovariantMethod (Method otherMethod) is 
not callable using argument types (Method)
smidgen/ast/klass.d(746): Error: forward reference to type 
Method[]
smidgen/ast/klass.d(746): Error: cannot implicitly convert 
expression (allWrappedMethods) of type Method[] to Method[]

I have a feeling that D doesn't fully support arrays of 
interfaces, e.g. Method[], particularly as a return type. Is 
there a better way to pass around lists of instances of an 
interface? I'm using DMD 2.064 on Linux 64bit,

thanks
Dec 31 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Abdulhaq:

 I have a feeling that D doesn't fully support arrays of 
 interfaces, e.g. Method[], particularly as a return type.
If that's true, than it seems a D bug worth fixing. Are you able and willing to create a minimized example (later useful for Bugzilla)? Bye, bearophile
Dec 31 2013
parent reply "Abdulhaq" <alynch4047 gmail.com> writes:
On Tuesday, 31 December 2013 at 14:26:33 UTC, bearophile wrote:
 Abdulhaq:

 I have a feeling that D doesn't fully support arrays of 
 interfaces, e.g. Method[], particularly as a return type.
If that's true, than it seems a D bug worth fixing. Are you able and willing to create a minimized example (later useful for Bugzilla)? Bye, bearophile
Honestly I'd like to do that but I'm pretty swamped ATM and I don't think a simple example is going to be easy to knock up. It might simply be a quirk somewhere in the code that's causing a load of spurious error messages. I'm going to try backing out my last change set and slowly reapply and see where it goes haywire, but I'm losing confidence in arrays of interfaces and really would like an alternative so that I can get coding on the real problem.
Dec 31 2013
parent reply "Abdulhaq" <alynch4047 gmail.com> writes:
Sorry to reply to me own post so quickly, a clue (it seems to me) 
is this part of the error:

smidgen/ast/klass.d(15): Error: size of type Method is not known

Line 15 is where I import the interface:
import smidgen.ast.method: Method, MethodImpl, Visibility, SMID;

and in the relevant file,

interface Method: ConverterManagerProvider {
	bool virtual();
	bool abstract_();
	bool static_();
	bool constructor();
	bool destructor();
	bool hasEllipsis();
	bool const_();
	bool transferBack();
etc...
	

Well, interfaces don't have sizes, do they? So does [] only 
really work for classes?
Dec 31 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 31 December 2013 at 14:43:25 UTC, Abdulhaq wrote:
 Well, interfaces don't have sizes, do they?
They have fixed size, interfaces are always implemented as pointers. Could be a forward reference problem, make sure you import the module with the interface above any use of it, and do a full import instead of a selective one and see what happens.
Dec 31 2013
parent reply "Abdulhaq" <alynch4047 gmail.com> writes:
On Tuesday, 31 December 2013 at 14:54:31 UTC, Adam D. Ruppe wrote:
 On Tuesday, 31 December 2013 at 14:43:25 UTC, Abdulhaq wrote:
 Well, interfaces don't have sizes, do they?
They have fixed size, interfaces are always implemented as pointers. Could be a forward reference problem, make sure you import the module with the interface above any use of it, and do a full import instead of a selective one and see what happens.
Ah! Great, doing the full import fixed it. The interface precedes the implementation in the same file, so it seems to me it's possibly a subtle glitch in the compiler with selective imports (the change I was making was in another module where I was subclassing Klass, which was the class with the array on it). Thanks both for your speedy replies!
Dec 31 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Abdulhaq:

 Ah! Great, doing the full import fixed it. The interface 
 precedes the implementation in the same file, so it seems to me 
 it's possibly a subtle glitch in the compiler with selective 
 imports (the change I was making was in another module where I 
 was subclassing Klass, which was the class with the array on 
 it).
Please create a reduced example that shows the problem, to be put in Bugzilla. Bye, bearophile
Dec 31 2013
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
Can you post more of the code? Maybe MethodImpl forgot to inherit 
from Method or there's a const mismatch or something like that.
Dec 31 2013
parent "Abdulhaq" <alynch4047 gmail.com> writes:
On Tuesday, 31 December 2013 at 14:41:39 UTC, Adam D. Ruppe wrote:
 Can you post more of the code? Maybe MethodImpl forgot to 
 inherit from Method or there's a const mismatch or something 
 like that.
Here you are: /** * The MethodImpl class is the main implementation of Method */ class MethodImpl: Method { /** * Either package_or klass should be set but not both, * package indicates it is a function */ private Klass _klass; private Package package_; /// index is used to distinguish methods of the same name but differing arguments private int index; private bool _virtual = false; private bool _abstract_ = false; private bool _static_ = false; private bool _constructor = false; private bool _destructor = false; private bool _hasEllipsis = false; private bool _const_ = false; private Annotation[] annotations; private Visibility _visibility; private string _name; private string _annotatedDName; private string _methodCodeD; private Argument[] _arguments; private CType _returnType; property bool virtual() {return _virtual;} property bool abstract_() {return _abstract_;} property bool static_() {return _static_;} property bool constructor() {return _constructor;} property bool destructor() {return _destructor;} property bool hasEllipsis() {return _hasEllipsis;} property bool const_() {return _const_;} property CType returnType() {return _returnType;} property Klass klass() {return _klass;} property Argument[] arguments() {return _arguments;} property Visibility visibility() {return _visibility;} property string name() {return _name;} string methodCodeD() {return _methodCodeD;} void setMethodCodeD(string code) {_methodCodeD = code;} property bool transferBack() { return canFind(annotations, new Annotation(TRANSFERBACK)); } etc....
Dec 31 2013