+ var pending = new PendingImplementation (container, missing_interfaces, abstract_methods, total);
+
+ //
+ // check for inherited conflicting methods
+ //
+ foreach (var p in pending.pending_implementations) {
+ //
+ // It can happen for generic interfaces only
+ //
+ if (!p.type.IsGeneric)
+ continue;
+
+ //
+ // CLR does not distinguishes between ref and out
+ //
+ for (int i = 0; i < p.methods.Count; ++i) {
+ MethodSpec compared_method = p.methods[i];
+ if (compared_method.Parameters.IsEmpty)
+ continue;
+
+ for (int ii = i + 1; ii < p.methods.Count; ++ii) {
+ MethodSpec tested_method = p.methods[ii];
+ if (compared_method.Name != tested_method.Name)
+ continue;
+
+ if (p.type != tested_method.DeclaringType)
+ continue;
+
+ if (!TypeSpecComparer.Override.IsSame (compared_method.Parameters.Types, tested_method.Parameters.Types))
+ continue;
+
+ bool exact_match = true;
+ bool ref_only_difference = false;
+ var cp = compared_method.Parameters.FixedParameters;
+ var tp = tested_method.Parameters.FixedParameters;
+
+ for (int pi = 0; pi < cp.Length; ++pi) {
+ //
+ // First check exact modifiers match
+ //
+ if ((cp[pi].ModFlags & Parameter.Modifier.RefOutMask) == (tp[pi].ModFlags & Parameter.Modifier.RefOutMask))
+ continue;
+
+ if (((cp[pi].ModFlags | tp[pi].ModFlags) & Parameter.Modifier.RefOutMask) == Parameter.Modifier.RefOutMask) {
+ ref_only_difference = true;
+ continue;
+ }
+
+ exact_match = false;
+ break;
+ }
+
+ if (!exact_match || !ref_only_difference)
+ continue;
+
+ pending.Report.SymbolRelatedToPreviousError (compared_method);
+ pending.Report.SymbolRelatedToPreviousError (tested_method);
+ pending.Report.Error (767, container.Location,
+ "Cannot implement interface `{0}' with the specified type parameters because it causes method `{1}' to differ on parameter modifiers only",
+ p.type.GetDefinition().GetSignatureForError (), compared_method.GetSignatureForError ());
+
+ break;
+ }
+ }
+ }
+
+ return pending;