First off, we should be clear what we mean by "guarantee". When you're talking about Rust, "guarantee" means "the compiler enforces this in an ironclad way, such that the programmer
cannot mess it up" (generally with the implied caveat that we assume unsafe is not used). C++ programmers generally use "guarantee" to mean "the standard says you
should follow these rules", because as the language is not type-safe the compiler is in general unable to enforce much of anything that is interesting, making the Rust sense of the word "guarantee" not a particularly useful concept in that language. Confusion between these two meanings of "guarantee" (along with related concepts like "safe") has resulted in a lot of misunderstandings over the years.
Bearing this in mind, neither concepts in C++ nor traits in Rust guarantee any semantics in the Rust sense of the word. In the C++ sense of the word, C++ concepts do carry guarantees, in that the spec says what they should do. But, in this sense, so does Rust: PartialEq [1], for example, has semantic requirements spelled out in the documentation. In my mind, the difference is that Rust programmers tend to program defensively, not trusting programmers to get things right that the compiler doesn't enforce. Thus you see a lot of conversations along the lines of "what if the implementer of trait X does something weird?" in the Rust space. This may give the impression that Rust traits don't have a clear and consistent semantics associated with them. But that's not right: the implementer of PartialOrd, for example, is absolutely expected to implement a proper partial order, as explained in the documentation. A specification for Rust could specify associated semantics for those traits, just like in C++.
[1]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html