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));
            }
Exemplo n.º 2
0
        private LifetimeTypeVariableGroup(Diagram diagram)
        {
            _variableSet     = diagram.GetVariableSet();
            _typeVariableSet = _variableSet.TypeVariableSet;
            LifetimeGraphTree       lifetimeGraphTree      = diagram.DfirRoot.GetLifetimeGraphTree();
            LifetimeGraphIdentifier diagramGraphIdentifier = diagram.GetLifetimeGraphIdentifier();

            LazyNewLifetime = new Lazy <Lifetime>(() => lifetimeGraphTree.CreateLifetimeThatIsBoundedByLifetimeGraph(diagramGraphIdentifier));
            LifetimeType    = _typeVariableSet.CreateReferenceToLifetimeType(LazyNewLifetime);
        }
Exemplo n.º 3
0
        public void TypeVariableWithCopyConstraintAndNonCopyableType_Unify_FailedConstraintReported()
        {
            TypeVariableSet       typeVariableSet  = new TypeVariableSet();
            TypeVariableReference literalReference = typeVariableSet.CreateReferenceToReferenceType(
                true,
                typeVariableSet.CreateTypeVariableReferenceFromNIType(NITypes.Int32),
                typeVariableSet.CreateReferenceToLifetimeType(Lifetime.Static));
            var constraint = new SimpleTraitConstraint("Copy");
            TypeVariableReference typeVariable = typeVariableSet.CreateReferenceToNewTypeVariable(constraint.ToEnumerable());
            var testTypeUnificationResult      = new TestTypeUnificationResult();

            typeVariableSet.Unify(typeVariable, literalReference, testTypeUnificationResult);

            Assert.IsTrue(testTypeUnificationResult.FailedConstraints.Contains(constraint));
        }
Exemplo n.º 4
0
        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.CreateTypeVariableReferenceFromNIType(constant.DataType.GetReferentType()),
                    // Assume for now that the reference will be in Lifetime.Static
                    _typeVariableSet.CreateReferenceToLifetimeType(Lifetime.Static));
            }
            else
            {
                constantTypeReference = _typeVariableSet.CreateTypeVariableReferenceFromNIType(constant.DataType);
            }
            _nodeFacade[valueOutput] = new SimpleTerminalFacade(valueOutput, constantTypeReference);
            return(true);
        }
            protected override TypeVariableReference ComputeTypeToUnifyWith(VariableReference inputFacadeVariable, out bool setExpectedMutable)
            {
                TypeVariableReference other = inputFacadeVariable.TypeVariableReference;
                TypeVariableReference u, otherReferenceLifetime;
                bool otherIsMutableReference;
                bool otherIsReference                = TypeVariableSet.TryDecomposeReferenceType(other, out u, out otherReferenceLifetime, out otherIsMutableReference);
                TypeVariableReference underlyingType = otherIsReference ? u : other;
                bool mutable = otherIsReference ? otherIsMutableReference : inputFacadeVariable.Mutable;

                TypeVariableReference typeToUnifyWith = default(TypeVariableReference);

                setExpectedMutable = false;
                switch (_mutability)
                {
                case InputReferenceMutability.RequireMutable:
                {
                    TypeVariableReference lifetimeType;
                    if (!otherIsReference)
                    {
                        _group.SetBorrowRequired(true);
                        lifetimeType = TypeVariableSet.CreateReferenceToLifetimeType(_group.BorrowLifetime);
                    }
                    else
                    {
                        lifetimeType = otherReferenceLifetime;
                    }
                    typeToUnifyWith    = TypeVariableSet.CreateReferenceToReferenceType(true, underlyingType, lifetimeType);
                    setExpectedMutable = !mutable;
                    break;
                }

                case InputReferenceMutability.AllowImmutable:
                {
                    bool needsBorrow = !(otherIsReference && !otherIsMutableReference);
                    TypeVariableReference lifetimeType;
                    if (needsBorrow)
                    {
                        lifetimeType = TypeVariableSet.CreateReferenceToLifetimeType(_group.BorrowLifetime);
                        _group.SetBorrowRequired(false);
                    }
                    else
                    {
                        lifetimeType = otherReferenceLifetime;
                    }
                    typeToUnifyWith = TypeVariableSet.CreateReferenceToReferenceType(false, underlyingType, lifetimeType);
                    break;
                }

                case InputReferenceMutability.Polymorphic:
                {
                    TypeVariableReference lifetimeType;
                    if (!otherIsReference)
                    {
                        _group.SetBorrowRequired(false /* TODO depends on current state and input mutability */);
                        lifetimeType = TypeVariableSet.CreateReferenceToLifetimeType(_group.BorrowLifetime);
                    }
                    else
                    {
                        // TODO: if TrueVariable.TypeVariableReference is already known to be immutable and
                        // wire reference is mutable, then we need a borrow
                        lifetimeType = otherReferenceLifetime;
                    }
                    typeToUnifyWith = TypeVariableSet.CreateReferenceToReferenceType(mutable, underlyingType, lifetimeType);
                    break;
                }
                }
                return(typeToUnifyWith);
            }