Challenge 3: What Concepts Change About Where Requirements Are Checked, and Why Rust Never Needed a Retrofit — Possible Solution ==================================================================== Before C++20, per cpp2-1's own material, a template's actual requirements on its type parameter (e.g. "T must support operator>") were never stated anywhere explicit -- they existed only implicitly, as whatever operations the template's BODY happened to use. If a caller instantiated the template with a type that didn't support one of those operations, the compiler would only discover the mismatch while trying to compile the template's own body FOR THAT SPECIFIC TYPE -- deep inside the instantiation, often producing a long, nested error originating from wherever inside the template body the unsupported operation was used, frequently obscuring the ACTUAL call site that triggered the whole problem. C++20 concepts change WHERE this check happens: a concept like `Addable` is declared explicitly, stating up front exactly what operations a valid T must support, and the template's own declaration (`template`) states this requirement directly in its signature. The compiler can now check whether a given T satisfies the concept BEFORE ever attempting to instantiate the template's body -- so if the requirement isn't met, the error is reported right at the CALL SITE, naming the unmet concept directly, rather than surfacing from deep inside a body the caller never wrote and may not have even looked at. Why Rust never needed an equivalent feature added later: per the chapter, Rust's trait bounds (`fn sum(...)`) have expressed generic constraints explicitly, in the function's own signature, since Rust's very first stable release -- this was simply how Rust's generics were designed from the start, not a capability retrofitted after users encountered years of confusing errors from an earlier, unconstrained design (the way C++ templates existed for roughly two decades before concepts arrived). Rust's compiler has always been able to check a generic function's constraints against its bounds before ever monomorphizing the body for a specific type, because those bounds were always a required, explicit part of the signature -- there was no earlier, weaker design that concepts needed to "catch up to," the way C++20 concepts caught up to a gap templates had carried since 1998. WHY THIS WORKS AS AN ANSWER ------------------------------ This explains precisely WHERE the check moves to (from deep inside instantiation to the call site, via an explicit up-front declaration) rather than a vague "concepts make errors better," and explains WHY Rust never needed a later retrofit by pointing to trait bounds being part of the language's ORIGINAL design rather than an addition correcting an earlier gap.