public void TwoDifferentLiteralTypes_Unify_TypeMismatchReported()
        {
            TypeVariableSet       typeVariableSet   = new TypeVariableSet();
            TypeVariableReference literalReference1 = typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32),
                                  literalReference2 = typeVariableSet.CreateReferenceToLiteralType(PFTypes.Boolean);
            var testTypeUnificationResult           = new TestTypeUnificationResult();

            typeVariableSet.Unify(literalReference2, literalReference1, testTypeUnificationResult);

            Assert.IsTrue(testTypeUnificationResult.TypeMismatch);
        }
            protected override TypeVariableReference ComputeTypeToUnifyWith(VariableReference inputFacadeVariable, out bool setExpectedMutable)
            {
                setExpectedMutable = false;
                TypeVariableReference other = inputFacadeVariable.TypeVariableReference;
                TypeVariableReference u, l;
                bool otherIsMutableReference;
                bool otherIsReference                = TypeVariableSet.TryDecomposeReferenceType(other, out u, out l, out otherIsMutableReference);
                TypeVariableReference underlyingType = otherIsReference ? u : other;

                NIType literalType;
                bool   underlyingTypeIsLiteral   = TypeVariableSet.TryGetLiteralType(underlyingType, out literalType);
                bool   inputCoercesToStringSlice = underlyingTypeIsLiteral &&
                                                   (literalType == PFTypes.String || literalType == DataTypes.StringSliceType);
                bool needsBorrow = !otherIsReference || !underlyingTypeIsLiteral || literalType != DataTypes.StringSliceType;
                TypeVariableReference lifetimeType = otherIsReference
                    ? l
                    : TypeVariableSet.CreateReferenceToLifetimeType(_group.BorrowLifetime);

                if (needsBorrow)
                {
                    _stringToSliceNeeded = true;
                    _group.SetBorrowRequired(false);
                }
                // If the input is allowed to coerce to a str, we can unify with str;
                // otherwise, unify with the underlying type to get a type mismatch.
                TypeVariableReference toUnifyUnderlyingType = inputCoercesToStringSlice
                    ? TypeVariableSet.CreateReferenceToLiteralType(DataTypes.StringSliceType)
                    : underlyingType;

                return(TypeVariableSet.CreateReferenceToReferenceType(
                           false,
                           toUnifyUnderlyingType,
                           lifetimeType));
            }
            private void InsertStringToSliceAheadOfTerminal(Terminal sliceReceiver, out VariableReference stringReferenceVariable, out Terminal stringReferenceTerminal)
            {
                FunctionalNode stringToSlice                = new FunctionalNode(sliceReceiver.ParentDiagram, Signatures.StringToSliceType);
                Terminal       stringToSliceInput           = stringToSlice.InputTerminals[0],
                               stringToSliceOutput          = stringToSlice.OutputTerminals[0];
                VariableReference sliceReceiverTrueVariable = sliceReceiver.GetTrueVariable();

                TypeVariableSet       typeVariableSet = stringToSliceInput.GetTypeVariableSet();
                TypeVariableReference stringSliceReferenceType = sliceReceiverTrueVariable.TypeVariableReference;
                TypeVariableReference u, lifetime;
                bool m;

                typeVariableSet.TryDecomposeReferenceType(stringSliceReferenceType, out u, out lifetime, out m);
                TypeVariableReference stringReferenceType = typeVariableSet.CreateReferenceToReferenceType(
                    false,
                    typeVariableSet.CreateReferenceToLiteralType(PFTypes.String),
                    lifetime);

                AutoBorrowNodeFacade stringToSliceFacade = AutoBorrowNodeFacade.GetNodeFacade(stringToSlice);

                stringToSliceFacade[stringToSliceInput]  = new SimpleTerminalFacade(stringToSliceInput, stringReferenceType);
                stringToSliceFacade[stringToSliceOutput] = new SimpleTerminalFacade(stringToSliceOutput, default(TypeVariableReference));

                sliceReceiver.ConnectedTerminal.ConnectTo(stringToSliceInput);
                stringToSliceOutput.WireTogether(sliceReceiver, SourceModelIdSource.NoSourceModelId);

                stringToSliceOutput.GetFacadeVariable().MergeInto(sliceReceiverTrueVariable);
                stringReferenceVariable = stringToSliceInput.GetFacadeVariable();
                stringReferenceTerminal = stringToSliceInput;
            }
        public void LiteralTypeAndConstructorType_Unify_TypeMismatchReported()
        {
            TypeVariableSet       typeVariableSet      = new TypeVariableSet();
            TypeVariableReference literalReference     = typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32),
                                  constructorReference = typeVariableSet.CreateReferenceToConstructorType("Vector", literalReference);
            var testTypeUnificationResult = new TestTypeUnificationResult();

            typeVariableSet.Unify(constructorReference, literalReference, testTypeUnificationResult);

            Assert.IsTrue(testTypeUnificationResult.TypeMismatch);
        }
        public void LiteralTypeAndTypeVariable_Unify_BothBecomeLiteralType()
        {
            TypeVariableSet       typeVariableSet  = new TypeVariableSet();
            TypeVariableReference literalReference = typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32);
            TypeVariableReference typeVariable     = typeVariableSet.CreateReferenceToNewTypeVariable();

            typeVariableSet.Unify(typeVariable, literalReference, new TestTypeUnificationResult());

            Assert.IsTrue(literalReference.RenderNIType().IsInt32());
            Assert.IsTrue(typeVariable.RenderNIType().IsInt32());
        }
        bool IDfirNodeVisitor <bool> .VisitConstant(Constant constant)
        {
            Terminal valueOutput = constant.OutputTerminals.ElementAt(0);
            TypeVariableReference constantTypeReference;

            if (constant.DataType.IsRebarReferenceType())
            {
                constantTypeReference = _typeVariableSet.CreateReferenceToReferenceType(
                    false,
                    // TODO: this is not always correct; need a more general way of turning NITypes into TypeVariableReferences
                    _typeVariableSet.CreateReferenceToLiteralType(constant.DataType.GetReferentType()),
                    // Assume for now that the reference will be in Lifetime.Static
                    _typeVariableSet.CreateReferenceToLifetimeType(Lifetime.Static));
            }
            else
            {
                constantTypeReference = _typeVariableSet.CreateReferenceToLiteralType(constant.DataType);
            }
            _nodeFacade[valueOutput] = new SimpleTerminalFacade(valueOutput, constantTypeReference);
            return(true);
        }
        public void TwoTypeVariables_Unify_BothBecomeSingleTypeVariable()
        {
            TypeVariableSet       typeVariableSet  = new TypeVariableSet();
            TypeVariableReference literalReference = typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32);
            TypeVariableReference typeVariable1    = typeVariableSet.CreateReferenceToNewTypeVariable(),
                                  typeVariable2    = typeVariableSet.CreateReferenceToNewTypeVariable();

            typeVariableSet.Unify(typeVariable2, typeVariable1, new TestTypeUnificationResult());
            typeVariableSet.Unify(typeVariable1, literalReference, new TestTypeUnificationResult());

            Assert.IsTrue(typeVariable1.RenderNIType().IsInt32());
            Assert.IsTrue(typeVariable2.RenderNIType().IsInt32());
        }
        public void TypeVariableWithCopyConstraintAndNonCopyableType_Unify_FailedConstraintReported()
        {
            TypeVariableSet       typeVariableSet  = new TypeVariableSet();
            TypeVariableReference literalReference = typeVariableSet.CreateReferenceToReferenceType(
                true,
                typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32),
                typeVariableSet.CreateReferenceToLifetimeType(Lifetime.Static));
            var constraint = new CopyConstraint();
            TypeVariableReference typeVariable = typeVariableSet.CreateReferenceToNewTypeVariable(constraint.ToEnumerable());
            var testTypeUnificationResult      = new TestTypeUnificationResult();

            typeVariableSet.Unify(typeVariable, literalReference, testTypeUnificationResult);

            Assert.IsTrue(testTypeUnificationResult.FailedConstraints.Contains(constraint));
        }
        public void TwoConstructorTypesWithSameConstructorNameAndDifferentInnerTypes_Unify_TypeMismatchReported()
        {
            TypeVariableSet       typeVariableSet  = new TypeVariableSet();
            TypeVariableReference constructorType1 = typeVariableSet.CreateReferenceToConstructorType("Vector",
                                                                                                      typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32));
            TypeVariableReference constructorType2 = typeVariableSet.CreateReferenceToConstructorType("Vector",
                                                                                                      typeVariableSet.CreateReferenceToLiteralType(PFTypes.Boolean));
            var typeUnificationResult = new TestTypeUnificationResult();

            typeVariableSet.Unify(constructorType1, constructorType2, typeUnificationResult);

            Assert.IsTrue(typeUnificationResult.TypeMismatch);
        }
        public void TwoConstructorTypesWithSameConstructorName_Unify_InnerTypesAreUnified()
        {
            TypeVariableSet       typeVariableSet   = new TypeVariableSet();
            TypeVariableReference innerTypeVariable = typeVariableSet.CreateReferenceToNewTypeVariable();
            TypeVariableReference constructorType1  = typeVariableSet.CreateReferenceToConstructorType("Vector",
                                                                                                       innerTypeVariable);
            TypeVariableReference constructorType2 = typeVariableSet.CreateReferenceToConstructorType("Vector",
                                                                                                      typeVariableSet.CreateReferenceToLiteralType(PFTypes.Int32));

            typeVariableSet.Unify(constructorType1, constructorType2, new TestTypeUnificationResult());

            Assert.IsTrue(innerTypeVariable.RenderNIType().IsInt32());
        }