Esempio n. 1
0
        public static bool CheckAllConstraints(
            this TypeSymbol type,
            ConversionsBase conversions)
        {
            var diagnostics = DiagnosticBag.GetInstance();

            type.CheckAllConstraints(conversions, NoLocation.Singleton, diagnostics);
            bool ok = !diagnostics.HasAnyErrors();

            diagnostics.Free();
            return(ok);
        }
Esempio n. 2
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true);
            ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(DeclaringCompilation, conversions, parameter.Locations[0], diagnostics);
            }
        }
Esempio n. 3
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            var location = this.Locations[0];

            this.CheckModifiersAndType(diagnostics);
            this.Type.CheckAllConstraints(DeclaringCompilation, conversions, location, diagnostics);

            if (this.TypeWithAnnotations.NeedsNullableAttribute())
            {
                this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
            }
        }
Esempio n. 4
0
        private static bool SatisfiesConstraintType(
            ConversionsBase conversions,
            TypeSymbol typeArgument,
            TypeSymbol constraintType,
            ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            if (constraintType.IsErrorType())
            {
                return(false);
            }

            // Spec 4.4.4 describes the valid conversions from
            // type argument A to constraint type C:

            // "An identity conversion (6.1.1).
            // An implicit reference conversion (6.1.6). ..."
            if (conversions.HasIdentityOrImplicitReferenceConversion(typeArgument, constraintType, ref useSiteDiagnostics))
            {
                return(true);
            }

            // "... A boxing conversion (6.1.7), provided that type A is a non-nullable value type. ..."
            // NOTE: we extend this to allow, for example, a conversion from Nullable<T> to object.
            if (typeArgument.IsValueType &&
                conversions.HasBoxingConversion(typeArgument.IsNullableType() ? ((NamedTypeSymbol)typeArgument).ConstructedFrom : typeArgument, constraintType, ref useSiteDiagnostics))
            {
                return(true);
            }

            if (typeArgument.TypeKind == TypeKind.TypeParameter)
            {
                var typeParameter = (TypeParameterSymbol)typeArgument;

                // "... An implicit reference, boxing, or type parameter conversion
                // from type parameter A to C."
                if (conversions.HasImplicitTypeParameterConversion(typeParameter, constraintType, ref useSiteDiagnostics))
                {
                    return(true);
                }

                // TypeBind::SatisfiesBound allows cases where one of the
                // type parameter constraints satisfies the constraint.
                foreach (var typeArgumentConstraint in typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics))
                {
                    if (SatisfiesConstraintType(conversions, typeArgumentConstraint, constraintType, ref useSiteDiagnostics))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Esempio n. 5
0
            internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
            {
                base.AfterAddingTypeMembersChecks(conversions, diagnostics);

                if (_refKind == RefKind.RefReadOnly)
                {
                    var syntax = (DelegateDeclarationSyntax)SyntaxRef.GetSyntax();
                    DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, syntax.ReturnType.GetLocation(), modifyCompilationForRefReadOnly: true);
                }

                ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
            }
Esempio n. 6
0
        internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            this.ReturnType.CheckAllConstraints(conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(conversions, parameter.Locations[0], diagnostics);
            }
        }
Esempio n. 7
0
        public bool CheckAllConstraints(
            LanguageCompilation compilation,
            ConversionsBase conversions)
        {
            var diagnostics = DiagnosticBag.GetInstance();

            // Nullability checks can only add warnings here so skip them for this check as we are only
            // concerned with errors.
            CheckAllConstraints(compilation, conversions, NoLocation.Singleton, diagnostics);
            bool ok = !diagnostics.HasAnyErrors();

            diagnostics.Free();
            return(ok);
        }
        internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            this.ReturnType.CheckAllConstraints(conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(conversions, parameter.Locations[0], diagnostics);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
        }
Esempio n. 9
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, BindingDiagnosticBag diagnostics)
        {
            var compilation = DeclaringCompilation;
            var location    = ErrorLocation;

            if (compilation.ShouldEmitNativeIntegerAttributes(Type))
            {
                compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            if (compilation.ShouldEmitNullableAttributes(this) &&
                TypeWithAnnotations.NeedsNullableAttribute())
            {
                compilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
            }
        }
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, BindingDiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            var location    = ReturnTypeLocation;
            var compilation = DeclaringCompilation;

            Debug.Assert(location != null);

            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.
            CheckConstraintsForExplicitInterfaceType(conversions, diagnostics);

            this.ReturnType.CheckAllConstraints(compilation, conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(compilation, conversions, parameter.Locations[0], diagnostics);
            }

            PartialMethodChecks(diagnostics);

            if (RefKind == RefKind.RefReadOnly)
            {
                compilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            if (compilation.ShouldEmitNativeIntegerAttributes(ReturnType))
            {
                compilation.EnsureNativeIntegerAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureNativeIntegerAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            ParameterHelpers.EnsureLifetimeAnnotationAttributeExists(compilation, Parameters, diagnostics, modifyCompilation: true);

            if (compilation.ShouldEmitNullableAttributes(this) && ReturnTypeWithAnnotations.NeedsNullableAttribute())
            {
                compilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureNullableAttributeExists(compilation, this, Parameters, diagnostics, modifyCompilation: true);
        }
Esempio n. 11
0
        public static bool CheckConstraints(
            this NamedTypeSymbol type,
            CSharpCompilation currentCompilation,
            ConversionsBase conversions,
            Location location,
            DiagnosticBag diagnostics)
        {
            // We do not report element locations in method parameters and return types
            // so we will simply unwrap the type if it was a tuple. We are relying on
            // TypeSymbolExtensions.VisitType to dig into the "Rest" tuple so that they
            // will be recursively unwrapped as well.
            type = (NamedTypeSymbol)type.TupleUnderlyingTypeOrSelf();

            if (!RequiresChecking(type))
            {
                return(true);
            }

            var diagnosticsBuilder = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance();

            ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();

            // we only check for distinct interfaces when the type is not from source, as we
            // trust that types that are from source have already been checked by the compiler
            // to prevent this from happening in the first place.
            if (!(currentCompilation != null && type.IsFromCompilation(currentCompilation)) && HasDuplicateInterfaces(type, null))
            {
                result = false;
                diagnostics.Add(ErrorCode.ERR_BogusType, location, type);
            }

            return(result);
        }
Esempio n. 12
0
        /// <summary>
        /// Infer return type. If `nullableState` is non-null, nullability is also inferred and `NullableWalker.Analyze`
        /// uses that state to set the inferred nullability of variables in the enclosing scope. `conversions` is
        /// only needed when nullability is inferred.
        /// </summary>
        public TypeWithAnnotations GetInferredReturnType(ConversionsBase conversions, NullableWalker.VariableState nullableState, ref HashSet <DiagnosticInfo> useSiteDiagnostics)
        {
            if (!InferredReturnType.UseSiteDiagnostics.IsEmpty)
            {
                if (useSiteDiagnostics == null)
                {
                    useSiteDiagnostics = new HashSet <DiagnosticInfo>();
                }
                foreach (var info in InferredReturnType.UseSiteDiagnostics)
                {
                    useSiteDiagnostics.Add(info);
                }
            }
            if (nullableState == null)
            {
                return(InferredReturnType.TypeWithAnnotations);
            }
            else
            {
                Debug.Assert(conversions != null);
                // Diagnostics from NullableWalker.Analyze can be dropped here since Analyze
                // will be called again from NullableWalker.ApplyConversion when the
                // BoundLambda is converted to an anonymous function.
                // https://github.com/dotnet/roslyn/issues/31752: Can we avoid generating extra
                // diagnostics? And is this exponential when there are nested lambdas?
                var returnTypes = ArrayBuilder <(BoundReturnStatement, TypeWithAnnotations)> .GetInstance();

                var diagnostics  = DiagnosticBag.GetInstance();
                var delegateType = Type.GetDelegateType();
                var compilation  = Binder.Compilation;
                NullableWalker.Analyze(compilation,
                                       lambda: this,
                                       (Conversions)conversions,
                                       diagnostics,
                                       delegateInvokeMethod: delegateType?.DelegateInvokeMethod,
                                       initialState: nullableState,
                                       analyzedNullabilityMapOpt: null,
                                       updatedMethodSymbolMapOpt: null,
                                       snapshotBuilderOpt: null,
                                       returnTypes);
                diagnostics.Free();
                var inferredReturnType = InferReturnType(returnTypes, node: this, compilation, conversions, delegateType, Symbol.IsAsync);
                returnTypes.Free();
                return(inferredReturnType.TypeWithAnnotations);
            }
        }
Esempio n. 13
0
 private static bool CheckTypeConstraints(
     NamedTypeSymbol type,
     ConversionsBase conversions,
     Compilation currentCompilation,
     ArrayBuilder <TypeParameterDiagnosticInfo> diagnosticsBuilder,
     ref ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
 {
     return(CheckConstraints(
                type,
                conversions,
                type.TypeSubstitution,
                type.OriginalDefinition.TypeParameters,
                type.TypeArgumentsNoUseSiteDiagnostics,
                currentCompilation,
                diagnosticsBuilder,
                ref useSiteDiagnosticsBuilder));
 }
Esempio n. 14
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            if ((object)_explicitInterfaceType != null)
            {
                var explicitInterfaceSpecifier = this.ExplicitInterfaceSpecifier;
                RoslynDebug.Assert(explicitInterfaceSpecifier != null);
                _explicitInterfaceType.CheckAllConstraints(DeclaringCompilation, conversions, new SourceLocation(explicitInterfaceSpecifier.Name), diagnostics);
            }

            if (!_explicitInterfaceImplementations.IsEmpty)
            {
                // Note: we delayed nullable-related checks that could pull on NonNullTypes
                EventSymbol explicitlyImplementedEvent = _explicitInterfaceImplementations[0];
                TypeSymbol.CheckNullableReferenceTypeMismatchOnImplementingMember(this.ContainingType, this, explicitlyImplementedEvent, isExplicit: true, diagnostics);
            }
        }
Esempio n. 15
0
        public static bool CheckConstraints(
            this NamedTypeSymbol type,
            ConversionsBase conversions,
            CSharpSyntaxNode typeSyntax,
            SeparatedSyntaxList <TypeSyntax> typeArgumentsSyntax, // may be omitted in synthesized invocations
            Compilation currentCompilation,
            ConsList <Symbol> basesBeingResolved,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(typeArgumentsSyntax.Count == 0 /*omitted*/ ||
                         typeArgumentsSyntax.Count == type.Arity - type.ImplicitTypeParameterCount /* @t-mawind part-inferred */ ||
                         typeArgumentsSyntax.Count == type.Arity);
            if (!RequiresChecking(type))
            {
                return(true);
            }

            var diagnosticsBuilder = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance();

            ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = !typeSyntax.HasErrors && CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                int ordinal  = pair.TypeParameter.Ordinal;
                var location = new SourceLocation(ordinal < typeArgumentsSyntax.Count ? typeArgumentsSyntax[ordinal] : typeSyntax);
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();

            if (HasDuplicateInterfaces(type, basesBeingResolved))
            {
                result = false;
                diagnostics.Add(ErrorCode.ERR_BogusType, typeSyntax.Location, type);
            }

            return(result);
        }
Esempio n. 16
0
    public static Conversion ClassifyConversionFromExpression(
        this ConversionsBase conversions,
        BoundExpression sourceExpression,
        TypeSymbol destination,
        ref HashSet <DiagnosticInfo> useSiteDiagnostics,
        bool forCast = false
        )
    {
        CompoundUseSiteInfo <AssemblySymbol> useSiteInfo = default;
        Conversion result = conversions.ClassifyConversionFromExpression(
            sourceExpression,
            destination,
            ref useSiteInfo,
            forCast
            );

        AddDiagnosticInfos(ref useSiteDiagnostics, useSiteInfo);
        return(result);
    }
Esempio n. 17
0
 private static bool CheckMethodConstraints(
     MethodSymbol method,
     ConversionsBase conversions,
     Compilation currentCompilation,
     ArrayBuilder <TypeParameterDiagnosticInfo> diagnosticsBuilder,
     ref ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder,
     BitVector skipParameters = default(BitVector))
 {
     return(CheckConstraints(
                method,
                conversions,
                method.TypeSubstitution,
                ((MethodSymbol)method.OriginalDefinition).TypeParameters,
                method.TypeArguments,
                currentCompilation,
                diagnosticsBuilder,
                ref useSiteDiagnosticsBuilder,
                skipParameters));
 }
Esempio n. 18
0
        public static bool CheckConstraints(
            this NamedTypeSymbol type,
            ConversionsBase conversions,
            CSharpSyntaxNode typeSyntax,
            SeparatedSyntaxList <TypeSyntax> typeArgumentsSyntax,
            Compilation currentCompilation,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(typeArgumentsSyntax.Count == type.Arity);
            if (!RequiresChecking(type))
            {
                return(true);
            }

            var diagnosticsBuilder = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance();

            ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                int ordinal  = pair.TypeParameter.Ordinal;
                var location = new SourceLocation(typeArgumentsSyntax[ordinal]);
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();

            if (!InterfacesAreDistinct(type))
            {
                result = false;
                diagnostics.Add(ErrorCode.ERR_BogusType, typeSyntax.Location, type);
            }

            return(result);
        }
Esempio n. 19
0
        public static bool CheckConstraints(
            this NamedTypeSymbol type,
            CSharpCompilation currentCompilation,
            ConversionsBase conversions,
            Location location,
            DiagnosticBag diagnostics)
        {
            if (!RequiresChecking(type))
            {
                return(true);
            }

            var diagnosticsBuilder = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance();

            ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();

            // we only check for distinct interfaces when the type is not from source, as we
            // trust that types that are from source have already been checked by the compiler
            // to prevent this from happening in the first place.
            if (!(currentCompilation != null && type.IsFromCompilation(currentCompilation)) && HasDuplicateInterfaces(type, null))
            {
                result = false;
                diagnostics.Add(ErrorCode.ERR_BogusType, location, type);
            }

            return(result);
        }
Esempio n. 20
0
            internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
            {
                var syntax   = (DelegateDeclarationSyntax)SyntaxRef.GetSyntax();
                var location = syntax.ReturnType.GetLocation();

                Debug.Assert(location != null);

                base.AfterAddingTypeMembersChecks(conversions, diagnostics);

                if (_refKind == RefKind.RefReadOnly)
                {
                    DeclaringCompilation.EnsureIsReadOnlyAttributeExists(diagnostics, location, modifyCompilation: true);
                }

                ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true);

                if (ReturnTypeWithAnnotations.NeedsNullableAttribute())
                {
                    this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
                }

                ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true);
            }
Esempio n. 21
0
        /// <summary>
        /// Check type parameter constraints for the containing type or method symbol.
        /// </summary>
        /// <param name="containingSymbol">The generic type or method.</param>
        /// <param name="conversions">Conversions instance.</param>
        /// <param name="substitution">The map from type parameters to type arguments.</param>
        /// <param name="typeParameters">Containing symbol type parameters.</param>
        /// <param name="typeArguments">Containing symbol type arguments.</param>
        /// <param name="currentCompilation">Improves error message detail.</param>
        /// <param name="diagnosticsBuilder">Diagnostics.</param>
        /// <param name="skipParameters">Parameters to skip.</param>
        /// <param name="useSiteDiagnosticsBuilder"/>
        /// <param name="ignoreTypeConstraintsDependentOnTypeParametersOpt">If an original form of a type constraint
        /// depends on a type parameter from this set, do not verify this type constraint.</param>
        /// <returns>True if the constraints were satisfied, false otherwise.</returns>
        public static bool CheckConstraints(
            this Symbol containingSymbol,
            ConversionsBase conversions,
            TypeMap substitution,
            ImmutableArray <TypeParameterSymbol> typeParameters,
            ImmutableArray <TypeSymbol> typeArguments,
            Compilation currentCompilation,
            ArrayBuilder <TypeParameterDiagnosticInfo> diagnosticsBuilder,
            ref ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder,
            BitVector skipParameters = default(BitVector),
            HashSet <TypeParameterSymbol> ignoreTypeConstraintsDependentOnTypeParametersOpt = null)
        {
            Debug.Assert(typeParameters.Length == typeArguments.Length);
            Debug.Assert(typeParameters.Length > 0);

            int  n         = typeParameters.Length;
            bool succeeded = true;

            for (int i = 0; i < n; i++)
            {
                if (skipParameters[i])
                {
                    continue;
                }

                var typeArgument  = typeArguments[i];
                var typeParameter = typeParameters[i];

                if (!CheckConstraints(containingSymbol, conversions, substitution, typeParameter, typeArgument, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder,
                                      ignoreTypeConstraintsDependentOnTypeParametersOpt))
                {
                    succeeded = false;
                }
            }

            return(succeeded);
        }
Esempio n. 22
0
        internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            this.ReturnType.CheckAllConstraints(DeclaringCompilation, conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(DeclaringCompilation, conversions, parameter.Locations[0], diagnostics);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilation: true);

            var location = ReturnTypeSyntax.Location;

            if (ReturnTypeWithAnnotations.NeedsNullableAttribute())
            {
                this.DeclaringCompilation.EnsureNullableAttributeExists(diagnostics, location, modifyCompilation: true);
            }

            ParameterHelpers.EnsureNullableAttributeExists(Parameters, diagnostics, modifyCompilation: true);
        }
Esempio n. 23
0
 public CheckConstraintsArgs(CSharpCompilation currentCompilation, ConversionsBase conversions, Location location, DiagnosticBag diagnostics)
 {
     this.CurrentCompilation = currentCompilation;
     this.Conversions = conversions;
     this.Location = location;
     this.Diagnostics = diagnostics;
 }
Esempio n. 24
0
 public static bool CheckAllConstraints(
     this TypeSymbol type,
     ConversionsBase conversions)
 {
     var diagnostics = DiagnosticBag.GetInstance();
     type.CheckAllConstraints(conversions, NoLocation.Singleton, diagnostics);
     bool ok = !diagnostics.HasAnyErrors();
     diagnostics.Free();
     return ok;
 }
Esempio n. 25
0
 /// <summary>
 /// Check all generic constraints on the given type and any containing types
 /// (such as A&lt;T&gt; in A&lt;T&gt;.B&lt;U&gt;). This includes checking constraints
 /// on generic types within the type (such as B&lt;T&gt; in A&lt;B&lt;T&gt;[]&gt;).
 /// </summary>
 public static void CheckAllConstraints(
     this TypeSymbol type,
     ConversionsBase conversions,
     Location location,
     DiagnosticBag diagnostics)
 {
     type.VisitType(s_checkConstraintsSingleTypeFunc, new CheckConstraintsArgs(type.DeclaringCompilation, conversions, location, diagnostics));
 }
        internal sealed override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            this.ReturnType.CheckAllConstraints(conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(conversions, parameter.Locations[0], diagnostics);
            }
        }
Esempio n. 27
0
        // See TypeBind::CheckSingleConstraint.
        private static bool CheckConstraints(
            Symbol containingSymbol,
            ConversionsBase conversions,
            TypeMap substitution,
            TypeParameterSymbol typeParameter,
            TypeSymbol typeArgument,
            Compilation currentCompilation,
            ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder,
            ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder,
            HashSet<TypeParameterSymbol> ignoreTypeConstraintsDependentOnTypeParametersOpt)
        {
            Debug.Assert(substitution != null);
            // The type parameters must be original definitions of type parameters from the containing symbol.
            Debug.Assert(ReferenceEquals(typeParameter.ContainingSymbol, containingSymbol.OriginalDefinition));

            if (typeArgument.IsErrorType())
            {
                return true;
            }

            if (typeArgument.IsPointerType() || typeArgument.IsRestrictedType() || typeArgument.SpecialType == SpecialType.System_Void)
            {
                // "The type '{0}' may not be used as a type argument"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_BadTypeArgument, typeArgument)));
                return false;
            }

            if (typeArgument.IsStatic)
            {
                // "'{0}': static types cannot be used as type arguments"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_GenericArgIsStaticClass, typeArgument)));
                return false;
            }

            if (typeParameter.HasReferenceTypeConstraint && !typeArgument.IsReferenceType)
            {
                // "The type '{2}' must be a reference type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_RefConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return false;
            }

            if (typeParameter.HasValueTypeConstraint && !typeArgument.IsNonNullableValueType())
            {
                // "The type '{2}' must be a non-nullable value type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_ValConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return false;
            }

            // The type parameters for a constructed type/method are the type parameters of
            // the ConstructedFrom type/method, so the constraint types are not substituted.
            // For instance with "class C<T, U> where T : U", the type parameter for T in "C<object, int>"
            // has constraint "U", not "int". We need to substitute the constraints from the
            // original definition of the type parameters using the map from the constructed symbol.
            var constraintTypes = ArrayBuilder<TypeSymbol>.GetInstance();
            HashSet<DiagnosticInfo> useSiteDiagnostics = null;
            substitution.SubstituteTypesDistinctWithoutModifiers(typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics), constraintTypes, 
                                                                 ignoreTypeConstraintsDependentOnTypeParametersOpt);

            bool hasError = false;

            foreach (var constraintType in constraintTypes)
            {
                if (SatisfiesConstraintType(conversions, typeArgument, constraintType, ref useSiteDiagnostics))
                {
                    continue;
                }

                ErrorCode errorCode;
                if (typeArgument.IsReferenceType)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedRefType;
                }
                else if (typeArgument.IsNullableType())
                {
                    errorCode = constraintType.IsInterfaceType() ? ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface : ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum;
                }
                else if (typeArgument.TypeKind == TypeKind.TypeParameter)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar;
                }
                else
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedValType;
                }

                SymbolDistinguisher distinguisher = new SymbolDistinguisher(currentCompilation, constraintType, typeArgument);
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(errorCode, containingSymbol.ConstructedFrom(), distinguisher.First, typeParameter, distinguisher.Second)));
                hasError = true;
            }

            if (AppendUseSiteDiagnostics(useSiteDiagnostics, typeParameter, ref useSiteDiagnosticsBuilder))
            {
                hasError = true;
            }

            constraintTypes.Free();

            // Check the constructor constraint.
            if (typeParameter.HasConstructorConstraint && !SatisfiesConstructorConstraint(typeArgument))
            {
                // "'{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_NewConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return false;
            }

            return !hasError;
        }
Esempio n. 28
0
 private static bool CheckMethodConstraints(
     MethodSymbol method,
     ConversionsBase conversions,
     Compilation currentCompilation,
     ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder,
     ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder,
     BitVector skipParameters = default(BitVector))
 {
     return CheckConstraints(
         method,
         conversions,
         method.TypeSubstitution,
         ((MethodSymbol)method.OriginalDefinition).TypeParameters,
         method.TypeArguments,
         currentCompilation,
         diagnosticsBuilder,
         ref useSiteDiagnosticsBuilder,
         skipParameters);
 }
Esempio n. 29
0
        public static bool CheckConstraints(
            this MethodSymbol method,
            ConversionsBase conversions,
            Location location,
            Compilation currentCompilation,
            DiagnosticBag diagnostics)
        {
            if (!RequiresChecking(method))
            {
                return true;
            }

            var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
            ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = CheckMethodConstraints(method, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();
            return result;
        }
Esempio n. 30
0
        // See TypeBind::CheckSingleConstraint.
        private static bool CheckConstraints(
            Symbol containingSymbol,
            ConversionsBase conversions,
            TypeMap substitution,
            TypeParameterSymbol typeParameter,
            TypeSymbol typeArgument,
            Compilation currentCompilation,
            ArrayBuilder <TypeParameterDiagnosticInfo> diagnosticsBuilder,
            ref ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
        {
            Debug.Assert(substitution != null);
            // The type parameters must be original definitions of type parameters from the containing symbol.
            Debug.Assert(ReferenceEquals(typeParameter.ContainingSymbol, containingSymbol.OriginalDefinition));

            if (typeArgument.IsErrorType())
            {
                return(true);
            }

            if (typeArgument.IsPointerType() || typeArgument.IsRestrictedType() || typeArgument.SpecialType == SpecialType.System_Void)
            {
                // "The type '{0}' may not be used as a type argument"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_BadTypeArgument, typeArgument)));
                return(false);
            }

            if (typeArgument.IsStatic)
            {
                // "'{0}': static types cannot be used as type arguments"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_GenericArgIsStaticClass, typeArgument)));
                return(false);
            }

            if (typeParameter.HasReferenceTypeConstraint && !typeArgument.IsReferenceType)
            {
                // "The type '{2}' must be a reference type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_RefConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return(false);
            }

            if (typeParameter.HasValueTypeConstraint && !typeArgument.IsNonNullableValueType())
            {
                // "The type '{2}' must be a non-nullable value type in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_ValConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return(false);
            }

            // The type parameters for a constructed type/method are the type parameters of
            // the ConstructedFrom type/method, so the constraint types are not substituted.
            // For instance with "class C<T, U> where T : U", the type parameter for T in "C<object, int>"
            // has constraint "U", not "int". We need to substitute the constraints from the
            // original definition of the type parameters using the map from the constructed symbol.
            var constraintTypes = ArrayBuilder <TypeSymbol> .GetInstance();

            HashSet <DiagnosticInfo> useSiteDiagnostics = null;

            substitution.SubstituteTypesDistinctWithoutModifiers(typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics), constraintTypes);

            bool hasError = false;

            foreach (var constraintType in constraintTypes)
            {
                if (SatisfiesConstraintType(conversions, typeArgument, constraintType, ref useSiteDiagnostics))
                {
                    continue;
                }

                ErrorCode errorCode;
                if (typeArgument.IsReferenceType)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedRefType;
                }
                else if (typeArgument.IsNullableType())
                {
                    errorCode = constraintType.IsInterfaceType() ? ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface : ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum;
                }
                else if (typeArgument.TypeKind == TypeKind.TypeParameter)
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar;
                }
                else
                {
                    errorCode = ErrorCode.ERR_GenericConstraintNotSatisfiedValType;
                }

                SymbolDistinguisher distinguisher = new SymbolDistinguisher(currentCompilation, constraintType, typeArgument);
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(errorCode, containingSymbol.ConstructedFrom(), distinguisher.First, typeParameter, distinguisher.Second)));
                hasError = true;
            }

            if (AppendUseSiteDiagnostics(useSiteDiagnostics, typeParameter, ref useSiteDiagnosticsBuilder))
            {
                hasError = true;
            }

            constraintTypes.Free();

            // Check the constructor constraint.
            if (typeParameter.HasConstructorConstraint && !SatisfiesConstructorConstraint(typeArgument))
            {
                // "'{2}' must be a non-abstract type with a public parameterless constructor in order to use it as parameter '{1}' in the generic type or method '{0}'"
                diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new CSDiagnosticInfo(ErrorCode.ERR_NewConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument)));
                return(false);
            }

            return(!hasError);
        }
Esempio n. 31
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(Parameters, diagnostics, modifyCompilationForRefReadOnly: true);
        }
        internal sealed override void AfterAddingTypeMembersChecks(
            ConversionsBase conversions,
            BindingDiagnosticBag diagnostics
            )
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            var compilation = DeclaringCompilation;

            this.ReturnType.CheckAllConstraints(
                compilation,
                conversions,
                this.Locations[0],
                diagnostics
                );

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(
                    compilation,
                    conversions,
                    parameter.Locations[0],
                    diagnostics
                    );
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(
                compilation,
                Parameters,
                diagnostics,
                modifyCompilation: true
                );

            if (ReturnType.ContainsNativeInteger())
            {
                compilation.EnsureNativeIntegerAttributeExists(
                    diagnostics,
                    ReturnTypeLocation,
                    modifyCompilation: true
                    );
            }

            ParameterHelpers.EnsureNativeIntegerAttributeExists(
                compilation,
                Parameters,
                diagnostics,
                modifyCompilation: true
                );

            if (
                compilation.ShouldEmitNullableAttributes(this) &&
                ReturnTypeWithAnnotations.NeedsNullableAttribute()
                )
            {
                compilation.EnsureNullableAttributeExists(
                    diagnostics,
                    ReturnTypeLocation,
                    modifyCompilation: true
                    );
            }

            ParameterHelpers.EnsureNullableAttributeExists(
                compilation,
                this,
                Parameters,
                diagnostics,
                modifyCompilation: true
                );
        }
 protected abstract void CheckConstraintsForExplicitInterfaceType(ConversionsBase conversions, BindingDiagnosticBag diagnostics);
Esempio n. 34
0
 internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
 {
     this.CheckModifiersAndType(diagnostics);
     this.Type.CheckAllConstraints(conversions, this.Locations[0], diagnostics);
 }
Esempio n. 35
0
        public static bool CheckConstraints(
            this MethodSymbol method,
            ConversionsBase conversions,
            CSharpSyntaxNode syntaxNode,
            Compilation currentCompilation,
            DiagnosticBag diagnostics,
            BitVector skipParameters = default(BitVector))
        {
            if (!RequiresChecking(method))
            {
                return true;
            }

            var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
            ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = CheckMethodConstraints(method, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder, skipParameters);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                var location = new SourceLocation(syntaxNode);
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();
            return result;
        }
Esempio n. 36
0
        public static bool CheckConstraints(
            this NamedTypeSymbol type,
            ConversionsBase conversions,
            SyntaxNode typeSyntax,
            SeparatedSyntaxList<TypeSyntax> typeArgumentsSyntax, // may be omitted in synthesized invocations
            Compilation currentCompilation,
            ConsList<Symbol> basesBeingResolved,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(typeArgumentsSyntax.Count == 0 /*omitted*/ || typeArgumentsSyntax.Count == type.Arity);
            if (!RequiresChecking(type))
            {
                return true;
            }

            var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
            ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = !typeSyntax.HasErrors && CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                int ordinal = pair.TypeParameter.Ordinal;
                var location = new SourceLocation(ordinal < typeArgumentsSyntax.Count ? typeArgumentsSyntax[ordinal] : typeSyntax);
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();

            if (HasDuplicateInterfaces(type, basesBeingResolved))
            {
                result = false;
                diagnostics.Add(ErrorCode.ERR_BogusType, typeSyntax.Location, type);
            }

            return result;
        }
Esempio n. 37
0
        public static bool CheckConstraints(
            this NamedTypeSymbol type,
            CSharpCompilation currentCompilation,
            ConversionsBase conversions,
            Location location,
            DiagnosticBag diagnostics)
        {
            if (!RequiresChecking(type))
            {
                return true;
            }

            var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
            ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();

            // we only check for distinct interfaces when the type is not from source, as we
            // trust that types that are from source have already been checked by the compiler
            // to prevent this from happening in the first place.
            if (!(currentCompilation != null && type.IsFromCompilation(currentCompilation)) && HasDuplicateInterfaces(type, null))
            {
                result = false;
                diagnostics.Add(ErrorCode.ERR_BogusType, location, type);
            }

            return result;
        }
Esempio n. 38
0
        /// <summary>
        /// Returns true if type a is encompassed by type b (spec 6.4.3),
        /// and returns false otherwise.
        /// </summary>
        private static bool IsEncompassedBy(ConversionsBase conversions, TypeSymbol a, TypeSymbol b, ref HashSet<DiagnosticInfo> useSiteDiagnostics)
        {
            Debug.Assert(IsValidEncompassedByArgument(a));
            Debug.Assert(IsValidEncompassedByArgument(b));

            return conversions.HasIdentityOrImplicitReferenceConversion(a, b, ref useSiteDiagnostics) || conversions.HasBoxingConversion(a, b, ref useSiteDiagnostics);
        }
Esempio n. 39
0
 private static bool CheckTypeConstraints(
     NamedTypeSymbol type,
     ConversionsBase conversions,
     Compilation currentCompilation,
     ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder,
     ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
 {
     return CheckConstraints(
         type,
         conversions,
         type.TypeSubstitution,
         type.OriginalDefinition.TypeParameters,
         type.TypeArgumentsNoUseSiteDiagnostics,
         currentCompilation,
         diagnosticsBuilder,
         ref useSiteDiagnosticsBuilder);
 }
 protected sealed override void CheckConstraintsForExplicitInterfaceType(ConversionsBase conversions, DiagnosticBag diagnostics)
 {
 }
Esempio n. 41
0
        /// <summary>
        /// Check type parameter constraints for the containing type or method symbol.
        /// </summary>
        /// <param name="containingSymbol">The generic type or method.</param>
        /// <param name="conversions">Conversions instance.</param>
        /// <param name="substitution">The map from type parameters to type arguments.</param>
        /// <param name="typeParameters">Containing symbol type parameters.</param>
        /// <param name="typeArguments">Containing symbol type arguments.</param>
        /// <param name="currentCompilation">Improves error message detail.</param>
        /// <param name="diagnosticsBuilder">Diagnostics.</param>
        /// <param name="skipParameters">Parameters to skip.</param>
        /// <param name="useSiteDiagnosticsBuilder"/>
        /// <param name="ignoreTypeConstraintsDependentOnTypeParametersOpt">If an original form of a type constraint 
        /// depends on a type parameter from this set, do not verify this type constraint.</param>
        /// <returns>True if the constraints were satisfied, false otherwise.</returns>
        public static bool CheckConstraints(
            this Symbol containingSymbol,
            ConversionsBase conversions,
            TypeMap substitution,
            ImmutableArray<TypeParameterSymbol> typeParameters,
            ImmutableArray<TypeSymbol> typeArguments,
            Compilation currentCompilation,
            ArrayBuilder<TypeParameterDiagnosticInfo> diagnosticsBuilder,
            ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder,
            BitVector skipParameters = default(BitVector),
            HashSet<TypeParameterSymbol> ignoreTypeConstraintsDependentOnTypeParametersOpt = null)
        {
            Debug.Assert(typeParameters.Length == typeArguments.Length);
            Debug.Assert(typeParameters.Length > 0);

            int n = typeParameters.Length;
            bool succeeded = true;

            for (int i = 0; i < n; i++)
            {
                if (skipParameters[i])
                {
                    continue;
                }

                var typeArgument = typeArguments[i];
                var typeParameter = typeParameters[i];

                if (!CheckConstraints(containingSymbol, conversions, substitution, typeParameter, typeArgument, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder,
                                      ignoreTypeConstraintsDependentOnTypeParametersOpt))
                {
                    succeeded = false;
                }
            }

            return succeeded;
        }
Esempio n. 42
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            base.AfterAddingTypeMembersChecks(conversions, diagnostics);

            if ((object)_explicitInterfaceType != null)
            {
                var explicitInterfaceSpecifier = this.ExplicitInterfaceSpecifier;
                Debug.Assert(explicitInterfaceSpecifier != null);
                _explicitInterfaceType.CheckAllConstraints(conversions, new SourceLocation(explicitInterfaceSpecifier.Name), diagnostics);
            }
        }
Esempio n. 43
0
        private static bool SatisfiesConstraintType(
            ConversionsBase conversions,
            TypeSymbol typeArgument,
            TypeSymbol constraintType,
            ref HashSet<DiagnosticInfo> useSiteDiagnostics)
        {
            if (constraintType.IsErrorType())
            {
                return false;
            }

            // Spec 4.4.4 describes the valid conversions from
            // type argument A to constraint type C:

            // "An identity conversion (6.1.1).
            // An implicit reference conversion (6.1.6). ..."
            if (conversions.HasIdentityOrImplicitReferenceConversion(typeArgument, constraintType, ref useSiteDiagnostics))
            {
                return true;
            }

            // "... A boxing conversion (6.1.7), provided that type A is a non-nullable value type. ..."
            // NOTE: we extend this to allow, for example, a conversion from Nullable<T> to object.
            if (typeArgument.IsValueType &&
                conversions.HasBoxingConversion(typeArgument.IsNullableType() ? ((NamedTypeSymbol)typeArgument).ConstructedFrom : typeArgument, constraintType, ref useSiteDiagnostics))
            {
                return true;
            }

            if (typeArgument.TypeKind == TypeKind.TypeParameter)
            {
                var typeParameter = (TypeParameterSymbol)typeArgument;

                // "... An implicit reference, boxing, or type parameter conversion
                // from type parameter A to C."
                if (conversions.HasImplicitTypeParameterConversion(typeParameter, constraintType, ref useSiteDiagnostics))
                {
                    return true;
                }

                // TypeBind::SatisfiesBound allows cases where one of the
                // type parameter constraints satisfies the constraint.
                foreach (var typeArgumentConstraint in typeParameter.ConstraintTypesWithDefinitionUseSiteDiagnostics(ref useSiteDiagnostics))
                {
                    if (SatisfiesConstraintType(conversions, typeArgumentConstraint, constraintType, ref useSiteDiagnostics))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
Esempio n. 44
0
 private static void CheckEffectiveAndDeducedBaseTypes(ConversionsBase conversions, TypeSymbol effectiveBase, TypeSymbol deducedBase)
 {
     Debug.Assert((object)deducedBase != null);
     Debug.Assert((object)effectiveBase != null);
     HashSet<DiagnosticInfo> useSiteDiagnostics = null;
     Debug.Assert(deducedBase.IsErrorType() ||
         effectiveBase.IsErrorType() ||
         conversions.HasIdentityOrImplicitReferenceConversion(deducedBase, effectiveBase, ref useSiteDiagnostics) ||
         conversions.HasBoxingConversion(deducedBase, effectiveBase, ref useSiteDiagnostics));
 }
Esempio n. 45
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // property name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            if ((object)_explicitInterfaceType != null)
            {
                var explicitInterfaceSpecifier = GetExplicitInterfaceSpecifier(this.CSharpSyntaxNode);
                Debug.Assert(explicitInterfaceSpecifier != null);
                _explicitInterfaceType.CheckAllConstraints(conversions, new SourceLocation(explicitInterfaceSpecifier.Name), diagnostics);
            }
        }
Esempio n. 46
0
        internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
        {
            // Check constraints on return type and parameters. Note: Dev10 uses the
            // method name location for any such errors. We'll do the same for return
            // type errors but for parameter errors, we'll use the parameter location.

            if ((object)_explicitInterfaceType != null)
            {
                var syntax = this.GetSyntax();
                Debug.Assert(syntax.ExplicitInterfaceSpecifier != null);
                _explicitInterfaceType.CheckAllConstraints(conversions, new SourceLocation(syntax.ExplicitInterfaceSpecifier.Name), diagnostics);
            }

            this.ReturnType.CheckAllConstraints(conversions, this.Locations[0], diagnostics);

            foreach (var parameter in this.Parameters)
            {
                parameter.Type.CheckAllConstraints(conversions, parameter.Locations[0], diagnostics);
            }

            var implementingPart = this.SourcePartialImplementation;
            if ((object)implementingPart != null)
            {
                PartialMethodChecks(this, implementingPart, diagnostics);
            }
        }
Esempio n. 47
0
 internal override void AfterAddingTypeMembersChecks(ConversionsBase conversions, DiagnosticBag diagnostics)
 {
     this.CheckModifiersAndType(diagnostics);
     this.Type.CheckAllConstraints(conversions, this.Locations[0], diagnostics);
 }
Esempio n. 48
0
        public static bool CheckConstraints(
            this NamedTypeSymbol type,
            ConversionsBase conversions,
            CSharpSyntaxNode typeSyntax,
            SeparatedSyntaxList<TypeSyntax> typeArgumentsSyntax,
            Compilation currentCompilation,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(typeArgumentsSyntax.Count == type.Arity);
            if (!RequiresChecking(type))
            {
                return true;
            }

            var diagnosticsBuilder = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
            ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
            var result = CheckTypeConstraints(type, conversions, currentCompilation, diagnosticsBuilder, ref useSiteDiagnosticsBuilder);

            if (useSiteDiagnosticsBuilder != null)
            {
                diagnosticsBuilder.AddRange(useSiteDiagnosticsBuilder);
            }

            foreach (var pair in diagnosticsBuilder)
            {
                int ordinal = pair.TypeParameter.Ordinal;
                var location = new SourceLocation(typeArgumentsSyntax[ordinal]);
                diagnostics.Add(new CSDiagnostic(pair.DiagnosticInfo, location));
            }

            diagnosticsBuilder.Free();

            if (!InterfacesAreDistinct(type))
            {
                result = false;
                diagnostics.Add(ErrorCode.ERR_BogusType, typeSyntax.Location, type);
            }

            return result;
        }