From dd50de56e9fb68c60a800479972d0ebe637c1990 Mon Sep 17 00:00:00 2001 From: jofas Date: Sun, 28 Jan 2024 15:59:48 +0100 Subject: [PATCH] Moved 'explicitly typed values' section from README.md to src/lib.rs --- README.md | 52 --------------------------------------------- src/hashbrown.rs | 2 +- src/lib.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 6fa3305..4b827ed 100644 --- a/README.md +++ b/README.md @@ -25,57 +25,5 @@ let hello = hash_map! { }; ``` -## Explicitly Typed Values for Trait Objects - -As shown in the example above, the compiler uses type inference to infer the correct type -for the created map. -Unfortunately, type inference alone can not detect [trait objects][trait objects]. -This will not work, because the compiler is unable to figure out the right type: - -```compile_fail -use std::collections::HashMap; -use std::fmt::Debug; - -use map_macro::hash_map; - -let hello: HashMap<&str, &dyn Debug> = hash_map! { - "en" => &"Hello", - "de" => &"Hallo", - "fr" => &"Bonjour", - "es" => &"Hola", -}; -``` - -The `map_e!` macro enables you to use trait objects as values through -[type coercion][type coercion], making the example above compile successfully: - -```rust -use std::collections::HashMap; -use std::fmt::Debug; - -use map_macro::hash_map_e; - -let hello: HashMap<&str, &dyn Debug> = hash_map_e! { - "en" => &"Hello", - "de" => &"Hallo", - "fr" => &"Bonjour", - "es" => &"Hola", -}; -``` - -Note that you need to give an explicit type to the binding when you use `map_e!`, because -it relies on knowing what type it should coerce the values to. -Also, only values and not keys can be trait objects, because keys must -implement the [`Hash`][hash] trait, which is not -[object safe][object safe]. - -Where the trait bounds on generic type parameters of the collections allow trait objects, -macros for explicitly typed variants are provided. -The explicitly typed versions of the macros are indicated by an `_e` suffix. - [std]: https://doc.rust-lang.org/std/collections/index.html -[trait objects]: https://doc.rust-lang.org/reference/types/trait-object.html -[type coercion]: https://doc.rust-lang.org/reference/type-coercions.html -[object safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety -[hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html [hashbrown]: https://docs.rs/hashbrown/latest/hashbrown/ diff --git a/src/hashbrown.rs b/src/hashbrown.rs index e8f1c50..a972bd4 100644 --- a/src/hashbrown.rs +++ b/src/hashbrown.rs @@ -17,7 +17,7 @@ //! **Note:** to be compatible with all versions of `hashbrown` at once, this //! crate doesn't re-export `hashbrown`, which means that if you rename //! `hashbrown` in your dependencies, the macros from this module won't be able -//! to import the types resulting in a compile-time error. +//! to import the needed types resulting in a compile-time error. //! /// Macro for creating a [`HashMap`](::hashbrown::HashMap). diff --git a/src/lib.rs b/src/lib.rs index c07940f..89edb41 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,59 @@ #![doc = include_str!("../README.md")] +//! +//! ## Explicitly Typed Values for Trait Objects +//! +//! As shown in the example above, the compiler uses type inference to infer the correct type +//! for the created map. +//! Unfortunately, type inference alone can not detect [trait objects][trait objects]. +//! This will not work, because the compiler is unable to figure out the right type: +//! +//! ```compile_fail +//! use std::collections::HashMap; +//! use std::fmt::Debug; +//! +//! use map_macro::hash_map; +//! +//! let hello: HashMap<&str, &dyn Debug> = hash_map! { +//! "en" => &"Hello", +//! "de" => &"Hallo", +//! "fr" => &"Bonjour", +//! "es" => &"Hola", +//! }; +//! ``` +//! +//! The `map_e!` macro enables you to use trait objects as values through +//! [type coercion][type coercion], making the example above compile successfully: +//! +//! ```rust +//! use std::collections::HashMap; +//! use std::fmt::Debug; +//! +//! use map_macro::hash_map_e; +//! +//! let hello: HashMap<&str, &dyn Debug> = hash_map_e! { +//! "en" => &"Hello", +//! "de" => &"Hallo", +//! "fr" => &"Bonjour", +//! "es" => &"Hola", +//! }; +//! ``` +//! +//! Note that you need to give an explicit type to the binding when you use `map_e!`, because +//! it relies on knowing what type it should coerce the values to. +//! Also, only values and not keys can be trait objects, because keys must +//! implement the [`Hash`][hash] trait, which is not +//! [object safe][object safe]. +//! +//! Where the trait bounds on generic type parameters of the collections allow trait objects, +//! macros for explicitly typed variants are provided. +//! The explicitly typed versions of the macros are indicated by an `_e` suffix. +//! +//! [trait objects]: https://doc.rust-lang.org/reference/types/trait-object.html +//! [type coercion]: https://doc.rust-lang.org/reference/type-coercions.html +//! [object safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety +//! [hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html +//! + #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![no_std]