From 94330b7796b80fca17682ccc2559008ed15be6d7 Mon Sep 17 00:00:00 2001
From: David Pedersen <david.pdrsn@gmail.com>
Date: Tue, 26 Oct 2021 22:44:16 +0200
Subject: [PATCH] Panic if routing to router (#427)

This panics if you pass a `Router` to `Router::route`. Thats invalid and
will result in unreachable routes.

Unfortunately I don't think we can make it a type error while supporting
general `Service`s. So I think this is a decent workaround.

Fixes https://github.com/tokio-rs/axum/issues/174
---
 src/routing/mod.rs | 7 +++++++
 src/tests/mod.rs   | 8 ++++++++
 2 files changed, 15 insertions(+)

diff --git a/src/routing/mod.rs b/src/routing/mod.rs
index 3167a3a9..22ee12d5 100644
--- a/src/routing/mod.rs
+++ b/src/routing/mod.rs
@@ -197,6 +197,13 @@ where
             panic!("Invalid route: empty path");
         }
 
+        let svc = match try_downcast::<Router<B>, _>(svc) {
+            Ok(_) => {
+                panic!("Invalid route: `Router::route` cannot be used with `Router`s. Use `Router::nest` instead")
+            }
+            Err(svc) => svc,
+        };
+
         let id = RouteId::next();
 
         if let Err(err) = self.node.insert(path, id) {
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index fc6c314b..f15b2e93 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -751,6 +751,14 @@ async fn middleware_still_run_for_unmatched_requests() {
     assert_eq!(COUNT.load(Ordering::SeqCst), 2);
 }
 
+#[tokio::test]
+#[should_panic(
+    expected = "Invalid route: `Router::route` cannot be used with `Router`s. Use `Router::nest` instead"
+)]
+async fn routing_to_router_panics() {
+    TestClient::new(Router::new().route("/", Router::new()));
+}
+
 pub(crate) fn assert_send<T: Send>() {}
 pub(crate) fn assert_sync<T: Sync>() {}
 pub(crate) fn assert_unpin<T: Unpin>() {}