protected override void CheckInterfaces(DiagnosticBag diagnostics) { // Check declared interfaces and all base interfaces. This is necessary // since references to all interfaces will be emitted to metadata // and it's possible to define derived interfaces with weaker // constraints than the base interfaces, at least in metadata. var interfaces = this.InterfacesAndTheirBaseInterfacesNoUseSiteDiagnostics; if (interfaces.IsEmpty) { // nothing to verify return; } // Check constraints on the first declaration with explicit bases. var singleDeclaration = this.FirstDeclarationWithExplicitBases(); if (singleDeclaration != null) { var corLibrary = this.ContainingAssembly.CorLibrary; var conversions = new TypeConversions(corLibrary); var location = singleDeclaration.NameLocation; foreach (var pair in interfaces) { MultiDictionary <NamedTypeSymbol, NamedTypeSymbol> .ValueSet set = pair.Value; foreach (var @interface in set) { @interface.CheckAllConstraints(DeclaringCompilation, conversions, location, diagnostics); } if (set.Count > 1) { NamedTypeSymbol other = pair.Key; foreach (var @interface in set) { if ((object)other == @interface) { continue; } Debug.Assert(!other.Equals(@interface, TypeCompareKind.ConsiderEverything)); if (other.Equals(@interface, TypeCompareKind.IgnoreNullableModifiersForReferenceTypes)) { if (!other.Equals(@interface, TypeCompareKind.ObliviousNullableModifierMatchesAny)) { diagnostics.Add(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, location, @interface, this); } } else if (other.Equals(@interface, TypeCompareKind.IgnoreTupleNames | TypeCompareKind.IgnoreNullableModifiersForReferenceTypes)) { diagnostics.Add(ErrorCode.ERR_DuplicateInterfaceWithTupleNamesInBaseList, location, @interface, other, this); } } } } } }
// finds syntax location where given type was inherited // should be used for error reporting on unexpected inherited types. private SourceLocation FindBaseRefSyntax(NamedTypeSymbol baseSym) { foreach (var decl in this.declaration.Declarations) { BaseListSyntax bases = GetBaseListOpt(decl); if (bases != null) { var baseBinder = this.DeclaringCompilation.GetBinder(bases); // Wrap base binder in a location-specific binder that will avoid generic constraint checks. baseBinder = baseBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); foreach (var baseTypeSyntax in bases.Types) { var b = baseTypeSyntax.Type; var tmpDiag = DiagnosticBag.GetInstance(); var curBaseSym = baseBinder.BindType(b, tmpDiag); tmpDiag.Free(); if (baseSym.Equals(curBaseSym)) { return(new SourceLocation(b)); } } } } return(null); }
public TupleElementFieldSymbol( NamedTypeSymbol container, FieldSymbol underlyingField, int tupleElementIndex, ImmutableArray<Location> locations, bool isImplicitlyDeclared, FieldSymbol? correspondingDefaultFieldOpt = null) : base(underlyingField) { Debug.Assert(tupleElementIndex >= 0); Debug.Assert(container.Equals(underlyingField.ContainingType, TypeCompareKind.IgnoreDynamicAndTupleNames) || this is TupleVirtualElementFieldSymbol, "virtual fields should be represented by " + nameof(TupleVirtualElementFieldSymbol)); Debug.Assert(!(underlyingField is TupleElementFieldSymbol)); // The fields on definition of ValueTuple<...> types don't need to be wrapped Debug.Assert(!container.IsDefinition); Debug.Assert(container.IsTupleType); _containingTuple = container; _tupleElementIndex = correspondingDefaultFieldOpt is null ? tupleElementIndex << 1 : (tupleElementIndex << 1) + 1; Debug.Assert(!locations.IsDefault); _locations = locations; _isImplicitlyDeclared = isImplicitlyDeclared; _correspondingDefaultField = correspondingDefaultFieldOpt ?? this; }
internal NativeIntegerTypeSymbol(NamedTypeSymbol underlyingType) : base(underlyingType, tupleData: null) { Debug.Assert(underlyingType.TupleData is null); Debug.Assert(!underlyingType.IsNativeIntegerType); Debug.Assert(underlyingType.SpecialType == SpecialType.System_IntPtr || underlyingType.SpecialType == SpecialType.System_UIntPtr); Debug.Assert(this.Equals(underlyingType)); Debug.Assert(underlyingType.Equals(this)); }
public TupleFieldSymbol(NamedTypeSymbol container, FieldSymbol underlyingField, int tupleElementIndex) : base(underlyingField) { Debug.Assert(container.IsTupleType); Debug.Assert(container.Equals(underlyingField.ContainingType, TypeCompareKind.IgnoreDynamicAndTupleNames) || this is TupleVirtualElementFieldSymbol, "virtual fields should be represented by " + nameof(TupleVirtualElementFieldSymbol)); _containingTuple = container; _tupleElementIndex = tupleElementIndex; }
internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) { if (ReferenceEquals(this, t2)) { return(true); } var other = t2 as Nested; #if XSHARP return((object)other != null && XSharpString.Equals(MetadataName, other.MetadataName) && arity == other.arity && _containingType.Equals(other._containingType, comparison)); #else return((object)other != null && string.Equals(MetadataName, other.MetadataName, StringComparison.Ordinal) && arity == other.arity && _containingType.Equals(other._containingType, comparison)); #endif }
internal override bool Equals(TypeSymbol t2, bool ignoreCustomModifiers, bool ignoreDynamic) { if (ReferenceEquals(this, t2)) { return(true); } var other = t2 as Nested; return((object)other != null && string.Equals(MetadataName, other.MetadataName, StringComparison.Ordinal) && arity == other.arity && containingType.Equals(other.containingType, ignoreCustomModifiers, ignoreDynamic)); }
internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison, IReadOnlyDictionary <TypeParameterSymbol, bool>?isValueTypeOverrideOpt = null) { if (ReferenceEquals(this, t2)) { return(true); } var other = t2 as Nested; return((object?)other != null && string.Equals(MetadataName, other.MetadataName, StringComparison.Ordinal) && arity == other.arity && _containingType.Equals(other._containingType, comparison, isValueTypeOverrideOpt)); }
private readonly bool _cannotUse; // With LanguageVersion 7, we will produce named elements that should not be used public TupleVirtualElementFieldSymbol( NamedTypeSymbol container, FieldSymbol underlyingField, string name, int tupleElementIndex, ImmutableArray <Location> locations, bool cannotUse, bool isImplicitlyDeclared, FieldSymbol?correspondingDefaultFieldOpt ) : base( container, underlyingField, tupleElementIndex, locations, isImplicitlyDeclared, correspondingDefaultFieldOpt ) { // The underlying field for 'Hanna' (an 8-th named element) in a long tuple is Item1. The corresponding field is Item8. Debug.Assert(container.IsTupleType); Debug.Assert(underlyingField.ContainingType.IsTupleType); Debug.Assert(name != null); Debug.Assert( name != underlyingField.Name || !container.Equals( underlyingField.ContainingType, TypeCompareKind.IgnoreDynamicAndTupleNames ), "fields that map directly to underlying should not be represented by " + nameof(TupleVirtualElementFieldSymbol) ); Debug.Assert( (correspondingDefaultFieldOpt is null) == (NamedTypeSymbol.TupleMemberName(tupleElementIndex + 1) == name) ); Debug.Assert(!(correspondingDefaultFieldOpt is TupleErrorFieldSymbol)); _name = name; _cannotUse = cannotUse; }
// finds syntax location where given type was inherited // should be used for error reporting on unexpected inherited types. private SourceLocation FindBaseRefSyntax(NamedTypeSymbol baseSym) { foreach (var decl in this.declaration.Declarations) { BaseListSyntax bases = GetBaseListOpt(decl); if (bases != null) { var baseBinder = this.DeclaringCompilation.GetBinder(bases); // Wrap base binder in a location-specific binder that will avoid generic constraint checks. baseBinder = baseBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); foreach (var baseTypeSyntax in bases.Types) { var b = baseTypeSyntax.Type; var tmpDiag = DiagnosticBag.GetInstance(); var curBaseSym = baseBinder.BindType(b, tmpDiag); tmpDiag.Free(); if (baseSym.Equals(curBaseSym)) { return new SourceLocation(b); } } } } return null; }