-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bounds to constructors #916
Comments
Let me start by saying that I feel your pain. Unfortunately what you're suggesting isn't possible. One might try to add the necessary bounds to impl<F, T> HandleErrorLayer<F, T> {
pub fn new<S, B>(f: F) -> Self
where
Self: Layer<S>,
<Self as Layer<S>>::Service: Service<Request<B>>,
{
Self {
f,
_extractor: PhantomData,
}
}
} However using it in practice: #[tokio::main]
async fn main() {
let app = Router::new().layer(
ServiceBuilder::new()
.layer(HandleErrorLayer::new(handle_error))
// removing this line gives you another error that forces you to add this line
// so it doesn't change the outcome
.timeout(Duration::from_secs(30))
);
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn handle_error(_: BoxError) {} Gives an inference error:
You cannot just copy the bounds from the
You've missed a key part from the docs:
Now we could change the definition of pub struct Html<T>(pub T) where T: Into<Full<Bytes>>; Which if you tried to return something silly like error[E0277]: the trait bound `axum::body::Full<axum::body::Bytes>: From<bool>` is not satisfied
--> examples/hello-world/src/main.rs:24:34
|
24 | async fn handler() -> Html<bool> {
| __________________________________^
25 | | todo!()
26 | | }
| |_^ the trait `From<bool>` is not implemented for `axum::body::Full<axum::body::Bytes>`
|
= help: the following implementations were found:
<axum::body::Full<D> as From<&'static [u8]>>
<axum::body::Full<D> as From<&'static str>>
<axum::body::Full<D> as From<Cow<'static, B>>>
<axum::body::Full<D> as From<String>>
and 2 others
= note: required because of the requirements on the impl of `Into<axum::body::Full<axum::body::Bytes>>` for `bool`
note: required by a bound in `Html` I'm not sure whether that error is more helpful but However this cannot be done consistently. Consider Because of this, in Rust, its generally recommended to only add trait bounds where they're needed as this leads for more flexibility. For example Really I think the compiler should give better error messages for these cases. Until I've learned how to contribute the compiler and worked on this, we have tools like |
I think it may actually be worthwhile to specify the minimal generics on the type itself, though For Unfortunately, all of these things are breaking changes so they're unlikely to happen anytime soon. I still see this as a reasonable thing down the road though because it doesn't constrain in any way: Removing or relaxing the bounds again later is fully backwards-compatible. |
Thank you very much for giving such a detailed and easy to understand explanation. Indeed, I missed the docs and the compiler message didn't help a lot either. It just seemed weird to me the compiler was complaining about the function while the problem was something else. Also, I noticed this pattern of not adding bounds to structs themselves and never quite understand why, so I'm also grateful for your thorough explanation. I had no idea I will try the debug handler as suggested :) Edit: wording |
Yeah it might be worth while to add some minimal bounds where possible. It probably wont improve the error messages related to
Yep this isn't something can address without breakage and I'd like to wait with that since we just shipped 0.5 😊 |
I think I'll close this. People are welcome to submit PRs to improve this but I don't think its high priority. |
Feature Request
Motivation
Currently on axum, most generic types have unbounded constructors (e.g:
Html
,HandleErrorLayer
) but their relevant trait implementations (IntoResponse
forHtml
,Layer
forHandleErrorLayer
) have bounds, leaving confusing error messages when using them with non conforming types (such as using aCow<'a, str>
withHtml
).Proposal
Add redundant bounds to constructors, also making the transition easier when rust's Implied Trait Bounds land.
Example of Status Quo
Say I'm writing an error handling middleware. According to the docs, this could work:
However I get this error on line 8 which should appear on
HandleErrorLayer::new
instead:The text was updated successfully, but these errors were encountered: