/// <summary>
 /// Constructs a new SynthesizedDefaultStructSymbol.
 /// </summary>
 /// <param name="name">
 /// The name of the default struct.
 /// </param>
 /// <param name="concept">
 /// The parent concept of the default struct.
 /// </param>
 public SynthesizedDefaultStructSymbol(string name, SourceNamedTypeSymbol concept)
     : base(
         name,
         concept,
         that =>
         // We add a type parameter for the calling witness, so the
         // default struct can call back into it.
         ImmutableArray <TypeParameterSymbol> .Empty
         .Add(
             new SynthesizedWitnessParameterSymbol(
                 // @t-mawind
                 //   need to make this not clash with any typar in
                 //   the parent scopes, hence generated name.
                 GeneratedNames.WitnessTypeParameterName(),
                 Location.None,
                 0,
                 that,
                 _ => ImmutableArray.Create((TypeSymbol)concept),
                 _ => TypeParameterConstraintKind.ValueType
                 )
             ),
         TypeMap.Empty
         )
 {
 }
        /// <summary>
        /// Constructs a new <see cref="SynthesizedImplicitConceptMethodSymbol"/>.
        /// </summary>
        /// <param name="method">
        /// The concept method to wrap.
        /// </param>
        internal SynthesizedImplicitConceptMethodSymbol(MethodSymbol method)
            : base()
        {
            Debug.Assert(method.ReceiverType != null, "implicit concept method must have a receiver");
            Debug.Assert(method.ReceiverType.IsConceptOrStandaloneInstanceType(),
                         "must wrap a method taken from a concept or standalone instance");
            Debug.Assert(method.ReceiverType.Kind == SymbolKind.NamedType, "concept receiver should be a named type");
            _originalReceiver = (NamedTypeSymbol)method.ReceiverType;

            _method = method;

            var paramsB = ArrayBuilder <TypeParameterSymbol> .GetInstance();

            paramsB.AddRange(_method.TypeParameters);
            paramsB.AddRange(_originalReceiver.TypeParameters);

            var argsB = ArrayBuilder <TypeSymbol> .GetInstance();

            argsB.AddRange(_method.TypeArguments);
            argsB.AddRange(_originalReceiver.TypeArguments);

            if (_originalReceiver.IsConcept)
            {
                // To make sure that any concept inference on this method
                // pulls down the correct concept, we also add a concept
                // witness as an extra, synthesised, type parameter.
                var witnessOrdinal = _method.Arity + _originalReceiver.Arity;
                var witness        =
                    new SynthesizedWitnessParameterSymbol(
                        GeneratedNames.WitnessTypeParameterName(),
                        Location.None,
                        witnessOrdinal,
                        _method,
                        _ => ImmutableArray.Create((TypeSymbol)_originalReceiver),
                        _ => TypeParameterConstraintKind.ValueType);

                paramsB.Add(witness);
                argsB.Add(witness);
            }

            _typeParameters = paramsB.ToImmutableAndFree();
            _typeArguments  = argsB.ToImmutableAndFree();

            _arity = _typeArguments.Length;
        }