Ergonomics of wrapping operations

I would still be opposed to this solution, even restricted to functions and blocks. I really don't like the idea of changing code semantics based on attributes. It makes it easy to make mistakes such as copy-pasting code that suddenly has a different meaning, not checking operations that should be checked because they're in a #[wrapping] function and one either forgets or finds it too unergonomic to explicitly use debug-checked operations for the block, etc.

It could also be confusing to figure out to what, exactly, it applies. I'll echo @Gankra, here. Does it apply to operations provided by methods (like pow)? Or the potential cast method discussed in this thread? (Probably not for either of those cases, but one could be forgiven for expecting otherwise.) What about using an operator like + on custom types? You proposal seems to suggest that it would call wrapping_add instead of add, which may or may not be surprising, depending on the type. What if a type implements Add but not WrappingAdd? does the operator fall-back? (Again, this may or may not be desirable, depending on the type and its semantics.) Is it a compile error?

Finally, I still don't like the risk for ambiguity between "for performance" and "semantically want wrapping".

I do think it would be worth while to have a attributes to enable and disable overflow checking for different regions in optimized builds (debug would still check, or at least have the option to) to tweak security vs performance trade-offs, but I think that can probably wait until more optimized "release-mode" checks are available (potentially aggregating checks, skipping checks for values that won't be used, potentially not checking overflow for parts expressions where the final result is guaranteed to be correct, etc.).