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

Invalid result of inferring parameterized type #310

Open
d367wang opened this issue Mar 9, 2021 · 0 comments
Open

Invalid result of inferring parameterized type #310

d367wang opened this issue Mar 9, 2021 · 0 comments

Comments

@d367wang
Copy link

d367wang commented Mar 9, 2021

For the following case:

import ostrusted.qual.OsTrusted;

interface Iterator<T> {
    T next();
}

abstract class CursorIterator implements Iterator<Object> {}

abstract class Test {
    @OsTrusted Object foo(CursorIterator it) {
        return it.next();
    }
}

The return type of foo(CursorIterator it), which is @OsTrusted, ought to lead parameterized type Iterator<Object> to be inferred as Iterator<@OsTrusted Object>.

While the actual result is

@OsUntrusted
interface Iterator<T> {
    T next(@OsTrusted Iterator<T> this);
}

@OsTrusted
abstract class CursorIterator implements @OsTrusted Iterator<Object> {}

abstract class Test {
    @OsTrusted Object foo(@OsTrusted CursorIterator it) {
        return it.next();
    }
}

The invalid result stems from multiple problems in CFI.

Problem I - Implementation of asMemberOf

when getting the annotated type of it.next(), the following steps are performed.

  1. Get the owner of method element next(), which is Iterator<T>
  2. Get the ATM of direct supertype of CursorIterator, which is Iterator<Double>
  3. Build mappings using results of step 1 and 2, as something like { T->@VarAnnot(?) }
  4. Substitute type variables in T next(Iterator<T> this) using the mappings in step 3

The problem occurs at step 2 when getting the annotated type of type element Iterator<Double>. The previously created @VarAnnot for CursorIterator class declaration is not used.

Problem II - Missing constraints

@VarAnnot(7)
interface Iterator<@VarAnnot(5) T extends @VarAnnot(6) Object> {
    @VarAnnot(9)
    T next(@VarAnnot(12) Iterator<@VarAnnot(13) T> this);
}

@VarAnnot(17)
abstract class CursorIterator implements @VarAnnot(15) Iterator<@VarAnnot(16) Object> {}

@VarAnnot(21)
abstract class Test {
    @OsTrusted Object foo(@VarAnnot(25) Test this, @VarAnnot(24) CursorIterator it) {
        return it.next();
    }
}

Only the following constraints are created. (unrelated constraints omitted)
15 <: 7
24 <: 12
24 <: 17

As a result of the above issue, the type of it.next() after running InferenceTreeAnnotator turns out to be Object. Since When the ontology type system didn't specify a default qualifier, it.next() eventually has no annotation on it, such that a null slot takes part in the constraint, a crash.
opprop/ontology#50 workarounds this issue by specifying the default qualifier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant