Opened 11 months ago

#207 new enhancement

Safe const variations are not considered for assertion satisfaction

Reported by: mlbrooks Owned by:
Priority: minor Component: cfa-cc
Version: 1.0 Keywords:
Cc:

Description

Assertion satisfaction is invariant in the function type, but it should be cotravariant in the function's parameters and covariant in the function's returns:

A function that consumes a const            reference does not satisfy an assertion for a function that consumes a mutation-allowed reference
A function that produces a mutation-allowed reference does not satisfy an assertion for a function that produces a const            reference
#ifndef QPROD
#define QPROD
#endif

#ifndef QCONS
#define QCONS
#endif

forall( | { void        helpConsume( QCONS int * );
            QPROD int * helpProduce(             ); } )
void f() {
    int copy = * helpProduce();
    helpConsume( & copy );
}

void helpConsume(int * x) {
    printf( "got %d\n", *x );
}

int *helpProduce() {
    static int theVal = 17;
    return & theVal;
}

int main() {
    f();
}

expected -DQPROD=const, expected -DCONS=const, actual plain: compile succeeds; program prints "got 17"

actual -DQPROD=const: No alternatives with satisfiable assertions for Applying ... f ... Could not satisfy assertion: helpProduce

actual -DQCONS=const: No alternatives with satisfiable assertions for Applying ... f ... Could not satisfy assertion: helpConsume

A practical example occurs in the sout ?|? treatment of tuples. The intuition is if a type T is has sout | T then by that it also has sout | [ ... T ... ].

We want and have sout | const char *. It is and should be usable as sout | char *. It is and should be usable to satisfy sout | [ ... const char * ...]. It should be, but by this bug is not, usable to satisfy sout | [ ... char * ...].

int main() {
    sout | "one";
    sout | 2;
  #ifdef WORKAROUND
    sout | [ ( const char * ) "three", 4 ];
  #else
    sout | [                  "three", 4 ];
  #endif
}

expected plain, actual -DWORKAROUND: compiles and runs with

one
2
three, 4

actual plain: No alternatives with satisfiable assertions for Applying untyped: Name: ?|? to: Name: sout, Untyped Tuple ...

Change History (0)

Note: See TracTickets for help on using tickets.