mirror of https://github.com/rwf2/Rocket.git
Make type macros inelgible as sentinels.
This commit is contained in:
parent
9ad4fb2781
commit
03d759ab90
|
@ -137,7 +137,7 @@ impl TypeExt for syn::Type {
|
|||
self.0 = false;
|
||||
return;
|
||||
}
|
||||
ImplTrait(_) | Infer(_) => {
|
||||
ImplTrait(_) | Infer(_) | Macro(_) => {
|
||||
self.0 = false;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -152,14 +152,14 @@ use crate::{Rocket, Ignite};
|
|||
///
|
||||
/// **Note:** _Rocket actively discourages using `impl Trait` in route
|
||||
/// signatures. In addition to impeding sentinel discovery, doing so decreases
|
||||
/// the ability to gleam handler functionality based on its type signature._
|
||||
/// the ability to gleam a handler's functionality based on its type signature._
|
||||
///
|
||||
/// The return type of the route `f` depends on its implementation. At present,
|
||||
/// it is not possible to name the underlying concrete type of an `impl Trait`
|
||||
/// at compile-time and thus not possible to determine if it implements
|
||||
/// `Sentinel`. As such, existentials _are not_ eligible to be sentinels. This
|
||||
/// limitation applies per embedded type: the directly named `AnotherSentinel`
|
||||
/// type continues to be eligible to be a sentinel.
|
||||
/// `Sentinel`. As such, existentials _are not_ eligible to be sentinels.
|
||||
/// However, this limitation applies per embedding, so the inner, directly named
|
||||
/// `AnotherSentinel` type continues to be eligible to be a sentinel.
|
||||
///
|
||||
/// When possible, prefer to name all types:
|
||||
///
|
||||
|
@ -202,6 +202,33 @@ use crate::{Rocket, Ignite};
|
|||
/// cases, a type alias _will_ "consider" embeddings. Nevertheless, prefer to
|
||||
/// write concrete types when possible.
|
||||
///
|
||||
/// ## Type Macros
|
||||
///
|
||||
/// It is impossible to determine, a priori, what a type macro will expand to.
|
||||
/// As such, Rocket is unable to determine which sentinels, if any, a type macro
|
||||
/// references, and thus no sentinels are discovered from type macros.
|
||||
///
|
||||
/// Even approximations are impossible. For example, consider the following:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use rocket::*;
|
||||
/// macro_rules! MyType {
|
||||
/// (State<'_, u32>) => (&'_ rocket::Config)
|
||||
/// }
|
||||
///
|
||||
/// #[get("/")]
|
||||
/// fn f(guard: MyType![State<'_, u32>]) {
|
||||
/// /* ... */
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// While the `MyType![State<'_, u32>]` type _appears_ to contain a `State`
|
||||
/// sentinel, the macro actually expands to `&'_ rocket::Config`, which is _not_
|
||||
/// the `State` sentinel.
|
||||
///
|
||||
/// You should prefer not to use type macros, or if necessary, restrict your use
|
||||
/// to those that always expand to types without sentinels.
|
||||
///
|
||||
/// # Custom Sentinels
|
||||
///
|
||||
/// Any type can implement `Sentinel`, and the implementation can arbitrarily
|
||||
|
|
Loading…
Reference in New Issue