/// <summary> /// Tries to generate an instance shim mapping a concept method to /// one on the given default struct. /// </summary> /// <param name="concept"> /// The concept containing the default struct. /// </param> /// <param name="conceptMethod"> /// The concept method we're implementing on an instance with a shim. /// </param> /// <param name="diagnostics"> /// A diagnostics set, to which we report default struct failures. /// </param> /// <returns> /// Null if we couldn't synthesize a shim; otherwise, the created shim. /// The shim might not be valid: this must be checked before acceptance. /// </returns> private SynthesizedDefaultShimMethod TrySynthesizeDefaultShim(NamedTypeSymbol concept, MethodSymbol conceptMethod, DiagnosticBag diagnostics) { var dstr = concept.GetDefaultStruct(); if (dstr == null) { return(null); } // Default-struct sanity checking var conceptLoc = concept.Locations.IsEmpty ? Location.None : Locations[0]; var instanceLoc = Locations.IsEmpty ? Location.None : Locations[0]; if (dstr.Arity != 1) { // Don't use the default struct's location: it is an // implementation detail and may not actually exist. diagnostics.Add(ErrorCode.ERR_DefaultStructBadArity, conceptLoc, concept.Name, dstr.Arity, concept.Arity + 1); return(null); } var witnessPar = dstr.TypeParameters[0]; if (!witnessPar.IsConceptWitness) { diagnostics.Add(ErrorCode.ERR_DefaultStructNoWitnessParam, conceptLoc, concept.Name); return(null); } return(new SynthesizedDefaultShimMethod(conceptMethod, dstr, this)); }