Draft: vala: check legality and usefulness of casts
The Vala compiler could do more to catch faulty and useless casts. For example:
class Foo {}
class Baz {}
class Bar : Foo {}
void main() {
var baz = (Baz) new Foo ();
var foo = (Foo) new Bar ();
}
The first cast is faulty. It will never succeed because Baz
has no possible relationship to Foo
. The second cast is unnecessary, because any Bar
is a Foo
. With this change, this is what the compiler outputs:
cast2.vala:6.15-6.30: error: Cast will always fail
6 | var baz = (Baz) new Foo ();
| ^~~~~~~~~~~~~~~~
cast2.vala:6.16-6.18: note: `Baz' does not relate to `Foo'
6 | var baz = (Baz) new Foo ();
| ^~~
cast2.vala:7.15-7.30: warning: Useless cast from `Bar' to `Foo'
7 | var foo = (Foo) new Bar ();
| ^~~~~~~~~~~~~~~~
cast2.vala:7.16-7.18: note: `Foo' is a supertype of `Bar'
7 | var foo = (Foo) new Bar ();
| ^~~
Compilation failed: 1 error(s), 1 warning(s)
This change is already catching some useless casts in real code. For example, Shotwell has many:
...
../src/dialogs/ExportDialog.vala:112.9-112.38: warning: Useless cast from `Gtk.Box' to `Gtk.Box'
112 | ((Gtk.Box) get_content_area()).add(table);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/searches/SavedSearchDialog.vala:617.13-617.44: warning: Useless cast from `Gtk.Box' to `Gtk.Box'
617 | ((Gtk.Box) d.get_content_area()).add(cal);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/searches/SavedSearchDialog.vala:711.13-711.46: warning: Useless cast from `Gtk.HeaderBar' to `Gtk.HeaderBar'
711 | ((Gtk.HeaderBar) get_header_bar()).set_custom_title(search_title);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/Printing.vala:686.9-686.44: warning: Useless cast from `Gtk.FontButton' to `Gtk.FontChooser'
686 | ((Gtk.FontChooser) title_print_font).set_font(fontname);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/Printing.vala:686.11-686.25: note: `Gtk.FontChooser' is a supertype of `Gtk.FontButton'
686 | ((Gtk.FontChooser) title_print_font).set_font(fontname);
| ^~~~~~~~~~~~~~~
../src/Printing.vala:699.16-699.51: warning: Useless cast from `Gtk.FontButton' to `Gtk.FontChooser'
699 | return ((Gtk.FontChooser) title_print_font).get_font();
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/Printing.vala:699.18-699.32: note: `Gtk.FontChooser' is a supertype of `Gtk.FontButton'
699 | return ((Gtk.FontChooser) title_print_font).get_font();
| ^~~~~~~~~~~~~~~
../src/publishing/PublishingUI.vala:39.13-39.46: warning: Useless cast from `Gtk.HeaderBar' to `Gtk.HeaderBar'
39 | ((Gtk.HeaderBar) get_header_bar()).set_show_close_button(false);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
However, this is still a draft because I haven't yet handled casts between generic types.