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)) { diagnostics.Add(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, location, @interface, this); } else if (other.Equals(@interface, TypeCompareKind.IgnoreTupleNames)) { 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) { ImplementListSyntax implements = GetImplementListOpt(decl); if (implements != null) { var baseBinder = this.DeclaringCompilation.GetBinder(implements); // Wrap base binder in a location-specific binder that will avoid generic constraint checks. baseBinder = baseBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); foreach (var baseTypeSyntax in implements.Types) { var b = baseTypeSyntax.Type; var tmpDiag = DiagnosticBag.GetInstance(); var curBaseSym = baseBinder.BindType(b, tmpDiag).TypeSymbol; tmpDiag.Free(); if (baseSym.Equals(curBaseSym)) { return(new SourceLocation(b)); } } } } return(null); }
internal override bool Equals(TypeSymbol t2, TypeCompareKind comparison) { 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)); }