diff --git a/JustDummies/ConstraintCall.cs b/JustDummies/ConstraintCall.cs index 18ab1835..a9aec59a 100644 --- a/JustDummies/ConstraintCall.cs +++ b/JustDummies/ConstraintCall.cs @@ -56,6 +56,27 @@ internal sealed class ConstraintCall : IEquatable { /// A constraint whose arguments are rendered, including the common case of a constraint that takes none — /// which is this factory called with no (Zero(), Distinct()). /// + /// + /// + /// takes rendered text — what the reader of a conflict message sees + /// between the parentheses — never a parameter name. Two shapes reach it. The ordinary one is a value the + /// declaring generator rendered itself (V(minimum), Join(values)), giving + /// Between(0, 100). The other is a word standing in for an argument that has no useful rendering, + /// written where it reads better than the ellipsis would give: + /// Distinct(comparer) for an equality, ContainingAny(<generator>) for a recipe. + /// + /// + /// Such a stand-in is passed as the literal it is, and nameof(...) does not belong here even when + /// the parameter it would name happens to spell it — Distinct(IEqualityComparer<T>) passes + /// "comparer", not nameof(comparer). The rule differs from 's on + /// purpose: a method name is a public symbol the message must follow through a rename, whereas a stand-in + /// is prose whose resemblance to a parameter is a coincidence of good naming. Tying it to the symbol would + /// let a rename local to one overload silently reword a user-facing message, and would leave the same + /// constraint reading differently across the generators declaring it as soon as two of them named their + /// parameter differently. <generator> is that same convention where no identifier could have + /// been mistaken for it. + /// + /// /// The declaring method's name, passed as nameof(...). /// The arguments, each already rendered by the declaring generator. /// The constraint, rendered as name(argument, argument).