Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing hint about incompatible return type (in strict mode) #20441

Closed
DartBot opened this issue Aug 9, 2014 · 10 comments
Closed

Missing hint about incompatible return type (in strict mode) #20441

DartBot opened this issue Aug 9, 2014 · 10 comments
Labels
analyzer-warning Issues with the analyzer's Warning codes area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug

Comments

@DartBot
Copy link

DartBot commented Aug 9, 2014

This issue was originally filed by andrew.m...@gmail.com


void main() {
  test();
}

Child test() {
  // => Warning should be here <=
  // type 'Base' is not a subtype of type 'Child' of 'function result'.
  return new Base();
}

class Base {
}

class Child extends Base {
}

@bwilkerson
Copy link
Member

According to the specification, given a return statement of the form "return e;"

    It is a static type warning if the type of e may not be assigned to the declared return type
    of the immediately enclosing function.

The type of 'e' is 'Base' and the declared return type is 'Child'. 'Base' is assignable to 'Child', so there isn't suppose to be any warning.

That said, we've been getting a lot of requests to add an option to turn on a strict type checking mode and could generate a hint in that case. I'll change the title and mark this as an enhancement request.


Removed Type-Defect, Priority-Unassigned labels.
Added Type-Enhancement, Priority-Medium, Area-Analyzer, Analyzer-Hint, Triaged labels.
Marked this as being blocked by #20443.
Changed the title to: "Missing hint about incompatible return type (in strict mode)".

@DartBot
Copy link
Author

DartBot commented Aug 9, 2014

This comment was originally written by andrew.m...@gmail.com


'Base' is assignable to 'Child'
This is nonsense.

Base is not assignable to Child.
// type 'Base' is not a subtype of type 'Child' of 'c'.
Child c = new Base();

How possible assign one type that is not a subtype of other type?

It is very unwise to assert that this is so and still get the opposite result.

Look at this code. It prints "Base.IsAssignableTo(Child): False"

using System;

================
public class Test
{
    public static void Main()
    {
        var assignable = typeof(Base).IsAssignableTo(typeof(Child));
        Console.WriteLine("Base.IsAssignableTo(Child): " + assignable);
        Console.ReadKey();
    }
}

public static class Ext
{
    public static bool IsAssignableTo(this Type self, Type type)
    {
        return type.IsAssignableFrom(self);
    }
}

class Base
{
}

class Child : Base
{
}
================

http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html

isAssignableFrom

public boolean isAssignableFrom(Class<?> cls)

Returns:
the boolean value indicating whether objects of the type cls can be assigned to objects of this class

OK, we tests that
  "objects of the type Base can be assigned to objects of Child"

I.e. we test that...
  Base can be assigned to objects of Child
  Base assigned to Child
  Base is assignable to Child

Also this means that Child.class.isAssignableFrom(Base.class) is the same as we read above

  the boolean value indicating whether objects of the type cls (Base, in our case) can be assigned to objects of this class (Child, in our case)

So, test.

================
package app02.app02;

import static java.lang.System.out;

public class Main {
    public static void main(String[] args) {
        Boolean assignable = Child.class.isAssignableFrom(Base.class);
        out.println("Child.class.isAssignableFrom(Base.class): " + assignable);
    }
}

Child.class.isAssignableFrom(Base.class): false
================

P.S.

'Base' is assignable to 'Child', so there isn't suppose to be any warning.

I am shocked by your judgments.

@DartBot
Copy link
Author

DartBot commented Aug 9, 2014

This comment was originally written by andrew.m...@gmail.com


P.S.
Sorry, but it looks like one of the two of us "crazy".
Maybe it's me (and Java with C# too...).

@DartBot
Copy link
Author

DartBot commented Aug 9, 2014

This comment was originally written by andrew.m...@gmail.com


Where I can read in specification about that the "'Base' is assignable to 'Child'"

Or, in other words, Where I can read in specification about that the "'superclass' is assignable to 'subclass'"

Please, give me a link or quote.

P.S.

If you thought that this allowed in the "production" mode than I can open a secret for you.

"String" also assignable to "int" (in production mode)...
...but we give a warning

A value of type 'String' cannot be assigned to a variable of type 'int'.

@bwilkerson
Copy link
Member

For completeness, the first quote, concerning the semantics of the return statement is in section 16.12.

The definition of assignability is in section 18.4, which states

   An interface type T may be assigned to a type S, written T <=> S, iff either T <: S or S <: T.

(where "T <: S" means that T is a subtype of S). The specification then contains the following commentary:

    This rule may surprise readers accustomed to conventional type checking. The intent of
    the <=> relation is not to ensure that an assignment is correct. Instead, it aims to only
    flag assignments that are almost certain to be erroneous, without precluding assignments
    that may work.

    For example, assigning a value of static type Object to a variable with static type String,
    while not guaranteed to be correct, might be fine if the runtime value happens to be a string.

That means that Base can be assigned to Child if either Base is a subclass of Child (which it isn't) or if Child is a subclass of Base (which it is).

I understand that this is different than Java. I understand that this, as predicted, is surprising to many developers. (Dart has an unsound type system, which surprises people in many ways.) That's why we're considering adding a "strict" mode (see issue #20443) that will interpret types in a more conventional way.

P.S. I don't think either of us is crazy, but then crazy people rarely think they are :-)

@DartBot
Copy link
Author

DartBot commented Aug 9, 2014

This comment was originally written by andrew.m...@gmail.com


I understand that this is different than Java.

This is different with all world.

might be fine if the runtime value happens to be a string.

It would be naive to write rules that rely only on a coincidence (luck).

P.S.
Possible assignable (in some cases) is not the same as the assignable (in all cases).
Do not need to confuse the concept and turning everything upside down.

@DartBot
Copy link
Author

DartBot commented Aug 9, 2014

This comment was originally written by @Emasoft


You said: "it might be fine if the runtime value happens to be a string". Well, that is the very definition of a NON TYPE CHECKED LANGUAGE. Because a language is non type checked when things go fine until the runtime value HAPPENS to be of the wrong type. Type checking is a system that prevents such things to happen depending on chance (the very source of untreaceable bugs), and make sure that a value would ALWAYS be of the correct type.
I'm happy to learn that a new "strict" type checking mode is coming to Dart.

@bwilkerson
Copy link
Member

I'm happy to learn that a new "strict" type checking mode is coming to Dart.

Then I'm sorry to have to disillusion you, but there is no commitment to provide such a mode. The community has expressed interest and we're considering it. But that's as far as it's gone. Please register your interest by starring issue #20443.

@DartBot DartBot added Type-Enhancement area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. analyzer-warning Issues with the analyzer's Warning codes labels Aug 9, 2014
@kevmoo kevmoo added P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug and removed triaged labels Mar 1, 2016
@srawlins
Copy link
Member

srawlins commented Dec 5, 2016

The original code now produces an error in Strong mode:

https://dartpad.dartlang.org/b8e86b5a1b4a2ce389b271201781d221

@bwilkerson
Copy link
Member

Yes, I believe that strong mode is (at least similar enough to) what the OP was asking for, so I'm going to close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-warning Issues with the analyzer's Warning codes area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants