Cannot convert from `GLib.TypeClass' to `GLib.ObjectClass' - vala

I was trying to compile libfriends (source) against valac (.28) and libgee (1.0). I specifically compiled these against Ubuntu-16.04 stack.
But I am getting following error
entry.vala:397.38-397.38: warning: if-statement without body
if (_selected != value);
^
entry.vala:172.52-172.86: error: Argument 1: Cannot convert from `GLib.TypeClass' to `GLib.ObjectClass'
binding_set = Gtk.BindingSet.by_class (typeof (InputTextView).class_ref ());
I don't really find anything wrong with code. Any Idea?
The entire buildlog is here: https://launchpadlibrarian.net/263631082/buildlog_ubuntu-xenial-i386.libfriends_0.1.2+14.10.20140709+201606051415~ubuntu16.04.1_BUILDING.txt.gz

I just checked and it compiles with valac-0.18, but doesn't compile with valac-0.28.
So there must have been a change between those valac versions that does more strict type checking in this case.
GLib.TypeClass (really GTypeClass in C) is the parent class of GLib.ObjectClass (really GObjectClass in C).
So the compiler is correct to not allow this without a cast. I don't know if the cast is correct in this situation, but it makes the code compile:
binding_set = Gtk.BindingSet.by_class ((ObjectClass) typeof (InputTextView).class_ref ())
See also valadoc for GObjectClass where a similar typecast is done in the example code:
http://valadoc.org/#!api=gobject-2.0/GLib.ObjectClass

Related

`Error: request to generate code for .compileTime proc`

I have a small helper proc that is supposed to tell me at compile-time whether a type is an object-type or not.
func isObject*[T](val: typedesc[T]): bool {.compileTime.} = T is (object or ref object)
However, when I call this proc with a simple echo to see whether it works, I receive an error:
type A = object
echo isObject(A)
Error: request to generate code for .compileTime proc: isObject
Why is that? It should be perfectly valid to just call this, isObject should just compile to true and in the end what's written there is echo true, why does this cause this cryptic error?
The problem here is that runtime code (The echo call) is trying to work with a compiletime proc.
That is not valid, as the compiler would not replace the function-call with its result, but try to actually call the function at runtime instead. The compiler knows this is invalid behaviour and thus prohibits it by throwing an error, albeit one that isn't that useful.
The only way this can be allowed is if you store the result of the compile-time proc in a compile-time variable, aka a const. These are allowed to be used at runtime.
So the calling code would look more like this instead:
type A = object
const x = isObject(A)
echo x
EDIT:
As Elegantbeef pointed out on nim's discord:
Another alternative is to just do what I thought would happen initially and have that isObject(A) call evaluate fully at compile-time, so that at runtime it goes away and all that's left is it's result, true.
To do so, just use static:
type A = object
echo static(isObject(A))

Nullability mismatch in simple assignment after switching to sound null safety

I switched to sound null safety and started getting runtime error in a simple assignment, that should never happen with sound null safety:
final widgetOnPressed = widget.onPressed;
Error:
type '(LogData) => void' is not a subtype of type '((LogData?) => void)?'
I can repro it for Flutter versions 2.12.0-4.1.pre and 2.13.0-0.0.pre.505.
PR: https://github.com/flutter/devtools/pull/3971
Failing line: https://github.com/flutter/devtools/blob/9fc560ff2e6749459e2ca6a1dc00bf6fb16ed93b/packages/devtools_app/lib/src/shared/table.dart#L1184
To repro, start DevTools at this PR for macos, connect to an app and click the tab 'Logging'. DevTools will show red screen and error in console.
Is it dart bug or the app bug? If it is the app bug, how can I debug it?
It's a bug in your code.
You didn't say which kind of error you got - a compile-time error or a runtime error. I'm guessing runtime error. (Well, you did say to launch it in the debugger, so that is a good hint too.)
The line final widgetOnPressed = widget.onPressed; looks like it can't possibly fail. After all, the type of the local variable is inferred from the expression assigned to it, and the runtime value of that expression will surely be a subtype of the static type because the type system is sound!
Isn't it? ISN'T IT?
It's not, sorry. Dart 2's type system is mostly sound, even more so with null safety, but class generics is covariant, which can still be unsound. It's fairly hard to hit one of the cases where that unsoundness shows its ugly head, but returning a function where the argument type is the class's type variable is one.
Your state class extends State<TableRow<T?>>, so the widget getter returns a TableRow<T?>. The onPressed of that type has type ItemCallback<T?>?, aka, void Function(T?)?.
You create a _TableRowState<LogData>, with its widget which has static type TableRow<LogData?>, but you somehow manage to pass it a TableRow<LogData> instead. That's fine. Class generics are covariant, so all is apparently fine at compile-time.
Then you do final widgetOnPressed = widget.onPressed;.
The static type of widgetOnPressed is void Function(LogData?) here.
The actual runtime type of onPressed is void Function(LogData) because it's from a TableRow<LogData>.
A void Function(LogData) is-not-a void Function(LogData?) because the former cannot be used in all places where the latter can (in particular, it can't be used in a place where it's called with null).
This assignment is potentially unsound, and actually unsound in this case. The compiler knows this and inserts an extra check to ensure that you don't assign a value to the variable which isn't actually valid. That check triggers and throws the error you see.
How do you avoid that?
Don't create a TableRow<LogData> where a TableRow<LogData?> is required.
Or type the variable as:
final ItemCallback<T>? widgetOnPressed = widget.onPressed;
(no ? on the T).
Or rewrite everything to avoid returning a function with a covariant type parameter (from the class) occurring contra-variantly (as an argument type).
Which solution fits you depends on what you want to be able to do.

HackLang by Facebook is not strict

Good day,
I have problem. I want to simulate some errors in hacklang.
<?hh
namespace Exsys\HHVM;
class HHVMFacade{
private $vector = Vector {1,2,3};
public function echoProduct() : Vector<string>{
return $this->vector;
}
public function test(Vector<string> $vector) : void{
var_dump($vector);
}
}
Function echoProduct() returns Vector of strings. But private property $vector is Vector of integers. When I call echoFunction and returning value use as argument for function test(). I get
object(HH\Vector)#35357 (3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
Why? I am expecting some error because types mismatch.
There's two things at play here:
Generics aren't reified, so the runtime has no information about them. This means the runtime is only checking that you're returning a Vector.
$this->vector itself isn't typed. This means the type checker (hh_client) treats it as a unknown type. Unknown types match against everything, so there's no problem returning an unknown type where a Vector<string> is expected.
This is to allow you to gradually type your code. Whenever a type isn't known, the type checker just assumes that the developer knows what's happening.
The first thing I'd do is change the file from partial mode to strict mode, which simply involves changing from <?hh to <?hh // strict. This causes the type checker to complain about any missing type information (as well as a couple of other things, like no superglobals and you can't call non-Hack code).
This produces the error:
test.hh:6:13,19: Please add a type hint (Naming[2001])
If you then type $vector as Vector<int> (private Vector<int> $vector), hh_client then produces:
test.hh:9:16,28: Invalid return type (Typing[4110])
test.hh:8:44,49: This is a string
test.hh:6:20,22: It is incompatible with an int
test.hh:8:44,49: Considering that this type argument is invariant with respect to Vector
Which is the error you expected. You can also get this error simply by adding the type to $vector, without switching to strict mode, though I prefer to write my Hack in the strongest mode that the code supports.
With more recent versions of HHVM, the type checker is called whenever Hack code is run (there's an INI flag to turn this off), so causing the type mismatch will also cause execution of the code to fail.

In dart web projects, shouldn't type and reference warnings be errors?

In dart, when developing a web application, if I invoke a method with a wrong number of arguments, the editor shows a warning message, the javascript compilation however runs successfully, and an error is only raised runtime. This is also the case for example if I refer and unexistent variable, or I pass a method argument of the wrong type.
I ask, if the editor already know that things won't work, why is the compilation successful? Why do we have types if they are not checked at compile time? I guess this behaviour has a reason, but I couldn't find it explained anywhere.
In Dart, many programming errors are warnings.
This is for two reasons.
The primary reason is that it allows you to run your program while you are developing it. If some of your code isn't complete yet, or it's only half refactored and still uses the old variable names, you can still test the other half. If you weren't allowed to run the program before it was perfect, that would not be possible.
The other reason is that warnings represent only static type checking, which doesn't know everything about your program, It might be that your program will work, it's just impossible for the analyser to determine.
Example:
class C {
int foo(int x) => x;
}
class D implements C {
num foo(num x, [num defaultValue]) => x == null ? defaultValue : x;
}
void bar(C c) => print(c.foo(4.1, 42)); // Static warning: wrong argument count, bad type.
main() { bar(new D()); } // Program runs fine.
If your program works, it shouldn't be stopped by a pedantic analyser that only knows half the truth. You should still look at the warnings, and consider whether there is something to worry about, but it is perfectly fine to decide that you actually know better than the compiler.
There is no compilation stage. What you see is warning based on type. For example:
This code will have warning:
void main() {
var foo = "";
foo.baz();
}
but this one won't:
void main() {
var foo;
foo.baz();
}
because code analyzer cant deduct the type of foo

Go []int to rune

for pos, char := range s {
fmt.Println( utf8.RuneLen(char) )
}
This code works in Go (pre v1) but doesn't work in Go1.
cannot use char (type []int) as type rune in function argument
I ran go fix which updated the "utf8" import to "unicode/utf8", but now I get the previous err.
The docs for rune mention a trivial conversion will resolve this error.
The code you posted works in Go1. Assuming s is a string.
Make sure you aren't unexpectedly introducing or using some other variable named char which has type []int, and make sure there are no typos in your code which would lead to unexpected usage of a different variable.

Resources