microsoft / CodeContracts

Source code for the CodeContracts tools for .NET
Other
882 stars 151 forks source link

F# tuple is not created when rewriten #419

Open xperiandri opened 8 years ago

xperiandri commented 8 years ago

Having method

    let addDoubleLevelElement ((position : InletPosition * OutletPosition))
        (element : DoubleLevelElement)
        logical =

        Contract.Requires<InvalidOperationException>(
            canAddDoubleLevelElement element logical,
            "Configuration with one more DoubleLevelElement of provided type is not supported.")
        Contract.Requires<InvalidOperationException>(
            canInsertDoubleLevelElementIntoPosition position logical,
            "DoubleLevelElement cannot be inserted across another DoubleLevelElement")

        { InLet = logical.InLet.Insert(fst position, element);
          OutLet = logical.OutLet.Insert(snd position, element) }

I got this code after rewriting

[CompilationArgumentCounts(new int[] { 2, 1, 1 })]
public static Logical addDoubleLevelElement(int position_0, int position_1, DoubleLevelElement element, Logical logical)
{
    Tuple<int, int> tuple;
    if (__ContractsRuntime.insideContractEvaluation <= 4)
    {
        try
        {
            __ContractsRuntime.insideContractEvaluation++;
            Tuple<int, int> tuple2 = new Tuple<int, int>(position_0, position_1);
            __ContractsRuntime.Requires<InvalidOperationException>(canAddDoubleLevelElement(element, logical), "Configuration with one more DoubleLevelElement of provided type is not supported.", "canAddDoubleLevelElement element logical");
            __ContractsRuntime.Requires<InvalidOperationException>(canInsertDoubleLevelElementIntoPosition(tuple2.get_Item1(), tuple2.get_Item2(), logical), "DoubleLevelElement cannot be inserted across another DoubleLevelElement", "canInsertDoubleLevelElementIntoPosition position logical");
        }
        finally
        {
            __ContractsRuntime.insideContractEvaluation--;
        }
    }
    return new Logical(logical.InLet@.Insert(Operators.Fst<int, int>(tuple), element), logical.OutLet@.Insert(Operators.Snd<int, int>(tuple), element));
}

Notice statement Tuple<int, int> tuple;, this tuple is never assigned.

SergeyTeplyakov commented 8 years ago

I'm really surprised that this is the only error that you have in your F# project.

C# and F# has really different code gens so the IL patterns are significantly different. So I don't think that code contracts ever tested with IL produced by F# compiler and I'm almost sure that it will fail to generate correct code because of complexity and exponential explosion of language patterns that needs to be covered to work properly with C# and F#.

xperiandri commented 8 years ago

I would try :) For now this is the only bug I found. How can I debug that piece of code and figure out what is wrong? Is this process trivial or complicated?